//===-- LLVMContextImpl.h - The LLVMContextImpl opaque class ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file declares LLVMContextImpl, the opaque implementation // of LLVMContext. // //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_IR_LLVMCONTEXTIMPL_H #define LLVM_LIB_IR_LLVMCONTEXTIMPL_H #include "AttributeImpl.h" #include "ConstantsContext.h" #include "LeaksContext.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/ValueHandle.h" #include namespace llvm { class ConstantInt; class ConstantFP; class DiagnosticInfoOptimizationRemark; class DiagnosticInfoOptimizationRemarkMissed; class DiagnosticInfoOptimizationRemarkAnalysis; class GCStrategy; class LLVMContext; class Type; class Value; struct DenseMapAPIntKeyInfo { 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(hash_value(Key)); } static bool isEqual(const APInt &LHS, const APInt &RHS) { return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS; } }; struct DenseMapAPFloatKeyInfo { 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(hash_value(Key)); } static bool isEqual(const APFloat &LHS, const APFloat &RHS) { return LHS.bitwiseIsEqual(RHS); } }; struct AnonStructTypeKeyInfo { struct KeyTy { ArrayRef ETypes; bool isPacked; KeyTy(const ArrayRef& E, bool P) : ETypes(E), isPacked(P) {} KeyTy(const StructType *ST) : ETypes(ST->elements()), isPacked(ST->isPacked()) {} bool operator==(const KeyTy& that) const { if (isPacked != that.isPacked) return false; if (ETypes != that.ETypes) return false; return true; } bool operator!=(const KeyTy& that) const { return !this->operator==(that); } }; static inline StructType* getEmptyKey() { return DenseMapInfo::getEmptyKey(); } static inline StructType* getTombstoneKey() { return DenseMapInfo::getTombstoneKey(); } static unsigned getHashValue(const KeyTy& Key) { return hash_combine(hash_combine_range(Key.ETypes.begin(), Key.ETypes.end()), Key.isPacked); } static unsigned getHashValue(const StructType *ST) { return getHashValue(KeyTy(ST)); } static bool isEqual(const KeyTy& LHS, const StructType *RHS) { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; return LHS == KeyTy(RHS); } static bool isEqual(const StructType *LHS, const StructType *RHS) { return LHS == RHS; } }; struct FunctionTypeKeyInfo { struct KeyTy { const Type *ReturnType; ArrayRef Params; bool isVarArg; KeyTy(const Type* R, const ArrayRef& P, bool V) : ReturnType(R), Params(P), isVarArg(V) {} KeyTy(const FunctionType *FT) : ReturnType(FT->getReturnType()), Params(FT->params()), isVarArg(FT->isVarArg()) {} bool operator==(const KeyTy& that) const { if (ReturnType != that.ReturnType) return false; if (isVarArg != that.isVarArg) return false; if (Params != that.Params) return false; return true; } bool operator!=(const KeyTy& that) const { return !this->operator==(that); } }; static inline FunctionType* getEmptyKey() { return DenseMapInfo::getEmptyKey(); } static inline FunctionType* getTombstoneKey() { return DenseMapInfo::getTombstoneKey(); } static unsigned getHashValue(const KeyTy& Key) { return hash_combine(Key.ReturnType, hash_combine_range(Key.Params.begin(), Key.Params.end()), Key.isVarArg); } static unsigned getHashValue(const FunctionType *FT) { return getHashValue(KeyTy(FT)); } static bool isEqual(const KeyTy& LHS, const FunctionType *RHS) { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; return LHS == KeyTy(RHS); } static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) { return LHS == RHS; } }; /// \brief DenseMapInfo for MDTuple. /// /// Note that we don't need the is-function-local bit, since that's implicit in /// the operands. struct MDTupleInfo { struct KeyTy { ArrayRef RawOps; ArrayRef Ops; unsigned Hash; KeyTy(ArrayRef Ops) : RawOps(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {} KeyTy(MDTuple *N) : Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {} bool operator==(const MDTuple *RHS) const { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; if (Hash != RHS->getHash()) return false; assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?"); return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS); } template static bool compareOps(ArrayRef Ops, const MDTuple *RHS) { if (Ops.size() != RHS->getNumOperands()) return false; return std::equal(Ops.begin(), Ops.end(), RHS->op_begin()); } }; static inline MDTuple *getEmptyKey() { return DenseMapInfo::getEmptyKey(); } static inline MDTuple *getTombstoneKey() { return DenseMapInfo::getTombstoneKey(); } static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; } static unsigned getHashValue(const MDTuple *U) { return U->getHash(); } static bool isEqual(const KeyTy &LHS, const MDTuple *RHS) { return LHS == RHS; } static bool isEqual(const MDTuple *LHS, const MDTuple *RHS) { return LHS == RHS; } }; /// \brief DenseMapInfo for MDLocation. struct MDLocationInfo { struct KeyTy { unsigned Line; unsigned Column; Metadata *Scope; Metadata *InlinedAt; KeyTy(unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt) : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt) {} KeyTy(const MDLocation *L) : Line(L->getLine()), Column(L->getColumn()), Scope(L->getScope()), InlinedAt(L->getInlinedAt()) {} bool operator==(const MDLocation *RHS) const { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; return Line == RHS->getLine() && Column == RHS->getColumn() && Scope == RHS->getScope() && InlinedAt == RHS->getInlinedAt(); } }; static inline MDLocation *getEmptyKey() { return DenseMapInfo::getEmptyKey(); } static inline MDLocation *getTombstoneKey() { return DenseMapInfo::getTombstoneKey(); } static unsigned getHashValue(const KeyTy &Key) { return hash_combine(Key.Line, Key.Column, Key.Scope, Key.InlinedAt); } static unsigned getHashValue(const MDLocation *U) { return getHashValue(KeyTy(U)); } static bool isEqual(const KeyTy &LHS, const MDLocation *RHS) { return LHS == RHS; } static bool isEqual(const MDLocation *LHS, const MDLocation *RHS) { return LHS == RHS; } }; class LLVMContextImpl { public: /// OwnedModules - The set of modules instantiated in this context, and which /// will be automatically deleted if this context is deleted. SmallPtrSet OwnedModules; LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler; void *InlineAsmDiagContext; LLVMContext::DiagnosticHandlerTy DiagnosticHandler; void *DiagnosticContext; bool RespectDiagnosticFilters; LLVMContext::YieldCallbackTy YieldCallback; void *YieldOpaqueHandle; typedef DenseMap IntMapTy; IntMapTy IntConstants; typedef DenseMap FPMapTy; FPMapTy FPConstants; FoldingSet AttrsSet; FoldingSet AttrsLists; FoldingSet AttrsSetNodes; StringMap MDStringCache; DenseMap ValuesAsMetadata; DenseMap MetadataAsValues; DenseSet MDTuples; DenseSet MDLocations; // MDNodes may be uniqued or not uniqued. When they're not uniqued, they // aren't in the MDNodeSet, but they're still shared between objects, so no // one object can destroy them. This set allows us to at least destroy them // on Context destruction. SmallPtrSet DistinctMDNodes; DenseMap CAZConstants; typedef ConstantUniqueMap ArrayConstantsTy; ArrayConstantsTy ArrayConstants; typedef ConstantUniqueMap StructConstantsTy; StructConstantsTy StructConstants; typedef ConstantUniqueMap VectorConstantsTy; VectorConstantsTy VectorConstants; DenseMap CPNConstants; DenseMap UVConstants; StringMap CDSConstants; DenseMap, BlockAddress *> BlockAddresses; ConstantUniqueMap ExprConstants; ConstantUniqueMap InlineAsms; ConstantInt *TheTrueVal; ConstantInt *TheFalseVal; LeakDetectorImpl LLVMObjects; LeakDetectorImpl LLVMMDObjects; // Basic type instances. Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy; Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy; IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty; /// TypeAllocator - All dynamically allocated types are allocated from this. /// They live forever until the context is torn down. BumpPtrAllocator TypeAllocator; DenseMap IntegerTypes; typedef DenseSet FunctionTypeSet; FunctionTypeSet FunctionTypes; typedef DenseSet StructTypeSet; StructTypeSet AnonStructTypes; StringMap NamedStructTypes; unsigned NamedStructTypesUniqueID; DenseMap, ArrayType*> ArrayTypes; DenseMap, VectorType*> VectorTypes; DenseMap PointerTypes; // Pointers in AddrSpace = 0 DenseMap, PointerType*> ASPointerTypes; /// ValueHandles - This map keeps track of all of the value handles that are /// watching a Value*. The Value::HasValueHandle bit is used to know /// whether or not a value has an entry in this map. typedef DenseMap ValueHandlesTy; ValueHandlesTy ValueHandles; /// CustomMDKindNames - Map to hold the metadata string to ID mapping. StringMap CustomMDKindNames; typedef std::pair MDPairTy; typedef SmallVector MDMapTy; /// MetadataStore - Collection of per-instruction metadata used in this /// context. DenseMap MetadataStore; /// 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. DenseMap, unsigned> DiscriminatorTable; /// IntrinsicIDCache - Cache of intrinsic name (string) to numeric ID mappings /// requested in this context typedef DenseMap IntrinsicIDCacheTy; IntrinsicIDCacheTy IntrinsicIDCache; /// \brief Mapping from a function to its prefix data, which is stored as the /// operand of an unparented ReturnInst so that the prefix data has a Use. typedef DenseMap 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 PrologueDataMapTy; PrologueDataMapTy PrologueDataMap; int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx); int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx); /// An owning list of all GCStrategies which have been created SmallVector, 1> GCStrategyList; /// A helper map to speedup lookups into the above list StringMap GCStrategyMap; /// Lookup the GCStrategy object associated with the given gc name. If one /// can't be found, returns nullptr. The lifetime of the returned objects /// is dictated by the lifetime of the associated context. No caller should /// attempt to delete the returned objects. GCStrategy *getGCStrategy(const StringRef Name); LLVMContextImpl(LLVMContext &C); ~LLVMContextImpl(); }; } #endif