X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstantsContext.h;h=cfcdf134ab84078ad3532c30c3eccf896714f30c;hb=34786a3ad760b9901912f70a8a17fd85e0643f21;hp=08224e4488b08d381c4f700e02a0a6dea426cecf;hpb=da23d93d9bb6238757e29b1abee571a0052ab8fc;p=oota-llvm.git diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h index 08224e4488b..cfcdf134ab8 100644 --- a/lib/VMCore/ConstantsContext.h +++ b/lib/VMCore/ConstantsContext.h @@ -15,6 +15,7 @@ #ifndef LLVM_CONSTANTSCONTEXT_H #define LLVM_CONSTANTSCONTEXT_H +#include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Operator.h" #include "llvm/Support/Debug.h" @@ -29,13 +30,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 { + virtual void anchor(); void *operator new(size_t, unsigned); // DO NOT IMPLEMENT 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; } @@ -45,6 +47,7 @@ public: /// 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); // DO NOT IMPLEMENT public: // allocate space for exactly two operands @@ -65,6 +68,7 @@ public: /// 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); // DO NOT IMPLEMENT public: // allocate space for exactly three operands @@ -85,6 +89,7 @@ public: /// 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); // DO NOT IMPLEMENT public: // allocate space for exactly two operands @@ -105,6 +110,7 @@ public: /// 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); // DO NOT IMPLEMENT public: // allocate space for exactly three operands @@ -126,6 +132,7 @@ public: /// 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); // DO NOT IMPLEMENT public: // allocate space for exactly three operands @@ -150,6 +157,7 @@ public: /// 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); // DO NOT IMPLEMENT public: // allocate space for exactly one operand @@ -158,7 +166,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; @@ -175,6 +183,7 @@ public: /// 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); // DO NOT IMPLEMENT public: // allocate space for exactly one operand @@ -183,7 +192,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; @@ -201,12 +210,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 { + virtual void anchor(); GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, - const Type *DestTy); + Type *DestTy); public: static GetElementPtrConstantExpr *Create(Constant *C, const std::vector&IdxList, - const Type *DestTy, + Type *DestTy, unsigned Flags) { GetElementPtrConstantExpr *Result = new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy); @@ -220,14 +230,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 { +class CompareConstantExpr : public ConstantExpr { + virtual void anchor(); void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +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; @@ -238,72 +250,80 @@ struct CompareConstantExpr : public ConstantExpr { }; template <> -struct OperandTraits : public FixedNumOperandTraits<1> { +struct OperandTraits : + public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value) template <> -struct OperandTraits : public FixedNumOperandTraits<2> { +struct OperandTraits : + public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value) template <> -struct OperandTraits : public FixedNumOperandTraits<3> { +struct OperandTraits : + public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value) template <> -struct OperandTraits : public FixedNumOperandTraits<2> { +struct OperandTraits : + public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value) template <> -struct OperandTraits : public FixedNumOperandTraits<3> { +struct OperandTraits : + public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) template <> -struct OperandTraits : public FixedNumOperandTraits<3> { +struct OperandTraits : + public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) template <> -struct OperandTraits : public FixedNumOperandTraits<1> { +struct OperandTraits : + public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value) template <> -struct OperandTraits : public FixedNumOperandTraits<2> { +struct OperandTraits : + public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value) template <> -struct OperandTraits : public VariadicOperandTraits<1> { +struct OperandTraits : + public VariadicOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value) template <> -struct OperandTraits : public FixedNumOperandTraits<2> { +struct OperandTraits : + public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value) struct ExprMapKeyType { - typedef SmallVector IndexList; - ExprMapKeyType(unsigned opc, - const std::vector &ops, + ArrayRef ops, unsigned short flags = 0, unsigned short optionalflags = 0, - const IndexList &inds = IndexList()) + ArrayRef inds = ArrayRef()) : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags), - operands(ops), indices(inds) {} + operands(ops.begin(), ops.end()), indices(inds.begin(), inds.end()) {} uint8_t opcode; uint8_t subclassoptionaldata; uint16_t subclassdata; std::vector operands; - IndexList indices; + SmallVector indices; bool operator==(const ExprMapKeyType& that) const { return this->opcode == that.opcode && this->subclassdata == that.subclassdata && @@ -327,6 +347,39 @@ struct ExprMapKeyType { } }; +struct InlineAsmKeyType { + InlineAsmKeyType(StringRef AsmString, + StringRef Constraints, bool hasSideEffects, + bool isAlignStack) + : asm_string(AsmString), constraints(Constraints), + has_side_effects(hasSideEffects), is_align_stack(isAlignStack) {} + std::string asm_string; + std::string constraints; + bool has_side_effects; + bool is_align_stack; + 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; + } + 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; + 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 @@ -341,9 +394,16 @@ struct ConstantTraits< std::vector > { } }; +template<> +struct ConstantTraits { + static unsigned uses(Constant * const & v) { + return 1; + } +}; + 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); } }; @@ -358,7 +418,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); @@ -414,14 +474,14 @@ struct ConstantKeyData { CE->isCompare() ? CE->getPredicate() : 0, CE->getRawSubclassOptionalData(), CE->hasIndices() ? - CE->getIndices() : SmallVector()); + CE->getIndices() : ArrayRef()); } }; // ConstantAggregateZero does not take extra "value" argument... template struct ConstantCreator { - static ConstantAggregateZero *create(const Type *Ty, const ValType &V){ + static ConstantAggregateZero *create(Type *Ty, const ValType &V){ return new ConstantAggregateZero(Ty); } }; @@ -473,7 +533,7 @@ struct ConstantKeyData { // ConstantPointerNull does not take extra "value" argument... template struct ConstantCreator { - static ConstantPointerNull *create(const PointerType *Ty, const ValType &V){ + static ConstantPointerNull *create(PointerType *Ty, const ValType &V){ return new ConstantPointerNull(Ty); } }; @@ -489,7 +549,7 @@ struct ConstantKeyData { // UndefValue does not take extra "value" argument... template struct ConstantCreator { - static UndefValue *create(const Type *Ty, const ValType &V) { + static UndefValue *create(Type *Ty, const ValType &V) { return new UndefValue(Ty); } }; @@ -502,15 +562,30 @@ struct ConstantKeyData { } }; -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); + } +}; + +template<> +struct ConstantKeyData { + typedef InlineAsmKeyType ValType; + static ValType getValType(InlineAsm *Asm) { + return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(), + Asm->hasSideEffects(), Asm->isAlignStack()); + } +}; + +template -class ConstantUniqueMap : public AbstractTypeUser { +class ConstantUniqueMap { public: - typedef std::pair MapKey; + typedef std::pair MapKey; typedef std::map MapTy; typedef std::map InverseMapTy; - typedef std::map - AbstractTypeMapTy; 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 @@ -523,10 +598,6 @@ private: /// through the map with very large keys. InverseMapTy InverseMap; - /// AbstractTypeMap - Map for abstract type constants. - /// - AbstractTypeMapTy AbstractTypeMap; - public: typename MapTy::iterator map_begin() { return Map.begin(); } typename MapTy::iterator map_end() { return Map.end(); } @@ -534,8 +605,8 @@ public: void freeConstants() { for (typename MapTy::iterator I=Map.begin(), E=Map.end(); I != E; ++I) { - if (I->second->use_empty()) - delete I->second; + // Asserts that use_empty(). + delete I->second; } } @@ -563,7 +634,7 @@ private: } typename MapTy::iterator I = - Map.find(MapKey(static_cast(CP->getRawType()), + 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 @@ -573,24 +644,8 @@ private: } return I; } - - void AddAbstractTypeUser(const Type *Ty, typename MapTy::iterator I) { - // If the type of the constant is abstract, make sure that an entry - // exists for it in the AbstractTypeMap. - if (Ty->isAbstract()) { - const DerivedType *DTy = static_cast(Ty); - typename AbstractTypeMapTy::iterator TI = AbstractTypeMap.find(DTy); - - if (TI == AbstractTypeMap.end()) { - // Add ourselves to the ATU list of the type. - cast(DTy)->addAbstractTypeUser(this); - - AbstractTypeMap.insert(TI, std::make_pair(DTy, I)); - } - } - } - ConstantClass* Create(const TypeClass *Ty, const ValType &V, + ConstantClass *Create(TypeClass *Ty, ValRefType V, typename MapTy::iterator I) { ConstantClass* Result = ConstantCreator::create(Ty, V); @@ -601,15 +656,13 @@ private: if (HasLargeKey) // Remember the reverse mapping if needed. InverseMap.insert(std::make_pair(Result, I)); - AddAbstractTypeUser(Ty, I); - return Result; } public: /// getOrCreate - Return the specified constant from the map, creating it if /// necessary. - ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) { + ConstantClass *getOrCreate(TypeClass *Ty, ValRefType V) { MapKey Lookup(Ty, V); ConstantClass* Result = 0; @@ -626,43 +679,6 @@ public: return Result; } - void UpdateAbstractTypeMap(const DerivedType *Ty, - typename MapTy::iterator I) { - assert(AbstractTypeMap.count(Ty) && - "Abstract type not in AbstractTypeMap?"); - typename MapTy::iterator &ATMEntryIt = AbstractTypeMap[Ty]; - if (ATMEntryIt == I) { - // Yes, we are removing the representative entry for this type. - // See if there are any other entries of the same type. - typename MapTy::iterator TmpIt = ATMEntryIt; - - // First check the entry before this one... - if (TmpIt != Map.begin()) { - --TmpIt; - if (TmpIt->first.first != Ty) // Not the same type, move back... - ++TmpIt; - } - - // If we didn't find the same type, try to move forward... - if (TmpIt == ATMEntryIt) { - ++TmpIt; - if (TmpIt == Map.end() || TmpIt->first.first != Ty) - --TmpIt; // No entry afterwards with the same type - } - - // If there is another entry in the map of the same abstract type, - // update the AbstractTypeMap entry now. - if (TmpIt != ATMEntryIt) { - ATMEntryIt = TmpIt; - } else { - // Otherwise, we are removing the last instance of this type - // from the table. Remove from the ATM, and from user list. - cast(Ty)->removeAbstractTypeUser(this); - AbstractTypeMap.erase(Ty); - } - } - } - void remove(ConstantClass *CP) { typename MapTy::iterator I = FindExistingElement(CP); assert(I != Map.end() && "Constant not found in constant table!"); @@ -670,12 +686,6 @@ public: if (HasLargeKey) // Remember the reverse mapping if needed. InverseMap.erase(CP); - - // Now that we found the entry, make sure this isn't the entry that - // the AbstractTypeMap points to. - const TypeClass *Ty = I->first.first; - if (Ty->isAbstract()) - UpdateAbstractTypeMap(static_cast(Ty), I); Map.erase(I); } @@ -689,18 +699,7 @@ public: assert(OldI != Map.end() && "Constant not found in constant table!"); assert(OldI->second == C && "Didn't find correct element?"); - // If this constant is the representative element for its abstract type, - // update the AbstractTypeMap so that the representative element is I. - if (C->getType()->isAbstract()) { - typename AbstractTypeMapTy::iterator ATI = - AbstractTypeMap.find(C->getType()); - assert(ATI != AbstractTypeMap.end() && - "Abstract type not in AbstractTypeMap?"); - if (ATI->second == OldI) - ATI->second = I; - } - - // Remove the old entry from the map. + // Remove the old entry from the map. Map.erase(OldI); // Update the inverse map so that we know that this constant is now @@ -710,58 +709,6 @@ public: InverseMap[C] = I; } } - - void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { - typename AbstractTypeMapTy::iterator I = AbstractTypeMap.find(OldTy); - - assert(I != AbstractTypeMap.end() && - "Abstract type not in AbstractTypeMap?"); - - // Convert a constant at a time until the last one is gone. The last one - // leaving will remove() itself, causing the AbstractTypeMapEntry to be - // eliminated eventually. - do { - ConstantClass *C = I->second->second; - MapKey Key(cast(NewTy), - ConstantKeyData::getValType(C)); - - std::pair IP = - Map.insert(std::make_pair(Key, C)); - if (IP.second) { - // The map didn't previously have an appropriate constant in the - // new type. - - // Remove the old entry. - typename MapTy::iterator OldI = - Map.find(MapKey(cast(OldTy), IP.first->first.second)); - assert(OldI != Map.end() && "Constant not in map!"); - UpdateAbstractTypeMap(OldTy, OldI); - Map.erase(OldI); - - // Set the constant's type. This is done in place! - setType(C, NewTy); - - // Update the inverse map so that we know that this constant is now - // located at descriptor I. - if (HasLargeKey) - InverseMap[C] = IP.first; - - AddAbstractTypeUser(NewTy, IP.first); - } else { - // The map already had an appropriate constant in the new type, so - // there's no longer a need for the old constant. - C->uncheckedReplaceAllUsesWith(IP.first->second); - C->destroyConstant(); // This constant is now dead, destroy it. - } - I = AbstractTypeMap.find(OldTy); - } while (I != AbstractTypeMap.end()); - } - - // If the type became concrete without being refined to any other existing - // type, we just remove ourselves from the ATU list. - void typeBecameConcrete(const DerivedType *AbsTy) { - AbsTy->removeAbstractTypeUser(this); - } void dump() const { DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n");