diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:49:41 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:49:41 +0000 | 
| commit | 45b533945f0851ec234ca846e1af5ee1e4df0b6e (patch) | |
| tree | 0a5b74c0b9ca73aded34df95c91fcaf3815230d8 /lib/CodeGen/BackendUtil.cpp | |
| parent | 7e86edd64bfae4e324224452e4ea879b3371a4bd (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/BackendUtil.cpp')
| -rw-r--r-- | lib/CodeGen/BackendUtil.cpp | 188 | 
1 files changed, 109 insertions, 79 deletions
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index afcb9e5c50559..82297e7ee417d 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -14,6 +14,7 @@  #include "clang/Frontend/CodeGenOptions.h"  #include "clang/Frontend/FrontendDiagnostic.h"  #include "clang/Frontend/Utils.h" +#include "llvm/ADT/StringExtras.h"  #include "llvm/ADT/StringSwitch.h"  #include "llvm/Analysis/TargetLibraryInfo.h"  #include "llvm/Analysis/TargetTransformInfo.h" @@ -21,6 +22,7 @@  #include "llvm/CodeGen/RegAllocRegistry.h"  #include "llvm/CodeGen/SchedulerRegistry.h"  #include "llvm/IR/DataLayout.h" +#include "llvm/IR/FunctionInfo.h"  #include "llvm/IR/IRPrintingPasses.h"  #include "llvm/IR/LegacyPassManager.h"  #include "llvm/IR/Module.h" @@ -52,6 +54,7 @@ class EmitAssemblyHelper {    const clang::TargetOptions &TargetOpts;    const LangOptions &LangOpts;    Module *TheModule; +  std::unique_ptr<FunctionInfoIndex> FunctionIndex;    Timer CodeGenerationTime; @@ -112,15 +115,14 @@ private:    bool AddEmitPasses(BackendAction Action, raw_pwrite_stream &OS);  public: -  EmitAssemblyHelper(DiagnosticsEngine &_Diags, -                     const CodeGenOptions &CGOpts, +  EmitAssemblyHelper(DiagnosticsEngine &_Diags, const CodeGenOptions &CGOpts,                       const clang::TargetOptions &TOpts, -                     const LangOptions &LOpts, -                     Module *M) -    : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), -      TheModule(M), CodeGenerationTime("Code Generation Time"), -      CodeGenPasses(nullptr), PerModulePasses(nullptr), -      PerFunctionPasses(nullptr) {} +                     const LangOptions &LOpts, Module *M, +                     std::unique_ptr<FunctionInfoIndex> Index) +      : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), +        TheModule(M), FunctionIndex(std::move(Index)), +        CodeGenerationTime("Code Generation Time"), CodeGenPasses(nullptr), +        PerModulePasses(nullptr), PerFunctionPasses(nullptr) {}    ~EmitAssemblyHelper() {      delete CodeGenPasses; @@ -166,14 +168,6 @@ static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase      PM.add(createObjCARCOptPass());  } -static void addSampleProfileLoaderPass(const PassManagerBuilder &Builder, -                                       legacy::PassManagerBase &PM) { -  const PassManagerBuilderWrapper &BuilderWrapper = -      static_cast<const PassManagerBuilderWrapper &>(Builder); -  const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); -  PM.add(createSampleProfileLoaderPass(CGOpts.SampleProfileFile)); -} -  static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder,                                       legacy::PassManagerBase &PM) {    PM.add(createAddDiscriminatorsPass()); @@ -201,14 +195,20 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,  static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,                                        legacy::PassManagerBase &PM) { -  PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/false)); -  PM.add(createAddressSanitizerModulePass(/*CompileKernel*/false)); +  const PassManagerBuilderWrapper &BuilderWrapper = +      static_cast<const PassManagerBuilderWrapper&>(Builder); +  const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); +  bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Address); +  PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/false, Recover)); +  PM.add(createAddressSanitizerModulePass(/*CompileKernel*/false, Recover));  }  static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder,                                              legacy::PassManagerBase &PM) { -  PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/true)); -  PM.add(createAddressSanitizerModulePass(/*CompileKernel*/true)); +  PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/true, +                                            /*Recover*/true)); +  PM.add(createAddressSanitizerModulePass(/*CompileKernel*/true, +                                          /*Recover*/true));  }  static void addMemorySanitizerPass(const PassManagerBuilder &Builder, @@ -272,6 +272,9 @@ static void addSymbolRewriterPass(const CodeGenOptions &Opts,  }  void EmitAssemblyHelper::CreatePasses() { +  if (CodeGenOpts.DisableLLVMPasses) +    return; +    unsigned OptLevel = CodeGenOpts.OptimizationLevel;    CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); @@ -283,6 +286,29 @@ void EmitAssemblyHelper::CreatePasses() {    }    PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts); + +  // Figure out TargetLibraryInfo. +  Triple TargetTriple(TheModule->getTargetTriple()); +  PMBuilder.LibraryInfo = createTLII(TargetTriple, CodeGenOpts); + +  switch (Inlining) { +  case CodeGenOptions::NoInlining: +    break; +  case CodeGenOptions::NormalInlining: { +    PMBuilder.Inliner = +        createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize); +    break; +  } +  case CodeGenOptions::OnlyAlwaysInlining: +    // Respect always_inline. +    if (OptLevel == 0) +      // Do not insert lifetime intrinsics at -O0. +      PMBuilder.Inliner = createAlwaysInlinerPass(false); +    else +      PMBuilder.Inliner = createAlwaysInlinerPass(); +    break; +  } +    PMBuilder.OptLevel = OptLevel;    PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;    PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB; @@ -295,13 +321,20 @@ void EmitAssemblyHelper::CreatePasses() {    PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;    PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; +  legacy::PassManager *MPM = getPerModulePasses(); + +  // If we are performing a ThinLTO importing compile, invoke the LTO +  // pipeline and pass down the in-memory function index. +  if (!CodeGenOpts.ThinLTOIndexFile.empty()) { +    assert(FunctionIndex && "Expected non-empty function index"); +    PMBuilder.FunctionIndex = FunctionIndex.get(); +    PMBuilder.populateLTOPassManager(*MPM); +    return; +  } +    PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,                           addAddDiscriminatorsPass); -  if (!CodeGenOpts.SampleProfileFile.empty()) -    PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, -                           addSampleProfileLoaderPass); -    // In ObjC ARC mode, add the main ARC optimization passes.    if (LangOpts.ObjCAutoRefCount) {      PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, @@ -363,27 +396,6 @@ void EmitAssemblyHelper::CreatePasses() {                             addDataFlowSanitizerPass);    } -  // Figure out TargetLibraryInfo. -  Triple TargetTriple(TheModule->getTargetTriple()); -  PMBuilder.LibraryInfo = createTLII(TargetTriple, CodeGenOpts); - -  switch (Inlining) { -  case CodeGenOptions::NoInlining: break; -  case CodeGenOptions::NormalInlining: { -    PMBuilder.Inliner = -        createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize); -    break; -  } -  case CodeGenOptions::OnlyAlwaysInlining: -    // Respect always_inline. -    if (OptLevel == 0) -      // Do not insert lifetime intrinsics at -O0. -      PMBuilder.Inliner = createAlwaysInlinerPass(false); -    else -      PMBuilder.Inliner = createAlwaysInlinerPass(); -    break; -  } -    // Set up the per-function pass manager.    legacy::FunctionPassManager *FPM = getPerFunctionPasses();    if (CodeGenOpts.VerifyModule) @@ -391,7 +403,6 @@ void EmitAssemblyHelper::CreatePasses() {    PMBuilder.populateFunctionPassManager(*FPM);    // Set up the per-module pass manager. -  legacy::PassManager *MPM = getPerModulePasses();    if (!CodeGenOpts.RewriteMapFiles.empty())      addSymbolRewriterPass(CodeGenOpts, MPM); @@ -420,6 +431,9 @@ void EmitAssemblyHelper::CreatePasses() {      MPM->add(createInstrProfilingPass(Options));    } +  if (!CodeGenOpts.SampleProfileFile.empty()) +    MPM->add(createSampleProfileLoaderPass(CodeGenOpts.SampleProfileFile)); +    PMBuilder.populateModulePassManager(*MPM);  } @@ -455,20 +469,16 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {      BackendArgs.push_back("-limit-float-precision");      BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());    } -  for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i) -    BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str()); +  for (const std::string &BackendOption : CodeGenOpts.BackendOptions) +    BackendArgs.push_back(BackendOption.c_str());    BackendArgs.push_back(nullptr);    llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,                                      BackendArgs.data()); -  std::string FeaturesStr; -  if (!TargetOpts.Features.empty()) { -    SubtargetFeatures Features; -    for (const std::string &Feature : TargetOpts.Features) -      Features.AddFeature(Feature); -    FeaturesStr = Features.getString(); -  } +  std::string FeaturesStr = +      llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ","); +  // Keep this synced with the equivalent code in tools/driver/cc1as_main.cpp.    llvm::Reloc::Model RM = llvm::Reloc::Default;    if (CodeGenOpts.RelocationModel == "static") {      RM = llvm::Reloc::Static; @@ -497,24 +507,16 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {        .Case("posix", llvm::ThreadModel::POSIX)        .Case("single", llvm::ThreadModel::Single); -  if (CodeGenOpts.DisableIntegratedAS) -    Options.DisableIntegratedAS = true; - -  if (CodeGenOpts.CompressDebugSections) -    Options.CompressDebugSections = true; - -  if (CodeGenOpts.UseInitArray) -    Options.UseInitArray = true; -    // Set float ABI type. -  if (CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp") -    Options.FloatABIType = llvm::FloatABI::Soft; -  else if (CodeGenOpts.FloatABI == "hard") -    Options.FloatABIType = llvm::FloatABI::Hard; -  else { -    assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!"); -    Options.FloatABIType = llvm::FloatABI::Default; -  } +  assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" || +          CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) && +         "Invalid Floating Point ABI!"); +  Options.FloatABIType = +      llvm::StringSwitch<llvm::FloatABI::ABIType>(CodeGenOpts.FloatABI) +          .Case("soft", llvm::FloatABI::Soft) +          .Case("softfp", llvm::FloatABI::Soft) +          .Case("hard", llvm::FloatABI::Hard) +          .Default(llvm::FloatABI::Default);    // Set FP fusion mode.    switch (CodeGenOpts.getFPContractMode()) { @@ -529,6 +531,17 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {      break;    } +  Options.UseInitArray = CodeGenOpts.UseInitArray; +  Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS; +  Options.CompressDebugSections = CodeGenOpts.CompressDebugSections; + +  // Set EABI version. +  Options.EABIVersion = llvm::StringSwitch<llvm::EABI>(CodeGenOpts.EABIVersion) +                            .Case("4", llvm::EABI::EABI4) +                            .Case("5", llvm::EABI::EABI5) +                            .Case("gnu", llvm::EABI::GNU) +                            .Default(llvm::EABI::Default); +    Options.LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD;    Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath;    Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath; @@ -539,11 +552,27 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {    Options.FunctionSections = CodeGenOpts.FunctionSections;    Options.DataSections = CodeGenOpts.DataSections;    Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames; +  Options.EmulatedTLS = CodeGenOpts.EmulatedTLS; +  switch (CodeGenOpts.getDebuggerTuning()) { +  case CodeGenOptions::DebuggerKindGDB: +    Options.DebuggerTuning = llvm::DebuggerKind::GDB; +    break; +  case CodeGenOptions::DebuggerKindLLDB: +    Options.DebuggerTuning = llvm::DebuggerKind::LLDB; +    break; +  case CodeGenOptions::DebuggerKindSCE: +    Options.DebuggerTuning = llvm::DebuggerKind::SCE; +    break; +  default: +    break; +  }    Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;    Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;    Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm;    Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack; +  Options.MCOptions.MCIncrementalLinkerCompatible = +      CodeGenOpts.IncrementalLinkerCompatible;    Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;    Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;    Options.MCOptions.ABIName = TargetOpts.ABI; @@ -605,7 +634,7 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,    if (UsesCodeGen && !TM)      return;    if (TM) -    TheModule->setDataLayout(*TM->getDataLayout()); +    TheModule->setDataLayout(TM->createDataLayout());    CreatePasses();    switch (Action) { @@ -613,8 +642,8 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,      break;    case Backend_EmitBC: -    getPerModulePasses()->add( -        createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists)); +    getPerModulePasses()->add(createBitcodeWriterPass( +        *OS, CodeGenOpts.EmitLLVMUseLists, CodeGenOpts.EmitFunctionSummary));      break;    case Backend_EmitLL: @@ -659,16 +688,17 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags,                                const clang::TargetOptions &TOpts,                                const LangOptions &LOpts, StringRef TDesc,                                Module *M, BackendAction Action, -                              raw_pwrite_stream *OS) { -  EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M); +                              raw_pwrite_stream *OS, +                              std::unique_ptr<FunctionInfoIndex> Index) { +  EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M, +                               std::move(Index));    AsmHelper.EmitAssembly(Action, OS);    // If an optional clang TargetInfo description string was passed in, use it to    // verify the LLVM TargetMachine's DataLayout.    if (AsmHelper.TM && !TDesc.empty()) { -    std::string DLDesc = -        AsmHelper.TM->getDataLayout()->getStringRepresentation(); +    std::string DLDesc = M->getDataLayout().getStringRepresentation();      if (DLDesc != TDesc) {        unsigned DiagID = Diags.getCustomDiagID(            DiagnosticsEngine::Error, "backend data layout '%0' does not match "  | 
