summaryrefslogtreecommitdiff
path: root/lib/Bitcode
diff options
context:
space:
mode:
authorSean Fertile <sfertile@ca.ibm.com>2017-10-26 15:00:26 +0000
committerSean Fertile <sfertile@ca.ibm.com>2017-10-26 15:00:26 +0000
commit509132b368efed10bbdad825403f45e9cf1d6e38 (patch)
tree0188bf3a173be5db35a9f51aaf443311357eab97 /lib/Bitcode
parentb25352f371cca1ddf19a7b0c1db681148da8ac66 (diff)
Represent runtime preemption in the IR.
Currently we do not represent runtime preemption in the IR, which has several drawbacks: 1) The semantics of GlobalValues differ depending on the object file format you are targeting (as well as the relocation-model and -fPIE value). 2) We have no way of disabling inlining of run time interposable functions, since in the IR we only know if a function is link-time interposable. Because of this llvm cannot support elf-interposition semantics. 3) In LTO builds of executables we will have extra knowledge that a symbol resolved to a local definition and can't be preemptable, but have no way to propagate that knowledge through the compiler. This patch adds preemptability specifiers to the IR with the following meaning: dso_local --> means the compiler may assume the symbol will resolve to a definition within the current linkage unit and the symbol may be accessed directly even if the definition is not within this compilation unit. dso_preemptable --> means that the compiler must assume the GlobalValue may be replaced with a definition from outside the current linkage unit at runtime. To ease transitioning dso_preemptable is treated as a 'default' in that low-level codegen will still do the same checks it did previously to see if a symbol should be accessed indirectly. Eventually when IR producers emit the specifiers on all Globalvalues we can change dso_preemptable to mean 'always access indirectly', and remove the current logic. Differential Revision: https://reviews.llvm.org/D20217 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316668 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bitcode')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp29
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp15
2 files changed, 36 insertions, 8 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 68b36eef5eb..c2272260f44 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -911,6 +911,14 @@ getDecodedDLLStorageClass(unsigned Val) {
}
}
+static bool getDecodedDSOLocal(unsigned Val) {
+ switch(Val) {
+ default: // Map unknown values to preemptable.
+ case 0: return false;
+ case 1: return true;
+ }
+}
+
static GlobalVariable::ThreadLocalMode getDecodedThreadLocalMode(unsigned Val) {
switch (Val) {
case 0: return GlobalVariable::NotThreadLocal;
@@ -2803,7 +2811,7 @@ Error BitcodeReader::parseComdatRecord(ArrayRef<uint64_t> Record) {
Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
// v1: [pointer type, isconst, initid, linkage, alignment, section,
// visibility, threadlocal, unnamed_addr, externally_initialized,
- // dllstorageclass, comdat, attributes] (name in VST)
+ // dllstorageclass, comdat, attributes, preemption specifier] (name in VST)
// v2: [strtab_offset, strtab_size, v1]
StringRef Name;
std::tie(Name, Record) = readNameFromStrtab(Record);
@@ -2888,13 +2896,18 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
auto AS = getAttributes(Record[12]).getFnAttributes();
NewGV->setAttributes(AS);
}
+
+ if (Record.size() > 13) {
+ NewGV->setDSOLocal(getDecodedDSOLocal(Record[13]));
+ }
+
return Error::success();
}
Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
// v1: [type, callingconv, isproto, linkage, paramattr, alignment, section,
// visibility, gc, unnamed_addr, prologuedata, dllstorageclass, comdat,
- // prefixdata] (name in VST)
+ // prefixdata, personalityfn, preemption specifier] (name in VST)
// v2: [strtab_offset, strtab_size, v1]
StringRef Name;
std::tie(Name, Record) = readNameFromStrtab(Record);
@@ -2968,6 +2981,10 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
if (Record.size() > 14 && Record[14] != 0)
FunctionPersonalityFns.push_back(std::make_pair(Func, Record[14] - 1));
+ if (Record.size() > 15) {
+ Func->setDSOLocal(getDecodedDSOLocal(Record[15]));
+ }
+
ValueList.push_back(Func);
// If this is a function with a body, remember the prototype we are
@@ -2984,9 +3001,11 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
unsigned BitCode, ArrayRef<uint64_t> Record) {
// v1 ALIAS_OLD: [alias type, aliasee val#, linkage] (name in VST)
// v1 ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility,
- // dllstorageclass] (name in VST)
+ // dllstorageclass, threadlocal, unnamed_addr,
+ // preemption specifier] (name in VST)
// v1 IFUNC: [alias type, addrspace, aliasee val#, linkage,
- // visibility, dllstorageclass] (name in VST)
+ // visibility, dllstorageclass, threadlocal, unnamed_addr,
+ // preemption specifier] (name in VST)
// v2: [strtab_offset, strtab_size, v1]
StringRef Name;
std::tie(Name, Record) = readNameFromStrtab(Record);
@@ -3036,6 +3055,8 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++]));
if (OpNum != Record.size())
NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++]));
+ if (OpNum != Record.size())
+ NewGA->setDSOLocal(getDecodedDSOLocal(Record[OpNum++]));
ValueList.push_back(NewGA);
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
return Error::success();
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index de154ba6be7..1e491aa066e 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1197,7 +1197,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
// GLOBALVAR: [strtab offset, strtab size, type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal,
// unnamed_addr, externally_initialized, dllstorageclass,
- // comdat, attributes]
+ // comdat, attributes, DSO_Local]
Vals.push_back(addToStrtab(GV.getName()));
Vals.push_back(GV.getName().size());
Vals.push_back(VE.getTypeID(GV.getValueType()));
@@ -1213,7 +1213,8 @@ void ModuleBitcodeWriter::writeModuleInfo() {
GV.isExternallyInitialized() ||
GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass ||
GV.hasComdat() ||
- GV.hasAttributes()) {
+ GV.hasAttributes() ||
+ GV.isDSOLocal()) {
Vals.push_back(getEncodedVisibility(GV));
Vals.push_back(getEncodedThreadLocalMode(GV));
Vals.push_back(getEncodedUnnamedAddr(GV));
@@ -1223,6 +1224,8 @@ void ModuleBitcodeWriter::writeModuleInfo() {
auto AL = GV.getAttributesAsList(AttributeList::FunctionIndex);
Vals.push_back(VE.getAttributeListID(AL));
+
+ Vals.push_back(GV.isDSOLocal());
} else {
AbbrevToUse = SimpleGVarAbbrev;
}
@@ -1236,7 +1239,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
// FUNCTION: [strtab offset, strtab size, type, callingconv, isproto,
// linkage, paramattrs, alignment, section, visibility, gc,
// unnamed_addr, prologuedata, dllstorageclass, comdat,
- // prefixdata, personalityfn]
+ // prefixdata, personalityfn, DSO_Local]
Vals.push_back(addToStrtab(F.getName()));
Vals.push_back(F.getName().size());
Vals.push_back(VE.getTypeID(F.getFunctionType()));
@@ -1258,6 +1261,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back(
F.hasPersonalityFn() ? (VE.getValueID(F.getPersonalityFn()) + 1) : 0);
+ Vals.push_back(F.isDSOLocal());
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
Vals.clear();
@@ -1266,7 +1270,8 @@ void ModuleBitcodeWriter::writeModuleInfo() {
// Emit the alias information.
for (const GlobalAlias &A : M.aliases()) {
// ALIAS: [strtab offset, strtab size, alias type, aliasee val#, linkage,
- // visibility, dllstorageclass, threadlocal, unnamed_addr]
+ // visibility, dllstorageclass, threadlocal, unnamed_addr,
+ // DSO_Local]
Vals.push_back(addToStrtab(A.getName()));
Vals.push_back(A.getName().size());
Vals.push_back(VE.getTypeID(A.getValueType()));
@@ -1277,6 +1282,8 @@ void ModuleBitcodeWriter::writeModuleInfo() {
Vals.push_back(getEncodedDLLStorageClass(A));
Vals.push_back(getEncodedThreadLocalMode(A));
Vals.push_back(getEncodedUnnamedAddr(A));
+ Vals.push_back(A.isDSOLocal());
+
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
Vals.clear();