18 #include "llvm/ADT/SmallSet.h" 19 #include "llvm/ADT/StringExtras.h" 20 #include "llvm/ADT/StringSwitch.h" 21 #include "llvm/ADT/Triple.h" 22 #include "llvm/Analysis/TargetLibraryInfo.h" 23 #include "llvm/Analysis/TargetTransformInfo.h" 24 #include "llvm/Bitcode/BitcodeReader.h" 25 #include "llvm/Bitcode/BitcodeWriter.h" 26 #include "llvm/Bitcode/BitcodeWriterPass.h" 27 #include "llvm/CodeGen/RegAllocRegistry.h" 28 #include "llvm/CodeGen/SchedulerRegistry.h" 29 #include "llvm/IR/DataLayout.h" 30 #include "llvm/IR/IRPrintingPasses.h" 31 #include "llvm/IR/LegacyPassManager.h" 32 #include "llvm/IR/Module.h" 33 #include "llvm/IR/ModuleSummaryIndex.h" 34 #include "llvm/IR/Verifier.h" 35 #include "llvm/LTO/LTOBackend.h" 36 #include "llvm/MC/MCAsmInfo.h" 37 #include "llvm/MC/SubtargetFeature.h" 38 #include "llvm/Passes/PassBuilder.h" 39 #include "llvm/Support/CommandLine.h" 40 #include "llvm/Support/MemoryBuffer.h" 41 #include "llvm/Support/PrettyStackTrace.h" 42 #include "llvm/Support/TargetRegistry.h" 43 #include "llvm/Support/Timer.h" 44 #include "llvm/Support/raw_ostream.h" 45 #include "llvm/Target/TargetMachine.h" 46 #include "llvm/Target/TargetOptions.h" 47 #include "llvm/CodeGen/TargetSubtargetInfo.h" 48 #include "llvm/Transforms/Coroutines.h" 49 #include "llvm/Transforms/IPO.h" 50 #include "llvm/Transforms/IPO/AlwaysInliner.h" 51 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 52 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" 53 #include "llvm/Transforms/Instrumentation.h" 54 #include "llvm/Transforms/Instrumentation/BoundsChecking.h" 55 #include "llvm/Transforms/ObjCARC.h" 56 #include "llvm/Transforms/Scalar.h" 57 #include "llvm/Transforms/Scalar/GVN.h" 58 #include "llvm/Transforms/Utils/NameAnonGlobals.h" 59 #include "llvm/Transforms/Utils/SymbolRewriter.h" 61 using namespace clang;
67 static constexpr
StringLiteral DefaultProfileGenName =
"default_%m.profraw";
69 class EmitAssemblyHelper {
77 Timer CodeGenerationTime;
79 std::unique_ptr<raw_pwrite_stream> OS;
81 TargetIRAnalysis getTargetIRAnalysis()
const {
83 return TM->getTargetIRAnalysis();
85 return TargetIRAnalysis();
88 void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM);
98 void CreateTargetMachine(
bool MustCreateTM);
103 bool AddEmitPasses(legacy::PassManager &CodeGenPasses,
BackendAction Action,
104 raw_pwrite_stream &OS);
112 : Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts),
113 TargetOpts(TOpts), LangOpts(LOpts), TheModule(M),
114 CodeGenerationTime(
"codegen",
"Code Generation Time") {}
116 ~EmitAssemblyHelper() {
117 if (CodeGenOpts.DisableFree)
121 std::unique_ptr<TargetMachine> TM;
124 std::unique_ptr<raw_pwrite_stream> OS);
127 std::unique_ptr<raw_pwrite_stream> OS);
132 class PassManagerBuilderWrapper :
public PassManagerBuilder {
134 PassManagerBuilderWrapper(
const Triple &TargetTriple,
137 : PassManagerBuilder(), TargetTriple(TargetTriple), CGOpts(CGOpts),
138 LangOpts(LangOpts) {}
139 const Triple &getTargetTriple()
const {
return TargetTriple; }
141 const LangOptions &getLangOpts()
const {
return LangOpts; }
144 const Triple &TargetTriple;
151 if (Builder.OptLevel > 0)
152 PM.add(createObjCARCAPElimPass());
156 if (Builder.OptLevel > 0)
157 PM.add(createObjCARCExpandPass());
161 if (Builder.OptLevel > 0)
162 PM.add(createObjCARCOptPass());
166 legacy::PassManagerBase &PM) {
167 PM.add(createAddDiscriminatorsPass());
171 legacy::PassManagerBase &PM) {
172 PM.add(createBoundsCheckingLegacyPass());
176 legacy::PassManagerBase &PM) {
177 const PassManagerBuilderWrapper &BuilderWrapper =
178 static_cast<const PassManagerBuilderWrapper&
>(Builder);
180 SanitizerCoverageOptions Opts;
182 static_cast<SanitizerCoverageOptions::Type
>(CGOpts.SanitizeCoverageType);
183 Opts.IndirectCalls = CGOpts.SanitizeCoverageIndirectCalls;
184 Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB;
185 Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp;
186 Opts.TraceDiv = CGOpts.SanitizeCoverageTraceDiv;
187 Opts.TraceGep = CGOpts.SanitizeCoverageTraceGep;
188 Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;
189 Opts.TracePC = CGOpts.SanitizeCoverageTracePC;
190 Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;
191 Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;
192 Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
193 Opts.PCTable = CGOpts.SanitizeCoveragePCTable;
194 Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;
195 PM.add(createSanitizerCoverageModulePass(Opts));
203 if (!CGOpts.SanitizeAddressGlobalsDeadStripping)
205 switch (T.getObjectFormat()) {
210 return CGOpts.DataSections && !CGOpts.DisableIntegratedAS;
217 legacy::PassManagerBase &PM) {
218 const PassManagerBuilderWrapper &BuilderWrapper =
219 static_cast<const PassManagerBuilderWrapper&
>(Builder);
220 const Triple &
T = BuilderWrapper.getTargetTriple();
223 bool UseAfterScope = CGOpts.SanitizeAddressUseAfterScope;
225 PM.add(createAddressSanitizerFunctionPass(
false, Recover,
227 PM.add(createAddressSanitizerModulePass(
false, Recover,
232 legacy::PassManagerBase &PM) {
233 PM.add(createAddressSanitizerFunctionPass(
236 PM.add(createAddressSanitizerModulePass(
true,
241 legacy::PassManagerBase &PM) {
242 const PassManagerBuilderWrapper &BuilderWrapper =
243 static_cast<const PassManagerBuilderWrapper &
>(Builder);
246 PM.add(createHWAddressSanitizerPass(Recover));
250 legacy::PassManagerBase &PM) {
251 const PassManagerBuilderWrapper &BuilderWrapper =
252 static_cast<const PassManagerBuilderWrapper&
>(Builder);
254 int TrackOrigins = CGOpts.SanitizeMemoryTrackOrigins;
256 PM.add(createMemorySanitizerPass(TrackOrigins, Recover));
261 if (Builder.OptLevel > 0) {
262 PM.add(createEarlyCSEPass());
263 PM.add(createReassociatePass());
264 PM.add(createLICMPass());
265 PM.add(createGVNPass());
266 PM.add(createInstructionCombiningPass());
267 PM.add(createDeadStoreEliminationPass());
272 legacy::PassManagerBase &PM) {
273 PM.add(createThreadSanitizerPass());
277 legacy::PassManagerBase &PM) {
278 const PassManagerBuilderWrapper &BuilderWrapper =
279 static_cast<const PassManagerBuilderWrapper&
>(Builder);
280 const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
285 legacy::PassManagerBase &PM) {
286 const PassManagerBuilderWrapper &BuilderWrapper =
287 static_cast<const PassManagerBuilderWrapper&
>(Builder);
288 const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
289 EfficiencySanitizerOptions Opts;
290 if (LangOpts.
Sanitize.
has(SanitizerKind::EfficiencyCacheFrag))
291 Opts.ToolType = EfficiencySanitizerOptions::ESAN_CacheFrag;
292 else if (LangOpts.
Sanitize.
has(SanitizerKind::EfficiencyWorkingSet))
293 Opts.ToolType = EfficiencySanitizerOptions::ESAN_WorkingSet;
294 PM.add(createEfficiencySanitizerPass(Opts));
297 static TargetLibraryInfoImpl *
createTLII(llvm::Triple &TargetTriple,
299 TargetLibraryInfoImpl *TLII =
new TargetLibraryInfoImpl(TargetTriple);
300 if (!CodeGenOpts.SimplifyLibCalls)
301 TLII->disableAllFunctions();
306 if (TLII->getLibFunc(FuncName, F))
307 TLII->setUnavailable(F);
310 switch (CodeGenOpts.getVecLib()) {
312 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::Accelerate);
315 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML);
324 legacy::PassManager *MPM) {
325 llvm::SymbolRewriter::RewriteDescriptorList DL;
327 llvm::SymbolRewriter::RewriteMapParser MapParser;
329 MapParser.parse(MapFile, &DL);
331 MPM->add(createRewriteSymbolsPass(DL));
335 switch (CodeGenOpts.OptimizationLevel) {
337 llvm_unreachable(
"Invalid optimization level!");
341 return CodeGenOpt::Less;
345 return CodeGenOpt::Aggressive;
351 unsigned CodeModel = llvm::StringSwitch<unsigned>(CodeGenOpts.
CodeModel)
352 .Case(
"small", llvm::CodeModel::Small)
353 .Case(
"kernel", llvm::CodeModel::Kernel)
354 .Case(
"medium", llvm::CodeModel::Medium)
355 .Case(
"large", llvm::CodeModel::Large)
356 .Case(
"default", ~1u)
358 assert(CodeModel != ~0u &&
"invalid code model!");
359 if (CodeModel == ~1u)
361 return static_cast<llvm::CodeModel::Model
>(CodeModel);
368 RM = llvm::StringSwitch<llvm::Reloc::Model>(CodeGenOpts.
RelocationModel)
369 .Case(
"static", llvm::Reloc::Static)
370 .Case(
"pic", llvm::Reloc::PIC_)
371 .Case(
"ropi", llvm::Reloc::ROPI)
372 .Case(
"rwpi", llvm::Reloc::RWPI)
373 .Case(
"ropi-rwpi", llvm::Reloc::ROPI_RWPI)
374 .Case(
"dynamic-no-pic", llvm::Reloc::DynamicNoPIC);
375 assert(RM.hasValue() &&
"invalid PIC model!");
381 return TargetMachine::CGFT_ObjectFile;
383 return TargetMachine::CGFT_Null;
386 return TargetMachine::CGFT_AssemblyFile;
395 Options.ThreadModel =
396 llvm::StringSwitch<llvm::ThreadModel::Model>(CodeGenOpts.
ThreadModel)
397 .Case(
"posix", llvm::ThreadModel::POSIX)
398 .Case(
"single", llvm::ThreadModel::Single);
401 assert((CodeGenOpts.
FloatABI ==
"soft" || CodeGenOpts.
FloatABI ==
"softfp" ||
403 "Invalid Floating Point ABI!");
404 Options.FloatABIType =
405 llvm::StringSwitch<llvm::FloatABI::ABIType>(CodeGenOpts.
FloatABI)
406 .Case(
"soft", llvm::FloatABI::Soft)
407 .Case(
"softfp", llvm::FloatABI::Soft)
408 .Case(
"hard", llvm::FloatABI::Hard)
409 .Default(llvm::FloatABI::Default);
412 switch (LangOpts.getDefaultFPContractMode()) {
416 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
419 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
422 Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
426 Options.UseInitArray = CodeGenOpts.UseInitArray;
427 Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS;
428 Options.CompressDebugSections = CodeGenOpts.getCompressDebugSections();
429 Options.RelaxELFRelocations = CodeGenOpts.RelaxELFRelocations;
434 if (LangOpts.SjLjExceptions)
435 Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
436 if (LangOpts.SEHExceptions)
437 Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
438 if (LangOpts.DWARFExceptions)
439 Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
441 Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath;
442 Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath;
443 Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
444 Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath;
445 Options.StackAlignmentOverride = CodeGenOpts.StackAlignment;
446 Options.FunctionSections = CodeGenOpts.FunctionSections;
447 Options.DataSections = CodeGenOpts.DataSections;
448 Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
449 Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
450 Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
452 if (CodeGenOpts.EnableSplitDwarf)
454 Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
455 Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
456 Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm;
457 Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
458 Options.MCOptions.MCIncrementalLinkerCompatible =
459 CodeGenOpts.IncrementalLinkerCompatible;
460 Options.MCOptions.MCPIECopyRelocations = CodeGenOpts.PIECopyRelocations;
461 Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
462 Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
463 Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;
464 Options.MCOptions.ABIName = TargetOpts.
ABI;
466 if (!Entry.IsFramework &&
470 Options.MCOptions.IASSearchPaths.push_back(
471 Entry.IgnoreSysRoot ? Entry.Path : HSOpts.
Sysroot + Entry.Path);
474 void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
475 legacy::FunctionPassManager &FPM) {
478 if (CodeGenOpts.DisableLLVMPasses)
485 Triple TargetTriple(TheModule->getTargetTriple());
486 std::unique_ptr<TargetLibraryInfoImpl> TLII(
489 PassManagerBuilderWrapper PMBuilder(TargetTriple, CodeGenOpts, LangOpts);
493 if (CodeGenOpts.OptimizationLevel <= 1) {
494 bool InsertLifetimeIntrinsics = (CodeGenOpts.OptimizationLevel != 0 &&
495 !CodeGenOpts.DisableLifetimeMarkers);
496 PMBuilder.Inliner = createAlwaysInlinerLegacyPass(InsertLifetimeIntrinsics);
501 PMBuilder.Inliner = createFunctionInliningPass(
502 CodeGenOpts.OptimizationLevel, CodeGenOpts.OptimizeSize,
504 CodeGenOpts.EmitSummaryIndex));
507 PMBuilder.OptLevel = CodeGenOpts.OptimizationLevel;
508 PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
509 PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
510 PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;
512 PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
513 PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions;
514 PMBuilder.PrepareForThinLTO = CodeGenOpts.EmitSummaryIndex;
515 PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
516 PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
518 MPM.add(
new TargetLibraryInfoWrapperPass(*TLII));
521 TM->adjustPassManager(PMBuilder);
523 if (CodeGenOpts.DebugInfoForProfiling ||
525 PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
529 if (LangOpts.ObjCAutoRefCount) {
530 PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
532 PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
534 PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
538 if (LangOpts.
Sanitize.
has(SanitizerKind::LocalBounds)) {
539 PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
541 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
545 if (CodeGenOpts.SanitizeCoverageType ||
546 CodeGenOpts.SanitizeCoverageIndirectCalls ||
547 CodeGenOpts.SanitizeCoverageTraceCmp) {
548 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
550 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
554 if (LangOpts.
Sanitize.
has(SanitizerKind::Address)) {
555 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
557 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
561 if (LangOpts.
Sanitize.
has(SanitizerKind::KernelAddress)) {
562 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
564 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
568 if (LangOpts.
Sanitize.
has(SanitizerKind::HWAddress)) {
569 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
571 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
575 if (LangOpts.
Sanitize.
has(SanitizerKind::Memory)) {
576 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
578 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
582 if (LangOpts.
Sanitize.
has(SanitizerKind::Thread)) {
583 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
585 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
589 if (LangOpts.
Sanitize.
has(SanitizerKind::DataFlow)) {
590 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
592 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
596 if (LangOpts.CoroutinesTS)
597 addCoroutinePassesToExtensionPoints(PMBuilder);
600 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
602 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
607 FPM.add(
new TargetLibraryInfoWrapperPass(*TLII));
608 if (CodeGenOpts.VerifyModule)
609 FPM.add(createVerifierPass());
615 if (!CodeGenOpts.DisableGCov &&
616 (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) {
620 Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
621 Options.EmitData = CodeGenOpts.EmitGcovArcs;
623 Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum;
624 Options.NoRedZone = CodeGenOpts.DisableRedZone;
625 Options.FunctionNamesInData =
626 !CodeGenOpts.CoverageNoFunctionNamesInData;
627 Options.ExitBlockBeforeBody = CodeGenOpts.CoverageExitBlockBeforeBody;
628 MPM.add(createGCOVProfilerPass(Options));
630 MPM.add(createStripSymbolsPass(
true));
634 InstrProfOptions Options;
635 Options.NoRedZone = CodeGenOpts.DisableRedZone;
637 MPM.add(createInstrProfilingLegacyPass(Options));
640 PMBuilder.EnablePGOInstrGen =
true;
644 PMBuilder.PGOInstrGen = DefaultProfileGenName;
652 PMBuilder.populateFunctionPassManager(FPM);
653 PMBuilder.populateModulePassManager(MPM);
658 BackendArgs.push_back(
"clang");
660 BackendArgs.push_back(
"-debug-pass");
661 BackendArgs.push_back(CodeGenOpts.
DebugPass.c_str());
664 BackendArgs.push_back(
"-limit-float-precision");
667 for (
const std::string &BackendOption : CodeGenOpts.
BackendOptions)
668 BackendArgs.push_back(BackendOption.c_str());
669 BackendArgs.push_back(
nullptr);
670 llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
674 void EmitAssemblyHelper::CreateTargetMachine(
bool MustCreateTM) {
677 std::string Triple = TheModule->getTargetTriple();
678 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
681 Diags.
Report(diag::err_fe_unable_to_create_target) <<
Error;
686 std::string FeaturesStr =
691 llvm::TargetOptions Options;
693 TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.
CPU, FeaturesStr,
694 Options, RM, CM, OptLevel));
697 bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
699 raw_pwrite_stream &OS) {
701 llvm::Triple TargetTriple(TheModule->getTargetTriple());
702 std::unique_ptr<TargetLibraryInfoImpl> TLII(
704 CodeGenPasses.add(
new TargetLibraryInfoWrapperPass(*TLII));
713 if (CodeGenOpts.OptimizationLevel > 0)
714 CodeGenPasses.add(createObjCARCContractPass());
716 if (TM->addPassesToEmitFile(CodeGenPasses, OS, CGFT,
717 !CodeGenOpts.VerifyModule)) {
718 Diags.
Report(diag::err_fe_unable_to_interface_with_target);
726 std::unique_ptr<raw_pwrite_stream> OS) {
727 TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime :
nullptr);
734 CreateTargetMachine(UsesCodeGen);
736 if (UsesCodeGen && !TM)
739 TheModule->setDataLayout(TM->createDataLayout());
741 legacy::PassManager PerModulePasses;
743 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
745 legacy::FunctionPassManager PerFunctionPasses(TheModule);
746 PerFunctionPasses.add(
747 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
749 CreatePasses(PerModulePasses, PerFunctionPasses);
751 legacy::PassManager CodeGenPasses;
753 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
755 std::unique_ptr<raw_fd_ostream> ThinLinkOS;
762 if (CodeGenOpts.EmitSummaryIndex) {
765 ThinLinkOS.reset(
new llvm::raw_fd_ostream(
767 llvm::sys::fs::F_None));
775 createWriteThinLTOBitcodePass(*OS, ThinLinkOS.get()));
779 createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists));
784 createPrintModulePass(*OS,
"", CodeGenOpts.EmitLLVMUseLists));
788 if (!AddEmitPasses(CodeGenPasses, Action, *OS))
793 cl::PrintOptionValues();
799 PrettyStackTraceString CrashInfo(
"Per-function optimization");
801 PerFunctionPasses.doInitialization();
802 for (Function &F : *TheModule)
803 if (!F.isDeclaration())
804 PerFunctionPasses.run(F);
805 PerFunctionPasses.doFinalization();
809 PrettyStackTraceString CrashInfo(
"Per-module optimization passes");
810 PerModulePasses.run(*TheModule);
814 PrettyStackTraceString CrashInfo(
"Code generation");
815 CodeGenPasses.run(*TheModule);
820 switch (Opts.OptimizationLevel) {
822 llvm_unreachable(
"Invalid optimization level!");
825 return PassBuilder::O1;
828 switch (Opts.OptimizeSize) {
830 llvm_unreachable(
"Invalide optimization level for size!");
833 return PassBuilder::O2;
836 return PassBuilder::Os;
839 return PassBuilder::Oz;
843 return PassBuilder::O3;
855 void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
856 BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) {
857 TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime :
nullptr);
862 CreateTargetMachine(
true);
866 TheModule->setDataLayout(TM->createDataLayout());
873 ? DefaultProfileGenName
875 "",
"",
true, CodeGenOpts.DebugInfoForProfiling);
879 CodeGenOpts.DebugInfoForProfiling);
883 CodeGenOpts.DebugInfoForProfiling);
884 else if (CodeGenOpts.DebugInfoForProfiling)
886 PGOOpt = PGOOptions(
"",
"",
"",
false,
true);
888 PassBuilder PB(TM.get(), PGOOpt);
890 LoopAnalysisManager LAM(CodeGenOpts.DebugPassManager);
891 FunctionAnalysisManager FAM(CodeGenOpts.DebugPassManager);
892 CGSCCAnalysisManager CGAM(CodeGenOpts.DebugPassManager);
893 ModuleAnalysisManager MAM(CodeGenOpts.DebugPassManager);
896 FAM.registerPass([&] {
return PB.buildDefaultAAPipeline(); });
900 Triple TargetTriple(TheModule->getTargetTriple());
901 std::unique_ptr<TargetLibraryInfoImpl> TLII(
903 FAM.registerPass([&] {
return TargetLibraryAnalysis(*TLII); });
904 MAM.registerPass([&] {
return TargetLibraryAnalysis(*TLII); });
907 PB.registerModuleAnalyses(MAM);
908 PB.registerCGSCCAnalyses(CGAM);
909 PB.registerFunctionAnalyses(FAM);
910 PB.registerLoopAnalyses(LAM);
911 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
913 ModulePassManager MPM(CodeGenOpts.DebugPassManager);
915 if (!CodeGenOpts.DisableLLVMPasses) {
916 bool IsThinLTO = CodeGenOpts.EmitSummaryIndex;
917 bool IsLTO = CodeGenOpts.PrepareForLTO;
919 if (CodeGenOpts.OptimizationLevel == 0) {
922 MPM.addPass(AlwaysInlinerPass());
925 if (LangOpts.
Sanitize.
has(SanitizerKind::LocalBounds))
926 MPM.addPass(createModuleToFunctionPassAdaptor(BoundsCheckingPass()));
930 MPM.addPass(NameAnonGlobalPass());
938 if (LangOpts.
Sanitize.
has(SanitizerKind::LocalBounds))
939 PB.registerScalarOptimizerLateEPCallback(
940 [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
941 FPM.addPass(BoundsCheckingPass());
945 MPM = PB.buildThinLTOPreLinkDefaultPipeline(
946 Level, CodeGenOpts.DebugPassManager);
947 MPM.addPass(NameAnonGlobalPass());
949 MPM = PB.buildLTOPreLinkDefaultPipeline(Level,
950 CodeGenOpts.DebugPassManager);
952 MPM = PB.buildPerModuleDefaultPipeline(Level,
953 CodeGenOpts.DebugPassManager);
960 legacy::PassManager CodeGenPasses;
961 bool NeedCodeGen =
false;
970 if (CodeGenOpts.EmitSummaryIndex) {
974 llvm::sys::fs::F_None);
976 Diags.
Report(diag::err_fe_unable_to_open_output)
982 ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &*ThinLinkOS :
nullptr));
984 MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
985 CodeGenOpts.EmitSummaryIndex,
986 CodeGenOpts.EmitSummaryIndex));
991 MPM.addPass(PrintModulePass(*OS,
"", CodeGenOpts.EmitLLVMUseLists));
999 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
1000 if (!AddEmitPasses(CodeGenPasses, Action, *OS))
1007 cl::PrintOptionValues();
1011 PrettyStackTraceString CrashInfo(
"Optimizer");
1012 MPM.run(*TheModule, MAM);
1017 PrettyStackTraceString CrashInfo(
"Code generation");
1018 CodeGenPasses.run(*TheModule);
1025 return BMsOrErr.takeError();
1029 for (BitcodeModule &BM : *BMsOrErr) {
1031 if (LTOInfo && LTOInfo->IsThinLTO)
1035 return make_error<StringError>(
"Could not find module summary",
1036 inconvertibleErrorCode());
1044 std::unique_ptr<raw_pwrite_stream> OS,
1045 std::string SampleProfile,
1047 StringMap<DenseMap<GlobalValue::GUID, GlobalValueSummary *>>
1048 ModuleToDefinedGVSummaries;
1049 CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1056 FunctionImporter::ImportMapTy ImportList;
1057 for (
auto &GlobalList : *CombinedIndex) {
1059 if (GlobalList.second.SummaryList.empty())
1062 auto GUID = GlobalList.first;
1063 assert(GlobalList.second.SummaryList.size() == 1 &&
1064 "Expected individual combined index to have one summary per GUID");
1065 auto &Summary = GlobalList.second.SummaryList[0];
1068 if (Summary->modulePath() == M->getModuleIdentifier())
1072 ImportList[Summary->modulePath()][GUID] = 1;
1075 std::vector<std::unique_ptr<llvm::MemoryBuffer>> OwnedImports;
1076 MapVector<llvm::StringRef, llvm::BitcodeModule>
ModuleMap;
1078 for (
auto &I : ImportList) {
1079 ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MBOrErr =
1080 llvm::MemoryBuffer::getFile(I.first());
1082 errs() <<
"Error loading imported file '" << I.first()
1083 <<
"': " << MBOrErr.getError().message() <<
"\n";
1089 handleAllErrors(BMOrErr.takeError(), [&](ErrorInfoBase &EIB) {
1090 errs() <<
"Error loading imported file '" << I.first()
1091 <<
"': " << EIB.message() <<
'\n';
1095 ModuleMap.insert({I.first(), *BMOrErr});
1097 OwnedImports.push_back(std::move(*MBOrErr));
1099 auto AddStream = [&](
size_t Task) {
1100 return llvm::make_unique<lto::NativeObjectStream>(std::move(OS));
1103 Conf.CPU = TOpts.
CPU;
1109 Conf.SampleProfile = std::move(SampleProfile);
1110 Conf.UseNewPM = CGOpts.ExperimentalNewPassManager;
1111 Conf.DebugPassManager = CGOpts.DebugPassManager;
1114 Conf.PreCodeGenModuleHook = [](
size_t Task,
const Module &Mod) {
1119 Conf.PreCodeGenModuleHook = [&](
size_t Task,
const Module &Mod) {
1120 M->
print(*OS,
nullptr, CGOpts.EmitLLVMUseLists);
1125 Conf.PreCodeGenModuleHook = [&](
size_t Task,
const Module &Mod) {
1126 WriteBitcodeToFile(M, *OS, CGOpts.EmitLLVMUseLists);
1134 if (
Error E = thinBackend(
1135 Conf, 0, AddStream, *M, *CombinedIndex, ImportList,
1136 ModuleToDefinedGVSummaries[M->getModuleIdentifier()], ModuleMap)) {
1137 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1138 errs() <<
"Error running ThinLTO backend: " << EIB.message() <<
'\n';
1148 const llvm::DataLayout &TDesc,
Module *M,
1150 std::unique_ptr<raw_pwrite_stream> OS) {
1159 logAllUnhandledErrors(IndexOrErr.takeError(), errs(),
1160 "Error loading index file '" +
1164 std::unique_ptr<ModuleSummaryIndex> CombinedIndex = std::move(*IndexOrErr);
1168 bool DoThinLTOBackend = CombinedIndex !=
nullptr;
1169 if (DoThinLTOBackend) {
1171 LOpts, std::move(OS), CGOpts.SampleProfileFile, Action);
1176 EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M);
1178 if (CGOpts.ExperimentalNewPassManager)
1179 AsmHelper.EmitAssemblyWithNewPassManager(Action, std::move(OS));
1181 AsmHelper.EmitAssembly(Action, std::move(OS));
1186 std::string DLDesc = M->getDataLayout().getStringRepresentation();
1187 if (DLDesc != TDesc.getStringRepresentation()) {
1190 "expected target description '%1'");
1191 Diags.
Report(DiagID) << DLDesc << TDesc.getStringRepresentation();
1197 switch (T.getObjectFormat()) {
1199 return "__LLVM,__bitcode";
1203 case Triple::UnknownObjectFormat:
1206 llvm_unreachable(
"Unimplemented ObjectFormatType");
1210 switch (T.getObjectFormat()) {
1212 return "__LLVM,__cmdline";
1216 case Triple::UnknownObjectFormat:
1219 llvm_unreachable(
"Unimplemented ObjectFormatType");
1225 llvm::MemoryBufferRef Buf) {
1231 SmallSet<GlobalValue*, 4> UsedGlobals;
1232 Type *UsedElementType = Type::getInt8Ty(M->getContext())->getPointerTo(0);
1233 GlobalVariable *
Used = collectUsedGlobalVariables(*M, UsedGlobals,
true);
1234 for (
auto *GV : UsedGlobals) {
1235 if (GV->getName() !=
"llvm.embedded.module" &&
1236 GV->getName() !=
"llvm.cmdline")
1237 UsedArray.push_back(
1238 ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
1241 Used->eraseFromParent();
1246 Triple
T(M->getTargetTriple());
1251 if (!isBitcode((
const unsigned char *)Buf.getBufferStart(),
1252 (
const unsigned char *)Buf.getBufferEnd())) {
1255 llvm::raw_string_ostream OS(Data);
1256 llvm::WriteBitcodeToFile(M, OS,
true);
1262 Buf.getBufferSize());
1264 llvm::Constant *ModuleConstant =
1265 llvm::ConstantDataArray::get(M->getContext(), ModuleData);
1266 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
1267 *M, ModuleConstant->getType(),
true, llvm::GlobalValue::PrivateLinkage,
1270 UsedArray.push_back(
1271 ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
1272 if (llvm::GlobalVariable *Old =
1273 M->getGlobalVariable(
"llvm.embedded.module",
true)) {
1274 assert(Old->hasOneUse() &&
1275 "llvm.embedded.module can only be used once in llvm.compiler.used");
1277 Old->eraseFromParent();
1279 GV->setName(
"llvm.embedded.module");
1287 llvm::Constant *CmdConstant =
1288 llvm::ConstantDataArray::get(M->getContext(), CmdData);
1289 GV =
new llvm::GlobalVariable(*M, CmdConstant->getType(),
true,
1290 llvm::GlobalValue::PrivateLinkage,
1293 UsedArray.push_back(
1294 ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
1295 if (llvm::GlobalVariable *Old =
1296 M->getGlobalVariable(
"llvm.cmdline",
true)) {
1297 assert(Old->hasOneUse() &&
1298 "llvm.cmdline can only be used once in llvm.compiler.used");
1300 Old->eraseFromParent();
1302 GV->setName(
"llvm.cmdline");
1306 if (UsedArray.empty())
1310 ArrayType *ATy = ArrayType::get(UsedElementType, UsedArray.size());
1311 auto *NewUsed =
new GlobalVariable(
1312 *M, ATy,
false, llvm::GlobalValue::AppendingLinkage,
1313 llvm::ConstantArray::get(ATy, UsedArray),
"llvm.compiler.used");
1314 NewUsed->setSection(
"llvm.metadata");
std::string ProfileInstrumentUsePath
Name of the profile file to use as input for -fprofile-instr-use.
static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M, const HeaderSearchOptions &HeaderOpts, const CodeGenOptions &CGOpts, const clang::TargetOptions &TOpts, const LangOptions &LOpts, std::unique_ptr< raw_pwrite_stream > OS, std::string SampleProfile, BackendAction Action)
Paths for '#include <>' added by '-I'.
static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
Emit human-readable LLVM assembly.
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Run CodeGen, but don't emit anything.
SanitizerSet Sanitize
Set of enabled sanitizers.
The base class of the type hierarchy.
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.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
static void addAddressSanitizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
std::vector< std::string > RewriteMapFiles
Set of files defining the rules for the symbol rewriting.
Don't emit anything (benchmarking mode)
Options for controlling the target.
std::string SplitDwarfFile
The name for the split debug info file that we'll break out.
std::string DebugPass
Enable additional debugging information.
SanitizerSet SanitizeRecover
Set of sanitizer checks that are non-fatal (i.e.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
std::vector< uint8_t > CmdArgs
List of backend command-line options for -fembed-bitcode.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::string CodeModel
The code model to use (-mcmodel).
Describes a module or submodule.
Concrete class used by the front-end to report problems and issues.
static void addThreadSanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
Defines the Diagnostic-related interfaces.
static CodeGenOpt::Level getCGOptLevel(const CodeGenOptions &CodeGenOpts)
static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts)
static void addSanitizerCoveragePass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
std::string FloatABI
The ABI to use for passing floating point arguments.
std::string ThreadModel
The thread model to use.
char CoverageVersion[4]
The version string to put into coverage files.
std::string LimitFloatPrecision
The float precision limit to use, if non-empty.
Defines the clang::LangOptions interface.
const FunctionProtoType * T
static void addHWAddressSanitizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM)
std::string RelocationModel
The name of the relocation model to use.
void print(raw_ostream &OS, unsigned Indent=0) const
Print the module map for this module to the given stream.
static TargetLibraryInfoImpl * createTLII(llvm::Triple &TargetTriple, const CodeGenOptions &CodeGenOpts)
Emit native object files.
Emit native assembly files.
std::string CPU
If given, the name of the target CPU to generate code for.
static llvm::Reloc::Model getRelocModel(const CodeGenOptions &CodeGenOpts)
std::string ABI
If given, the name of the target ABI to use.
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.
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings startin...
static void initTargetOptions(llvm::TargetOptions &Options, const CodeGenOptions &CodeGenOpts, const clang::TargetOptions &TargetOpts, const LangOptions &LangOpts, const HeaderSearchOptions &HSOpts)
static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts)
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
llvm::EABI EABIVersion
The EABI version to use.
'#include ""' paths, added by 'gcc -iquote'.
std::string ThinLTOIndexFile
Name of the function summary index file to use for ThinLTO function importing.
Like Angled, but marks system directories.
static TargetMachine::CodeGenFileType getCodeGenFileType(BackendAction Action)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
Dataflow Directional Tag Classes.
bool hasProfileIRUse() const
Check if IR level profile use is on.
void EmitBackendOutput(DiagnosticsEngine &Diags, const HeaderSearchOptions &, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, const llvm::DataLayout &TDesc, llvm::Module *M, BackendAction Action, std::unique_ptr< raw_pwrite_stream > OS)
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
llvm::Expected< llvm::BitcodeModule > FindThinLTOModule(llvm::MemoryBufferRef MBRef)
static const char * getSectionNameForBitcode(const Triple &T)
static const char * getSectionNameForCommandline(const Triple &T)
void BuryPointer(const void *Ptr)
static void addBoundsCheckingPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
static void addEfficiencySanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
static Optional< llvm::CodeModel::Model > getCodeModel(const CodeGenOptions &CodeGenOpts)
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM)
bool hasProfileIRInstr() const
Check if IR level profile instrumentation is on.
const std::vector< std::string > & getNoBuiltinFuncs() const
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
StringLiteral - This represents a string literal expression, e.g.
static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
std::string InstrProfileOutput
Name of the profile file to use as output for -fprofile-instr-generate and -fprofile-generate.
std::string ThinLinkBitcodeFile
Name of a file that can optionally be written with minimized bitcode to be used as input for the Thin...
std::vector< std::string > SanitizerBlacklistFiles
Paths to blacklist files specifying which objects (files, functions, variables) should not be instrum...
std::vector< std::string > BackendOptions
A list of command-line options to forward to the LLVM backend.
static void addMemorySanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts)