diff options
Diffstat (limited to 'lib/CodeGen/BackendUtil.cpp')
| -rw-r--r-- | lib/CodeGen/BackendUtil.cpp | 109 | 
1 files changed, 78 insertions, 31 deletions
| diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index 0a1915b485d7..62f87c983bfa 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -27,7 +27,7 @@  #include "llvm/Support/TargetRegistry.h"  #include "llvm/Support/Timer.h"  #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetData.h" +#include "llvm/DataLayout.h"  #include "llvm/Target/TargetLibraryInfo.h"  #include "llvm/Target/TargetMachine.h"  #include "llvm/Target/TargetOptions.h" @@ -54,36 +54,67 @@ class EmitAssemblyHelper {    mutable FunctionPassManager *PerFunctionPasses;  private: -  PassManager *getCodeGenPasses() const { +  PassManager *getCodeGenPasses(TargetMachine *TM) const {      if (!CodeGenPasses) {        CodeGenPasses = new PassManager(); -      CodeGenPasses->add(new TargetData(TheModule)); +      CodeGenPasses->add(new DataLayout(TheModule)); +      // Add TargetTransformInfo. +      if (TM) { +        TargetTransformInfo *TTI = +        new TargetTransformInfo(TM->getScalarTargetTransformInfo(), +                                TM->getVectorTargetTransformInfo()); +        CodeGenPasses->add(TTI); +      }      }      return CodeGenPasses;    } -  PassManager *getPerModulePasses() const { +  PassManager *getPerModulePasses(TargetMachine *TM) const {      if (!PerModulePasses) {        PerModulePasses = new PassManager(); -      PerModulePasses->add(new TargetData(TheModule)); +      PerModulePasses->add(new DataLayout(TheModule)); +      if (TM) { +        TargetTransformInfo *TTI = +        new TargetTransformInfo(TM->getScalarTargetTransformInfo(), +                                TM->getVectorTargetTransformInfo()); +        PerModulePasses->add(TTI); +      }      }      return PerModulePasses;    } -  FunctionPassManager *getPerFunctionPasses() const { +  FunctionPassManager *getPerFunctionPasses(TargetMachine *TM) const {      if (!PerFunctionPasses) {        PerFunctionPasses = new FunctionPassManager(TheModule); -      PerFunctionPasses->add(new TargetData(TheModule)); +      PerFunctionPasses->add(new DataLayout(TheModule)); +      if (TM) { +        TargetTransformInfo *TTI = +        new TargetTransformInfo(TM->getScalarTargetTransformInfo(), +                                TM->getVectorTargetTransformInfo()); +        PerFunctionPasses->add(TTI); +      }      }      return PerFunctionPasses;    } -  void CreatePasses(); + +  void CreatePasses(TargetMachine *TM); + +  /// CreateTargetMachine - Generates the TargetMachine. +  /// Returns Null if it is unable to create the target machine. +  /// Some of our clang tests specify triples which are not built +  /// into clang. This is okay because these tests check the generated +  /// IR, and they require DataLayout which depends on the triple. +  /// In this case, we allow this method to fail and not report an error. +  /// When MustCreateTM is used, we print an error if we are unable to load +  /// the requested target. +  TargetMachine *CreateTargetMachine(bool MustCreateTM);    /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.    ///    /// \return True on success. -  bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS); +  bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS, +                     TargetMachine *TM);  public:    EmitAssemblyHelper(DiagnosticsEngine &_Diags, @@ -137,9 +168,9 @@ static void addThreadSanitizerPass(const PassManagerBuilder &Builder,    PM.add(createThreadSanitizerPass());  } -void EmitAssemblyHelper::CreatePasses() { +void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {    unsigned OptLevel = CodeGenOpts.OptimizationLevel; -  CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining; +  CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();    // Handle disabling of LLVM optimization, where we want to preserve the    // internal module before any optimization. @@ -174,14 +205,14 @@ void EmitAssemblyHelper::CreatePasses() {                             addBoundsCheckingPass);    } -  if (LangOpts.AddressSanitizer) { -    PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, +  if (LangOpts.SanitizeAddress) { +    PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,                             addAddressSanitizerPass);      PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,                             addAddressSanitizerPass);    } -  if (LangOpts.ThreadSanitizer) { +  if (LangOpts.SanitizeThread) {      PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,                             addThreadSanitizerPass);      PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, @@ -218,38 +249,36 @@ void EmitAssemblyHelper::CreatePasses() {      break;    } -     // Set up the per-function pass manager. -  FunctionPassManager *FPM = getPerFunctionPasses(); +  FunctionPassManager *FPM = getPerFunctionPasses(TM);    if (CodeGenOpts.VerifyModule)      FPM->add(createVerifierPass());    PMBuilder.populateFunctionPassManager(*FPM);    // Set up the per-module pass manager. -  PassManager *MPM = getPerModulePasses(); +  PassManager *MPM = getPerModulePasses(TM);    if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) {      MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes,                                      CodeGenOpts.EmitGcovArcs,                                      TargetTriple.isMacOSX())); -    if (CodeGenOpts.DebugInfo == CodeGenOptions::NoDebugInfo) +    if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo)        MPM->add(createStripSymbolsPass(true));    } -   -   +    PMBuilder.populateModulePassManager(*MPM);  } -bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, -                                       formatted_raw_ostream &OS) { +TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {    // Create the TargetMachine for generating code.    std::string Error;    std::string Triple = TheModule->getTargetTriple();    const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);    if (!TheTarget) { -    Diags.Report(diag::err_fe_unable_to_create_target) << Error; -    return false; +    if (MustCreateTM) +      Diags.Report(diag::err_fe_unable_to_create_target) << Error; +    return 0;    }    // FIXME: Expose these capabilities via actual APIs!!!! Aside from just @@ -361,7 +390,7 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,      break;    case LangOptions::FPC_Fast:      Options.AllowFPOpFusion = llvm::FPOpFusion::Fast; -    break;               +    break;    }    Options.LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD; @@ -375,6 +404,7 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,    Options.DisableTailCalls = CodeGenOpts.DisableTailCalls;    Options.TrapFuncName = CodeGenOpts.TrapFuncName;    Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; +  Options.SSPBufferSize = CodeGenOpts.SSPBufferSize;    TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,                                                       FeaturesStr, Options, @@ -391,15 +421,27 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,    if (CodeGenOpts.NoExecStack)      TM->setMCNoExecStack(true); +  return TM; +} + +bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, +                                       formatted_raw_ostream &OS, +                                       TargetMachine *TM) { +    // Create the code generator passes. -  PassManager *PM = getCodeGenPasses(); +  PassManager *PM = getCodeGenPasses(TM);    // Add LibraryInfo. -  TargetLibraryInfo *TLI = new TargetLibraryInfo(); +  llvm::Triple TargetTriple(TheModule->getTargetTriple()); +  TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);    if (!CodeGenOpts.SimplifyLibCalls)      TLI->disableAllFunctions();    PM->add(TLI); +  // Add TargetTransformInfo. +  PM->add(new TargetTransformInfo(TM->getScalarTargetTransformInfo(), +                                  TM->getVectorTargetTransformInfo())); +    // Normal mode, emit a .s or .o file by running the code generator. Note,    // this also adds codegenerator level optimization passes.    TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile; @@ -430,23 +472,28 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {    TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0);    llvm::formatted_raw_ostream FormattedOS; -  CreatePasses(); +  bool UsesCodeGen = (Action != Backend_EmitNothing && +                      Action != Backend_EmitBC && +                      Action != Backend_EmitLL); +  TargetMachine *TM = CreateTargetMachine(UsesCodeGen); +  CreatePasses(TM); +    switch (Action) {    case Backend_EmitNothing:      break;    case Backend_EmitBC: -    getPerModulePasses()->add(createBitcodeWriterPass(*OS)); +    getPerModulePasses(TM)->add(createBitcodeWriterPass(*OS));      break;    case Backend_EmitLL:      FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM); -    getPerModulePasses()->add(createPrintModulePass(&FormattedOS)); +    getPerModulePasses(TM)->add(createPrintModulePass(&FormattedOS));      break;    default:      FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM); -    if (!AddEmitPasses(Action, FormattedOS)) +    if (!AddEmitPasses(Action, FormattedOS, TM))        return;    } | 
