diff options
Diffstat (limited to 'lib/CodeGen/BackendUtil.cpp')
-rw-r--r-- | lib/CodeGen/BackendUtil.cpp | 143 |
1 files changed, 98 insertions, 45 deletions
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index b9e3ed9..2f44711 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -43,7 +43,7 @@ namespace { class EmitAssemblyHelper { DiagnosticsEngine &Diags; const CodeGenOptions &CodeGenOpts; - const TargetOptions &TargetOpts; + const clang::TargetOptions &TargetOpts; const LangOptions &LangOpts; Module *TheModule; @@ -87,7 +87,8 @@ private: public: EmitAssemblyHelper(DiagnosticsEngine &_Diags, - const CodeGenOptions &CGOpts, const TargetOptions &TOpts, + const CodeGenOptions &CGOpts, + const clang::TargetOptions &TOpts, const LangOptions &LOpts, Module *M) : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), @@ -105,6 +106,11 @@ public: } +static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { + if (Builder.OptLevel > 0) + PM.add(createObjCARCAPElimPass()); +} + static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { if (Builder.OptLevel > 0) PM.add(createObjCARCExpandPass()); @@ -115,6 +121,16 @@ static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase PM.add(createObjCARCOptPass()); } +static void addAddressSanitizerPass(const PassManagerBuilder &Builder, + PassManagerBase &PM) { + PM.add(createAddressSanitizerPass()); +} + +static void addThreadSanitizerPass(const PassManagerBuilder &Builder, + PassManagerBase &PM) { + PM.add(createThreadSanitizerPass()); +} + void EmitAssemblyHelper::CreatePasses() { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining; @@ -138,10 +154,26 @@ void EmitAssemblyHelper::CreatePasses() { if (LangOpts.ObjCAutoRefCount) { PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addObjCARCExpandPass); + PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, + addObjCARCAPElimPass); PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addObjCARCOptPass); } - + + if (LangOpts.AddressSanitizer) { + PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, + addAddressSanitizerPass); + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, + addAddressSanitizerPass); + } + + if (LangOpts.ThreadSanitizer) { + PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, + addThreadSanitizerPass); + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, + addThreadSanitizerPass); + } + // Figure out TargetLibraryInfo. Triple TargetTriple(TheModule->getTargetTriple()); PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple); @@ -164,7 +196,11 @@ void EmitAssemblyHelper::CreatePasses() { } case CodeGenOptions::OnlyAlwaysInlining: // Respect always_inline. - PMBuilder.Inliner = createAlwaysInlinerPass(); + if (OptLevel == 0) + // Do not insert lifetime intrinsics at -O0. + PMBuilder.Inliner = createAlwaysInlinerPass(false); + else + PMBuilder.Inliner = createAlwaysInlinerPass(); break; } @@ -206,35 +242,6 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, // being gross, this is also totally broken if we ever care about // concurrency. - // Set frame pointer elimination mode. - if (!CodeGenOpts.DisableFPElim) { - llvm::NoFramePointerElim = false; - llvm::NoFramePointerElimNonLeaf = false; - } else if (CodeGenOpts.OmitLeafFramePointer) { - llvm::NoFramePointerElim = false; - llvm::NoFramePointerElimNonLeaf = true; - } else { - llvm::NoFramePointerElim = true; - llvm::NoFramePointerElimNonLeaf = true; - } - - // Set float ABI type. - if (CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp") - llvm::FloatABIType = llvm::FloatABI::Soft; - else if (CodeGenOpts.FloatABI == "hard") - llvm::FloatABIType = llvm::FloatABI::Hard; - else { - assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!"); - llvm::FloatABIType = llvm::FloatABI::Default; - } - - llvm::LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD; - llvm::NoInfsFPMath = CodeGenOpts.NoInfsFPMath; - llvm::NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath; - NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS; - llvm::UnsafeFPMath = CodeGenOpts.UnsafeFPMath; - llvm::UseSoftFloat = CodeGenOpts.SoftFloat; - TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose); TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections); @@ -255,7 +262,7 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, CM = llvm::CodeModel::Default; } - std::vector<const char *> BackendArgs; + SmallVector<const char *, 16> BackendArgs; BackendArgs.push_back("clang"); // Fake program name. if (!CodeGenOpts.DebugPass.empty()) { BackendArgs.push_back("-debug-pass"); @@ -273,7 +280,7 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, BackendArgs.push_back("-global-merge=false"); BackendArgs.push_back(0); llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1, - const_cast<char **>(&BackendArgs[0])); + BackendArgs.data()); std::string FeaturesStr; if (TargetOpts.Features.size()) { @@ -296,8 +303,52 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, RM = llvm::Reloc::DynamicNoPIC; } + CodeGenOpt::Level OptLevel = CodeGenOpt::Default; + switch (CodeGenOpts.OptimizationLevel) { + default: break; + case 0: OptLevel = CodeGenOpt::None; break; + case 3: OptLevel = CodeGenOpt::Aggressive; break; + } + + llvm::TargetOptions Options; + + // Set frame pointer elimination mode. + if (!CodeGenOpts.DisableFPElim) { + Options.NoFramePointerElim = false; + Options.NoFramePointerElimNonLeaf = false; + } else if (CodeGenOpts.OmitLeafFramePointer) { + Options.NoFramePointerElim = false; + Options.NoFramePointerElimNonLeaf = true; + } else { + Options.NoFramePointerElim = true; + Options.NoFramePointerElimNonLeaf = true; + } + + // Set float ABI type. + if (CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp") + Options.FloatABIType = llvm::FloatABI::Soft; + else if (CodeGenOpts.FloatABI == "hard") + Options.FloatABIType = llvm::FloatABI::Hard; + else { + assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!"); + Options.FloatABIType = llvm::FloatABI::Default; + } + + Options.LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD; + Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath; + Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath; + Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS; + Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath; + Options.UseSoftFloat = CodeGenOpts.SoftFloat; + Options.StackAlignmentOverride = CodeGenOpts.StackAlignment; + Options.RealignStack = CodeGenOpts.StackRealignment; + Options.DisableTailCalls = CodeGenOpts.DisableTailCalls; + Options.TrapFuncName = CodeGenOpts.TrapFuncName; + Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; + TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU, - FeaturesStr, RM, CM); + FeaturesStr, Options, + RM, CM, OptLevel); if (CodeGenOpts.RelaxAll) TM->setMCRelaxAll(true); @@ -305,18 +356,19 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, TM->setMCSaveTempLabels(true); if (CodeGenOpts.NoDwarf2CFIAsm) TM->setMCUseCFI(false); + if (!CodeGenOpts.NoDwarfDirectoryAsm) + TM->setMCUseDwarfDirectory(true); if (CodeGenOpts.NoExecStack) TM->setMCNoExecStack(true); // Create the code generator passes. PassManager *PM = getCodeGenPasses(); - CodeGenOpt::Level OptLevel = CodeGenOpt::Default; - switch (CodeGenOpts.OptimizationLevel) { - default: break; - case 0: OptLevel = CodeGenOpt::None; break; - case 3: OptLevel = CodeGenOpt::Aggressive; break; - } + // Add LibraryInfo. + TargetLibraryInfo *TLI = new TargetLibraryInfo(); + if (!CodeGenOpts.SimplifyLibCalls) + TLI->disableAllFunctions(); + PM->add(TLI); // Normal mode, emit a .s or .o file by running the code generator. Note, // this also adds codegenerator level optimization passes. @@ -331,10 +383,11 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, // Add ObjC ARC final-cleanup optimizations. This is done as part of the // "codegen" passes so that it isn't run multiple times when there is // inlining happening. - if (LangOpts.ObjCAutoRefCount) + if (LangOpts.ObjCAutoRefCount && + CodeGenOpts.OptimizationLevel > 0) PM->add(createObjCARCContractPass()); - if (TM->addPassesToEmitFile(*PM, OS, CGFT, OptLevel, + if (TM->addPassesToEmitFile(*PM, OS, CGFT, /*DisableVerify=*/!CodeGenOpts.VerifyModule)) { Diags.Report(diag::err_fe_unable_to_interface_with_target); return false; @@ -397,7 +450,7 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) { void clang::EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, - const TargetOptions &TOpts, + const clang::TargetOptions &TOpts, const LangOptions &LOpts, Module *M, BackendAction Action, raw_ostream *OS) { |