diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp | 214 |
1 files changed, 134 insertions, 80 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp b/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp index afcb9e5..6d746c2 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp @@ -14,6 +14,7 @@ #include "clang/Frontend/CodeGenOptions.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/Utils.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" @@ -21,11 +22,13 @@ #include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/FunctionInfo.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include "llvm/MC/SubtargetFeature.h" +#include "llvm/Object/FunctionIndexObjectFile.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/TargetRegistry.h" @@ -94,7 +97,7 @@ private: return PerFunctionPasses; } - void CreatePasses(); + void CreatePasses(FunctionInfoIndex *FunctionIndex); /// Generates the TargetMachine. /// Returns Null if it is unable to create the target machine. @@ -112,15 +115,13 @@ private: bool AddEmitPasses(BackendAction Action, raw_pwrite_stream &OS); public: - EmitAssemblyHelper(DiagnosticsEngine &_Diags, - const CodeGenOptions &CGOpts, + EmitAssemblyHelper(DiagnosticsEngine &_Diags, const CodeGenOptions &CGOpts, const clang::TargetOptions &TOpts, - const LangOptions &LOpts, - Module *M) - : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), - TheModule(M), CodeGenerationTime("Code Generation Time"), - CodeGenPasses(nullptr), PerModulePasses(nullptr), - PerFunctionPasses(nullptr) {} + const LangOptions &LOpts, Module *M) + : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), + TheModule(M), CodeGenerationTime("Code Generation Time"), + CodeGenPasses(nullptr), PerModulePasses(nullptr), + PerFunctionPasses(nullptr) {} ~EmitAssemblyHelper() { delete CodeGenPasses; @@ -166,14 +167,6 @@ static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase PM.add(createObjCARCOptPass()); } -static void addSampleProfileLoaderPass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - const PassManagerBuilderWrapper &BuilderWrapper = - static_cast<const PassManagerBuilderWrapper &>(Builder); - const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); - PM.add(createSampleProfileLoaderPass(CGOpts.SampleProfileFile)); -} - static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { PM.add(createAddDiscriminatorsPass()); @@ -201,14 +194,20 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder, static void addAddressSanitizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/false)); - PM.add(createAddressSanitizerModulePass(/*CompileKernel*/false)); + const PassManagerBuilderWrapper &BuilderWrapper = + static_cast<const PassManagerBuilderWrapper&>(Builder); + const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); + bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Address); + PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/false, Recover)); + PM.add(createAddressSanitizerModulePass(/*CompileKernel*/false, Recover)); } static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/true)); - PM.add(createAddressSanitizerModulePass(/*CompileKernel*/true)); + PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/true, + /*Recover*/true)); + PM.add(createAddressSanitizerModulePass(/*CompileKernel*/true, + /*Recover*/true)); } static void addMemorySanitizerPass(const PassManagerBuilder &Builder, @@ -249,6 +248,13 @@ static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple); if (!CodeGenOpts.SimplifyLibCalls) TLII->disableAllFunctions(); + else { + // Disable individual libc/libm calls in TargetLibraryInfo. + LibFunc::Func F; + for (auto &FuncName : CodeGenOpts.getNoBuiltinFuncs()) + if (TLII->getLibFunc(FuncName, F)) + TLII->setUnavailable(F); + } switch (CodeGenOpts.getVecLib()) { case CodeGenOptions::Accelerate: @@ -271,7 +277,10 @@ static void addSymbolRewriterPass(const CodeGenOptions &Opts, MPM->add(createRewriteSymbolsPass(DL)); } -void EmitAssemblyHelper::CreatePasses() { +void EmitAssemblyHelper::CreatePasses(FunctionInfoIndex *FunctionIndex) { + if (CodeGenOpts.DisableLLVMPasses) + return; + unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); @@ -283,6 +292,29 @@ void EmitAssemblyHelper::CreatePasses() { } PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts); + + // Figure out TargetLibraryInfo. + Triple TargetTriple(TheModule->getTargetTriple()); + PMBuilder.LibraryInfo = createTLII(TargetTriple, CodeGenOpts); + + switch (Inlining) { + case CodeGenOptions::NoInlining: + break; + case CodeGenOptions::NormalInlining: { + PMBuilder.Inliner = + createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize); + break; + } + case CodeGenOptions::OnlyAlwaysInlining: + // Respect always_inline. + if (OptLevel == 0) + // Do not insert lifetime intrinsics at -O0. + PMBuilder.Inliner = createAlwaysInlinerPass(false); + else + PMBuilder.Inliner = createAlwaysInlinerPass(); + break; + } + PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB; @@ -295,13 +327,19 @@ void EmitAssemblyHelper::CreatePasses() { PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO; PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; + legacy::PassManager *MPM = getPerModulePasses(); + + // If we are performing a ThinLTO importing compile, invoke the LTO + // pipeline and pass down the in-memory function index. + if (FunctionIndex) { + PMBuilder.FunctionIndex = FunctionIndex; + PMBuilder.populateLTOPassManager(*MPM); + return; + } + PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addAddDiscriminatorsPass); - if (!CodeGenOpts.SampleProfileFile.empty()) - PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, - addSampleProfileLoaderPass); - // In ObjC ARC mode, add the main ARC optimization passes. if (LangOpts.ObjCAutoRefCount) { PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, @@ -363,27 +401,6 @@ void EmitAssemblyHelper::CreatePasses() { addDataFlowSanitizerPass); } - // Figure out TargetLibraryInfo. - Triple TargetTriple(TheModule->getTargetTriple()); - PMBuilder.LibraryInfo = createTLII(TargetTriple, CodeGenOpts); - - switch (Inlining) { - case CodeGenOptions::NoInlining: break; - case CodeGenOptions::NormalInlining: { - PMBuilder.Inliner = - createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize); - break; - } - case CodeGenOptions::OnlyAlwaysInlining: - // Respect always_inline. - if (OptLevel == 0) - // Do not insert lifetime intrinsics at -O0. - PMBuilder.Inliner = createAlwaysInlinerPass(false); - else - PMBuilder.Inliner = createAlwaysInlinerPass(); - break; - } - // Set up the per-function pass manager. legacy::FunctionPassManager *FPM = getPerFunctionPasses(); if (CodeGenOpts.VerifyModule) @@ -391,7 +408,6 @@ void EmitAssemblyHelper::CreatePasses() { PMBuilder.populateFunctionPassManager(*FPM); // Set up the per-module pass manager. - legacy::PassManager *MPM = getPerModulePasses(); if (!CodeGenOpts.RewriteMapFiles.empty()) addSymbolRewriterPass(CodeGenOpts, MPM); @@ -420,6 +436,9 @@ void EmitAssemblyHelper::CreatePasses() { MPM->add(createInstrProfilingPass(Options)); } + if (!CodeGenOpts.SampleProfileFile.empty()) + MPM->add(createSampleProfileLoaderPass(CodeGenOpts.SampleProfileFile)); + PMBuilder.populateModulePassManager(*MPM); } @@ -455,20 +474,16 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { BackendArgs.push_back("-limit-float-precision"); BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str()); } - for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i) - BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str()); + for (const std::string &BackendOption : CodeGenOpts.BackendOptions) + BackendArgs.push_back(BackendOption.c_str()); BackendArgs.push_back(nullptr); llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1, BackendArgs.data()); - std::string FeaturesStr; - if (!TargetOpts.Features.empty()) { - SubtargetFeatures Features; - for (const std::string &Feature : TargetOpts.Features) - Features.AddFeature(Feature); - FeaturesStr = Features.getString(); - } + std::string FeaturesStr = + llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ","); + // Keep this synced with the equivalent code in tools/driver/cc1as_main.cpp. llvm::Reloc::Model RM = llvm::Reloc::Default; if (CodeGenOpts.RelocationModel == "static") { RM = llvm::Reloc::Static; @@ -497,24 +512,16 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { .Case("posix", llvm::ThreadModel::POSIX) .Case("single", llvm::ThreadModel::Single); - if (CodeGenOpts.DisableIntegratedAS) - Options.DisableIntegratedAS = true; - - if (CodeGenOpts.CompressDebugSections) - Options.CompressDebugSections = true; - - if (CodeGenOpts.UseInitArray) - Options.UseInitArray = 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; - } + assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" || + CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) && + "Invalid Floating Point ABI!"); + Options.FloatABIType = + llvm::StringSwitch<llvm::FloatABI::ABIType>(CodeGenOpts.FloatABI) + .Case("soft", llvm::FloatABI::Soft) + .Case("softfp", llvm::FloatABI::Soft) + .Case("hard", llvm::FloatABI::Hard) + .Default(llvm::FloatABI::Default); // Set FP fusion mode. switch (CodeGenOpts.getFPContractMode()) { @@ -529,6 +536,17 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { break; } + Options.UseInitArray = CodeGenOpts.UseInitArray; + Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS; + Options.CompressDebugSections = CodeGenOpts.CompressDebugSections; + + // Set EABI version. + Options.EABIVersion = llvm::StringSwitch<llvm::EABI>(CodeGenOpts.EABIVersion) + .Case("4", llvm::EABI::EABI4) + .Case("5", llvm::EABI::EABI5) + .Case("gnu", llvm::EABI::GNU) + .Default(llvm::EABI::Default); + Options.LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD; Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath; Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath; @@ -539,11 +557,27 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { Options.FunctionSections = CodeGenOpts.FunctionSections; Options.DataSections = CodeGenOpts.DataSections; Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames; + Options.EmulatedTLS = CodeGenOpts.EmulatedTLS; + switch (CodeGenOpts.getDebuggerTuning()) { + case CodeGenOptions::DebuggerKindGDB: + Options.DebuggerTuning = llvm::DebuggerKind::GDB; + break; + case CodeGenOptions::DebuggerKindLLDB: + Options.DebuggerTuning = llvm::DebuggerKind::LLDB; + break; + case CodeGenOptions::DebuggerKindSCE: + Options.DebuggerTuning = llvm::DebuggerKind::SCE; + break; + default: + break; + } Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll; Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels; Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm; Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack; + Options.MCOptions.MCIncrementalLinkerCompatible = + CodeGenOpts.IncrementalLinkerCompatible; Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings; Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose; Options.MCOptions.ABIName = TargetOpts.ABI; @@ -605,16 +639,37 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, if (UsesCodeGen && !TM) return; if (TM) - TheModule->setDataLayout(*TM->getDataLayout()); - CreatePasses(); + TheModule->setDataLayout(TM->createDataLayout()); + + // If we are performing a ThinLTO importing compile, load the function + // index into memory and pass it into CreatePasses, which will add it + // to the PassManagerBuilder and invoke LTO passes. + std::unique_ptr<FunctionInfoIndex> FunctionIndex; + if (!CodeGenOpts.ThinLTOIndexFile.empty()) { + ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = + llvm::getFunctionIndexForFile(CodeGenOpts.ThinLTOIndexFile, + [&](const DiagnosticInfo &DI) { + TheModule->getContext().diagnose(DI); + }); + if (std::error_code EC = IndexOrErr.getError()) { + std::string Error = EC.message(); + errs() << "Error loading index file '" << CodeGenOpts.ThinLTOIndexFile + << "': " << Error << "\n"; + return; + } + FunctionIndex = std::move(IndexOrErr.get()); + assert(FunctionIndex && "Expected non-empty function index"); + } + + CreatePasses(FunctionIndex.get()); switch (Action) { case Backend_EmitNothing: break; case Backend_EmitBC: - getPerModulePasses()->add( - createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists)); + getPerModulePasses()->add(createBitcodeWriterPass( + *OS, CodeGenOpts.EmitLLVMUseLists, CodeGenOpts.EmitFunctionSummary)); break; case Backend_EmitLL: @@ -667,8 +722,7 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags, // 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(); + std::string DLDesc = M->getDataLayout().getStringRepresentation(); if (DLDesc != TDesc) { unsigned DiagID = Diags.getCustomDiagID( DiagnosticsEngine::Error, "backend data layout '%0' does not match " |