diff options
Diffstat (limited to 'lib/CodeGen/BackendUtil.cpp')
-rw-r--r-- | lib/CodeGen/BackendUtil.cpp | 121 |
1 files changed, 82 insertions, 39 deletions
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index 513896d98634..2c033e0f7c02 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -44,13 +44,14 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/Transforms/Coroutines.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/BoundsChecking.h" #include "llvm/Transforms/ObjCARC.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" @@ -168,7 +169,7 @@ static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder, static void addBoundsCheckingPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createBoundsCheckingPass()); + PM.add(createBoundsCheckingLegacyPass()); } static void addSanitizerCoveragePass(const PassManagerBuilder &Builder, @@ -189,6 +190,8 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder, Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard; Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune; Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters; + Opts.PCTable = CGOpts.SanitizeCoveragePCTable; + Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth; PM.add(createSanitizerCoverageModulePass(Opts)); } @@ -234,6 +237,11 @@ static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, /*Recover*/true)); } +static void addHWAddressSanitizerPasses(const PassManagerBuilder &Builder, + legacy::PassManagerBase &PM) { + PM.add(createHWAddressSanitizerPass()); +} + static void addMemorySanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { const PassManagerBuilderWrapper &BuilderWrapper = @@ -334,16 +342,18 @@ static CodeGenOpt::Level getCGOptLevel(const CodeGenOptions &CodeGenOpts) { } } -static llvm::CodeModel::Model getCodeModel(const CodeGenOptions &CodeGenOpts) { - 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); +static Optional<llvm::CodeModel::Model> +getCodeModel(const CodeGenOptions &CodeGenOpts) { + 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", ~1u) + .Default(~0u); assert(CodeModel != ~0u && "invalid code model!"); + if (CodeModel == ~1u) + return None; return static_cast<llvm::CodeModel::Model>(CodeModel); } @@ -419,6 +429,10 @@ static void initTargetOptions(llvm::TargetOptions &Options, if (LangOpts.SjLjExceptions) Options.ExceptionModel = llvm::ExceptionHandling::SjLj; + if (LangOpts.SEHExceptions) + Options.ExceptionModel = llvm::ExceptionHandling::WinEH; + if (LangOpts.DWARFExceptions) + Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI; Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath; Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath; @@ -547,6 +561,13 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM, addKernelAddressSanitizerPasses); } + if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) { + PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, + addHWAddressSanitizerPasses); + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, + addHWAddressSanitizerPasses); + } + if (LangOpts.Sanitize.has(SanitizerKind::Memory)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); @@ -657,7 +678,7 @@ void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { return; } - llvm::CodeModel::Model CM = getCodeModel(CodeGenOpts); + Optional<llvm::CodeModel::Model> CM = getCodeModel(CodeGenOpts); std::string FeaturesStr = llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ","); llvm::Reloc::Model RM = getRelocModel(CodeGenOpts); @@ -840,37 +861,44 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( return; TheModule->setDataLayout(TM->createDataLayout()); - PGOOptions PGOOpt; - - // -fprofile-generate. - PGOOpt.RunProfileGen = CodeGenOpts.hasProfileIRInstr(); - if (PGOOpt.RunProfileGen) - PGOOpt.ProfileGenFile = CodeGenOpts.InstrProfileOutput.empty() ? - DefaultProfileGenName : CodeGenOpts.InstrProfileOutput; - - // -fprofile-use. - if (CodeGenOpts.hasProfileIRUse()) - PGOOpt.ProfileUseFile = CodeGenOpts.ProfileInstrumentUsePath; - - if (!CodeGenOpts.SampleProfileFile.empty()) - PGOOpt.SampleProfileFile = CodeGenOpts.SampleProfileFile; - - // Only pass a PGO options struct if -fprofile-generate or - // -fprofile-use were passed on the cmdline. - PassBuilder PB(TM.get(), - (PGOOpt.RunProfileGen || - !PGOOpt.ProfileUseFile.empty() || - !PGOOpt.SampleProfileFile.empty()) ? - Optional<PGOOptions>(PGOOpt) : None); - - LoopAnalysisManager LAM; - FunctionAnalysisManager FAM; - CGSCCAnalysisManager CGAM; - ModuleAnalysisManager MAM; + Optional<PGOOptions> PGOOpt; + + if (CodeGenOpts.hasProfileIRInstr()) + // -fprofile-generate. + PGOOpt = PGOOptions(CodeGenOpts.InstrProfileOutput.empty() + ? DefaultProfileGenName + : CodeGenOpts.InstrProfileOutput, + "", "", true, CodeGenOpts.DebugInfoForProfiling); + else if (CodeGenOpts.hasProfileIRUse()) + // -fprofile-use. + PGOOpt = PGOOptions("", CodeGenOpts.ProfileInstrumentUsePath, "", false, + CodeGenOpts.DebugInfoForProfiling); + else if (!CodeGenOpts.SampleProfileFile.empty()) + // -fprofile-sample-use + PGOOpt = PGOOptions("", "", CodeGenOpts.SampleProfileFile, false, + CodeGenOpts.DebugInfoForProfiling); + else if (CodeGenOpts.DebugInfoForProfiling) + // -fdebug-info-for-profiling + PGOOpt = PGOOptions("", "", "", false, true); + + PassBuilder PB(TM.get(), PGOOpt); + + LoopAnalysisManager LAM(CodeGenOpts.DebugPassManager); + FunctionAnalysisManager FAM(CodeGenOpts.DebugPassManager); + CGSCCAnalysisManager CGAM(CodeGenOpts.DebugPassManager); + ModuleAnalysisManager MAM(CodeGenOpts.DebugPassManager); // Register the AA manager first so that our version is the one used. FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); }); + // Register the target library analysis directly and give it a customized + // preset TLI. + Triple TargetTriple(TheModule->getTargetTriple()); + std::unique_ptr<TargetLibraryInfoImpl> TLII( + createTLII(TargetTriple, CodeGenOpts)); + FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); + MAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); + // Register all the basic analyses with the managers. PB.registerModuleAnalyses(MAM); PB.registerCGSCCAnalyses(CGAM); @@ -888,6 +916,12 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( // Build a minimal pipeline based on the semantics required by Clang, // which is just that always inlining occurs. MPM.addPass(AlwaysInlinerPass()); + + // At -O0 we directly run necessary sanitizer passes. + if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) + MPM.addPass(createModuleToFunctionPassAdaptor(BoundsCheckingPass())); + + // Lastly, add a semantically necessary pass for ThinLTO. if (IsThinLTO) MPM.addPass(NameAnonGlobalPass()); } else { @@ -895,6 +929,14 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( // configure the pipeline. PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts); + // Register callbacks to schedule sanitizer passes at the appropriate part of + // the pipeline. + if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) + PB.registerScalarOptimizerLateEPCallback( + [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { + FPM.addPass(BoundsCheckingPass()); + }); + if (IsThinLTO) { MPM = PB.buildThinLTOPreLinkDefaultPipeline( Level, CodeGenOpts.DebugPassManager); @@ -1062,6 +1104,7 @@ static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M, initTargetOptions(Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts); Conf.SampleProfile = std::move(SampleProfile); Conf.UseNewPM = CGOpts.ExperimentalNewPassManager; + Conf.DebugPassManager = CGOpts.DebugPassManager; switch (Action) { case Backend_EmitNothing: Conf.PreCodeGenModuleHook = [](size_t Task, const Module &Mod) { |