Commit 05454123d4

Andrew Kelley <andrew@ziglang.org>
2019-07-20 00:07:31
update clang driver code to llvm9
upstream commit 1931d3cb20a00da732c5210b123656632982fde0
1 parent 70e05c6
src/zig_clang_cc1_main.cpp
@@ -1,9 +1,8 @@
 //===-- cc1_main.cpp - Clang CC1 Compiler Frontend ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -14,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Basic/Stack.h"
+#include "clang/Basic/TargetOptions.h"
 #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
 #include "clang/Config/config.h"
 #include "clang/Driver/DriverDiagnostic.h"
@@ -35,10 +35,14 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Signals.h"
+#include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
 #include <cstdio>
 
 #ifdef CLANG_HAVE_RLIMITS
@@ -159,6 +163,23 @@ static void ensureSufficientStack() {
 static void ensureSufficientStack() {}
 #endif
 
+/// Print supported cpus of the given target.
+static int PrintSupportedCPUs(std::string TargetStr) {
+  std::string Error;
+  const llvm::Target *TheTarget =
+      llvm::TargetRegistry::lookupTarget(TargetStr, Error);
+  if (!TheTarget) {
+    llvm::errs() << Error;
+    return 1;
+  }
+
+  // the target machine will handle the mcpu printing
+  llvm::TargetOptions Options;
+  std::unique_ptr<llvm::TargetMachine> TheTargetMachine(
+      TheTarget->createTargetMachine(TargetStr, "", "+cpuHelp", Options, None));
+  return 0;
+}
+
 int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
   ensureSufficientStack();
 
@@ -184,6 +205,13 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
   bool Success = CompilerInvocation::CreateFromArgs(
       Clang->getInvocation(), Argv.begin(), Argv.end(), Diags);
 
+  if (Clang->getFrontendOpts().TimeTrace)
+    llvm::timeTraceProfilerInitialize();
+
+  // --print-supported-cpus takes priority over the actual compilation.
+  if (Clang->getFrontendOpts().PrintSupportedCPUs)
+    return PrintSupportedCPUs(Clang->getTargetOpts().Triple);
+
   // Infer the builtin include path if unspecified.
   if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
       Clang->getHeaderSearchOpts().ResourceDir.empty())
@@ -205,12 +233,36 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
     return 1;
 
   // Execute the frontend actions.
-  Success = ExecuteCompilerInvocation(Clang.get());
+  {
+    llvm::TimeTraceScope TimeScope("ExecuteCompiler", StringRef(""));
+    Success = ExecuteCompilerInvocation(Clang.get());
+  }
 
   // If any timers were active but haven't been destroyed yet, print their
   // results now.  This happens in -disable-free mode.
   llvm::TimerGroup::printAll(llvm::errs());
 
+  if (llvm::timeTraceProfilerEnabled()) {
+    SmallString<128> Path(Clang->getFrontendOpts().OutputFile);
+    llvm::sys::path::replace_extension(Path, "json");
+    auto profilerOutput =
+        Clang->createOutputFile(Path.str(),
+                                /*Binary=*/false,
+                                /*RemoveFileOnSignal=*/false, "",
+                                /*Extension=*/"json",
+                                /*useTemporary=*/false);
+
+    llvm::timeTraceProfilerWrite(*profilerOutput);
+    // FIXME(ibiryukov): make profilerOutput flush in destructor instead.
+    profilerOutput->flush();
+    llvm::timeTraceProfilerCleanup();
+
+    llvm::errs() << "Time trace json-file dumped to " << Path.str() << "\n";
+    llvm::errs()
+        << "Use chrome://tracing or Speedscope App "
+           "(https://www.speedscope.app) for flamegraph visualization\n";
+  }
+
   // Our error handler depends on the Diagnostics object, which we're
   // potentially about to delete. Uninstall the handler now so that any
   // later errors use the default handling behavior instead.
@@ -224,4 +276,3 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
 
   return !Success;
 }
-
src/zig_clang_cc1as_main.cpp
@@ -1,9 +1,8 @@
 //===-- cc1as_main.cpp - Clang Assembler  ---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -99,7 +98,7 @@ struct AssemblerInvocation {
   llvm::DebugCompressionType CompressDebugSections =
       llvm::DebugCompressionType::None;
   std::string MainFileName;
-  std::string SplitDwarfFile;
+  std::string SplitDwarfOutput;
 
   /// @}
   /// @name Frontend Options
@@ -138,6 +137,10 @@ struct AssemblerInvocation {
   /// The name of the relocation model to use.
   std::string RelocationModel;
 
+  /// The ABI targeted by the backend. Specified using -target-abi. Empty
+  /// otherwise.
+  std::string TargetABI;
+
   /// @}
 
 public:
@@ -255,7 +258,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
   }
   Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
   Opts.OutputPath = Args.getLastArgValue(OPT_o);
