diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp | 192 |
1 files changed, 94 insertions, 98 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp b/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp index 90b0f68..cec48f3 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp +++ b/contrib/llvm/tools/clang/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; + } + } } |