Simplify use of formatted_raw_ostream.
[oota-llvm.git] / tools / gold / gold-plugin.cpp
index e654a1581f7d50ee13df549f52dd38aaccd7a522..2c7bf5a64eef3b5e5f7b8185fce2d31373911309 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/CodeGen/Analysis.h"
 #include "llvm/CodeGen/CommandFlags.h"
+#include "llvm/IR/AutoUpgrade.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
@@ -30,7 +31,7 @@
 #include "llvm/Linker/Linker.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Object/IRObjectFile.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -90,6 +91,7 @@ namespace options {
   };
   static bool generate_api_file = false;
   static OutputType TheOutputType = OT_NORMAL;
+  static unsigned OptLevel = 2;
   static std::string obj_path;
   static std::string extra_library_path;
   static std::string triple;
@@ -123,6 +125,10 @@ namespace options {
       TheOutputType = OT_SAVE_TEMPS;
     } else if (opt == "disable-output") {
       TheOutputType = OT_DISABLE;
+    } else if (opt.size() == 2 && opt[0] == 'O') {
+      if (opt[1] < '0' || opt[1] > '3')
+        report_fatal_error("Optimization level must be between 0 and 3");
+      OptLevel = opt[1] - '0';
     } else {
       // Save this option to pass to the code generator.
       // ParseCommandLineOptions() expects argv[0] to be program name. Lazily
@@ -273,11 +279,11 @@ static bool shouldSkip(uint32_t Symflags) {
 }
 
 static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
-  assert(DI.getSeverity() == DS_Error && "Only expecting errors");
-  const auto &BDI = cast<BitcodeDiagnosticInfo>(DI);
-  std::error_code EC = BDI.getError();
-  if (EC == BitcodeError::InvalidBitcodeSignature)
-    return;
+  if (const auto *BDI = dyn_cast<BitcodeDiagnosticInfo>(&DI)) {
+    std::error_code EC = BDI->getError();
+    if (EC == BitcodeError::InvalidBitcodeSignature)
+      return;
+  }
 
   std::string ErrStorage;
   {
@@ -285,8 +291,21 @@ static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
     DiagnosticPrinterRawOStream DP(OS);
     DI.print(DP);
   }
-  message(LDPL_FATAL, "LLVM gold plugin has failed to create LTO module: %s",
-          ErrStorage.c_str());
+  ld_plugin_level Level;
+  switch (DI.getSeverity()) {
+  case DS_Error:
+    message(LDPL_FATAL, "LLVM gold plugin has failed to create LTO module: %s",
+            ErrStorage.c_str());
+    llvm_unreachable("Fatal doesn't return.");
+  case DS_Warning:
+    Level = LDPL_WARNING;
+    break;
+  case DS_Note:
+  case DS_Remark:
+    Level = LDPL_INFO;
+    break;
+  }
+  message(Level, "LLVM gold plugin: %s",  ErrStorage.c_str());
 }
 
 /// Called by gold to see whether this file is one that our plugin can handle.
@@ -561,7 +580,7 @@ static void freeSymName(ld_plugin_symbol &Sym) {
 
 static std::unique_ptr<Module>
 getModuleForFile(LLVMContext &Context, claimed_file &F,
-                 off_t Filesize, raw_fd_ostream *ApiFile,
+                 ld_plugin_input_file &Info, raw_fd_ostream *ApiFile,
                  StringSet<> &Internalize, StringSet<> &Maybe) {
 
   if (get_symbols(F.handle, F.syms.size(), &F.syms[0]) != LDPS_OK)
@@ -571,7 +590,8 @@ getModuleForFile(LLVMContext &Context, claimed_file &F,
   if (get_view(F.handle, &View) != LDPS_OK)
     message(LDPL_FATAL, "Failed to get a view of file");
 
-  MemoryBufferRef BufferRef(StringRef((const char *)View, Filesize), "");
+  MemoryBufferRef BufferRef(StringRef((const char *)View, Info.filesize),
+                            Info.name);
   ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
       object::IRObjectFile::create(BufferRef, Context);
 
@@ -583,6 +603,9 @@ getModuleForFile(LLVMContext &Context, claimed_file &F,
 
   Module &M = Obj.getModule();
 
+  M.materializeMetadata();
+  UpgradeDebugInfo(M);
+
   SmallPtrSet<GlobalValue *, 8> Used;
   collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
 
@@ -694,10 +717,9 @@ getModuleForFile(LLVMContext &Context, claimed_file &F,
 
 static void runLTOPasses(Module &M, TargetMachine &TM) {
   if (const DataLayout *DL = TM.getDataLayout())
-    M.setDataLayout(DL);
+    M.setDataLayout(*DL);
 
   legacy::PassManager passes;
-  passes.add(new DataLayoutPass());
   passes.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
 
   PassManagerBuilder PMB;
@@ -707,6 +729,7 @@ static void runLTOPasses(Module &M, TargetMachine &TM) {
   PMB.VerifyOutput = true;
   PMB.LoopVectorize = true;
   PMB.SLPVectorize = true;
+  PMB.OptLevel = options::OptLevel;
   PMB.populateLTOPassManager(passes);
   passes.run(M);
 }
@@ -737,9 +760,24 @@ static void codegen(Module &M) {
     Features.AddFeature(A);
 
   TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  CodeGenOpt::Level CGOptLevel;
+  switch (options::OptLevel) {
+  case 0:
+    CGOptLevel = CodeGenOpt::None;
+    break;
+  case 1:
+    CGOptLevel = CodeGenOpt::Less;
+    break;
+  case 2:
+    CGOptLevel = CodeGenOpt::Default;
+    break;
+  case 3:
+    CGOptLevel = CodeGenOpt::Aggressive;
+    break;
+  }
   std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine(
       TripleStr, options::mcpu, Features.getString(), Options, RelocationModel,
-      CodeModel::Default, CodeGenOpt::Aggressive));
+      CodeModel::Default, CGOptLevel));
 
   runLTOPasses(M, *TM);
 
@@ -747,7 +785,6 @@ static void codegen(Module &M) {
     saveBCFile(output_name + ".opt.bc", M);
 
   legacy::PassManager CodeGenPasses;
-  CodeGenPasses.add(new DataLayoutPass());
 
   SmallString<128> Filename;
   int FD;
@@ -767,9 +804,8 @@ static void codegen(Module &M) {
 
   {
     raw_fd_ostream OS(FD, true);
-    formatted_raw_ostream FOS(OS);
 
-    if (TM->addPassesToEmitFile(CodeGenPasses, FOS,
+    if (TM->addPassesToEmitFile(CodeGenPasses, OS,
                                 TargetMachine::CGFT_ObjectFile))
       message(LDPL_FATAL, "Failed to setup codegen");
     CodeGenPasses.run(M);
@@ -792,6 +828,8 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
     return LDPS_OK;
 
   LLVMContext Context;
+  Context.setDiagnosticHandler(diagnosticHandler, nullptr, true);
+
   std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context));
   Linker L(Combined.get());
 
@@ -804,8 +842,7 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
     if (get_input_file(F.handle, &File) != LDPS_OK)
       message(LDPL_FATAL, "Failed to get file information");
     std::unique_ptr<Module> M =
-        getModuleForFile(Context, F, File.filesize, ApiFile,
-                         Internalize, Maybe);
+        getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe);
     if (!options::triple.empty())
       M->setTargetTriple(options::triple.c_str());
     else if (M->getTargetTriple().empty()) {