summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2016-12-08 05:28:30 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2016-12-08 05:28:30 +0000
commitf4257528e967dae1cf49328f2a8cfdc28815a2f3 (patch)
treefc36e6dc56613a56774c2e8b5476f0c09fc71ff0
parentb2979d84647ab3b2e449c5302b256da2b846e02e (diff)
downloadbcm5719-llvm-f4257528e967dae1cf49328f2a8cfdc28815a2f3.tar.gz
bcm5719-llvm-f4257528e967dae1cf49328f2a8cfdc28815a2f3.zip
LTO: Hash the parts of the LTO configuration that affect code generation.
Most importantly, we need to hash the relocation model, otherwise we can end up trying to link non-PIC object files into PIEs or DSOs. Differential Revision: https://reviews.llvm.org/D27556 llvm-svn: 289024
-rw-r--r--llvm/include/llvm/CodeGen/CommandFlags.h6
-rw-r--r--llvm/include/llvm/LTO/Config.h2
-rw-r--r--llvm/lib/LTO/LTO.cpp39
-rw-r--r--llvm/test/ThinLTO/X86/cache-config.ll27
-rw-r--r--llvm/tools/llvm-lto2/llvm-lto2.cpp42
5 files changed, 113 insertions, 3 deletions
diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h
index 51013ca07b2..aab522d00de 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.h
+++ b/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -232,6 +232,11 @@ UseCtors("use-ctors",
cl::desc("Use .ctors instead of .init_array."),
cl::init(false));
+cl::opt<bool> RelaxELFRelocations(
+ "relax-elf-relocations",
+ cl::desc("Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
+ cl::init(false));
+
cl::opt<bool> DataSections("data-sections",
cl::desc("Emit data into separate sections"),
cl::init(false));
@@ -288,6 +293,7 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
Options.StackAlignmentOverride = OverrideStackAlignment;
Options.StackSymbolOrdering = StackSymbolOrdering;
Options.UseInitArray = !UseCtors;
+ Options.RelaxELFRelocations = RelaxELFRelocations;
Options.DataSections = DataSections;
Options.FunctionSections = FunctionSections;
Options.UniqueSectionNames = UniqueSectionNames;
diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h
index 72bdf68d0b4..e162ac3eaa4 100644
--- a/llvm/include/llvm/LTO/Config.h
+++ b/llvm/include/llvm/LTO/Config.h
@@ -33,6 +33,8 @@ namespace lto {
/// LTO configuration. A linker can configure LTO by setting fields in this data
/// structure and passing it to the lto::LTO constructor.
struct Config {
+ // Note: when adding fields here, consider whether they need to be added to
+ // computeCacheKey in LTO.cpp.
std::string CPU;
TargetOptions Options;
std::vector<std::string> MAttrs;
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index c8587465e4b..108b5a42d75 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -50,8 +50,8 @@ using namespace object;
// export/import and other global analysis results.
// The hash is produced in \p Key.
static void computeCacheKey(
- SmallString<40> &Key, const ModuleSummaryIndex &Index, StringRef ModuleID,
- const FunctionImporter::ImportMapTy &ImportList,
+ SmallString<40> &Key, const Config &Conf, const ModuleSummaryIndex &Index,
+ StringRef ModuleID, const FunctionImporter::ImportMapTy &ImportList,
const FunctionImporter::ExportSetTy &ExportList,
const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
const GVSummaryMapTy &DefinedGlobals) {
@@ -67,6 +67,39 @@ static void computeCacheKey(
Hasher.update(LLVM_REVISION);
#endif
+ // Include the parts of the LTO configuration that affect code generation.
+ auto AddString = [&](StringRef Str) {
+ Hasher.update(Str);
+ Hasher.update(ArrayRef<uint8_t>{0});
+ };
+ auto AddUnsigned = [&](unsigned I) {
+ uint8_t Data[4];
+ Data[0] = I;
+ Data[1] = I >> 8;
+ Data[2] = I >> 16;
+ Data[3] = I >> 24;
+ Hasher.update(ArrayRef<uint8_t>{Data, 4});
+ };
+ AddString(Conf.CPU);
+ // FIXME: Hash more of Options. For now all clients initialize Options from
+ // command-line flags (which is unsupported in production), but may set
+ // RelaxELFRelocations. The clang driver can also pass FunctionSections,
+ // DataSections and DebuggerTuning via command line flags.
+ AddUnsigned(Conf.Options.RelaxELFRelocations);
+ AddUnsigned(Conf.Options.FunctionSections);
+ AddUnsigned(Conf.Options.DataSections);
+ AddUnsigned((unsigned)Conf.Options.DebuggerTuning);
+ for (auto &A : Conf.MAttrs)
+ AddString(A);
+ AddUnsigned(Conf.RelocModel);
+ AddUnsigned(Conf.CodeModel);
+ AddUnsigned(Conf.CGOptLevel);
+ AddUnsigned(Conf.OptLevel);
+ AddString(Conf.OptPipeline);
+ AddString(Conf.AAPipeline);
+ AddString(Conf.OverrideTriple);
+ AddString(Conf.DefaultTriple);
+
// Include the hash for the current module
auto ModHash = Index.getModuleHash(ModuleID);
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
@@ -562,7 +595,7 @@ public:
SmallString<40> Key;
// The module may be cached, this helps handling it.
- computeCacheKey(Key, CombinedIndex, ModuleID, ImportList, ExportList,
+ computeCacheKey(Key, Conf, CombinedIndex, ModuleID, ImportList, ExportList,
ResolvedODR, DefinedGlobals);
if (AddStreamFn CacheAddStream = Cache(Task, Key))
return RunThinBackend(CacheAddStream);
diff --git a/llvm/test/ThinLTO/X86/cache-config.ll b/llvm/test/ThinLTO/X86/cache-config.ll
new file mode 100644
index 00000000000..a947969f669
--- /dev/null
+++ b/llvm/test/ThinLTO/X86/cache-config.ll
@@ -0,0 +1,27 @@
+; RUN: rm -rf %t.cache && mkdir %t.cache
+; RUN: opt -module-hash -module-summary %s -o %t.bc
+
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -mcpu=yonah
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -relax-elf-relocations
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -function-sections
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -data-sections
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -debugger-tune=sce
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -mattr=+sse2
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -relocation-model=static
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -code-model=large
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -cg-opt-level=0
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -O1
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -opt-pipeline=loweratomic
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -aa-pipeline=basic-aa
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -override-triple=x86_64-unknown-linux-gnu
+; RUN: llvm-lto2 -o %t.o %t.bc -cache-dir %t.cache -r=%t.bc,globalfunc,plx -default-triple=x86_64-unknown-linux-gnu
+; RUN: ls %t.cache | count 15
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @globalfunc() {
+entry:
+ ret void
+}
diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index 01756d2c764..e8bf7a397f2 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -17,6 +17,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/LTO/Caching.h"
+#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetSelect.h"
@@ -31,6 +32,11 @@ static cl::opt<char>
"(default = '-O2')"),
cl::Prefix, cl::ZeroOrMore, cl::init('2'));
+static cl::opt<char> CGOptLevel(
+ "cg-opt-level",
+ cl::desc("Codegen optimization level (0, 1, 2 or 3, default = '2')"),
+ cl::init('2'));
+
static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore,
cl::desc("<input bitcode files>"));
@@ -74,6 +80,15 @@ static cl::list<std::string> SymbolResolutions(
"A resolution for each symbol must be specified."),
cl::ZeroOrMore);
+static cl::opt<std::string> OverrideTriple(
+ "override-triple",
+ cl::desc("Replace target triples in input files with this triple"));
+
+static cl::opt<std::string> DefaultTriple(
+ "default-triple",
+ cl::desc(
+ "Replace unspecified target triples in input files with this triple"));
+
static void check(Error E, std::string Msg) {
if (!E)
return;
@@ -146,6 +161,13 @@ int main(int argc, char **argv) {
exit(1);
};
+ Conf.CPU = MCPU;
+ Conf.Options = InitTargetOptionsFromCodeGenFlags();
+ Conf.MAttrs = MAttrs;
+ if (auto RM = getRelocModel())
+ Conf.RelocModel = *RM;
+ Conf.CodeModel = CMModel;
+
if (SaveTemps)
check(Conf.addSaveTemps(OutputFilename + "."),
"Config::addSaveTemps failed");
@@ -155,6 +177,26 @@ int main(int argc, char **argv) {
Conf.AAPipeline = AAPipeline;
Conf.OptLevel = OptLevel - '0';
+ switch (CGOptLevel) {
+ case '0':
+ Conf.CGOptLevel = CodeGenOpt::None;
+ break;
+ case '1':
+ Conf.CGOptLevel = CodeGenOpt::Less;
+ break;
+ case '2':
+ Conf.CGOptLevel = CodeGenOpt::Default;
+ break;
+ case '3':
+ Conf.CGOptLevel = CodeGenOpt::Aggressive;
+ break;
+ default:
+ llvm::errs() << "invalid cg optimization level: " << CGOptLevel << '\n';
+ return 1;
+ }
+
+ Conf.OverrideTriple = OverrideTriple;
+ Conf.DefaultTriple = DefaultTriple;
ThinBackend Backend;
if (ThinLTODistributedIndexes)
OpenPOWER on IntegriCloud