diff options
Diffstat (limited to 'lib/IR/Module.cpp')
| -rw-r--r-- | lib/IR/Module.cpp | 128 | 
1 files changed, 81 insertions, 47 deletions
| diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp index f1b1f9a2acc8..d32ffcdac337 100644 --- a/lib/IR/Module.cpp +++ b/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,16 +470,28 @@ 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 { +  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIC Level")); + +  if (Val == NULL) +    return PICLevel::Default; + +  return static_cast<PICLevel::Level>( +      cast<ConstantInt>(Val->getValue())->getZExtValue()); +} + +void Module::setPICLevel(PICLevel::Level PL) { +  addModuleFlag(ModFlagBehavior::Error, "PIC Level", PL); +} | 
