diff options
Diffstat (limited to 'lib/CodeGen/BackendUtil.cpp')
| -rw-r--r-- | lib/CodeGen/BackendUtil.cpp | 192 | 
1 files changed, 94 insertions, 98 deletions
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index 90b0f68bd6936..cec48f35a2e9c 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -13,13 +13,15 @@  #include "clang/Basic/TargetOptions.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "clang/Frontend/FrontendDiagnostic.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Assembly/PrintModulePass.h" -#include "llvm/Bitcode/ReaderWriter.h" +#include "clang/Frontend/Utils.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Bitcode/BitcodeWriterPass.h"  #include "llvm/CodeGen/RegAllocRegistry.h"  #include "llvm/CodeGen/SchedulerRegistry.h"  #include "llvm/IR/DataLayout.h" +#include "llvm/IR/IRPrintingPasses.h"  #include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h"  #include "llvm/MC/SubtargetFeature.h"  #include "llvm/PassManager.h"  #include "llvm/Support/CommandLine.h" @@ -36,6 +38,7 @@  #include "llvm/Transforms/Instrumentation.h"  #include "llvm/Transforms/ObjCARC.h"  #include "llvm/Transforms/Scalar.h" +#include <memory>  using namespace clang;  using namespace llvm; @@ -55,38 +58,37 @@ class EmitAssemblyHelper {    mutable FunctionPassManager *PerFunctionPasses;  private: -  PassManager *getCodeGenPasses(TargetMachine *TM) const { +  PassManager *getCodeGenPasses() const {      if (!CodeGenPasses) {        CodeGenPasses = new PassManager(); -      CodeGenPasses->add(new DataLayout(TheModule)); +      CodeGenPasses->add(new DataLayoutPass(TheModule));        if (TM)          TM->addAnalysisPasses(*CodeGenPasses);      }      return CodeGenPasses;    } -  PassManager *getPerModulePasses(TargetMachine *TM) const { +  PassManager *getPerModulePasses() const {      if (!PerModulePasses) {        PerModulePasses = new PassManager(); -      PerModulePasses->add(new DataLayout(TheModule)); +      PerModulePasses->add(new DataLayoutPass(TheModule));        if (TM)          TM->addAnalysisPasses(*PerModulePasses);      }      return PerModulePasses;    } -  FunctionPassManager *getPerFunctionPasses(TargetMachine *TM) const { +  FunctionPassManager *getPerFunctionPasses() const {      if (!PerFunctionPasses) {        PerFunctionPasses = new FunctionPassManager(TheModule); -      PerFunctionPasses->add(new DataLayout(TheModule)); +      PerFunctionPasses->add(new DataLayoutPass(TheModule));        if (TM)          TM->addAnalysisPasses(*PerFunctionPasses);      }      return PerFunctionPasses;    } - -  void CreatePasses(TargetMachine *TM); +  void CreatePasses();    /// CreateTargetMachine - Generates the TargetMachine.    /// Returns Null if it is unable to create the target machine. @@ -101,8 +103,7 @@ private:    /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.    ///    /// \return True on success. -  bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS, -                     TargetMachine *TM); +  bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS);  public:    EmitAssemblyHelper(DiagnosticsEngine &_Diags, @@ -112,14 +113,19 @@ public:                       Module *M)      : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),        TheModule(M), CodeGenerationTime("Code Generation Time"), -      CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {} +      CodeGenPasses(nullptr), PerModulePasses(nullptr), +      PerFunctionPasses(nullptr) {}    ~EmitAssemblyHelper() {      delete CodeGenPasses;      delete PerModulePasses;      delete PerFunctionPasses; +    if (CodeGenOpts.DisableFree) +      BuryPointer(TM.release());    } +  std::unique_ptr<TargetMachine> TM; +    void EmitAssembly(BackendAction Action, raw_ostream *OS);  }; @@ -162,6 +168,11 @@ static void addSampleProfileLoaderPass(const PassManagerBuilder &Builder,    PM.add(createSampleProfileLoaderPass(CGOpts.SampleProfileFile));  } +static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder, +                                     PassManagerBase &PM) { +  PM.add(createAddDiscriminatorsPass()); +} +  static void addBoundsCheckingPass(const PassManagerBuilder &Builder,                                      PassManagerBase &PM) {    PM.add(createBoundsCheckingPass()); @@ -169,20 +180,8 @@ static void addBoundsCheckingPass(const PassManagerBuilder &Builder,  static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,                                        PassManagerBase &PM) { -  const PassManagerBuilderWrapper &BuilderWrapper = -      static_cast<const PassManagerBuilderWrapper&>(Builder); -  const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); -  const LangOptions &LangOpts = BuilderWrapper.getLangOpts(); -  PM.add(createAddressSanitizerFunctionPass( -      LangOpts.Sanitize.InitOrder, -      LangOpts.Sanitize.UseAfterReturn, -      LangOpts.Sanitize.UseAfterScope, -      CGOpts.SanitizerBlacklistFile, -      CGOpts.SanitizeAddressZeroBaseShadow)); -  PM.add(createAddressSanitizerModulePass( -      LangOpts.Sanitize.InitOrder, -      CGOpts.SanitizerBlacklistFile, -      CGOpts.SanitizeAddressZeroBaseShadow)); +  PM.add(createAddressSanitizerFunctionPass()); +  PM.add(createAddressSanitizerModulePass());  }  static void addMemorySanitizerPass(const PassManagerBuilder &Builder, @@ -190,8 +189,7 @@ static void addMemorySanitizerPass(const PassManagerBuilder &Builder,    const PassManagerBuilderWrapper &BuilderWrapper =        static_cast<const PassManagerBuilderWrapper&>(Builder);    const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); -  PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins, -                                   CGOpts.SanitizerBlacklistFile)); +  PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins));    // MemorySanitizer inserts complex instrumentation that mostly follows    // the logic of the original code, but operates on "shadow" values. @@ -208,10 +206,7 @@ static void addMemorySanitizerPass(const PassManagerBuilder &Builder,  static void addThreadSanitizerPass(const PassManagerBuilder &Builder,                                     PassManagerBase &PM) { -  const PassManagerBuilderWrapper &BuilderWrapper = -      static_cast<const PassManagerBuilderWrapper&>(Builder); -  const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); -  PM.add(createThreadSanitizerPass(CGOpts.SanitizerBlacklistFile)); +  PM.add(createThreadSanitizerPass());  }  static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder, @@ -222,7 +217,7 @@ static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,    PM.add(createDataFlowSanitizerPass(CGOpts.SanitizerBlacklistFile));  } -void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) { +void EmitAssemblyHelper::CreatePasses() {    unsigned OptLevel = CodeGenOpts.OptimizationLevel;    CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); @@ -240,10 +235,14 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {    PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;    PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; +  PMBuilder.DisableTailCalls = CodeGenOpts.DisableTailCalls;    PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;    PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;    PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; +  PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, +                         addAddDiscriminatorsPass); +    if (!CodeGenOpts.SampleProfileFile.empty())      PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,                             addSampleProfileLoaderPass); @@ -298,19 +297,12 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {    PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);    if (!CodeGenOpts.SimplifyLibCalls)      PMBuilder.LibraryInfo->disableAllFunctions(); -   +    switch (Inlining) {    case CodeGenOptions::NoInlining: break;    case CodeGenOptions::NormalInlining: { -    // FIXME: Derive these constants in a principled fashion. -    unsigned Threshold = 225; -    if (CodeGenOpts.OptimizeSize == 1)      // -Os -      Threshold = 75; -    else if (CodeGenOpts.OptimizeSize == 2) // -Oz -      Threshold = 25; -    else if (OptLevel > 2) -      Threshold = 275; -    PMBuilder.Inliner = createFunctionInliningPass(Threshold); +    PMBuilder.Inliner = +        createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize);      break;    }    case CodeGenOptions::OnlyAlwaysInlining: @@ -324,13 +316,15 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {    }    // Set up the per-function pass manager. -  FunctionPassManager *FPM = getPerFunctionPasses(TM); +  FunctionPassManager *FPM = getPerFunctionPasses();    if (CodeGenOpts.VerifyModule)      FPM->add(createVerifierPass());    PMBuilder.populateFunctionPassManager(*FPM);    // Set up the per-module pass manager. -  PassManager *MPM = getPerModulePasses(TM); +  PassManager *MPM = getPerModulePasses(); +  if (CodeGenOpts.VerifyModule) +    MPM->add(createDebugInfoVerifierPass());    if (!CodeGenOpts.DisableGCov &&        (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) { @@ -360,32 +354,19 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {    if (!TheTarget) {      if (MustCreateTM)        Diags.Report(diag::err_fe_unable_to_create_target) << Error; -    return 0; +    return nullptr;    } -  // FIXME: Expose these capabilities via actual APIs!!!! Aside from just -  // being gross, this is also totally broken if we ever care about -  // concurrency. - -  TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose); - -  TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections); -  TargetMachine::setDataSections    (CodeGenOpts.DataSections); - -  // FIXME: Parse this earlier. -  llvm::CodeModel::Model CM; -  if (CodeGenOpts.CodeModel == "small") { -    CM = llvm::CodeModel::Small; -  } else if (CodeGenOpts.CodeModel == "kernel") { -    CM = llvm::CodeModel::Kernel; -  } else if (CodeGenOpts.CodeModel == "medium") { -    CM = llvm::CodeModel::Medium; -  } else if (CodeGenOpts.CodeModel == "large") { -    CM = llvm::CodeModel::Large; -  } else { -    assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!"); -    CM = llvm::CodeModel::Default; -  } +  unsigned CodeModel = +    llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel) +      .Case("small", llvm::CodeModel::Small) +      .Case("kernel", llvm::CodeModel::Kernel) +      .Case("medium", llvm::CodeModel::Medium) +      .Case("large", llvm::CodeModel::Large) +      .Case("default", llvm::CodeModel::Default) +      .Default(~0u); +  assert(CodeModel != ~0u && "invalid code model!"); +  llvm::CodeModel::Model CM = static_cast<llvm::CodeModel::Model>(CodeModel);    SmallVector<const char *, 16> BackendArgs;    BackendArgs.push_back("clang"); // Fake program name. @@ -402,8 +383,8 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {    for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i)      BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str());    if (CodeGenOpts.NoGlobalMerge) -    BackendArgs.push_back("-global-merge=false"); -  BackendArgs.push_back(0); +    BackendArgs.push_back("-enable-global-merge=false"); +  BackendArgs.push_back(nullptr);    llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,                                      BackendArgs.data()); @@ -437,6 +418,12 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {    llvm::TargetOptions Options; +  if (CodeGenOpts.DisableIntegratedAS) +    Options.DisableIntegratedAS = true; + +  if (CodeGenOpts.CompressDebugSections) +    Options.CompressDebugSections = true; +    // Set frame pointer elimination mode.    if (!CodeGenOpts.DisableFPElim) {      Options.NoFramePointerElim = false; @@ -482,32 +469,27 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {    Options.DisableTailCalls = CodeGenOpts.DisableTailCalls;    Options.TrapFuncName = CodeGenOpts.TrapFuncName;    Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; -  Options.EnableSegmentedStacks = CodeGenOpts.EnableSegmentedStacks; +  Options.FunctionSections = CodeGenOpts.FunctionSections; +  Options.DataSections = CodeGenOpts.DataSections; + +  Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll; +  Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels; +  Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm; +  Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack; +  Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;    TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,                                                       FeaturesStr, Options,                                                       RM, CM, OptLevel); -  if (CodeGenOpts.RelaxAll) -    TM->setMCRelaxAll(true); -  if (CodeGenOpts.SaveTempLabels) -    TM->setMCSaveTempLabels(true); -  if (CodeGenOpts.NoDwarf2CFIAsm) -    TM->setMCUseCFI(false); -  if (!CodeGenOpts.NoDwarfDirectoryAsm) -    TM->setMCUseDwarfDirectory(true); -  if (CodeGenOpts.NoExecStack) -    TM->setMCNoExecStack(true); -    return TM;  }  bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, -                                       formatted_raw_ostream &OS, -                                       TargetMachine *TM) { +                                       formatted_raw_ostream &OS) {    // Create the code generator passes. -  PassManager *PM = getCodeGenPasses(TM); +  PassManager *PM = getCodeGenPasses();    // Add LibraryInfo.    llvm::Triple TargetTriple(TheModule->getTargetTriple()); @@ -546,33 +528,34 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,  }  void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) { -  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0); +  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);    llvm::formatted_raw_ostream FormattedOS;    bool UsesCodeGen = (Action != Backend_EmitNothing &&                        Action != Backend_EmitBC &&                        Action != Backend_EmitLL); -  TargetMachine *TM = CreateTargetMachine(UsesCodeGen); +  if (!TM) +    TM.reset(CreateTargetMachine(UsesCodeGen)); +    if (UsesCodeGen && !TM) return; -  llvm::OwningPtr<TargetMachine> TMOwner(CodeGenOpts.DisableFree ? 0 : TM); -  CreatePasses(TM); +  CreatePasses();    switch (Action) {    case Backend_EmitNothing:      break;    case Backend_EmitBC: -    getPerModulePasses(TM)->add(createBitcodeWriterPass(*OS)); +    getPerModulePasses()->add(createBitcodeWriterPass(*OS));      break;    case Backend_EmitLL:      FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM); -    getPerModulePasses(TM)->add(createPrintModulePass(&FormattedOS)); +    getPerModulePasses()->add(createPrintModulePass(FormattedOS));      break;    default:      FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM); -    if (!AddEmitPasses(Action, FormattedOS, TM)) +    if (!AddEmitPasses(Action, FormattedOS))        return;    } @@ -607,10 +590,23 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {  void clang::EmitBackendOutput(DiagnosticsEngine &Diags,                                const CodeGenOptions &CGOpts,                                const clang::TargetOptions &TOpts, -                              const LangOptions &LOpts, -                              Module *M, -                              BackendAction Action, raw_ostream *OS) { +                              const LangOptions &LOpts, StringRef TDesc, +                              Module *M, BackendAction Action, +                              raw_ostream *OS) {    EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);    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(); +    if (DLDesc != TDesc) { +      unsigned DiagID = Diags.getCustomDiagID( +          DiagnosticsEngine::Error, "backend data layout '%0' does not match " +                                    "expected target description '%1'"); +      Diags.Report(DiagID) << DLDesc << TDesc; +    } +  }  }  | 
