class Value;
struct DenseMapAPIntKeyInfo {
- struct KeyTy {
- APInt val;
- Type* type;
- KeyTy(const APInt& V, Type* Ty) : val(V), type(Ty) {}
- bool operator==(const KeyTy& that) const {
- return type == that.type && this->val == that.val;
- }
- bool operator!=(const KeyTy& that) const {
- return !this->operator==(that);
- }
- friend hash_code hash_value(const KeyTy &Key) {
- return hash_combine(Key.type, Key.val);
- }
- };
- static inline KeyTy getEmptyKey() { return KeyTy(APInt(1,0), nullptr); }
- static inline KeyTy getTombstoneKey() { return KeyTy(APInt(1,1), nullptr); }
- static unsigned getHashValue(const KeyTy &Key) {
+ static inline APInt getEmptyKey() {
+ APInt V(nullptr, 0);
+ V.VAL = 0;
+ return V;
+ }
+ static inline APInt getTombstoneKey() {
+ APInt V(nullptr, 0);
+ V.VAL = 1;
+ return V;
+ }
+ static unsigned getHashValue(const APInt &Key) {
return static_cast<unsigned>(hash_value(Key));
}
- static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
- return LHS == RHS;
+ static bool isEqual(const APInt &LHS, const APInt &RHS) {
+ return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS;
}
};
struct DenseMapAPFloatKeyInfo {
- struct KeyTy {
- APFloat val;
- KeyTy(const APFloat& V) : val(V){}
- bool operator==(const KeyTy& that) const {
- return this->val.bitwiseIsEqual(that.val);
- }
- bool operator!=(const KeyTy& that) const {
- return !this->operator==(that);
- }
- friend hash_code hash_value(const KeyTy &Key) {
- return hash_combine(Key.val);
- }
- };
- static inline KeyTy getEmptyKey() {
- return KeyTy(APFloat(APFloat::Bogus,1));
- }
- static inline KeyTy getTombstoneKey() {
- return KeyTy(APFloat(APFloat::Bogus,2));
- }
- static unsigned getHashValue(const KeyTy &Key) {
+ static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus, 1); }
+ static inline APFloat getTombstoneKey() { return APFloat(APFloat::Bogus, 2); }
+ static unsigned getHashValue(const APFloat &Key) {
return static_cast<unsigned>(hash_value(Key));
}
- static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
- return LHS == RHS;
+ static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
+ return LHS.bitwiseIsEqual(RHS);
}
};
/// the operands.
struct GenericMDNodeInfo {
struct KeyTy {
- ArrayRef<Value *> Ops;
+ ArrayRef<Metadata *> RawOps;
+ ArrayRef<MDOperand> Ops;
unsigned Hash;
- KeyTy(ArrayRef<Value *> Ops)
- : Ops(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {}
+ KeyTy(ArrayRef<Metadata *> Ops)
+ : RawOps(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {}
- KeyTy(GenericMDNode *N, SmallVectorImpl<Value *> &Storage) {
- Storage.resize(N->getNumOperands());
- for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I)
- Storage[I] = N->getOperand(I);
- Ops = Storage;
- Hash = hash_combine_range(Ops.begin(), Ops.end());
- }
+ KeyTy(GenericMDNode *N)
+ : Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {}
bool operator==(const GenericMDNode *RHS) const {
if (RHS == getEmptyKey() || RHS == getTombstoneKey())
return false;
- if (Hash != RHS->getHash() || Ops.size() != RHS->getNumOperands())
+ if (Hash != RHS->getHash())
return false;
- for (unsigned I = 0, E = Ops.size(); I != E; ++I)
- if (Ops[I] != RHS->getOperand(I))
- return false;
- return true;
+ assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
+ return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS);
+ }
+ template <class T>
+ static bool compareOps(ArrayRef<T> Ops, const GenericMDNode *RHS) {
+ if (Ops.size() != RHS->getNumOperands())
+ return false;
+ return std::equal(Ops.begin(), Ops.end(), RHS->op_begin());
}
};
static inline GenericMDNode *getEmptyKey() {
}
};
-/// DebugRecVH - This is a CallbackVH used to keep the Scope -> index maps
-/// up to date as MDNodes mutate. This class is implemented in DebugLoc.cpp.
-class DebugRecVH : public CallbackVH {
- /// Ctx - This is the LLVM Context being referenced.
- LLVMContextImpl *Ctx;
-
- /// Idx - The index into either ScopeRecordIdx or ScopeInlinedAtRecords that
- /// this reference lives in. If this is zero, then it represents a
- /// non-canonical entry that has no DenseMap value. This can happen due to
- /// RAUW.
- int Idx;
-public:
- DebugRecVH(MDNode *n, LLVMContextImpl *ctx, int idx)
- : CallbackVH(n), Ctx(ctx), Idx(idx) {}
-
- MDNode *get() const {
- return cast_or_null<MDNode>(getValPtr());
- }
-
- void deleted() override;
- void allUsesReplacedWith(Value *VNew) override;
-};
-
class LLVMContextImpl {
public:
/// OwnedModules - The set of modules instantiated in this context, and which
LLVMContext::YieldCallbackTy YieldCallback;
void *YieldOpaqueHandle;
- typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt *,
- DenseMapAPIntKeyInfo> IntMapTy;
+ typedef DenseMap<APInt, ConstantInt *, DenseMapAPIntKeyInfo> IntMapTy;
IntMapTy IntConstants;
-
- typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*,
- DenseMapAPFloatKeyInfo> FPMapTy;
+
+ typedef DenseMap<APFloat, ConstantFP *, DenseMapAPFloatKeyInfo> FPMapTy;
FPMapTy FPConstants;
FoldingSet<AttributeImpl> AttrsSet;
FoldingSet<AttributeSetNode> AttrsSetNodes;
StringMap<MDString> MDStringCache;
+ DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
+ DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
DenseSet<GenericMDNode *, GenericMDNodeInfo> MDNodeSet;
ConstantInt *TheFalseVal;
LeakDetectorImpl<Value> LLVMObjects;
-
+ LeakDetectorImpl<Metadata> LLVMMDObjects;
+
// Basic type instances.
Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy;
Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy;
BumpPtrAllocator TypeAllocator;
DenseMap<unsigned, IntegerType*> IntegerTypes;
-
- typedef DenseMap<FunctionType*, bool, FunctionTypeKeyInfo> FunctionTypeMap;
- FunctionTypeMap FunctionTypes;
- typedef DenseMap<StructType*, bool, AnonStructTypeKeyInfo> StructTypeMap;
- StructTypeMap AnonStructTypes;
+
+ typedef DenseSet<FunctionType *, FunctionTypeKeyInfo> FunctionTypeSet;
+ FunctionTypeSet FunctionTypes;
+ typedef DenseSet<StructType *, AnonStructTypeKeyInfo> StructTypeSet;
+ StructTypeSet AnonStructTypes;
StringMap<StructType*> NamedStructTypes;
unsigned NamedStructTypesUniqueID;
/// CustomMDKindNames - Map to hold the metadata string to ID mapping.
StringMap<unsigned> CustomMDKindNames;
-
- typedef std::pair<unsigned, TrackingVH<MDNode> > MDPairTy;
+
+ typedef std::pair<unsigned, TrackingMDNodeRef> MDPairTy;
typedef SmallVector<MDPairTy, 2> MDMapTy;
/// MetadataStore - Collection of per-instruction metadata used in this
/// context.
DenseMap<const Instruction *, MDMapTy> MetadataStore;
- /// ScopeRecordIdx - This is the index in ScopeRecords for an MDNode scope
- /// entry with no "inlined at" element.
- DenseMap<MDNode*, int> ScopeRecordIdx;
-
- /// ScopeRecords - These are the actual mdnodes (in a value handle) for an
- /// index. The ValueHandle ensures that ScopeRecordIdx stays up to date if
- /// the MDNode is RAUW'd.
- std::vector<DebugRecVH> ScopeRecords;
-
- /// ScopeInlinedAtIdx - This is the index in ScopeInlinedAtRecords for an
- /// scope/inlined-at pair.
- DenseMap<std::pair<MDNode*, MDNode*>, int> ScopeInlinedAtIdx;
-
- /// ScopeInlinedAtRecords - These are the actual mdnodes (in value handles)
- /// for an index. The ValueHandle ensures that ScopeINlinedAtIdx stays up
- /// to date.
- std::vector<std::pair<DebugRecVH, DebugRecVH> > ScopeInlinedAtRecords;
-
/// DiscriminatorTable - This table maps file:line locations to an
/// integer representing the next DWARF path discriminator to assign to
/// instructions in different blocks at the same location.
typedef DenseMap<const Function *, ReturnInst *> PrefixDataMapTy;
PrefixDataMapTy PrefixDataMap;
+ /// \brief Mapping from a function to its prologue data, which is stored as
+ /// the operand of an unparented ReturnInst so that the prologue data has a
+ /// Use.
+ typedef DenseMap<const Function *, ReturnInst *> PrologueDataMapTy;
+ PrologueDataMapTy PrologueDataMap;
+
int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx);
int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);