diff options
Diffstat (limited to 'contrib/llvm/lib/IR/Module.cpp')
-rw-r--r-- | contrib/llvm/lib/IR/Module.cpp | 119 |
1 files changed, 70 insertions, 49 deletions
diff --git a/contrib/llvm/lib/IR/Module.cpp b/contrib/llvm/lib/IR/Module.cpp index 58584bd..d32ffcd 100644 --- a/contrib/llvm/lib/IR/Module.cpp +++ b/contrib/llvm/lib/IR/Module.cpp @@ -22,7 +22,7 @@ #include "llvm/IR/GVMaterializer.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/LLVMContext.h" -#include "llvm/IR/LeakDetector.h" +#include "llvm/IR/TypeFinder.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Path.h" #include "llvm/Support/RandomNumberGenerator.h" @@ -46,7 +46,7 @@ template class llvm::SymbolTableListTraits<GlobalAlias, Module>; // Module::Module(StringRef MID, LLVMContext &C) - : Context(C), Materializer(), ModuleID(MID), RNG(nullptr), DL("") { + : Context(C), Materializer(), ModuleID(MID), DL("") { ValSymTab = new ValueSymbolTable(); NamedMDSymTab = new StringMap<NamedMDNode *>(); Context.addModule(this); @@ -61,9 +61,27 @@ Module::~Module() { NamedMDList.clear(); delete ValSymTab; delete static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab); - delete RNG; } +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. @@ -259,6 +277,17 @@ void Module::eraseNamedMetadata(NamedMDNode *NMD) { NamedMDList.erase(NMD); } +bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) { + if (ConstantInt *Behavior = mdconst::dyn_extract<ConstantInt>(MD)) { + uint64_t Val = Behavior->getLimitedValue(); + if (Val >= ModFlagBehaviorFirstVal && Val <= ModFlagBehaviorLastVal) { + MFB = static_cast<ModFlagBehavior>(Val); + return true; + } + } + return false; +} + /// getModuleFlagsMetadata - Returns the module flags in the provided vector. void Module:: getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const { @@ -266,22 +295,22 @@ getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const { if (!ModFlags) return; for (const MDNode *Flag : ModFlags->operands()) { - if (Flag->getNumOperands() >= 3 && isa<ConstantInt>(Flag->getOperand(0)) && + ModFlagBehavior MFB; + if (Flag->getNumOperands() >= 3 && + isValidModFlagBehavior(Flag->getOperand(0), MFB) && isa<MDString>(Flag->getOperand(1))) { // Check the operands of the MDNode before accessing the operands. // The verifier will actually catch these failures. - ConstantInt *Behavior = cast<ConstantInt>(Flag->getOperand(0)); MDString *Key = cast<MDString>(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<Module::ModuleFlagEntry, 8> ModuleFlags; getModuleFlagsMetadata(ModuleFlags); for (const ModuleFlagEntry &MFE : ModuleFlags) { @@ -309,14 +338,18 @@ 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); addModuleFlag(Behavior, Key, ConstantInt::get(Int32Ty, Val)); @@ -324,7 +357,7 @@ 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<ConstantInt>(Node->getOperand(0)) && + assert(mdconst::hasa<ConstantInt>(Node->getOperand(0)) && isa<MDString>(Node->getOperand(1)) && "Invalid operand types for module flag!"); getOrInsertModuleFlagsMetadata()->addOperand(Node); @@ -358,16 +391,6 @@ const DataLayout *Module::getDataLayout() const { return &DL; } -// We want reproducible builds, but ModuleID may be a full path so we just use -// the filename to salt the RNG (although it is not guaranteed to be unique). -RandomNumberGenerator &Module::getRNG() const { - if (RNG == nullptr) { - StringRef Salt = sys::path::filename(ModuleID); - RNG = new RandomNumberGenerator(Salt); - } - return *RNG; -} - //===----------------------------------------------------------------------===// // Methods to control the materialization of GlobalValues in the Module. // @@ -378,28 +401,17 @@ void Module::setMaterializer(GVMaterializer *GVM) { 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(); - std::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) { @@ -413,13 +425,10 @@ std::error_code Module::materializeAll() { return Materializer->MaterializeModule(this); } -std::error_code Module::materializeAllPermanently(bool ReleaseBuffer) { +std::error_code Module::materializeAllPermanently() { if (std::error_code EC = materializeAll()) return EC; - if (ReleaseBuffer) - Materializer->releaseBuffer(); - Materializer.reset(); return std::error_code(); } @@ -428,6 +437,19 @@ std::error_code Module::materializeAllPermanently(bool ReleaseBuffer) { // Other module related stuff. // +std::vector<StructType *> 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<StructType *> 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 @@ -448,27 +470,26 @@ void Module::dropAllReferences() { } unsigned Module::getDwarfVersion() const { - Value *Val = getModuleFlag("Dwarf Version"); + auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Dwarf Version")); if (!Val) return dwarf::DWARF_VERSION; - return cast<ConstantInt>(Val)->getZExtValue(); + return cast<ConstantInt>(Val->getValue())->getZExtValue(); } Comdat *Module::getOrInsertComdat(StringRef Name) { - Comdat C; - StringMapEntry<Comdat> &Entry = - ComdatSymTab.GetOrCreateValue(Name, std::move(C)); + auto &Entry = *ComdatSymTab.insert(std::make_pair(Name, Comdat())).first; Entry.second.Name = &Entry; return &Entry.second; } PICLevel::Level Module::getPICLevel() const { - Value *Val = getModuleFlag("PIC Level"); + auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIC Level")); if (Val == NULL) return PICLevel::Default; - return static_cast<PICLevel::Level>(cast<ConstantInt>(Val)->getZExtValue()); + return static_cast<PICLevel::Level>( + cast<ConstantInt>(Val->getValue())->getZExtValue()); } void Module::setPICLevel(PICLevel::Level PL) { |