X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstantsContext.h;h=996eb12d69ea1ceb404020044ec58a9ffd856248;hb=3e2d76c946ba753c2b11af192a52e25b6f9b46ff;hp=bd134d9b892de09376cbe24380d003cba471828e;hpb=1afcace3a3a138b1b18e5c6270caa8dae2261ae2;p=oota-llvm.git diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h index bd134d9b892..996eb12d69e 100644 --- a/lib/VMCore/ConstantsContext.h +++ b/lib/VMCore/ConstantsContext.h @@ -15,6 +15,8 @@ #ifndef LLVM_CONSTANTSCONTEXT_H #define LLVM_CONSTANTSCONTEXT_H +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Hashing.h" #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Operator.h" @@ -30,13 +32,14 @@ struct ConstantTraits; /// UnaryConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement unary constant exprs. class UnaryConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + virtual void anchor(); + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly one operand void *operator new(size_t s) { return User::operator new(s, 1); } - UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty) + UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty) : ConstantExpr(Ty, Opcode, &Op<0>(), 1) { Op<0>() = C; } @@ -46,7 +49,8 @@ public: /// BinaryConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement binary constant exprs. class BinaryConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + virtual void anchor(); + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -66,7 +70,8 @@ public: /// SelectConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement select constant exprs. class SelectConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + virtual void anchor(); + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly three operands void *operator new(size_t s) { @@ -86,7 +91,8 @@ public: /// Constants.cpp, and is used behind the scenes to implement /// extractelement constant exprs. class ExtractElementConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + virtual void anchor(); + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -106,7 +112,8 @@ public: /// Constants.cpp, and is used behind the scenes to implement /// insertelement constant exprs. class InsertElementConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + virtual void anchor(); + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly three operands void *operator new(size_t s) { @@ -127,7 +134,8 @@ public: /// Constants.cpp, and is used behind the scenes to implement /// shufflevector constant exprs. class ShuffleVectorConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + virtual void anchor(); + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly three operands void *operator new(size_t s) { @@ -151,7 +159,8 @@ public: /// Constants.cpp, and is used behind the scenes to implement /// extractvalue constant exprs. class ExtractValueConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + virtual void anchor(); + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly one operand void *operator new(size_t s) { @@ -159,7 +168,7 @@ public: } ExtractValueConstantExpr(Constant *Agg, const SmallVector &IdxList, - const Type *DestTy) + Type *DestTy) : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1), Indices(IdxList) { Op<0>() = Agg; @@ -176,7 +185,8 @@ public: /// Constants.cpp, and is used behind the scenes to implement /// insertvalue constant exprs. class InsertValueConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + virtual void anchor(); + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; public: // allocate space for exactly one operand void *operator new(size_t s) { @@ -184,7 +194,7 @@ public: } InsertValueConstantExpr(Constant *Agg, Constant *Val, const SmallVector &IdxList, - const Type *DestTy) + Type *DestTy) : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2), Indices(IdxList) { Op<0>() = Agg; @@ -202,12 +212,13 @@ public: /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is /// used behind the scenes to implement getelementpr constant exprs. class GetElementPtrConstantExpr : public ConstantExpr { - GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, - const Type *DestTy); + virtual void anchor(); + GetElementPtrConstantExpr(Constant *C, ArrayRef IdxList, + Type *DestTy); public: static GetElementPtrConstantExpr *Create(Constant *C, - const std::vector&IdxList, - const Type *DestTy, + ArrayRef IdxList, + Type *DestTy, unsigned Flags) { GetElementPtrConstantExpr *Result = new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy); @@ -221,14 +232,16 @@ public: // CompareConstantExpr - This class is private to Constants.cpp, and is used // behind the scenes to implement ICmp and FCmp constant expressions. This is // needed in order to store the predicate value for these instructions. -struct CompareConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +class CompareConstantExpr : public ConstantExpr { + virtual void anchor(); + void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; +public: // allocate space for exactly two operands void *operator new(size_t s) { return User::operator new(s, 2); } unsigned short predicate; - CompareConstantExpr(const Type *ty, Instruction::OtherOps opc, + CompareConstantExpr(Type *ty, Instruction::OtherOps opc, unsigned short pred, Constant* LHS, Constant* RHS) : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) { Op<0>() = LHS; @@ -339,18 +352,21 @@ struct ExprMapKeyType { struct InlineAsmKeyType { InlineAsmKeyType(StringRef AsmString, StringRef Constraints, bool hasSideEffects, - bool isAlignStack) + bool isAlignStack, InlineAsm::AsmDialect asmDialect) : asm_string(AsmString), constraints(Constraints), - has_side_effects(hasSideEffects), is_align_stack(isAlignStack) {} + has_side_effects(hasSideEffects), is_align_stack(isAlignStack), + asm_dialect(asmDialect) {} std::string asm_string; std::string constraints; bool has_side_effects; bool is_align_stack; + InlineAsm::AsmDialect asm_dialect; bool operator==(const InlineAsmKeyType& that) const { return this->asm_string == that.asm_string && this->constraints == that.constraints && this->has_side_effects == that.has_side_effects && - this->is_align_stack == that.is_align_stack; + this->is_align_stack == that.is_align_stack && + this->asm_dialect == that.asm_dialect; } bool operator<(const InlineAsmKeyType& that) const { if (this->asm_string != that.asm_string) @@ -361,6 +377,8 @@ struct InlineAsmKeyType { return this->has_side_effects < that.has_side_effects; if (this->is_align_stack != that.is_align_stack) return this->is_align_stack < that.is_align_stack; + if (this->asm_dialect != that.asm_dialect) + return this->asm_dialect < that.asm_dialect; return false; } @@ -392,11 +410,18 @@ struct ConstantTraits { template struct ConstantCreator { - static ConstantClass *create(const TypeClass *Ty, const ValType &V) { + static ConstantClass *create(TypeClass *Ty, const ValType &V) { return new(ConstantTraits::uses(V)) ConstantClass(Ty, V); } }; +template +struct ConstantArrayCreator { + static ConstantClass *create(TypeClass *Ty, ArrayRef V) { + return new(V.size()) ConstantClass(Ty, V); + } +}; + template struct ConstantKeyData { typedef void ValType; @@ -407,7 +432,7 @@ struct ConstantKeyData { template<> struct ConstantCreator { - static ConstantExpr *create(const Type *Ty, const ExprMapKeyType &V, + static ConstantExpr *create(Type *Ty, const ExprMapKeyType &V, unsigned short pred = 0) { if (Instruction::isCast(V.opcode)) return new UnaryConstantExpr(V.opcode, V.operands[0], Ty); @@ -447,7 +472,6 @@ struct ConstantCreator { return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata, V.operands[0], V.operands[1]); llvm_unreachable("Invalid ConstantExpr!"); - return 0; } }; @@ -467,95 +491,12 @@ struct ConstantKeyData { } }; -// ConstantAggregateZero does not take extra "value" argument... -template -struct ConstantCreator { - static ConstantAggregateZero *create(const Type *Ty, const ValType &V){ - return new ConstantAggregateZero(Ty); - } -}; - -template<> -struct ConstantKeyData { - typedef std::vector ValType; - static ValType getValType(ConstantVector *CP) { - std::vector Elements; - Elements.reserve(CP->getNumOperands()); - for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) - Elements.push_back(CP->getOperand(i)); - return Elements; - } -}; - -template<> -struct ConstantKeyData { - typedef char ValType; - static ValType getValType(ConstantAggregateZero *C) { - return 0; - } -}; - -template<> -struct ConstantKeyData { - typedef std::vector ValType; - static ValType getValType(ConstantArray *CA) { - std::vector Elements; - Elements.reserve(CA->getNumOperands()); - for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) - Elements.push_back(cast(CA->getOperand(i))); - return Elements; - } -}; - -template<> -struct ConstantKeyData { - typedef std::vector ValType; - static ValType getValType(ConstantStruct *CS) { - std::vector Elements; - Elements.reserve(CS->getNumOperands()); - for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) - Elements.push_back(cast(CS->getOperand(i))); - return Elements; - } -}; - -// ConstantPointerNull does not take extra "value" argument... -template -struct ConstantCreator { - static ConstantPointerNull *create(const PointerType *Ty, const ValType &V){ - return new ConstantPointerNull(Ty); - } -}; - -template<> -struct ConstantKeyData { - typedef char ValType; - static ValType getValType(ConstantPointerNull *C) { - return 0; - } -}; - -// UndefValue does not take extra "value" argument... -template -struct ConstantCreator { - static UndefValue *create(const Type *Ty, const ValType &V) { - return new UndefValue(Ty); - } -}; - -template<> -struct ConstantKeyData { - typedef char ValType; - static ValType getValType(UndefValue *C) { - return 0; - } -}; - template<> struct ConstantCreator { - static InlineAsm *create(const PointerType *Ty, const InlineAsmKeyType &Key) { + static InlineAsm *create(PointerType *Ty, const InlineAsmKeyType &Key) { return new InlineAsm(Ty, Key.asm_string, Key.constraints, - Key.has_side_effects, Key.is_align_stack); + Key.has_side_effects, Key.is_align_stack, + Key.asm_dialect); } }; @@ -564,7 +505,8 @@ struct ConstantKeyData { typedef InlineAsmKeyType ValType; static ValType getValType(InlineAsm *Asm) { return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(), - Asm->hasSideEffects(), Asm->isAlignStack()); + Asm->hasSideEffects(), Asm->isAlignStack(), + Asm->getDialect()); } }; @@ -572,7 +514,7 @@ template class ConstantUniqueMap { public: - typedef std::pair MapKey; + typedef std::pair MapKey; typedef std::map MapTy; typedef std::map InverseMapTy; private: @@ -623,7 +565,7 @@ private: } typename MapTy::iterator I = - Map.find(MapKey(static_cast(CP->getType()), + Map.find(MapKey(static_cast(CP->getType()), ConstantKeyData::getValType(CP))); if (I == Map.end() || I->second != CP) { // FIXME: This should not use a linear scan. If this gets to be a @@ -634,7 +576,7 @@ private: return I; } - ConstantClass *Create(const TypeClass *Ty, ValRefType V, + ConstantClass *Create(TypeClass *Ty, ValRefType V, typename MapTy::iterator I) { ConstantClass* Result = ConstantCreator::create(Ty, V); @@ -651,7 +593,7 @@ public: /// getOrCreate - Return the specified constant from the map, creating it if /// necessary. - ConstantClass *getOrCreate(const TypeClass *Ty, ValRefType V) { + ConstantClass *getOrCreate(TypeClass *Ty, ValRefType V) { MapKey Lookup(Ty, V); ConstantClass* Result = 0; @@ -704,6 +646,129 @@ public: } }; +// Unique map for aggregate constants +template +class ConstantAggrUniqueMap { +public: + typedef ArrayRef Operands; + typedef std::pair LookupKey; +private: + struct MapInfo { + typedef DenseMapInfo ConstantClassInfo; + typedef DenseMapInfo ConstantInfo; + typedef DenseMapInfo TypeClassInfo; + static inline ConstantClass* getEmptyKey() { + return ConstantClassInfo::getEmptyKey(); + } + static inline ConstantClass* getTombstoneKey() { + return ConstantClassInfo::getTombstoneKey(); + } + static unsigned getHashValue(const ConstantClass *CP) { + SmallVector CPOperands; + CPOperands.reserve(CP->getNumOperands()); + for (unsigned I = 0, E = CP->getNumOperands(); I < E; ++I) + CPOperands.push_back(CP->getOperand(I)); + return getHashValue(LookupKey(CP->getType(), CPOperands)); + } + static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) { + return LHS == RHS; + } + static unsigned getHashValue(const LookupKey &Val) { + return hash_combine(Val.first, hash_combine_range(Val.second.begin(), + Val.second.end())); + } + static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) { + if (RHS == getEmptyKey() || RHS == getTombstoneKey()) + return false; + if (LHS.first != RHS->getType() + || LHS.second.size() != RHS->getNumOperands()) + return false; + for (unsigned I = 0, E = RHS->getNumOperands(); I < E; ++I) { + if (LHS.second[I] != RHS->getOperand(I)) + return false; + } + return true; + } + }; +public: + typedef DenseMap MapTy; + +private: + /// Map - This is the main map from the element descriptor to the Constants. + /// This is the primary way we avoid creating two of the same shape + /// constant. + MapTy Map; + +public: + typename MapTy::iterator map_begin() { return Map.begin(); } + typename MapTy::iterator map_end() { return Map.end(); } + + void freeConstants() { + for (typename MapTy::iterator I=Map.begin(), E=Map.end(); + I != E; ++I) { + // Asserts that use_empty(). + delete I->first; + } + } + +private: + typename MapTy::iterator findExistingElement(ConstantClass *CP) { + return Map.find(CP); + } + + ConstantClass *Create(TypeClass *Ty, Operands V, typename MapTy::iterator I) { + ConstantClass* Result = + ConstantArrayCreator::create(Ty, V); + + assert(Result->getType() == Ty && "Type specified is not correct!"); + Map[Result] = '\0'; + + return Result; + } +public: + + /// getOrCreate - Return the specified constant from the map, creating it if + /// necessary. + ConstantClass *getOrCreate(TypeClass *Ty, Operands V) { + LookupKey Lookup(Ty, V); + ConstantClass* Result = 0; + + typename MapTy::iterator I = Map.find_as(Lookup); + // Is it in the map? + if (I != Map.end()) + Result = I->first; + + if (!Result) { + // If no preexisting value, create one now... + Result = Create(Ty, V, I); + } + + return Result; + } + + /// Find the constant by lookup key. + typename MapTy::iterator find(LookupKey Lookup) { + return Map.find_as(Lookup); + } + + /// Insert the constant into its proper slot. + void insert(ConstantClass *CP) { + Map[CP] = '\0'; + } + + /// Remove this constant from the map + void remove(ConstantClass *CP) { + typename MapTy::iterator I = findExistingElement(CP); + assert(I != Map.end() && "Constant not found in constant table!"); + assert(I->first == CP && "Didn't find correct element?"); + Map.erase(I); + } + + void dump() const { + DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); + } +}; + } #endif