X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FModule.cpp;h=5b5176b3c70bc5150b934eccecb9ac248ae50db5;hb=ad41dcfd875e8d3421a5f0970b6a886b6e10b3b7;hp=503e70891721bfa4f8cc6c4992edb3dada455229;hpb=26028f27ddd132b3284943e11aca130c2911abc4;p=oota-llvm.git diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index 503e7089172..5b5176b3c70 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -15,12 +15,14 @@ #include "llvm/InstrTypes.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/GVMaterializer.h" #include "llvm/LLVMContext.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/LeakDetector.h" #include "SymbolTableListTraitsImpl.h" -#include "llvm/TypeSymbolTable.h" #include #include #include @@ -30,25 +32,10 @@ using namespace llvm; // Methods to implement the globals and functions lists. // -GlobalVariable *ilist_traits::createSentinel() { - GlobalVariable *Ret = new GlobalVariable(Type::getInt32Ty(getGlobalContext()), - false, GlobalValue::ExternalLinkage); - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(Ret); - return Ret; -} -GlobalAlias *ilist_traits::createSentinel() { - GlobalAlias *Ret = new GlobalAlias(Type::getInt32Ty(getGlobalContext()), - GlobalValue::ExternalLinkage); - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(Ret); - return Ret; -} - // Explicit instantiations of SymbolTableListTraits since some of the methods // are not in the public header file. -template class llvm::SymbolTableListTraits; template class llvm::SymbolTableListTraits; +template class llvm::SymbolTableListTraits; template class llvm::SymbolTableListTraits; //===----------------------------------------------------------------------===// @@ -56,13 +43,14 @@ template class llvm::SymbolTableListTraits; // Module::Module(StringRef MID, LLVMContext& C) - : Context(C), ModuleID(MID), DataLayout("") { + : Context(C), Materializer(NULL), ModuleID(MID) { ValSymTab = new ValueSymbolTable(); - TypeSymTab = new TypeSymbolTable(); - NamedMDSymTab = new MDSymbolTable(); + NamedMDSymTab = new StringMap(); + Context.addModule(this); } Module::~Module() { + Context.removeModule(this); dropAllReferences(); GlobalList.clear(); FunctionList.clear(); @@ -70,39 +58,41 @@ Module::~Module() { LibraryList.clear(); NamedMDList.clear(); delete ValSymTab; - delete TypeSymTab; - delete NamedMDSymTab; + delete static_cast *>(NamedMDSymTab); } -/// Target endian information... +/// Target endian information. Module::Endianness Module::getEndianness() const { StringRef temp = DataLayout; Module::Endianness ret = AnyEndianness; - + while (!temp.empty()) { - StringRef token = DataLayout; - tie(token, temp) = getToken(DataLayout, "-"); - + std::pair P = getToken(temp, "-"); + + StringRef token = P.first; + temp = P.second; + if (token[0] == 'e') { ret = LittleEndian; } else if (token[0] == 'E') { ret = BigEndian; } } - + return ret; } -/// Target Pointer Size information... +/// Target Pointer Size information. Module::PointerSize Module::getPointerSize() const { StringRef temp = DataLayout; Module::PointerSize ret = AnyPointerSize; - + while (!temp.empty()) { - StringRef token, signalToken; - tie(token, temp) = getToken(temp, "-"); - tie(signalToken, token) = getToken(token, ":"); - + std::pair TmpP = getToken(temp, "-"); + temp = TmpP.second; + TmpP = getToken(TmpP.first, ":"); + StringRef token = TmpP.second, signalToken = TmpP.first; + if (signalToken[0] == 'p') { int size = 0; getToken(token, ":").first.getAsInteger(10, size); @@ -112,7 +102,7 @@ Module::PointerSize Module::getPointerSize() const { ret = Pointer64; } } - + return ret; } @@ -147,7 +137,7 @@ void Module::getMDKindNames(SmallVectorImpl &Result) const { // the symbol table directly for this common task. // Constant *Module::getOrInsertFunction(StringRef Name, - const FunctionType *Ty, + FunctionType *Ty, AttrListPtr AttributeList) { // See if we have a definition for the specified function already. GlobalValue *F = getNamedValue(Name); @@ -174,13 +164,13 @@ Constant *Module::getOrInsertFunction(StringRef Name, // right type. if (F->getType() != PointerType::getUnqual(Ty)) return ConstantExpr::getBitCast(F, PointerType::getUnqual(Ty)); - + // Otherwise, we just found the existing function or a prototype. - return F; + return F; } Constant *Module::getOrInsertTargetIntrinsic(StringRef Name, - const FunctionType *Ty, + FunctionType *Ty, AttrListPtr AttributeList) { // See if we have a definition for the specified function already. GlobalValue *F = getNamedValue(Name); @@ -193,13 +183,12 @@ Constant *Module::getOrInsertTargetIntrinsic(StringRef Name, } // Otherwise, we just found the existing function or a prototype. - return F; + return F; } Constant *Module::getOrInsertFunction(StringRef Name, - const FunctionType *Ty) { - AttrListPtr AttributeList = AttrListPtr::get((AttributeWithIndex *)0, 0); - return getOrInsertFunction(Name, Ty, AttributeList); + FunctionType *Ty) { + return getOrInsertFunction(Name, Ty, AttrListPtr()); } // getOrInsertFunction - Look up the specified function in the module symbol @@ -209,13 +198,13 @@ Constant *Module::getOrInsertFunction(StringRef Name, // Constant *Module::getOrInsertFunction(StringRef Name, AttrListPtr AttributeList, - const Type *RetTy, ...) { + Type *RetTy, ...) { va_list Args; va_start(Args, RetTy); // Build the list of argument types... - std::vector ArgTys; - while (const Type *ArgTy = va_arg(Args, const Type*)) + std::vector ArgTys; + while (Type *ArgTy = va_arg(Args, Type*)) ArgTys.push_back(ArgTy); va_end(Args); @@ -227,21 +216,21 @@ Constant *Module::getOrInsertFunction(StringRef Name, } Constant *Module::getOrInsertFunction(StringRef Name, - const Type *RetTy, ...) { + Type *RetTy, ...) { va_list Args; va_start(Args, RetTy); // Build the list of argument types... - std::vector ArgTys; - while (const Type *ArgTy = va_arg(Args, const Type*)) + std::vector ArgTys; + while (Type *ArgTy = va_arg(Args, Type*)) ArgTys.push_back(ArgTy); va_end(Args); // Build the function type and chain to the other getOrInsertFunction... - return getOrInsertFunction(Name, + return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false), - AttrListPtr::get((AttributeWithIndex *)0, 0)); + AttrListPtr()); } // getFunction - Look up the specified function in the module symbol table. @@ -264,7 +253,7 @@ Function *Module::getFunction(StringRef Name) const { /// GlobalVariable *Module::getGlobalVariable(StringRef Name, bool AllowLocal) const { - if (GlobalVariable *Result = + if (GlobalVariable *Result = dyn_cast_or_null(getNamedValue(Name))) if (AllowLocal || !Result->hasLocalLinkage()) return Result; @@ -277,7 +266,7 @@ GlobalVariable *Module::getGlobalVariable(StringRef Name, /// with a constantexpr cast to the right type. /// 3. Finally, if the existing global is the correct delclaration, return the /// existing global. -Constant *Module::getOrInsertGlobal(StringRef Name, const Type *Ty) { +Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { // See if we have a definition for the specified global already. GlobalVariable *GV = dyn_cast_or_null(getNamedValue(Name)); if (GV == 0) { @@ -292,7 +281,7 @@ Constant *Module::getOrInsertGlobal(StringRef Name, const Type *Ty) { // right type. if (GV->getType() != PointerType::getUnqual(Ty)) return ConstantExpr::getBitCast(GV, PointerType::getUnqual(Ty)); - + // Otherwise, we just found the existing function or a prototype. return GV; } @@ -309,66 +298,134 @@ GlobalAlias *Module::getNamedAlias(StringRef Name) const { } /// getNamedMetadata - Return the first NamedMDNode in the module with the -/// specified name. This method returns null if a NamedMDNode with the -//// specified name is not found. -NamedMDNode *Module::getNamedMetadata(StringRef Name) const { - return NamedMDSymTab->lookup(Name); +/// specified name. This method returns null if a NamedMDNode with the +/// specified name is not found. +NamedMDNode *Module::getNamedMetadata(const Twine &Name) const { + SmallString<256> NameData; + StringRef NameRef = Name.toStringRef(NameData); + return static_cast *>(NamedMDSymTab)->lookup(NameRef); } -/// getOrInsertNamedMetadata - Return the first named MDNode in the module -/// with the specified name. This method returns a new NamedMDNode if a +/// getOrInsertNamedMetadata - Return the first named MDNode in the module +/// with the specified name. This method returns a new NamedMDNode if a /// NamedMDNode with the specified name is not found. NamedMDNode *Module::getOrInsertNamedMetadata(StringRef Name) { - NamedMDNode *NMD = NamedMDSymTab->lookup(Name); - if (!NMD) - NMD = NamedMDNode::Create(getContext(), Name, NULL, 0, this); + NamedMDNode *&NMD = + (*static_cast *>(NamedMDSymTab))[Name]; + if (!NMD) { + NMD = new NamedMDNode(Name); + NMD->setParent(this); + NamedMDList.push_back(NMD); + } return NMD; } -//===----------------------------------------------------------------------===// -// Methods for easy access to the types in the module. -// +/// eraseNamedMetadata - Remove the given NamedMDNode from this module and +/// delete it. +void Module::eraseNamedMetadata(NamedMDNode *NMD) { + static_cast *>(NamedMDSymTab)->erase(NMD->getName()); + NamedMDList.erase(NMD); +} +/// getModuleFlagsMetadata - Returns the module flags in the provided vector. +void Module:: +getModuleFlagsMetadata(SmallVectorImpl &Flags) const { + const NamedMDNode *ModFlags = getModuleFlagsMetadata(); + if (!ModFlags) return; + + for (unsigned i = 0, e = ModFlags->getNumOperands(); i != e; ++i) { + MDNode *Flag = ModFlags->getOperand(i); + ConstantInt *Behavior = cast(Flag->getOperand(0)); + MDString *Key = cast(Flag->getOperand(1)); + Value *Val = Flag->getOperand(2); + Flags.push_back(ModuleFlagEntry(ModFlagBehavior(Behavior->getZExtValue()), + Key, Val)); + } +} -// addTypeName - Insert an entry in the symbol table mapping Str to Type. If -// there is already an entry for this name, true is returned and the symbol -// table is not modified. -// -bool Module::addTypeName(StringRef Name, const Type *Ty) { - TypeSymbolTable &ST = getTypeSymbolTable(); +/// getModuleFlagsMetadata - Returns the NamedMDNode in the module that +/// represents module-level flags. This method returns null if there are no +/// module-level flags. +NamedMDNode *Module::getModuleFlagsMetadata() const { + return getNamedMetadata("llvm.module.flags"); +} - if (ST.lookup(Name)) return true; // Already in symtab... +/// getOrInsertModuleFlagsMetadata - Returns the NamedMDNode in the module that +/// represents module-level flags. If module-level flags aren't found, it +/// creates the named metadata that contains them. +NamedMDNode *Module::getOrInsertModuleFlagsMetadata() { + return getOrInsertNamedMetadata("llvm.module.flags"); +} - // Not in symbol table? Set the name with the Symtab as an argument so the - // type knows what to update... - ST.insert(Name, Ty); +/// addModuleFlag - Add a module-level flag to the module-level flags +/// metadata. It will create the module-level flags named metadata if it doesn't +/// already exist. +void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, + Value *Val) { + Type *Int32Ty = Type::getInt32Ty(Context); + Value *Ops[3] = { + ConstantInt::get(Int32Ty, Behavior), MDString::get(Context, Key), Val + }; + getOrInsertModuleFlagsMetadata()->addOperand(MDNode::get(Context, Ops)); +} +void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, + uint32_t Val) { + Type *Int32Ty = Type::getInt32Ty(Context); + addModuleFlag(Behavior, Key, ConstantInt::get(Int32Ty, Val)); +} +void Module::addModuleFlag(MDNode *Node) { + assert(Node->getNumOperands() == 3 && + "Invalid number of operands for module flag!"); + assert(isa(Node->getOperand(0)) && + isa(Node->getOperand(1)) && + "Invalid operand types for module flag!"); + getOrInsertModuleFlagsMetadata()->addOperand(Node); +} +//===----------------------------------------------------------------------===// +// Methods to control the materialization of GlobalValues in the Module. +// +void Module::setMaterializer(GVMaterializer *GVM) { + assert(!Materializer && + "Module already has a GVMaterializer. Call MaterializeAllPermanently" + " to clear it out before setting another one."); + Materializer.reset(GVM); +} + +bool Module::isMaterializable(const GlobalValue *GV) const { + if (Materializer) + return Materializer->isMaterializable(GV); return false; } -/// getTypeByName - Return the type with the specified name in this module, or -/// null if there is none by that name. -const Type *Module::getTypeByName(StringRef Name) const { - const TypeSymbolTable &ST = getTypeSymbolTable(); - return cast_or_null(ST.lookup(Name)); +bool Module::isDematerializable(const GlobalValue *GV) const { + if (Materializer) + return Materializer->isDematerializable(GV); + return false; } -// getTypeName - If there is at least one entry in the symbol table for the -// specified type, return it. -// -std::string Module::getTypeName(const Type *Ty) const { - const TypeSymbolTable &ST = getTypeSymbolTable(); +bool Module::Materialize(GlobalValue *GV, std::string *ErrInfo) { + if (Materializer) + return Materializer->Materialize(GV, ErrInfo); + return false; +} - TypeSymbolTable::const_iterator TI = ST.begin(); - TypeSymbolTable::const_iterator TE = ST.end(); - if ( TI == TE ) return ""; // No names for types +void Module::Dematerialize(GlobalValue *GV) { + if (Materializer) + return Materializer->Dematerialize(GV); +} - while (TI != TE && TI->second != Ty) - ++TI; +bool Module::MaterializeAll(std::string *ErrInfo) { + if (!Materializer) + return false; + return Materializer->MaterializeModule(this, ErrInfo); +} - if (TI != TE) // Must have found an entry! - return TI->first; - return ""; // Must not have found anything... +bool Module::MaterializeAllPermanently(std::string *ErrInfo) { + if (MaterializeAll(ErrInfo)) + return true; + Materializer.reset(); + return false; } //===----------------------------------------------------------------------===// @@ -376,7 +433,7 @@ std::string Module::getTypeName(const Type *Ty) const { // -// dropAllReferences() - This function causes all the subelementss to "let go" +// dropAllReferences() - This function causes all the subelements to "let go" // of all references that they are maintaining. This allows one to 'delete' a // whole module at a time, even though there may be circular references... first // all references are dropped, and all use counts go to zero. Then everything