X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FModule.cpp;h=5b5176b3c70bc5150b934eccecb9ac248ae50db5;hb=ad41dcfd875e8d3421a5f0970b6a886b6e10b3b7;hp=896245d69e6754cb2b21cb9304f7b164fcc00c05;hpb=49de98214b82fefeb8f16efbf8cdd8813a85469b;p=oota-llvm.git diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index 896245d69e6..5b5176b3c70 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -15,11 +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 @@ -29,104 +32,101 @@ using namespace llvm; // Methods to implement the globals and functions lists. // -Function *ilist_traits::createSentinel() { - FunctionType *FTy = - FunctionType::get(Type::VoidTy, std::vector(), false); - Function *Ret = Function::Create(FTy, GlobalValue::ExternalLinkage); - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(Ret); - return Ret; -} -GlobalVariable *ilist_traits::createSentinel() { - GlobalVariable *Ret = new GlobalVariable(Type::Int32Ty, false, - GlobalValue::ExternalLinkage); - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(Ret); - return Ret; -} -GlobalAlias *ilist_traits::createSentinel() { - GlobalAlias *Ret = new GlobalAlias(Type::Int32Ty, - GlobalValue::ExternalLinkage); - // This should not be garbage monitored. - LeakDetector::removeGarbageObject(Ret); - return Ret; -} - -iplist &ilist_traits::getList(Module *M) { - return M->getFunctionList(); -} -iplist &ilist_traits::getList(Module *M) { - return M->getGlobalList(); -} -iplist &ilist_traits::getList(Module *M) { - return M->getAliasList(); -} - // Explicit instantiations of SymbolTableListTraits since some of the methods // are not in the public header file. -template class SymbolTableListTraits; -template class SymbolTableListTraits; -template class SymbolTableListTraits; +template class llvm::SymbolTableListTraits; +template class llvm::SymbolTableListTraits; +template class llvm::SymbolTableListTraits; //===----------------------------------------------------------------------===// // Primitive Module methods. // -Module::Module(const std::string &MID) - : ModuleID(MID), DataLayout("") { +Module::Module(StringRef MID, LLVMContext& C) + : Context(C), Materializer(NULL), ModuleID(MID) { ValSymTab = new ValueSymbolTable(); - TypeSymTab = new TypeSymbolTable(); + NamedMDSymTab = new StringMap(); + Context.addModule(this); } Module::~Module() { + Context.removeModule(this); dropAllReferences(); GlobalList.clear(); FunctionList.clear(); AliasList.clear(); LibraryList.clear(); + NamedMDList.clear(); delete ValSymTab; - delete TypeSymTab; + delete static_cast *>(NamedMDSymTab); } -/// Target endian information... +/// Target endian information. Module::Endianness Module::getEndianness() const { - std::string temp = DataLayout; + StringRef temp = DataLayout; Module::Endianness ret = AnyEndianness; - + while (!temp.empty()) { - std::string token = getToken(temp, "-"); - + 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 { - std::string temp = DataLayout; + StringRef temp = DataLayout; Module::PointerSize ret = AnyPointerSize; - + while (!temp.empty()) { - std::string token = getToken(temp, "-"); - char signal = getToken(token, ":")[0]; - - if (signal == 'p') { - int size = atoi(getToken(token, ":").c_str()); + 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); if (size == 32) ret = Pointer32; else if (size == 64) ret = Pointer64; } } - + return ret; } +/// getNamedValue - Return the first global value in the module with +/// the specified name, of arbitrary type. This method returns null +/// if a global with the specified name is not found. +GlobalValue *Module::getNamedValue(StringRef Name) const { + return cast_or_null(getValueSymbolTable().lookup(Name)); +} + +/// getMDKindID - Return a unique non-zero ID for the specified metadata kind. +/// This ID is uniqued across modules in the current LLVMContext. +unsigned Module::getMDKindID(StringRef Name) const { + return Context.getMDKindID(Name); +} + +/// getMDKindNames - Populate client supplied SmallVector with the name for +/// custom metadata IDs registered in this LLVMContext. ID #0 is not used, +/// so it is filled in as an empty string. +void Module::getMDKindNames(SmallVectorImpl &Result) const { + return Context.getMDKindNames(Result); +} + + //===----------------------------------------------------------------------===// // Methods for easy access to the functions in the module. // @@ -136,13 +136,11 @@ Module::PointerSize Module::getPointerSize() const { // it. This is nice because it allows most passes to get away with not handling // the symbol table directly for this common task. // -Constant *Module::getOrInsertFunction(const std::string &Name, - const FunctionType *Ty, +Constant *Module::getOrInsertFunction(StringRef Name, + FunctionType *Ty, AttrListPtr AttributeList) { - ValueSymbolTable &SymTab = getValueSymbolTable(); - // See if we have a definition for the specified function already. - GlobalValue *F = dyn_cast_or_null(SymTab.lookup(Name)); + GlobalValue *F = getNamedValue(Name); if (F == 0) { // Nope, add it Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name); @@ -158,7 +156,7 @@ Constant *Module::getOrInsertFunction(const std::string &Name, F->setName(""); // Retry, now there won't be a conflict. Constant *NewF = getOrInsertFunction(Name, Ty); - F->setName(&Name[0], Name.size()); + F->setName(Name); return NewF; } @@ -166,18 +164,16 @@ Constant *Module::getOrInsertFunction(const std::string &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(const std::string &Name, - const FunctionType *Ty, +Constant *Module::getOrInsertTargetIntrinsic(StringRef Name, + FunctionType *Ty, AttrListPtr AttributeList) { - ValueSymbolTable &SymTab = getValueSymbolTable(); - // See if we have a definition for the specified function already. - GlobalValue *F = dyn_cast_or_null(SymTab.lookup(Name)); + GlobalValue *F = getNamedValue(Name); if (F == 0) { // Nope, add it Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name); @@ -187,13 +183,12 @@ Constant *Module::getOrInsertTargetIntrinsic(const std::string &Name, } // Otherwise, we just found the existing function or a prototype. - return F; + return F; } -Constant *Module::getOrInsertFunction(const std::string &Name, - const FunctionType *Ty) { - AttrListPtr AttributeList = AttrListPtr::get((AttributeWithIndex *)0, 0); - return getOrInsertFunction(Name, Ty, AttributeList); +Constant *Module::getOrInsertFunction(StringRef Name, + FunctionType *Ty) { + return getOrInsertFunction(Name, Ty, AttrListPtr()); } // getOrInsertFunction - Look up the specified function in the module symbol @@ -201,52 +196,48 @@ Constant *Module::getOrInsertFunction(const std::string &Name, // This version of the method takes a null terminated list of function // arguments, which makes it easier for clients to use. // -Constant *Module::getOrInsertFunction(const std::string &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); // Build the function type and chain to the other getOrInsertFunction... - return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false), + return getOrInsertFunction(Name, + FunctionType::get(RetTy, ArgTys, false), AttributeList); } -Constant *Module::getOrInsertFunction(const std::string &Name, - const Type *RetTy, ...) { +Constant *Module::getOrInsertFunction(StringRef Name, + 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, FunctionType::get(RetTy, ArgTys, false), - AttrListPtr::get((AttributeWithIndex *)0, 0)); + return getOrInsertFunction(Name, + FunctionType::get(RetTy, ArgTys, false), + AttrListPtr()); } // getFunction - Look up the specified function in the module symbol table. // If it does not exist, return null. // -Function *Module::getFunction(const std::string &Name) const { - const ValueSymbolTable &SymTab = getValueSymbolTable(); - return dyn_cast_or_null(SymTab.lookup(Name)); -} - -Function *Module::getFunction(const char *Name) const { - const ValueSymbolTable &SymTab = getValueSymbolTable(); - return dyn_cast_or_null(SymTab.lookup(Name, Name+strlen(Name))); +Function *Module::getFunction(StringRef Name) const { + return dyn_cast_or_null(getNamedValue(Name)); } //===----------------------------------------------------------------------===// @@ -260,13 +251,12 @@ Function *Module::getFunction(const char *Name) const { /// If AllowLocal is set to true, this function will return types that /// have an local. By default, these types are not returned. /// -GlobalVariable *Module::getGlobalVariable(const std::string &Name, +GlobalVariable *Module::getGlobalVariable(StringRef Name, bool AllowLocal) const { - if (Value *V = ValSymTab->lookup(Name)) { - GlobalVariable *Result = dyn_cast(V); - if (Result && (AllowLocal || !Result->hasLocalLinkage())) + if (GlobalVariable *Result = + dyn_cast_or_null(getNamedValue(Name))) + if (AllowLocal || !Result->hasLocalLinkage()) return Result; - } return 0; } @@ -276,24 +266,22 @@ GlobalVariable *Module::getGlobalVariable(const std::string &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(const std::string &Name, const Type *Ty) { - ValueSymbolTable &SymTab = getValueSymbolTable(); - +Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { // See if we have a definition for the specified global already. - GlobalVariable *GV = dyn_cast_or_null(SymTab.lookup(Name)); + GlobalVariable *GV = dyn_cast_or_null(getNamedValue(Name)); if (GV == 0) { // Nope, add it GlobalVariable *New = - new GlobalVariable(Ty, false, GlobalVariable::ExternalLinkage, 0, Name); - GlobalList.push_back(New); - return New; // Return the new declaration. + new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage, + 0, Name); + return New; // Return the new declaration. } // If the variable exists but has the wrong type, return a bitcast to the // 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; } @@ -305,55 +293,139 @@ Constant *Module::getOrInsertGlobal(const std::string &Name, const Type *Ty) { // getNamedAlias - Look up the specified global in the module symbol table. // If it does not exist, return null. // -GlobalAlias *Module::getNamedAlias(const std::string &Name) const { - const ValueSymbolTable &SymTab = getValueSymbolTable(); - return dyn_cast_or_null(SymTab.lookup(Name)); +GlobalAlias *Module::getNamedAlias(StringRef Name) const { + return dyn_cast_or_null(getNamedValue(Name)); } -//===----------------------------------------------------------------------===// -// Methods for easy access to the types in the module. -// +/// 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(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 +/// NamedMDNode with the specified name is not found. +NamedMDNode *Module::getOrInsertNamedMetadata(StringRef Name) { + NamedMDNode *&NMD = + (*static_cast *>(NamedMDSymTab))[Name]; + if (!NMD) { + NMD = new NamedMDNode(Name); + NMD->setParent(this); + NamedMDList.push_back(NMD); + } + return NMD; +} -// 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(const std::string &Name, const Type *Ty) { - TypeSymbolTable &ST = getTypeSymbolTable(); +/// 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); +} - if (ST.lookup(Name)) return true; // Already in symtab... +/// 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)); + } +} - // Not in symbol table? Set the name with the Symtab as an argument so the - // type knows what to update... - ST.insert(Name, Ty); +/// 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"); +} - return false; +/// 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"); } -/// getTypeByName - Return the type with the specified name in this module, or -/// null if there is none by that name. -const Type *Module::getTypeByName(const std::string &Name) const { - const TypeSymbolTable &ST = getTypeSymbolTable(); - return cast_or_null(ST.lookup(Name)); +/// 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); } -// getTypeName - If there is at least one entry in the symbol table for the -// specified type, return it. +//===----------------------------------------------------------------------===// +// Methods to control the materialization of GlobalValues in the Module. // -std::string Module::getTypeName(const Type *Ty) const { - const TypeSymbolTable &ST = getTypeSymbolTable(); +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; +} + +bool Module::isDematerializable(const GlobalValue *GV) const { + if (Materializer) + return Materializer->isDematerializable(GV); + return false; +} - TypeSymbolTable::const_iterator TI = ST.begin(); - TypeSymbolTable::const_iterator TE = ST.end(); - if ( TI == TE ) return ""; // No names for types +bool Module::Materialize(GlobalValue *GV, std::string *ErrInfo) { + if (Materializer) + return Materializer->Materialize(GV, ErrInfo); + return false; +} - while (TI != TE && TI->second != Ty) - ++TI; +void Module::Dematerialize(GlobalValue *GV) { + if (Materializer) + return Materializer->Dematerialize(GV); +} - if (TI != TE) // Must have found an entry! - return TI->first; - return ""; // Must not have found anything... +bool Module::MaterializeAll(std::string *ErrInfo) { + if (!Materializer) + return false; + return Materializer->MaterializeModule(this, ErrInfo); +} + +bool Module::MaterializeAllPermanently(std::string *ErrInfo) { + if (MaterializeAll(ErrInfo)) + return true; + Materializer.reset(); + return false; } //===----------------------------------------------------------------------===// @@ -361,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 @@ -379,14 +451,14 @@ void Module::dropAllReferences() { I->dropAllReferences(); } -void Module::addLibrary(const std::string& Lib) { +void Module::addLibrary(StringRef Lib) { for (Module::lib_iterator I = lib_begin(), E = lib_end(); I != E; ++I) if (*I == Lib) return; LibraryList.push_back(Lib); } -void Module::removeLibrary(const std::string& Lib) { +void Module::removeLibrary(StringRef Lib) { LibraryListType::iterator I = LibraryList.begin(); LibraryListType::iterator E = LibraryList.end(); for (;I != E; ++I)