X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FModule.cpp;h=ac578d6dba0fa3949cffbddb3d543aae492c96df;hb=62babebeeb57f8110c5b7233cb56dff38b10e840;hp=996c5b67a4183181da005f4897b3edf610432dda;hpb=0b5675926a3cecfa1f593567d60813924d0f49d6;p=oota-llvm.git diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp index 996c5b67a41..ac578d6dba0 100644 --- a/lib/IR/Module.cpp +++ b/lib/IR/Module.cpp @@ -17,15 +17,19 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/GVMaterializer.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/GVMaterializer.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/LLVMContext.h" -#include "llvm/Support/LeakDetector.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/RandomNumberGenerator.h" #include #include #include + using namespace llvm; //===----------------------------------------------------------------------===// @@ -34,16 +38,16 @@ using namespace llvm; // 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; +template class llvm::SymbolTableListTraits; +template class llvm::SymbolTableListTraits; //===----------------------------------------------------------------------===// // Primitive Module methods. // -Module::Module(StringRef MID, LLVMContext& C) - : Context(C), Materializer(NULL), ModuleID(MID) { +Module::Module(StringRef MID, LLVMContext &C) + : Context(C), Materializer(), ModuleID(MID), DL("") { ValSymTab = new ValueSymbolTable(); NamedMDSymTab = new StringMap(); Context.addModule(this); @@ -60,6 +64,24 @@ Module::~Module() { delete static_cast *>(NamedMDSymTab); } +RandomNumberGenerator *Module::createRNG(const Pass* P) const { + SmallString<32> Salt(P->getPassName()); + + // This RNG is guaranteed to produce the same random stream only + // when the Module ID and thus the input filename is the same. This + // might be problematic if the input filename extension changes + // (e.g. from .c to .bc or .ll). + // + // We could store this salt in NamedMetadata, but this would make + // the parameter non-const. This would unfortunately make this + // interface unusable by any Machine passes, since they only have a + // const reference to their IR Module. Alternatively we can always + // store salt metadata from the Module constructor. + Salt += sys::path::filename(getModuleIdentifier()); + + return new RandomNumberGenerator(Salt); +} + /// 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. @@ -80,6 +102,9 @@ void Module::getMDKindNames(SmallVectorImpl &Result) const { return Context.getMDKindNames(Result); } +void Module::getOperandBundleTags(SmallVectorImpl &Result) const { + return Context.getOperandBundleTags(Result); +} //===----------------------------------------------------------------------===// // Methods for easy access to the functions in the module. @@ -95,7 +120,7 @@ Constant *Module::getOrInsertFunction(StringRef Name, AttributeSet AttributeList) { // See if we have a definition for the specified function already. GlobalValue *F = getNamedValue(Name); - if (F == 0) { + if (!F) { // Nope, add it Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name); if (!New->isIntrinsic()) // Intrinsics get attrs set on construction @@ -104,16 +129,6 @@ Constant *Module::getOrInsertFunction(StringRef Name, return New; // Return the new prototype. } - // Okay, the function exists. Does it have externally visible linkage? - if (F->hasLocalLinkage()) { - // Clear the function's name. - F->setName(""); - // Retry, now there won't be a conflict. - Constant *NewF = getOrInsertFunction(Name, Ty); - F->setName(Name); - return NewF; - } - // If the function exists but has the wrong type, return a bitcast to the // right type. if (F->getType() != PointerType::getUnqual(Ty)) @@ -193,7 +208,7 @@ GlobalVariable *Module::getGlobalVariable(StringRef Name, bool AllowLocal) { dyn_cast_or_null(getNamedValue(Name))) if (AllowLocal || !Result->hasLocalLinkage()) return Result; - return 0; + return nullptr; } /// getOrInsertGlobal - Look up the specified global in the module symbol table. @@ -205,11 +220,11 @@ GlobalVariable *Module::getGlobalVariable(StringRef Name, bool AllowLocal) { 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) { + if (!GV) { // Nope, add it GlobalVariable *New = new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage, - 0, Name); + nullptr, Name); return New; // Return the new declaration. } @@ -262,7 +277,18 @@ NamedMDNode *Module::getOrInsertNamedMetadata(StringRef Name) { /// delete it. void Module::eraseNamedMetadata(NamedMDNode *NMD) { static_cast *>(NamedMDSymTab)->erase(NMD->getName()); - NamedMDList.erase(NMD); + NamedMDList.erase(NMD->getIterator()); +} + +bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) { + if (ConstantInt *Behavior = mdconst::dyn_extract_or_null(MD)) { + uint64_t Val = Behavior->getLimitedValue(); + if (Val >= ModFlagBehaviorFirstVal && Val <= ModFlagBehaviorLastVal) { + MFB = static_cast(Val); + return true; + } + } + return false; } /// getModuleFlagsMetadata - Returns the module flags in the provided vector. @@ -271,32 +297,30 @@ 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); - if (Flag->getNumOperands() >= 3 && isa(Flag->getOperand(0)) && - isa(Flag->getOperand(1))) { + for (const MDNode *Flag : ModFlags->operands()) { + ModFlagBehavior MFB; + if (Flag->getNumOperands() >= 3 && + isValidModFlagBehavior(Flag->getOperand(0), MFB) && + dyn_cast_or_null(Flag->getOperand(1))) { // Check the operands of the MDNode before accessing the operands. // The verifier will actually catch these failures. - 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)); + Metadata *Val = Flag->getOperand(2); + Flags.push_back(ModuleFlagEntry(MFB, Key, Val)); } } } /// Return the corresponding value if Key appears in module flags, otherwise /// return null. -Value *Module::getModuleFlag(StringRef Key) const { +Metadata *Module::getModuleFlag(StringRef Key) const { SmallVector ModuleFlags; getModuleFlagsMetadata(ModuleFlags); - for (unsigned I = 0, E = ModuleFlags.size(); I < E; ++I) { - const ModuleFlagEntry &MFE = ModuleFlags[I]; + for (const ModuleFlagEntry &MFE : ModuleFlags) { if (Key == MFE.Key->getString()) return MFE.Val; } - return 0; + return nullptr; } /// getModuleFlagsMetadata - Returns the NamedMDNode in the module that @@ -317,13 +341,17 @@ NamedMDNode *Module::getOrInsertModuleFlagsMetadata() { /// 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) { + Metadata *Val) { Type *Int32Ty = Type::getInt32Ty(Context); - Value *Ops[3] = { - ConstantInt::get(Int32Ty, Behavior), MDString::get(Context, Key), Val - }; + Metadata *Ops[3] = { + ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Behavior)), + MDString::get(Context, Key), Val}; getOrInsertModuleFlagsMetadata()->addOperand(MDNode::get(Context, Ops)); } +void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, + Constant *Val) { + addModuleFlag(Behavior, Key, ConstantAsMetadata::get(Val)); +} void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, uint32_t Val) { Type *Int32Ty = Type::getInt32Ty(Context); @@ -332,73 +360,67 @@ void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, void Module::addModuleFlag(MDNode *Node) { assert(Node->getNumOperands() == 3 && "Invalid number of operands for module flag!"); - assert(isa(Node->getOperand(0)) && + assert(mdconst::hasa(Node->getOperand(0)) && isa(Node->getOperand(1)) && "Invalid operand types for module flag!"); getOrInsertModuleFlagsMetadata()->addOperand(Node); } +void Module::setDataLayout(StringRef Desc) { + DL.reset(Desc); +} + +void Module::setDataLayout(const DataLayout &Other) { DL = Other; } + +const DataLayout &Module::getDataLayout() const { return DL; } + //===----------------------------------------------------------------------===// // Methods to control the materialization of GlobalValues in the Module. // void Module::setMaterializer(GVMaterializer *GVM) { assert(!Materializer && - "Module already has a GVMaterializer. Call MaterializeAllPermanently" + "Module already has a GVMaterializer. Call materializeAll" " 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; -} - -bool Module::Materialize(GlobalValue *GV, std::string *ErrInfo) { +std::error_code Module::materialize(GlobalValue *GV) { if (!Materializer) - return false; + return std::error_code(); - error_code EC = Materializer->Materialize(GV); - if (!EC) - return false; - if (ErrInfo) - *ErrInfo = EC.message(); - return true; + return Materializer->materialize(GV); } -void Module::Dematerialize(GlobalValue *GV) { - if (Materializer) - return Materializer->Dematerialize(GV); +std::error_code Module::materializeAll() { + if (!Materializer) + return std::error_code(); + std::unique_ptr M = std::move(Materializer); + return M->materializeModule(); } -bool Module::MaterializeAll(std::string *ErrInfo) { +std::error_code Module::materializeMetadata() { if (!Materializer) - return false; - error_code EC = Materializer->MaterializeModule(this); - if (!EC) - return false; - if (ErrInfo) - *ErrInfo = EC.message(); - return true; -} - -bool Module::MaterializeAllPermanently(std::string *ErrInfo) { - if (MaterializeAll(ErrInfo)) - return true; - Materializer.reset(); - return false; + return std::error_code(); + return Materializer->materializeMetadata(); } //===----------------------------------------------------------------------===// // Other module related stuff. // +std::vector Module::getIdentifiedStructTypes() const { + // If we have a materializer, it is possible that some unread function + // uses a type that is currently not visible to a TypeFinder, so ask + // the materializer which types it created. + if (Materializer) + return Materializer->getIdentifiedStructTypes(); + + std::vector Ret; + TypeFinder SrcStructTypes; + SrcStructTypes.run(*this, true); + Ret.assign(SrcStructTypes.begin(), SrcStructTypes.end()); + return Ret; +} // dropAllReferences() - This function causes all the subelements to "let go" // of all references that they are maintaining. This allows one to 'delete' a @@ -408,12 +430,58 @@ bool Module::MaterializeAllPermanently(std::string *ErrInfo) { // has "dropped all references", except operator delete. // void Module::dropAllReferences() { - for(Module::iterator I = begin(), E = end(); I != E; ++I) - I->dropAllReferences(); + for (Function &F : *this) + F.dropAllReferences(); + + for (GlobalVariable &GV : globals()) + GV.dropAllReferences(); + + for (GlobalAlias &GA : aliases()) + GA.dropAllReferences(); +} + +unsigned Module::getDwarfVersion() const { + auto *Val = cast_or_null(getModuleFlag("Dwarf Version")); + if (!Val) + return 0; + return cast(Val->getValue())->getZExtValue(); +} - for(Module::global_iterator I = global_begin(), E = global_end(); I != E; ++I) - I->dropAllReferences(); +unsigned Module::getCodeViewFlag() const { + auto *Val = cast_or_null(getModuleFlag("CodeView")); + if (!Val) + return 0; + return cast(Val->getValue())->getZExtValue(); +} + +Comdat *Module::getOrInsertComdat(StringRef Name) { + auto &Entry = *ComdatSymTab.insert(std::make_pair(Name, Comdat())).first; + Entry.second.Name = &Entry; + return &Entry.second; +} + +PICLevel::Level Module::getPICLevel() const { + auto *Val = cast_or_null(getModuleFlag("PIC Level")); + + if (!Val) + return PICLevel::Default; + + return static_cast( + cast(Val->getValue())->getZExtValue()); +} + +void Module::setPICLevel(PICLevel::Level PL) { + addModuleFlag(ModFlagBehavior::Error, "PIC Level", PL); +} + +void Module::setMaximumFunctionCount(uint64_t Count) { + addModuleFlag(ModFlagBehavior::Error, "MaxFunctionCount", Count); +} - for(Module::alias_iterator I = alias_begin(), E = alias_end(); I != E; ++I) - I->dropAllReferences(); +Optional Module::getMaximumFunctionCount() { + auto *Val = + cast_or_null(getModuleFlag("MaxFunctionCount")); + if (!Val) + return None; + return cast(Val->getValue())->getZExtValue(); }