]> granicus.if.org Git - llvm/commitdiff
[LTO] Make sure we flush buffers to work around linker shenanigans.
authorDavide Italiano <davide@freebsd.org>
Mon, 13 Feb 2017 14:39:51 +0000 (14:39 +0000)
committerDavide Italiano <davide@freebsd.org>
Mon, 13 Feb 2017 14:39:51 +0000 (14:39 +0000)
lld, at least, doesn't call global destructors by default (unless
--full-shutdown is passed) because it's, allegedly, expensive.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294953 91177308-0d34-0410-b5e6-96231b3b80d8

lib/LTO/LTOBackend.cpp

index 1afdc13045bc2cb28b485afd4322a52d6b675693..00959cbea6931962cfe6528ae41378dc27252196 100644 (file)
@@ -340,6 +340,16 @@ Expected<const Target *> initAndLookupTarget(Config &C, Module &Mod) {
 
 }
 
+static void
+finalizeOptimizationRemarks(std::unique_ptr<tool_output_file> DiagOutputFile) {
+  // Make sure we flush the diagnostic remarks file in case the linker doesn't
+  // call the global destructors before exiting.
+  if (!DiagOutputFile)
+    return;
+  DiagOutputFile->keep();
+  DiagOutputFile->os().flush();
+}
+
 static void handleAsmUndefinedRefs(Module &Mod, TargetMachine &TM) {
   // Collect the list of undefined symbols used in asm and update
   // llvm.compiler.used to prevent optimization to drop these from the output.
@@ -371,10 +381,14 @@ Error lto::backend(Config &C, AddStreamFn AddStream,
       Mod->getContext(), C.RemarksFilename, C.RemarksWithHotness);
   if (!DiagFileOrErr)
     return DiagFileOrErr.takeError();
+  auto DiagnosticOutputFile = std::move(*DiagFileOrErr);
 
-  if (!C.CodeGenOnly)
-    if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false, CombinedIndex))
+  if (!C.CodeGenOnly) {
+    if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false, CombinedIndex)) {
+      finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
       return Error::success();
+    }
+  }
 
   if (ParallelCodeGenParallelismLevel == 1) {
     codegen(C, TM.get(), AddStream, 0, *Mod);
@@ -382,6 +396,7 @@ Error lto::backend(Config &C, AddStreamFn AddStream,
     splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel,
                  std::move(Mod));
   }
+  finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
   return Error::success();
 }