17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/Analysis/TargetLibraryInfo.h"
19 #include "llvm/Analysis/TargetTransformInfo.h"
20 #include "llvm/Bitcode/BitcodeWriterPass.h"
21 #include "llvm/CodeGen/RegAllocRegistry.h"
22 #include "llvm/CodeGen/SchedulerRegistry.h"
23 #include "llvm/IR/DataLayout.h"
24 #include "llvm/IR/IRPrintingPasses.h"
25 #include "llvm/IR/LegacyPassManager.h"
26 #include "llvm/IR/Module.h"
27 #include "llvm/IR/Verifier.h"
28 #include "llvm/MC/SubtargetFeature.h"
29 #include "llvm/Support/CommandLine.h"
30 #include "llvm/Support/PrettyStackTrace.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/Timer.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include "llvm/Target/TargetMachine.h"
35 #include "llvm/Target/TargetOptions.h"
36 #include "llvm/Target/TargetSubtargetInfo.h"
37 #include "llvm/Transforms/IPO.h"
38 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
39 #include "llvm/Transforms/Instrumentation.h"
40 #include "llvm/Transforms/ObjCARC.h"
41 #include "llvm/Transforms/Scalar.h"
42 #include "llvm/Transforms/Utils/SymbolRewriter.h"
44 using namespace clang;
49 class EmitAssemblyHelper {
56 Timer CodeGenerationTime;
58 mutable legacy::PassManager *CodeGenPasses;
59 mutable legacy::PassManager *PerModulePasses;
60 mutable legacy::FunctionPassManager *PerFunctionPasses;
63 TargetIRAnalysis getTargetIRAnalysis()
const {
65 return TM->getTargetIRAnalysis();
67 return TargetIRAnalysis();
70 legacy::PassManager *getCodeGenPasses()
const {
72 CodeGenPasses =
new legacy::PassManager();
74 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
79 legacy::PassManager *getPerModulePasses()
const {
80 if (!PerModulePasses) {
81 PerModulePasses =
new legacy::PassManager();
83 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
85 return PerModulePasses;
88 legacy::FunctionPassManager *getPerFunctionPasses()
const {
89 if (!PerFunctionPasses) {
90 PerFunctionPasses =
new legacy::FunctionPassManager(TheModule);
91 PerFunctionPasses->add(
92 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
94 return PerFunctionPasses;
107 TargetMachine *CreateTargetMachine(
bool MustCreateTM);
120 : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),
121 TheModule(M), CodeGenerationTime(
"Code Generation Time"),
122 CodeGenPasses(nullptr), PerModulePasses(nullptr),
123 PerFunctionPasses(nullptr) {}
125 ~EmitAssemblyHelper() {
126 delete CodeGenPasses;
127 delete PerModulePasses;
128 delete PerFunctionPasses;
129 if (CodeGenOpts.DisableFree)
133 std::unique_ptr<TargetMachine> TM;
140 class PassManagerBuilderWrapper :
public PassManagerBuilder {
144 : PassManagerBuilder(), CGOpts(CGOpts), LangOpts(LangOpts) {}
146 const LangOptions &getLangOpts()
const {
return LangOpts; }
155 if (Builder.OptLevel > 0)
156 PM.add(createObjCARCAPElimPass());
160 if (Builder.OptLevel > 0)
161 PM.add(createObjCARCExpandPass());
165 if (Builder.OptLevel > 0)
166 PM.add(createObjCARCOptPass());
170 legacy::PassManagerBase &PM) {
171 const PassManagerBuilderWrapper &BuilderWrapper =
172 static_cast<const PassManagerBuilderWrapper &
>(
Builder);
178 legacy::PassManagerBase &PM) {
179 PM.add(createAddDiscriminatorsPass());
183 legacy::PassManagerBase &PM) {
184 PM.add(createBoundsCheckingPass());
188 legacy::PassManagerBase &PM) {
189 const PassManagerBuilderWrapper &BuilderWrapper =
190 static_cast<const PassManagerBuilderWrapper&
>(
Builder);
192 SanitizerCoverageOptions Opts;
194 static_cast<SanitizerCoverageOptions::Type
>(CGOpts.SanitizeCoverageType);
195 Opts.IndirectCalls = CGOpts.SanitizeCoverageIndirectCalls;
196 Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB;
197 Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp;
198 Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;
199 PM.add(createSanitizerCoverageModulePass(Opts));
203 legacy::PassManagerBase &PM) {
204 PM.add(createAddressSanitizerFunctionPass(
false));
205 PM.add(createAddressSanitizerModulePass(
false));
209 legacy::PassManagerBase &PM) {
210 PM.add(createAddressSanitizerFunctionPass(
true));
211 PM.add(createAddressSanitizerModulePass(
true));
215 legacy::PassManagerBase &PM) {
216 const PassManagerBuilderWrapper &BuilderWrapper =
217 static_cast<const PassManagerBuilderWrapper&
>(
Builder);
219 PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins));
224 if (Builder.OptLevel > 0) {
225 PM.add(createEarlyCSEPass());
226 PM.add(createReassociatePass());
227 PM.add(createLICMPass());
228 PM.add(createGVNPass());
229 PM.add(createInstructionCombiningPass());
230 PM.add(createDeadStoreEliminationPass());
235 legacy::PassManagerBase &PM) {
236 PM.add(createThreadSanitizerPass());
240 legacy::PassManagerBase &PM) {
241 const PassManagerBuilderWrapper &BuilderWrapper =
242 static_cast<const PassManagerBuilderWrapper&
>(
Builder);
243 const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
247 static TargetLibraryInfoImpl *
createTLII(llvm::Triple &TargetTriple,
249 TargetLibraryInfoImpl *TLII =
new TargetLibraryInfoImpl(TargetTriple);
250 if (!CodeGenOpts.SimplifyLibCalls)
251 TLII->disableAllFunctions();
253 switch (CodeGenOpts.getVecLib()) {
255 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::Accelerate);
264 legacy::PassManager *MPM) {
265 llvm::SymbolRewriter::RewriteDescriptorList DL;
267 llvm::SymbolRewriter::RewriteMapParser MapParser;
269 MapParser.parse(MapFile, &DL);
271 MPM->add(createRewriteSymbolsPass(DL));
274 void EmitAssemblyHelper::CreatePasses() {
275 unsigned OptLevel = CodeGenOpts.OptimizationLevel;
280 if (CodeGenOpts.DisableLLVMOpts) {
282 Inlining = CodeGenOpts.NoInlining;
285 PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts);
286 PMBuilder.OptLevel = OptLevel;
287 PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
288 PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB;
289 PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
290 PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;
292 PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
293 PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
294 PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions;
295 PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
296 PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
298 PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
301 if (!CodeGenOpts.SampleProfileFile.empty())
302 PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
306 if (LangOpts.ObjCAutoRefCount) {
307 PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
309 PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
311 PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
315 if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) {
316 PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
318 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
322 if (CodeGenOpts.SanitizeCoverageType ||
323 CodeGenOpts.SanitizeCoverageIndirectCalls ||
324 CodeGenOpts.SanitizeCoverageTraceCmp) {
325 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
327 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
331 if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
332 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
334 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
338 if (LangOpts.Sanitize.has(SanitizerKind::KernelAddress)) {
339 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
341 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
345 if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
346 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
348 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
352 if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
353 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
355 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
359 if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
360 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
362 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
367 Triple TargetTriple(TheModule->getTargetTriple());
368 PMBuilder.LibraryInfo =
createTLII(TargetTriple, CodeGenOpts);
374 createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize);
381 PMBuilder.Inliner = createAlwaysInlinerPass(
false);
383 PMBuilder.Inliner = createAlwaysInlinerPass();
388 legacy::FunctionPassManager *FPM = getPerFunctionPasses();
389 if (CodeGenOpts.VerifyModule)
390 FPM->add(createVerifierPass());
391 PMBuilder.populateFunctionPassManager(*FPM);
394 legacy::PassManager *MPM = getPerModulePasses();
395 if (!CodeGenOpts.RewriteMapFiles.empty())
398 if (!CodeGenOpts.DisableGCov &&
399 (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) {
403 Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
404 Options.EmitData = CodeGenOpts.EmitGcovArcs;
405 memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4);
406 Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum;
407 Options.NoRedZone = CodeGenOpts.DisableRedZone;
408 Options.FunctionNamesInData =
409 !CodeGenOpts.CoverageNoFunctionNamesInData;
410 Options.ExitBlockBeforeBody = CodeGenOpts.CoverageExitBlockBeforeBody;
411 MPM->add(createGCOVProfilerPass(Options));
413 MPM->add(createStripSymbolsPass(
true));
416 if (CodeGenOpts.ProfileInstrGenerate) {
418 Options.NoRedZone = CodeGenOpts.DisableRedZone;
419 Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
420 MPM->add(createInstrProfilingPass(Options));
423 PMBuilder.populateModulePassManager(*MPM);
426 TargetMachine *EmitAssemblyHelper::CreateTargetMachine(
bool MustCreateTM) {
429 std::string Triple = TheModule->getTargetTriple();
430 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
433 Diags.Report(diag::err_fe_unable_to_create_target) <<
Error;
438 llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
439 .Case(
"small", llvm::CodeModel::Small)
440 .Case(
"kernel", llvm::CodeModel::Kernel)
441 .Case(
"medium", llvm::CodeModel::Medium)
442 .Case(
"large", llvm::CodeModel::Large)
443 .Case(
"default", llvm::CodeModel::Default)
445 assert(CodeModel != ~0u &&
"invalid code model!");
446 llvm::CodeModel::Model CM =
static_cast<llvm::CodeModel::Model
>(CodeModel);
449 BackendArgs.push_back(
"clang");
450 if (!CodeGenOpts.DebugPass.empty()) {
451 BackendArgs.push_back(
"-debug-pass");
452 BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
454 if (!CodeGenOpts.LimitFloatPrecision.empty()) {
455 BackendArgs.push_back(
"-limit-float-precision");
456 BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
458 for (
unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i)
459 BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str());
460 BackendArgs.push_back(
nullptr);
461 llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
464 std::string FeaturesStr;
465 if (!TargetOpts.Features.empty()) {
466 SubtargetFeatures Features;
467 for (
const std::string &Feature : TargetOpts.Features)
468 Features.AddFeature(Feature);
469 FeaturesStr = Features.getString();
472 llvm::Reloc::Model RM = llvm::Reloc::Default;
473 if (CodeGenOpts.RelocationModel ==
"static") {
474 RM = llvm::Reloc::Static;
475 }
else if (CodeGenOpts.RelocationModel ==
"pic") {
476 RM = llvm::Reloc::PIC_;
478 assert(CodeGenOpts.RelocationModel ==
"dynamic-no-pic" &&
479 "Invalid PIC model!");
480 RM = llvm::Reloc::DynamicNoPIC;
484 switch (CodeGenOpts.OptimizationLevel) {
487 case 3: OptLevel = CodeGenOpt::Aggressive;
break;
492 if (!TargetOpts.Reciprocals.empty())
493 Options.Reciprocals = TargetRecip(TargetOpts.Reciprocals);
495 Options.ThreadModel =
496 llvm::StringSwitch<llvm::ThreadModel::Model>(CodeGenOpts.ThreadModel)
497 .Case(
"posix", llvm::ThreadModel::POSIX)
498 .Case(
"single", llvm::ThreadModel::Single);
500 if (CodeGenOpts.DisableIntegratedAS)
501 Options.DisableIntegratedAS =
true;
503 if (CodeGenOpts.CompressDebugSections)
504 Options.CompressDebugSections =
true;
506 if (CodeGenOpts.UseInitArray)
507 Options.UseInitArray =
true;
510 if (CodeGenOpts.FloatABI ==
"soft" || CodeGenOpts.FloatABI ==
"softfp")
511 Options.FloatABIType = llvm::FloatABI::Soft;
512 else if (CodeGenOpts.FloatABI ==
"hard")
513 Options.FloatABIType = llvm::FloatABI::Hard;
515 assert(CodeGenOpts.FloatABI.empty() &&
"Invalid float abi!");
516 Options.FloatABIType = llvm::FloatABI::Default;
520 switch (CodeGenOpts.getFPContractMode()) {
522 Options.AllowFPOpFusion = llvm::FPOpFusion::Strict;
525 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
528 Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
532 Options.LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD;
533 Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath;
534 Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath;
535 Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
536 Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath;
537 Options.StackAlignmentOverride = CodeGenOpts.StackAlignment;
538 Options.PositionIndependentExecutable = LangOpts.PIELevel != 0;
539 Options.FunctionSections = CodeGenOpts.FunctionSections;
540 Options.DataSections = CodeGenOpts.DataSections;
541 Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
543 Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
544 Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
545 Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm;
546 Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
547 Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
548 Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
549 Options.MCOptions.ABIName = TargetOpts.ABI;
551 TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,
552 FeaturesStr, Options,
559 raw_pwrite_stream &OS) {
562 legacy::PassManager *PM = getCodeGenPasses();
565 llvm::Triple TargetTriple(TheModule->getTargetTriple());
566 std::unique_ptr<TargetLibraryInfoImpl> TLII(
568 PM->add(
new TargetLibraryInfoWrapperPass(*TLII));
572 TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
574 CGFT = TargetMachine::CGFT_ObjectFile;
576 CGFT = TargetMachine::CGFT_Null;
583 if (CodeGenOpts.OptimizationLevel > 0)
584 PM->add(createObjCARCContractPass());
586 if (TM->addPassesToEmitFile(*PM, OS, CGFT,
587 !CodeGenOpts.VerifyModule)) {
588 Diags.Report(diag::err_fe_unable_to_interface_with_target);
596 raw_pwrite_stream *OS) {
597 TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime :
nullptr);
603 TM.reset(CreateTargetMachine(UsesCodeGen));
605 if (UsesCodeGen && !TM)
608 TheModule->setDataLayout(*TM->getDataLayout());
616 getPerModulePasses()->add(
617 createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists));
621 getPerModulePasses()->add(
622 createPrintModulePass(*OS,
"", CodeGenOpts.EmitLLVMUseLists));
626 if (!AddEmitPasses(Action, *OS))
631 cl::PrintOptionValues();
636 if (PerFunctionPasses) {
637 PrettyStackTraceString CrashInfo(
"Per-function optimization");
639 PerFunctionPasses->doInitialization();
640 for (Function &F : *TheModule)
641 if (!F.isDeclaration())
642 PerFunctionPasses->run(F);
643 PerFunctionPasses->doFinalization();
646 if (PerModulePasses) {
647 PrettyStackTraceString CrashInfo(
"Per-module optimization passes");
648 PerModulePasses->run(*TheModule);
652 PrettyStackTraceString CrashInfo(
"Code generation");
653 CodeGenPasses->run(*TheModule);
662 raw_pwrite_stream *OS) {
663 EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
665 AsmHelper.EmitAssembly(Action, OS);
669 if (AsmHelper.TM && !TDesc.empty()) {
671 AsmHelper.TM->getDataLayout()->getStringRepresentation();
672 if (DLDesc != TDesc) {
675 "expected target description '%1'");
676 Diags.
Report(DiagID) << DLDesc << TDesc;
static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM)
Emit human-readable LLVM assembly.
Run CodeGen, but don't emit anything.
static void addSampleProfileLoaderPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
std::string SampleProfileFile
Name of the profile file to use with -fprofile-sample-use.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
static void addAddressSanitizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
std::vector< std::string > RewriteMapFiles
Set of files definining the rules for the symbol rewriting.
Don't emit anything (benchmarking mode)
Options for controlling the target.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, StringRef TDesc, llvm::Module *M, BackendAction Action, raw_pwrite_stream *OS)
Concrete class used by the front-end to report problems and issues.
static void addThreadSanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
static void addSanitizerCoveragePass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
Defines the clang::LangOptions interface.
static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM)
static TargetLibraryInfoImpl * createTLII(llvm::Triple &TargetTriple, const CodeGenOptions &CodeGenOpts)
Emit native object files.
Emit native assembly files.
const MatchFinder::MatchFinderOptions & Options
static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
static void addSymbolRewriterPass(const CodeGenOptions &Opts, legacy::PassManager *MPM)
static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
Defines the clang::TargetOptions class.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Defines the Diagnostic-related interfaces.
void BuryPointer(const void *Ptr)
static void addBoundsCheckingPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM)
BoundNodesTreeBuilder *const Builder
static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
std::vector< std::string > SanitizerBlacklistFiles
Paths to blacklist files specifying which objects (files, functions, variables) should not be instrum...
static void addMemorySanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)