about summary refs log tree commit diff
path: root/src/rustllvm/PassWrapper.cpp
diff options
context:
space:
mode:
authorBrad Gibson <b2b@humanenginuity.com>2018-07-29 20:03:15 -0700
committerBrad Gibson <b2b@humanenginuity.com>2018-07-29 22:13:12 -0700
commit56016cb1e02ece29f25c619b297f9c9797db821c (patch)
tree70dd7a5658527a54769c7603e6e17bfe27985f86 /src/rustllvm/PassWrapper.cpp
parent6a78c0a10f2e719117fe4bb929bfb38549acfeec (diff)
parent866a713258915e6cbb212d135f751a6a8c9e1c0a (diff)
downloadrust-56016cb1e02ece29f25c619b297f9c9797db821c.tar.gz
rust-56016cb1e02ece29f25c619b297f9c9797db821c.zip
resolved upstream merge conflicts
Diffstat (limited to 'src/rustllvm/PassWrapper.cpp')
-rw-r--r--src/rustllvm/PassWrapper.cpp61
1 files changed, 42 insertions, 19 deletions
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 382ef2cc407..85fbc4bf378 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -388,7 +388,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
   Options.FunctionSections = FunctionSections;
 
   if (TrapUnreachable) {
-    // Tell LLVM to translate `unreachable` into an explicit trap instruction.
+    // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
     // This limits the extent of possible undefined behavior in some cases, as
     // it prevents control flow from "falling through" into whatever code
     // happens to be laid out next in memory.
@@ -428,13 +428,17 @@ extern "C" void LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
 
 extern "C" void LLVMRustConfigurePassManagerBuilder(
     LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
-    bool MergeFunctions, bool SLPVectorize, bool LoopVectorize,
+    bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
     const char* PGOGenPath, const char* PGOUsePath) {
-  // Ignore mergefunc for now as enabling it causes crashes.
-  // unwrap(PMBR)->MergeFunctions = MergeFunctions;
+#if LLVM_RUSTLLVM
+  unwrap(PMBR)->MergeFunctions = MergeFunctions;
+#endif
   unwrap(PMBR)->SLPVectorize = SLPVectorize;
   unwrap(PMBR)->OptLevel = fromRust(OptLevel);
   unwrap(PMBR)->LoopVectorize = LoopVectorize;
+#if LLVM_VERSION_GE(4, 0)
+  unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO;
+#endif
 
 #ifdef PGO_AVAILABLE
   if (PGOGenPath) {
@@ -541,7 +545,11 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
     return LLVMRustResult::Failure;
   }
 
+#if LLVM_VERSION_GE(7, 0)
+  unwrap(Target)->addPassesToEmitFile(*PM, OS, nullptr, FileType, false);
+#else
   unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
+#endif
   PM->run(*unwrap(M));
 
   // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
@@ -1076,11 +1084,40 @@ LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef
 extern "C" bool
 LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
   Module &Mod = *unwrap(M);
+
   const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
   auto Loader = [&](StringRef Identifier) {
     const auto &Memory = Data->ModuleMap.lookup(Identifier);
     auto &Context = Mod.getContext();
-    return getLazyBitcodeModule(Memory, Context, true, true);
+    auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
+
+    if (!MOrErr)
+      return std::move(MOrErr);
+
+    // The rest of this closure is a workaround for
+    // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
+    // we accidentally import wasm custom sections into different modules,
+    // duplicating them by in the final output artifact.
+    //
+    // The issue is worked around here by manually removing the
+    // `wasm.custom_sections` named metadata node from any imported module. This
+    // we know isn't used by any optimization pass so there's no need for it to
+    // be imported.
+    //
+    // Note that the metadata is currently lazily loaded, so we materialize it
+    // here before looking up if there's metadata inside. The `FunctionImporter`
+    // will immediately materialize metadata anyway after an import, so this
+    // shouldn't be a perf hit.
+    if (Error Err = (*MOrErr)->materializeMetadata()) {
+      Expected<std::unique_ptr<Module>> Ret(std::move(Err));
+      return std::move(Ret);
+    }
+
+    auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
+    if (WasmCustomSections)
+      WasmCustomSections->eraseFromParent();
+
+    return std::move(MOrErr);
   };
   FunctionImporter Importer(Data->Index, Loader);
   Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
@@ -1220,15 +1257,6 @@ LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
   MD->addOperand(Unit);
 }
 
-extern "C" void
-LLVMRustThinLTORemoveAvailableExternally(LLVMModuleRef Mod) {
-  Module *M = unwrap(Mod);
-  for (Function &F : M->functions()) {
-    if (F.hasAvailableExternallyLinkage())
-      F.deleteBody();
-  }
-}
-
 #else
 
 extern "C" bool
@@ -1320,9 +1348,4 @@ LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod) {
   report_fatal_error("ThinLTO not available");
 }
 
-extern "C" void
-LLVMRustThinLTORemoveAvailableExternally(LLVMModuleRef Mod) {
-  report_fatal_error("ThinLTO not available");
-}
-
 #endif // LLVM_VERSION_GE(4, 0)