From 169d2bd06003c39970bc94c99669a34b61bb7e45 Mon Sep 17 00:00:00 2001 From: dim Date: Mon, 8 Apr 2013 18:41:23 +0000 Subject: Vendor import of llvm trunk r178860: http://llvm.org/svn/llvm-project/llvm/trunk@178860 --- lib/IR/ConstantsContext.h | 774 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 774 insertions(+) create mode 100644 lib/IR/ConstantsContext.h (limited to 'lib/IR/ConstantsContext.h') diff --git a/lib/IR/ConstantsContext.h b/lib/IR/ConstantsContext.h new file mode 100644 index 0000000..e995858 --- /dev/null +++ b/lib/IR/ConstantsContext.h @@ -0,0 +1,774 @@ +//===-- ConstantsContext.h - Constants-related Context Interals -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines various helper methods and classes used by +// LLVMContextImpl for creating and managing constants. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CONSTANTSCONTEXT_H +#define LLVM_CONSTANTSCONTEXT_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Operator.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include + +namespace llvm { +template +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 { + 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, Type *Ty) + : ConstantExpr(Ty, Opcode, &Op<0>(), 1) { + Op<0>() = C; + } + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// BinaryConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement binary constant exprs. +class BinaryConstantExpr : 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); + } + BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2, + unsigned Flags) + : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) { + Op<0>() = C1; + Op<1>() = C2; + SubclassOptionalData = Flags; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// SelectConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement select constant exprs. +class SelectConstantExpr : public ConstantExpr { + 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) { + return User::operator new(s, 3); + } + SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) { + Op<0>() = C1; + Op<1>() = C2; + Op<2>() = C3; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// ExtractElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// extractelement constant exprs. +class ExtractElementConstantExpr : 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); + } + ExtractElementConstantExpr(Constant *C1, Constant *C2) + : ConstantExpr(cast(C1->getType())->getElementType(), + Instruction::ExtractElement, &Op<0>(), 2) { + Op<0>() = C1; + Op<1>() = C2; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// InsertElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// insertelement constant exprs. +class InsertElementConstantExpr : public ConstantExpr { + 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) { + return User::operator new(s, 3); + } + InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C1->getType(), Instruction::InsertElement, + &Op<0>(), 3) { + Op<0>() = C1; + Op<1>() = C2; + Op<2>() = C3; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// ShuffleVectorConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// shufflevector constant exprs. +class ShuffleVectorConstantExpr : public ConstantExpr { + 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) { + return User::operator new(s, 3); + } + ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(VectorType::get( + cast(C1->getType())->getElementType(), + cast(C3->getType())->getNumElements()), + Instruction::ShuffleVector, + &Op<0>(), 3) { + Op<0>() = C1; + Op<1>() = C2; + Op<2>() = C3; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// ExtractValueConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// extractvalue constant exprs. +class ExtractValueConstantExpr : public ConstantExpr { + 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); + } + ExtractValueConstantExpr(Constant *Agg, + const SmallVector &IdxList, + Type *DestTy) + : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1), + Indices(IdxList) { + Op<0>() = Agg; + } + + /// Indices - These identify which value to extract. + const SmallVector Indices; + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// InsertValueConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// insertvalue constant exprs. +class InsertValueConstantExpr : public ConstantExpr { + 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, 2); + } + InsertValueConstantExpr(Constant *Agg, Constant *Val, + const SmallVector &IdxList, + Type *DestTy) + : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2), + Indices(IdxList) { + Op<0>() = Agg; + Op<1>() = Val; + } + + /// Indices - These identify the position for the insertion. + const SmallVector Indices; + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + + +/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is +/// used behind the scenes to implement getelementpr constant exprs. +class GetElementPtrConstantExpr : public ConstantExpr { + virtual void anchor(); + GetElementPtrConstantExpr(Constant *C, ArrayRef IdxList, + Type *DestTy); +public: + static GetElementPtrConstantExpr *Create(Constant *C, + ArrayRef IdxList, + Type *DestTy, + unsigned Flags) { + GetElementPtrConstantExpr *Result = + new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy); + Result->SubclassOptionalData = Flags; + return Result; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +// 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. +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(Type *ty, Instruction::OtherOps opc, + unsigned short pred, Constant* LHS, Constant* RHS) + : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) { + Op<0>() = LHS; + Op<1>() = RHS; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value) + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value) + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value) + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value) + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value) + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value) + +template <> +struct OperandTraits : + public VariadicOperandTraits { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value) + + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value) + +struct ExprMapKeyType { + ExprMapKeyType(unsigned opc, + ArrayRef ops, + unsigned short flags = 0, + unsigned short optionalflags = 0, + ArrayRef inds = ArrayRef()) + : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags), + operands(ops.begin(), ops.end()), indices(inds.begin(), inds.end()) {} + uint8_t opcode; + uint8_t subclassoptionaldata; + uint16_t subclassdata; + std::vector operands; + SmallVector indices; + bool operator==(const ExprMapKeyType& that) const { + return this->opcode == that.opcode && + this->subclassdata == that.subclassdata && + this->subclassoptionaldata == that.subclassoptionaldata && + this->operands == that.operands && + this->indices == that.indices; + } + bool operator<(const ExprMapKeyType & that) const { + if (this->opcode != that.opcode) return this->opcode < that.opcode; + if (this->operands != that.operands) return this->operands < that.operands; + if (this->subclassdata != that.subclassdata) + return this->subclassdata < that.subclassdata; + if (this->subclassoptionaldata != that.subclassoptionaldata) + return this->subclassoptionaldata < that.subclassoptionaldata; + if (this->indices != that.indices) return this->indices < that.indices; + return false; + } + + bool operator!=(const ExprMapKeyType& that) const { + return !(*this == that); + } +}; + +struct InlineAsmKeyType { + InlineAsmKeyType(StringRef AsmString, + StringRef Constraints, bool hasSideEffects, + bool isAlignStack, InlineAsm::AsmDialect asmDialect) + : asm_string(AsmString), constraints(Constraints), + 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->asm_dialect == that.asm_dialect; + } + bool operator<(const InlineAsmKeyType& that) const { + if (this->asm_string != that.asm_string) + return this->asm_string < that.asm_string; + if (this->constraints != that.constraints) + return this->constraints < that.constraints; + if (this->has_side_effects != that.has_side_effects) + 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; + } + + bool operator!=(const InlineAsmKeyType& that) const { + return !(*this == that); + } +}; + +// The number of operands for each ConstantCreator::create method is +// determined by the ConstantTraits template. +// ConstantCreator - A class that is used to create constants by +// ConstantUniqueMap*. This class should be partially specialized if there is +// something strange that needs to be done to interface to the ctor for the +// constant. +// +template +struct ConstantTraits< std::vector > { + static unsigned uses(const std::vector& v) { + return v.size(); + } +}; + +template<> +struct ConstantTraits { + static unsigned uses(Constant * const & v) { + return 1; + } +}; + +template +struct ConstantCreator { + 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; + static ValType getValType(ConstantClass *C) { + llvm_unreachable("Unknown Constant type!"); + } +}; + +template<> +struct ConstantCreator { + 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); + if ((V.opcode >= Instruction::BinaryOpsBegin && + V.opcode < Instruction::BinaryOpsEnd)) + return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1], + V.subclassoptionaldata); + if (V.opcode == Instruction::Select) + return new SelectConstantExpr(V.operands[0], V.operands[1], + V.operands[2]); + if (V.opcode == Instruction::ExtractElement) + return new ExtractElementConstantExpr(V.operands[0], V.operands[1]); + if (V.opcode == Instruction::InsertElement) + return new InsertElementConstantExpr(V.operands[0], V.operands[1], + V.operands[2]); + if (V.opcode == Instruction::ShuffleVector) + return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1], + V.operands[2]); + if (V.opcode == Instruction::InsertValue) + return new InsertValueConstantExpr(V.operands[0], V.operands[1], + V.indices, Ty); + if (V.opcode == Instruction::ExtractValue) + return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty); + if (V.opcode == Instruction::GetElementPtr) { + std::vector IdxList(V.operands.begin()+1, V.operands.end()); + return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty, + V.subclassoptionaldata); + } + + // The compare instructions are weird. We have to encode the predicate + // value and it is combined with the instruction opcode by multiplying + // the opcode by one hundred. We must decode this to get the predicate. + if (V.opcode == Instruction::ICmp) + return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata, + V.operands[0], V.operands[1]); + if (V.opcode == Instruction::FCmp) + return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata, + V.operands[0], V.operands[1]); + llvm_unreachable("Invalid ConstantExpr!"); + } +}; + +template<> +struct ConstantKeyData { + typedef ExprMapKeyType ValType; + static ValType getValType(ConstantExpr *CE) { + std::vector Operands; + Operands.reserve(CE->getNumOperands()); + for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) + Operands.push_back(cast(CE->getOperand(i))); + return ExprMapKeyType(CE->getOpcode(), Operands, + CE->isCompare() ? CE->getPredicate() : 0, + CE->getRawSubclassOptionalData(), + CE->hasIndices() ? + CE->getIndices() : ArrayRef()); + } +}; + +template<> +struct ConstantCreator { + 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.asm_dialect); + } +}; + +template<> +struct ConstantKeyData { + typedef InlineAsmKeyType ValType; + static ValType getValType(InlineAsm *Asm) { + return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(), + Asm->hasSideEffects(), Asm->isAlignStack(), + Asm->getDialect()); + } +}; + +template +class ConstantUniqueMap { +public: + typedef std::pair MapKey; + typedef std::map MapTy; + typedef std::map InverseMapTy; +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; + + /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping + /// from the constants to their element in Map. This is important for + /// removal of constants from the array, which would otherwise have to scan + /// through the map with very large keys. + InverseMapTy InverseMap; + +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->second; + } + } + + /// InsertOrGetItem - Return an iterator for the specified element. + /// If the element exists in the map, the returned iterator points to the + /// entry and Exists=true. If not, the iterator points to the newly + /// inserted entry and returns Exists=false. Newly inserted entries have + /// I->second == 0, and should be filled in. + typename MapTy::iterator InsertOrGetItem(std::pair + &InsertVal, + bool &Exists) { + std::pair IP = Map.insert(InsertVal); + Exists = !IP.second; + return IP.first; + } + +private: + typename MapTy::iterator FindExistingElement(ConstantClass *CP) { + if (HasLargeKey) { + typename InverseMapTy::iterator IMI = InverseMap.find(CP); + assert(IMI != InverseMap.end() && IMI->second != Map.end() && + IMI->second->second == CP && + "InverseMap corrupt!"); + return IMI->second; + } + + typename MapTy::iterator I = + 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 + // performance problem, someone should look at this. + for (I = Map.begin(); I != Map.end() && I->second != CP; ++I) + /* empty */; + } + return I; + } + + ConstantClass *Create(TypeClass *Ty, ValRefType V, + typename MapTy::iterator I) { + ConstantClass* Result = + ConstantCreator::create(Ty, V); + + assert(Result->getType() == Ty && "Type specified is not correct!"); + I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result)); + + if (HasLargeKey) // Remember the reverse mapping if needed. + InverseMap.insert(std::make_pair(Result, I)); + + return Result; + } +public: + + /// getOrCreate - Return the specified constant from the map, creating it if + /// necessary. + ConstantClass *getOrCreate(TypeClass *Ty, ValRefType V) { + MapKey Lookup(Ty, V); + ConstantClass* Result = 0; + + typename MapTy::iterator I = Map.find(Lookup); + // Is it in the map? + if (I != Map.end()) + Result = I->second; + + if (!Result) { + // If no preexisting value, create one now... + Result = Create(Ty, V, I); + } + + return Result; + } + + void remove(ConstantClass *CP) { + typename MapTy::iterator I = FindExistingElement(CP); + assert(I != Map.end() && "Constant not found in constant table!"); + assert(I->second == CP && "Didn't find correct element?"); + + if (HasLargeKey) // Remember the reverse mapping if needed. + InverseMap.erase(CP); + + Map.erase(I); + } + + /// MoveConstantToNewSlot - If we are about to change C to be the element + /// specified by I, update our internal data structures to reflect this + /// fact. + void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) { + // First, remove the old location of the specified constant in the map. + typename MapTy::iterator OldI = FindExistingElement(C); + assert(OldI != Map.end() && "Constant not found in constant table!"); + assert(OldI->second == C && "Didn't find correct element?"); + + // Remove the old entry from the map. + Map.erase(OldI); + + // Update the inverse map so that we know that this constant is now + // located at descriptor I. + if (HasLargeKey) { + assert(I->second == C && "Bad inversemap entry!"); + InverseMap[C] = I; + } + } + + void dump() const { + DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); + } +}; + +// 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 -- cgit v1.1