-  Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
+  Opts.SplitDwarfOutput = Args.getLastArgValue(OPT_split_dwarf_output);
   if (Arg *A = Args.getLastArg(OPT_filetype)) {
     StringRef Name = A->getValue();
     unsigned OutputType = StringSwitch<unsigned>(Name)
@@ -283,6 +286,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
   Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack);
   Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
   Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic");
+  Opts.TargetABI = Args.getLastArgValue(OPT_target_abi);
   Opts.IncrementalLinkerCompatible =
       Args.hasArg(OPT_mincremental_linker_compatible);
   Opts.SymbolDefs = Args.getAllArgValues(OPT_defsym);
@@ -337,7 +341,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
   SourceMgr SrcMgr;
 
   // Tell SrcMgr about this buffer, which is what the parser will pick up.
-  SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());
+  unsigned BufferIndex = SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());
 
   // Record the location of the include directories so that the lexer can find
   // it later.
@@ -363,8 +367,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
   if (!FDOS)
     return true;
   std::unique_ptr<raw_fd_ostream> DwoOS;
-  if (!Opts.SplitDwarfFile.empty())
-    DwoOS = getOutputStream(Opts.SplitDwarfFile, Diags, IsBinary);
+  if (!Opts.SplitDwarfOutput.empty())
+    DwoOS = getOutputStream(Opts.SplitDwarfOutput, Diags, IsBinary);
 
   // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
   // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
@@ -394,12 +398,21 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
     Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
   if (!Opts.DebugCompilationDir.empty())
     Ctx.setCompilationDir(Opts.DebugCompilationDir);
+  else {
+    // If no compilation dir is set, try to use the current directory.
+    SmallString<128> CWD;
+    if (!sys::fs::current_path(CWD))
+      Ctx.setCompilationDir(CWD);
+  }
   if (!Opts.DebugPrefixMap.empty())
     for (const auto &KV : Opts.DebugPrefixMap)
       Ctx.addDebugPrefixMapEntry(KV.first, KV.second);
   if (!Opts.MainFileName.empty())
     Ctx.setMainFileName(StringRef(Opts.MainFileName));
   Ctx.setDwarfVersion(Opts.DwarfVersion);
+  if (Opts.GenDwarfForAssembly)
+    Ctx.setGenDwarfRootFile(Opts.InputFile,
+                            SrcMgr.getMemoryBuffer(BufferIndex)->getBuffer());
 
   // Build up the feature string from the target feature list.
   std::string FS;
@@ -418,6 +431,9 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
   raw_pwrite_stream *Out = FDOS.get();
   std::unique_ptr<buffer_ostream> BOS;
 
+  MCTargetOptions MCOptions;
+  MCOptions.ABIName = Opts.TargetABI;
+
   // FIXME: There is a bit of code duplication with addPassesToEmitFile.
   if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
     MCInstPrinter *IP = TheTarget->createMCInstPrinter(
@@ -426,7 +442,6 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
     std::unique_ptr<MCCodeEmitter> CE;
     if (Opts.ShowEncoding)
       CE.reset(TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
-    MCTargetOptions MCOptions;
     std::unique_ptr<MCAsmBackend> MAB(
         TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
 
@@ -447,7 +462,6 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
 
     std::unique_ptr<MCCodeEmitter> CE(
         TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
-    MCTargetOptions MCOptions;
     std::unique_ptr<MCAsmBackend> MAB(
         TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
     std::unique_ptr<MCObjectWriter> OW =
@@ -481,9 +495,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
       createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
 
   // FIXME: init MCTargetOptions from sanitizer flags here.
-  MCTargetOptions Options;
   std::unique_ptr<MCTargetAsmParser> TAP(
-      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
+      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
   if (!TAP)
     Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
 
@@ -514,8 +527,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
   if (Failed) {
     if (Opts.OutputPath != "-")
       sys::fs::remove(Opts.OutputPath);
-    if (!Opts.SplitDwarfFile.empty() && Opts.SplitDwarfFile != "-")
-      sys::fs::remove(Opts.SplitDwarfFile);
+    if (!Opts.SplitDwarfOutput.empty() && Opts.SplitDwarfOutput != "-")
+      sys::fs::remove(Opts.SplitDwarfOutput);
   }
 
   return Failed;
@@ -594,4 +607,3 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
 
   return !!Failed;
 }
-
src/zig_clang_driver.cpp
@@ -1,9 +1,8 @@
 //===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -339,7 +338,7 @@ int ZigClang_main(int argc_, const char **argv_) {
   // response files written by clang will tokenize the same way in either mode.
   bool ClangCLMode = false;
   if (StringRef(TargetAndMode.DriverMode).equals("--driver-mode=cl") ||
-      std::find_if(argv.begin(), argv.end(), [](const char *F) {
+      llvm::find_if(argv, [](const char *F) {
         return F && strcmp(F, "--driver-mode=cl") == 0;
       }) != argv.end()) {
     ClangCLMode = true;
@@ -510,4 +509,3 @@ int ZigClang_main(int argc_, const char **argv_) {
   // failing command.
   return Res;
 }
-