#define BITCODE_READER_H
#include "llvm/ModuleProvider.h"
-#include "llvm/ParameterAttributes.h"
+#include "llvm/Attributes.h"
#include "llvm/Type.h"
#include "llvm/OperandTraits.h"
#include "llvm/Bitcode/BitstreamReader.h"
class BitcodeReaderValueList : public User {
unsigned Capacity;
+
+ /// ResolveConstants - As we resolve forward-referenced constants, we add
+ /// information about them to this vector. This allows us to resolve them in
+ /// bulk instead of resolving each reference at a time. See the code in
+ /// ResolveConstantForwardRefs for more information about this.
+ ///
+ /// The key of this vector is the placeholder constant, the value is the slot
+ /// number that holds the resolved value.
+ typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
+ ResolveConstantsTy ResolveConstants;
public:
BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0)
, Capacity(0) {}
+ ~BitcodeReaderValueList() {
+ assert(ResolveConstants.empty() && "Constants not resolved?");
+ }
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
}
void clear() {
+ assert(ResolveConstants.empty() && "Constants not resolved?");
if (OperandList) dropHungoffUses(OperandList);
Capacity = 0;
}
if (Idx == size()) {
push_back(V);
} else if (Value *OldV = getOperand(Idx)) {
- // If there was a forward reference to this value, replace it.
- setOperand(Idx, V);
- OldV->replaceAllUsesWith(V);
- delete OldV;
+ // 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
+ /// resolves any forward references.
+ void ResolveConstantForwardRefs();
+
private:
void initVal(unsigned Idx, Value *V) {
if (Idx >= size()) {
};
template <>
-struct OperandTraits<BitcodeReaderValueList> : HungoffOperandTraits</*16 FIXME*/> {
+struct OperandTraits<BitcodeReaderValueList>
+ : HungoffOperandTraits</*16 FIXME*/> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitcodeReaderValueList, Value)
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
- /// ParamAttrs - The set of parameter attributes by index. Index zero in the
+ /// Attributes - The set of parameter attributes by index. Index zero in the
/// file is for null, and is thus not represented here. As such all indices
/// are off by one.
- std::vector<PAListPtr> ParamAttrs;
+ std::vector<AttrListPtr> Attributes;
/// FunctionBBs - While parsing a function body, this is a list of the basic
/// blocks for the function.
if (ID >= FunctionBBs.size()) return 0; // Invalid ID
return FunctionBBs[ID];
}
- PAListPtr getParamAttrs(unsigned i) const {
- if (i-1 < ParamAttrs.size())
- return ParamAttrs[i-1];
- return PAListPtr();
+ AttrListPtr getAttributes(unsigned i) const {
+ if (i-1 < Attributes.size())
+ return Attributes[i-1];
+ return AttrListPtr();
}
/// getValueTypePair - Read a value/type pair out of the specified record from
bool ParseModule(const std::string &ModuleID);
- bool ParseParamAttrBlock();
+ bool ParseAttributeBlock();
bool ParseTypeTable();
bool ParseTypeSymbolTable();
bool ParseValueSymbolTable();