mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 11:02:59 +02:00
reimplement BitcodeReaderValueList in terms of WeakVH instead of making
it be an LLVM IR User object. llvm-svn: 68156
This commit is contained in:
parent
87466e0995
commit
000abfca03
@ -146,64 +146,67 @@ namespace {
|
|||||||
|
|
||||||
|
|
||||||
/// Provide fast operand accessors
|
/// Provide fast operand accessors
|
||||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
//DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: can we inherit this from ConstantExpr?
|
||||||
// FIXME: can we inherit this from ConstantExpr?
|
|
||||||
template <>
|
template <>
|
||||||
struct OperandTraits<ConstantPlaceHolder> : FixedNumOperandTraits<1> {
|
struct OperandTraits<ConstantPlaceHolder> : FixedNumOperandTraits<1> {
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcodeReaderValueList::resize(unsigned Desired) {
|
|
||||||
if (Desired > Capacity) {
|
void BitcodeReaderValueList::AssignValue(Value *V, unsigned Idx) {
|
||||||
// Since we expect many values to come from the bitcode file we better
|
if (Idx == size()) {
|
||||||
// allocate the double amount, so that the array size grows exponentially
|
push_back(V);
|
||||||
// at each reallocation. Also, add a small amount of 100 extra elements
|
return;
|
||||||
// each time, to reallocate less frequently when the array is still small.
|
}
|
||||||
//
|
|
||||||
Capacity = Desired * 2 + 100;
|
if (Idx >= size())
|
||||||
Use *New = allocHungoffUses(Capacity);
|
resize(Idx+1);
|
||||||
Use *Old = OperandList;
|
|
||||||
unsigned Ops = getNumOperands();
|
WeakVH &OldV = ValuePtrs[Idx];
|
||||||
for (int i(Ops - 1); i >= 0; --i)
|
if (OldV == 0) {
|
||||||
New[i] = Old[i].get();
|
OldV = V;
|
||||||
OperandList = New;
|
return;
|
||||||
if (Old) Use::zap(Old, Old + Ops, true);
|
}
|
||||||
|
|
||||||
|
// Handle constants and non-constants (e.g. instrs) differently for
|
||||||
|
// efficiency.
|
||||||
|
if (Constant *PHC = dyn_cast<Constant>(&*OldV)) {
|
||||||
|
ResolveConstants.push_back(std::make_pair(PHC, Idx));
|
||||||
|
OldV = V;
|
||||||
|
} else {
|
||||||
|
// If there was a forward reference to this value, replace it.
|
||||||
|
Value *PrevVal = OldV;
|
||||||
|
OldV->replaceAllUsesWith(V);
|
||||||
|
delete PrevVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
|
Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
|
||||||
const Type *Ty) {
|
const Type *Ty) {
|
||||||
if (Idx >= size()) {
|
if (Idx >= size())
|
||||||
// Insert a bunch of null values.
|
|
||||||
resize(Idx + 1);
|
resize(Idx + 1);
|
||||||
NumOperands = Idx+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Value *V = OperandList[Idx]) {
|
if (Value *V = ValuePtrs[Idx]) {
|
||||||
assert(Ty == V->getType() && "Type mismatch in constant table!");
|
assert(Ty == V->getType() && "Type mismatch in constant table!");
|
||||||
return cast<Constant>(V);
|
return cast<Constant>(V);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and return a placeholder, which will later be RAUW'd.
|
// Create and return a placeholder, which will later be RAUW'd.
|
||||||
Constant *C = new ConstantPlaceHolder(Ty);
|
Constant *C = new ConstantPlaceHolder(Ty);
|
||||||
OperandList[Idx] = C;
|
ValuePtrs[Idx] = C;
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) {
|
Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) {
|
||||||
if (Idx >= size()) {
|
if (Idx >= size())
|
||||||
// Insert a bunch of null values.
|
|
||||||
resize(Idx + 1);
|
resize(Idx + 1);
|
||||||
NumOperands = Idx+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Value *V = OperandList[Idx]) {
|
if (Value *V = ValuePtrs[Idx]) {
|
||||||
assert((Ty == 0 || Ty == V->getType()) && "Type mismatch in value table!");
|
assert((Ty == 0 || Ty == V->getType()) && "Type mismatch in value table!");
|
||||||
return V;
|
return V;
|
||||||
}
|
}
|
||||||
@ -213,7 +216,7 @@ Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) {
|
|||||||
|
|
||||||
// Create and return a placeholder, which will later be RAUW'd.
|
// Create and return a placeholder, which will later be RAUW'd.
|
||||||
Value *V = new Argument(Ty);
|
Value *V = new Argument(Ty);
|
||||||
OperandList[Idx] = V;
|
ValuePtrs[Idx] = V;
|
||||||
return V;
|
return V;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +235,7 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() {
|
|||||||
SmallVector<Constant*, 64> NewOps;
|
SmallVector<Constant*, 64> NewOps;
|
||||||
|
|
||||||
while (!ResolveConstants.empty()) {
|
while (!ResolveConstants.empty()) {
|
||||||
Value *RealVal = getOperand(ResolveConstants.back().second);
|
Value *RealVal = operator[](ResolveConstants.back().second);
|
||||||
Constant *Placeholder = ResolveConstants.back().first;
|
Constant *Placeholder = ResolveConstants.back().first;
|
||||||
ResolveConstants.pop_back();
|
ResolveConstants.pop_back();
|
||||||
|
|
||||||
@ -268,7 +271,7 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() {
|
|||||||
std::pair<Constant*, unsigned>(cast<Constant>(*I),
|
std::pair<Constant*, unsigned>(cast<Constant>(*I),
|
||||||
0));
|
0));
|
||||||
assert(It != ResolveConstants.end() && It->first == *I);
|
assert(It != ResolveConstants.end() && It->first == *I);
|
||||||
NewOp = this->getOperand(It->second);
|
NewOp = operator[](It->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
NewOps.push_back(cast<Constant>(NewOp));
|
NewOps.push_back(cast<Constant>(NewOp));
|
||||||
@ -2064,7 +2067,7 @@ Module *BitcodeReader::materializeModule(std::string *ErrInfo) {
|
|||||||
if (CallInst* CI = dyn_cast<CallInst>(*UI++))
|
if (CallInst* CI = dyn_cast<CallInst>(*UI++))
|
||||||
UpgradeIntrinsicCall(CI, I->second);
|
UpgradeIntrinsicCall(CI, I->second);
|
||||||
}
|
}
|
||||||
ValueList.replaceUsesOfWith(I->first, I->second);
|
I->first->replaceAllUsesWith(I->second);
|
||||||
I->first->eraseFromParent();
|
I->first->eraseFromParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "llvm/OperandTraits.h"
|
#include "llvm/OperandTraits.h"
|
||||||
#include "llvm/Bitcode/BitstreamReader.h"
|
#include "llvm/Bitcode/BitstreamReader.h"
|
||||||
#include "llvm/Bitcode/LLVMBitCodes.h"
|
#include "llvm/Bitcode/LLVMBitCodes.h"
|
||||||
|
#include "llvm/Support/ValueHandle.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -30,8 +31,8 @@ namespace llvm {
|
|||||||
// BitcodeReaderValueList Class
|
// BitcodeReaderValueList Class
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
class BitcodeReaderValueList : public User {
|
class BitcodeReaderValueList {
|
||||||
unsigned Capacity;
|
std::vector<WeakVH> ValuePtrs;
|
||||||
|
|
||||||
/// ResolveConstants - As we resolve forward-referenced constants, we add
|
/// ResolveConstants - As we resolve forward-referenced constants, we add
|
||||||
/// information about them to this vector. This allows us to resolve them in
|
/// information about them to this vector. This allows us to resolve them in
|
||||||
@ -43,88 +44,46 @@ class BitcodeReaderValueList : public User {
|
|||||||
typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
|
typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
|
||||||
ResolveConstantsTy ResolveConstants;
|
ResolveConstantsTy ResolveConstants;
|
||||||
public:
|
public:
|
||||||
BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0)
|
BitcodeReaderValueList() {}
|
||||||
, Capacity(0) {}
|
|
||||||
~BitcodeReaderValueList() {
|
~BitcodeReaderValueList() {
|
||||||
assert(ResolveConstants.empty() && "Constants not resolved?");
|
assert(ResolveConstants.empty() && "Constants not resolved?");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provide fast operand accessors
|
|
||||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
|
||||||
|
|
||||||
// vector compatibility methods
|
// vector compatibility methods
|
||||||
unsigned size() const { return getNumOperands(); }
|
unsigned size() const { return ValuePtrs.size(); }
|
||||||
void resize(unsigned);
|
void resize(unsigned N) { ValuePtrs.resize(N); }
|
||||||
void push_back(Value *V) {
|
void push_back(Value *V) {
|
||||||
unsigned OldOps(NumOperands), NewOps(NumOperands + 1);
|
ValuePtrs.push_back(V);
|
||||||
resize(NewOps);
|
|
||||||
NumOperands = NewOps;
|
|
||||||
OperandList[OldOps] = V;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
assert(ResolveConstants.empty() && "Constants not resolved?");
|
assert(ResolveConstants.empty() && "Constants not resolved?");
|
||||||
if (OperandList) dropHungoffUses(OperandList);
|
ValuePtrs.clear();
|
||||||
Capacity = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *operator[](unsigned i) const { return getOperand(i); }
|
Value *operator[](unsigned i) const {
|
||||||
|
assert(i < ValuePtrs.size());
|
||||||
|
return ValuePtrs[i];
|
||||||
|
}
|
||||||
|
|
||||||
Value *back() const { return getOperand(size() - 1); }
|
Value *back() const { return ValuePtrs.back(); }
|
||||||
void pop_back() { setOperand(size() - 1, 0); --NumOperands; }
|
void pop_back() { ValuePtrs.pop_back(); }
|
||||||
bool empty() const { return NumOperands == 0; }
|
bool empty() const { return ValuePtrs.empty(); }
|
||||||
void shrinkTo(unsigned N) {
|
void shrinkTo(unsigned N) {
|
||||||
assert(N <= NumOperands && "Invalid shrinkTo request!");
|
assert(N <= size() && "Invalid shrinkTo request!");
|
||||||
while (NumOperands > N)
|
ValuePtrs.resize(N);
|
||||||
pop_back();
|
|
||||||
}
|
}
|
||||||
virtual void print(std::ostream&) const {}
|
|
||||||
|
|
||||||
Constant *getConstantFwdRef(unsigned Idx, const Type *Ty);
|
Constant *getConstantFwdRef(unsigned Idx, const Type *Ty);
|
||||||
Value *getValueFwdRef(unsigned Idx, const Type *Ty);
|
Value *getValueFwdRef(unsigned Idx, const Type *Ty);
|
||||||
|
|
||||||
void AssignValue(Value *V, unsigned Idx) {
|
void AssignValue(Value *V, unsigned Idx);
|
||||||
if (Idx == size()) {
|
|
||||||
push_back(V);
|
|
||||||
} else if (Value *OldV = getOperand(Idx)) {
|
|
||||||
// Handle constants and non-constants (e.g. instrs) differently for
|
|
||||||
// efficiency.
|
|
||||||
if (Constant *PHC = dyn_cast<Constant>(OldV)) {
|
|
||||||
ResolveConstants.push_back(std::make_pair(PHC, Idx));
|
|
||||||
setOperand(Idx, V);
|
|
||||||
} else {
|
|
||||||
// If there was a forward reference to this value, replace it.
|
|
||||||
setOperand(Idx, V);
|
|
||||||
OldV->replaceAllUsesWith(V);
|
|
||||||
delete OldV;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
initVal(Idx, V);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ResolveConstantForwardRefs - Once all constants are read, this method bulk
|
/// ResolveConstantForwardRefs - Once all constants are read, this method bulk
|
||||||
/// resolves any forward references.
|
/// resolves any forward references.
|
||||||
void ResolveConstantForwardRefs();
|
void ResolveConstantForwardRefs();
|
||||||
|
|
||||||
private:
|
|
||||||
void initVal(unsigned Idx, Value *V) {
|
|
||||||
if (Idx >= size()) {
|
|
||||||
// Insert a bunch of null values.
|
|
||||||
resize(Idx * 2 + 1);
|
|
||||||
}
|
|
||||||
assert(getOperand(Idx) == 0 && "Cannot init an already init'd Use!");
|
|
||||||
OperandList[Idx] = V;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
struct OperandTraits<BitcodeReaderValueList>
|
|
||||||
: HungoffOperandTraits</*16 FIXME*/> {
|
|
||||||
};
|
|
||||||
|
|
||||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitcodeReaderValueList, Value)
|
|
||||||
|
|
||||||
class BitcodeReader : public ModuleProvider {
|
class BitcodeReader : public ModuleProvider {
|
||||||
MemoryBuffer *Buffer;
|
MemoryBuffer *Buffer;
|
||||||
BitstreamReader Stream;
|
BitstreamReader Stream;
|
||||||
|
Loading…
Reference in New Issue
Block a user