summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/IR/Module.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/IR/Module.cpp')
-rw-r--r--contrib/llvm/lib/IR/Module.cpp119
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) {
OpenPOWER on IntegriCloud