//
//===----------------------------------------------------------------------===//
-#include "llvm/Module.h"
+#include "llvm/IR/Module.h"
#include "SymbolTableListTraitsImpl.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/GVMaterializer.h"
-#include "llvm/InstrTypes.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Support/LeakDetector.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/IR/LeakDetector.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/RandomNumberGenerator.h"
#include <algorithm>
#include <cstdarg>
#include <cstdlib>
// 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), RNG(nullptr), DL("") {
ValSymTab = new ValueSymbolTable();
NamedMDSymTab = new StringMap<NamedMDNode *>();
Context.addModule(this);
NamedMDList.clear();
delete ValSymTab;
delete static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab);
-}
-
-/// Target endian information.
-Module::Endianness Module::getEndianness() const {
- StringRef temp = DataLayout;
- Module::Endianness ret = AnyEndianness;
-
- while (!temp.empty()) {
- std::pair<StringRef, StringRef> 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.
-Module::PointerSize Module::getPointerSize() const {
- StringRef temp = DataLayout;
- Module::PointerSize ret = AnyPointerSize;
-
- while (!temp.empty()) {
- std::pair<StringRef, StringRef> 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;
+ delete RNG;
}
/// getNamedValue - Return the first global value in the module with
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
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))
return F;
}
-Constant *Module::getOrInsertTargetIntrinsic(StringRef Name,
- FunctionType *Ty,
- AttributeSet AttributeList) {
- // See if we have a definition for the specified function already.
- GlobalValue *F = getNamedValue(Name);
- if (F == 0) {
- // Nope, add it
- Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name);
- New->setAttributes(AttributeList);
- FunctionList.push_back(New);
- return New; // Return the new prototype.
- }
-
- // Otherwise, we just found the existing function or a prototype.
- return F;
-}
-
Constant *Module::getOrInsertFunction(StringRef Name,
FunctionType *Ty) {
return getOrInsertFunction(Name, Ty, AttributeSet());
/// 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(StringRef Name,
- bool AllowLocal) const {
+GlobalVariable *Module::getGlobalVariable(StringRef Name, bool AllowLocal) {
if (GlobalVariable *Result =
dyn_cast_or_null<GlobalVariable>(getNamedValue(Name)))
if (AllowLocal || !Result->hasLocalLinkage())
return Result;
- return 0;
+ return nullptr;
}
/// getOrInsertGlobal - Look up the specified global in the module symbol table.
/// 1. If it does not exist, add a declaration of the global and return it.
/// 2. Else, the global exists but has the wrong type: return the function
/// with a constantexpr cast to the right type.
-/// 3. Finally, if the existing global is the correct delclaration, return the
+/// 3. Finally, if the existing global is the correct declaration, return the
/// existing global.
Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) {
// See if we have a definition for the specified global already.
GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(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.
}
// 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));
+ Type *GVTy = GV->getType();
+ PointerType *PTy = PointerType::get(Ty, GVTy->getPointerAddressSpace());
+ if (GVTy != PTy)
+ return ConstantExpr::getBitCast(GV, PTy);
// Otherwise, we just found the existing function or a prototype.
return GV;
NamedMDList.erase(NMD);
}
+bool Module::isValidModFlagBehavior(Value *V, ModFlagBehavior &MFB) {
+ if (ConstantInt *Behavior = dyn_cast<ConstantInt>(V)) {
+ 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 {
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<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));
+ for (const MDNode *Flag : ModFlags->operands()) {
+ 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.
+ MDString *Key = cast<MDString>(Flag->getOperand(1));
+ Value *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 {
+ SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
+ getModuleFlagsMetadata(ModuleFlags);
+ for (const ModuleFlagEntry &MFE : ModuleFlags) {
+ if (Key == MFE.Key->getString())
+ return MFE.Val;
}
+ return nullptr;
}
/// getModuleFlagsMetadata - Returns the NamedMDNode in the module that
getOrInsertModuleFlagsMetadata()->addOperand(Node);
}
+void Module::setDataLayout(StringRef Desc) {
+ DL.reset(Desc);
+
+ if (Desc.empty()) {
+ DataLayoutStr = "";
+ } else {
+ DataLayoutStr = DL.getStringRepresentation();
+ // DataLayoutStr is now equivalent to Desc, but since the representation
+ // is not unique, they may not be identical.
+ }
+}
+
+void Module::setDataLayout(const DataLayout *Other) {
+ if (!Other) {
+ DataLayoutStr = "";
+ DL.reset("");
+ } else {
+ DL = *Other;
+ DataLayoutStr = DL.getStringRepresentation();
+ }
+}
+
+const DataLayout *Module::getDataLayout() const {
+ if (DataLayoutStr.empty())
+ return nullptr;
+ 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.
//
}
bool Module::Materialize(GlobalValue *GV, std::string *ErrInfo) {
- if (Materializer)
- return Materializer->Materialize(GV, ErrInfo);
- return false;
+ if (!Materializer)
+ return false;
+
+ std::error_code EC = Materializer->Materialize(GV);
+ if (!EC)
+ return false;
+ if (ErrInfo)
+ *ErrInfo = EC.message();
+ return true;
}
void Module::Dematerialize(GlobalValue *GV) {
return Materializer->Dematerialize(GV);
}
-bool Module::MaterializeAll(std::string *ErrInfo) {
+std::error_code Module::materializeAll() {
if (!Materializer)
- return false;
- return Materializer->MaterializeModule(this, ErrInfo);
+ return std::error_code();
+ return Materializer->MaterializeModule(this);
}
-bool Module::MaterializeAllPermanently(std::string *ErrInfo) {
- if (MaterializeAll(ErrInfo))
- return true;
+std::error_code Module::materializeAllPermanently() {
+ if (std::error_code EC = materializeAll())
+ return EC;
+
Materializer.reset();
- return false;
+ return std::error_code();
}
//===----------------------------------------------------------------------===//
// 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(Module::global_iterator I = global_begin(), E = global_end(); I != E; ++I)
- I->dropAllReferences();
+ for (GlobalAlias &GA : aliases())
+ GA.dropAllReferences();
+}
+
+unsigned Module::getDwarfVersion() const {
+ Value *Val = getModuleFlag("Dwarf Version");
+ if (!Val)
+ return dwarf::DWARF_VERSION;
+ return cast<ConstantInt>(Val)->getZExtValue();
+}
- for(Module::alias_iterator I = alias_begin(), E = alias_end(); I != E; ++I)
- I->dropAllReferences();
+Comdat *Module::getOrInsertComdat(StringRef Name) {
+ Comdat C;
+ StringMapEntry<Comdat> &Entry =
+ ComdatSymTab.GetOrCreateValue(Name, std::move(C));
+ Entry.second.Name = &Entry;
+ return &Entry.second;
}