diff options
Diffstat (limited to 'lib/CodeGen/BackendUtil.cpp')
-rw-r--r-- | lib/CodeGen/BackendUtil.cpp | 153 |
1 files changed, 103 insertions, 50 deletions
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index 62f87c9..45079c0 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -9,31 +9,32 @@ #include "clang/CodeGen/BackendUtil.h" #include "clang/Basic/Diagnostic.h" -#include "clang/Basic/TargetOptions.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/TargetOptions.h" #include "clang/Frontend/CodeGenOptions.h" #include "clang/Frontend/FrontendDiagnostic.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/CodeGen/SchedulerRegistry.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Module.h" #include "llvm/MC/SubtargetFeature.h" +#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/DataLayout.h" #include "llvm/Target/TargetLibraryInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/ObjCARC.h" #include "llvm/Transforms/Scalar.h" using namespace clang; using namespace llvm; @@ -58,13 +59,8 @@ private: if (!CodeGenPasses) { CodeGenPasses = new PassManager(); CodeGenPasses->add(new DataLayout(TheModule)); - // Add TargetTransformInfo. - if (TM) { - TargetTransformInfo *TTI = - new TargetTransformInfo(TM->getScalarTargetTransformInfo(), - TM->getVectorTargetTransformInfo()); - CodeGenPasses->add(TTI); - } + if (TM) + TM->addAnalysisPasses(*CodeGenPasses); } return CodeGenPasses; } @@ -73,12 +69,8 @@ private: if (!PerModulePasses) { PerModulePasses = new PassManager(); PerModulePasses->add(new DataLayout(TheModule)); - if (TM) { - TargetTransformInfo *TTI = - new TargetTransformInfo(TM->getScalarTargetTransformInfo(), - TM->getVectorTargetTransformInfo()); - PerModulePasses->add(TTI); - } + if (TM) + TM->addAnalysisPasses(*PerModulePasses); } return PerModulePasses; } @@ -87,12 +79,8 @@ private: if (!PerFunctionPasses) { PerFunctionPasses = new FunctionPassManager(TheModule); PerFunctionPasses->add(new DataLayout(TheModule)); - if (TM) { - TargetTransformInfo *TTI = - new TargetTransformInfo(TM->getScalarTargetTransformInfo(), - TM->getVectorTargetTransformInfo()); - PerFunctionPasses->add(TTI); - } + if (TM) + TM->addAnalysisPasses(*PerFunctionPasses); } return PerFunctionPasses; } @@ -135,6 +123,20 @@ public: void EmitAssembly(BackendAction Action, raw_ostream *OS); }; +// We need this wrapper to access LangOpts and CGOpts from extension functions +// that we add to the PassManagerBuilder. +class PassManagerBuilderWrapper : public PassManagerBuilder { +public: + PassManagerBuilderWrapper(const CodeGenOptions &CGOpts, + const LangOptions &LangOpts) + : PassManagerBuilder(), CGOpts(CGOpts), LangOpts(LangOpts) {} + const CodeGenOptions &getCGOpts() const { return CGOpts; } + const LangOptions &getLangOpts() const { return LangOpts; } +private: + const CodeGenOptions &CGOpts; + const LangOptions &LangOpts; +}; + } static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { @@ -152,20 +154,56 @@ static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase PM.add(createObjCARCOptPass()); } -static unsigned BoundsChecking; static void addBoundsCheckingPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { - PM.add(createBoundsCheckingPass(BoundsChecking)); + PM.add(createBoundsCheckingPass()); } -static void addAddressSanitizerPass(const PassManagerBuilder &Builder, - PassManagerBase &PM) { - PM.add(createAddressSanitizerPass()); +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)); +} + +static void addMemorySanitizerPass(const PassManagerBuilder &Builder, + PassManagerBase &PM) { + const PassManagerBuilderWrapper &BuilderWrapper = + static_cast<const PassManagerBuilderWrapper&>(Builder); + const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); + PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins, + CGOpts.SanitizerBlacklistFile)); + + // MemorySanitizer inserts complex instrumentation that mostly follows + // the logic of the original code, but operates on "shadow" values. + // It can benefit from re-running some general purpose optimization passes. + if (Builder.OptLevel > 0) { + PM.add(createEarlyCSEPass()); + PM.add(createReassociatePass()); + PM.add(createLICMPass()); + PM.add(createGVNPass()); + PM.add(createInstructionCombiningPass()); + PM.add(createDeadStoreEliminationPass()); + } } static void addThreadSanitizerPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { - PM.add(createThreadSanitizerPass()); + const PassManagerBuilderWrapper &BuilderWrapper = + static_cast<const PassManagerBuilderWrapper&>(Builder); + const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); + PM.add(createThreadSanitizerPass(CGOpts.SanitizerBlacklistFile)); } void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) { @@ -178,8 +216,8 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } - - PassManagerBuilder PMBuilder; + + PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts); PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; @@ -197,22 +235,28 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) { addObjCARCOptPass); } - if (CodeGenOpts.BoundsChecking > 0) { - BoundsChecking = CodeGenOpts.BoundsChecking; + if (LangOpts.Sanitize.Bounds) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addBoundsCheckingPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addBoundsCheckingPass); } - if (LangOpts.SanitizeAddress) { + if (LangOpts.Sanitize.Address) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addAddressSanitizerPass); + addAddressSanitizerPasses); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addAddressSanitizerPass); + addAddressSanitizerPasses); } - if (LangOpts.SanitizeThread) { + if (LangOpts.Sanitize.Memory) { + PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, + addMemorySanitizerPass); + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, + addMemorySanitizerPass); + } + + if (LangOpts.Sanitize.Thread) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, @@ -258,11 +302,19 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) { // Set up the per-module pass manager. PassManager *MPM = getPerModulePasses(TM); - if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) { - MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes, - CodeGenOpts.EmitGcovArcs, - TargetTriple.isMacOSX())); - + if (!CodeGenOpts.DisableGCov && + (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) { + // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if + // LLVM's -default-gcov-version flag is set to something invalid. + GCOVOptions Options; + Options.EmitNotes = CodeGenOpts.EmitGcovNotes; + Options.EmitData = CodeGenOpts.EmitGcovArcs; + memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4); + Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum; + Options.NoRedZone = CodeGenOpts.DisableRedZone; + Options.FunctionNamesInData = + !CodeGenOpts.CoverageNoFunctionNamesInData; + MPM->add(createGCOVProfilerPass(Options)); if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo) MPM->add(createStripSymbolsPass(true)); } @@ -381,14 +433,14 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { } // Set FP fusion mode. - switch (LangOpts.getFPContractMode()) { - case LangOptions::FPC_Off: + switch (CodeGenOpts.getFPContractMode()) { + case CodeGenOptions::FPC_Off: Options.AllowFPOpFusion = llvm::FPOpFusion::Strict; break; - case LangOptions::FPC_On: + case CodeGenOptions::FPC_On: Options.AllowFPOpFusion = llvm::FPOpFusion::Standard; break; - case LangOptions::FPC_Fast: + case CodeGenOptions::FPC_Fast: Options.AllowFPOpFusion = llvm::FPOpFusion::Fast; break; } @@ -405,6 +457,7 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { Options.TrapFuncName = CodeGenOpts.TrapFuncName; Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; Options.SSPBufferSize = CodeGenOpts.SSPBufferSize; + Options.EnableSegmentedStacks = CodeGenOpts.EnableSegmentedStacks; TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr, Options, @@ -438,9 +491,8 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, TLI->disableAllFunctions(); PM->add(TLI); - // Add TargetTransformInfo. - PM->add(new TargetTransformInfo(TM->getScalarTargetTransformInfo(), - TM->getVectorTargetTransformInfo())); + // Add Target specific analysis passes. + TM->addAnalysisPasses(*PM); // Normal mode, emit a .s or .o file by running the code generator. Note, // this also adds codegenerator level optimization passes. @@ -476,6 +528,7 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) { Action != Backend_EmitBC && Action != Backend_EmitLL); TargetMachine *TM = CreateTargetMachine(UsesCodeGen); + if (UsesCodeGen && !TM) return; CreatePasses(TM); switch (Action) { |