summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp214
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 "
OpenPOWER on IntegriCloud