clang: lib/CodeGen/BackendUtil.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

19#include "llvm/ADT/ScopeExit.h"

20#include "llvm/ADT/StringExtras.h"

21#include "llvm/ADT/StringSwitch.h"

22#include "llvm/Analysis/GlobalsModRef.h"

23#include "llvm/Analysis/TargetLibraryInfo.h"

24#include "llvm/Analysis/TargetTransformInfo.h"

25#include "llvm/Bitcode/BitcodeReader.h"

26#include "llvm/Bitcode/BitcodeWriter.h"

27#include "llvm/Bitcode/BitcodeWriterPass.h"

28#include "llvm/CodeGen/TargetSubtargetInfo.h"

29#include "llvm/Frontend/Driver/CodeGenOptions.h"

30#include "llvm/IR/DataLayout.h"

31#include "llvm/IR/DebugInfo.h"

32#include "llvm/IR/LegacyPassManager.h"

33#include "llvm/IR/Module.h"

34#include "llvm/IR/ModuleSummaryIndex.h"

35#include "llvm/IR/PassManager.h"

36#include "llvm/IR/Verifier.h"

37#include "llvm/IRPrinter/IRPrintingPasses.h"

38#include "llvm/LTO/LTOBackend.h"

39#include "llvm/MC/TargetRegistry.h"

40#include "llvm/Object/OffloadBinary.h"

41#include "llvm/Passes/PassBuilder.h"

42#include "llvm/Passes/PassPlugin.h"

43#include "llvm/Passes/StandardInstrumentations.h"

44#include "llvm/ProfileData/InstrProfCorrelator.h"

45#include "llvm/Support/BuryPointer.h"

46#include "llvm/Support/CommandLine.h"

47#include "llvm/Support/MemoryBuffer.h"

48#include "llvm/Support/PrettyStackTrace.h"

49#include "llvm/Support/Program.h"

50#include "llvm/Support/TimeProfiler.h"

51#include "llvm/Support/Timer.h"

52#include "llvm/Support/ToolOutputFile.h"

53#include "llvm/Support/VirtualFileSystem.h"

54#include "llvm/Support/raw_ostream.h"

55#include "llvm/Target/TargetMachine.h"

56#include "llvm/Target/TargetOptions.h"

57#include "llvm/TargetParser/SubtargetFeature.h"

58#include "llvm/TargetParser/Triple.h"

59#include "llvm/Transforms/HipStdPar/HipStdPar.h"

60#include "llvm/Transforms/IPO/EmbedBitcodePass.h"

61#include "llvm/Transforms/IPO/LowerTypeTests.h"

62#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"

63#include "llvm/Transforms/InstCombine/InstCombine.h"

64#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"

65#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"

66#include "llvm/Transforms/Instrumentation/BoundsChecking.h"

67#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"

68#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"

69#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"

70#include "llvm/Transforms/Instrumentation/InstrProfiling.h"

71#include "llvm/Transforms/Instrumentation/KCFI.h"

72#include "llvm/Transforms/Instrumentation/LowerAllowCheckPass.h"

73#include "llvm/Transforms/Instrumentation/MemProfiler.h"

74#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"

75#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"

76#include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"

77#include "llvm/Transforms/Instrumentation/RealtimeSanitizer.h"

78#include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h"

79#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"

80#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"

81#include "llvm/Transforms/Instrumentation/TypeSanitizer.h"

82#include "llvm/Transforms/ObjCARC.h"

83#include "llvm/Transforms/Scalar/EarlyCSE.h"

84#include "llvm/Transforms/Scalar/GVN.h"

85#include "llvm/Transforms/Scalar/JumpThreading.h"

86#include "llvm/Transforms/Utils/Debugify.h"

87#include "llvm/Transforms/Utils/ModuleUtils.h"

88#include

89#include

90#include

91using namespace clang;

92using namespace llvm;

93

94#define HANDLE_EXTENSION(Ext) \

95 llvm::PassPluginLibraryInfo get##Ext##PluginInfo();

96#include "llvm/Support/Extension.def"

97

98namespace llvm {

100

101

103 "sanitizer-early-opt-ep", cl::Optional,

104 cl::desc("Insert sanitizers on OptimizerEarlyEP."));

105

106

107

109 "pgo-cold-func-opt", cl::init(PGOOptions::ColdFuncOpt::Default), cl::Hidden,

110 cl::desc(

111 "Function attribute to apply to cold functions as determined by PGO"),

112 cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default",

113 "Default (no attribute)"),

114 clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize",

115 "Mark cold functions with optsize."),

116 clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize",

117 "Mark cold functions with minsize."),

118 clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone",

119 "Mark cold functions with optnone.")));

120

121extern cl::optInstrProfCorrelator::ProfCorrelatorKind ProfileCorrelate;

122}

125}

126

127namespace {

128

129

130std::string getDefaultProfileGenName() {

131 return DebugInfoCorrelate || ProfileCorrelate != InstrProfCorrelator::NONE

132 ? "default_%m.proflite"

133 : "default_%m.profraw";

134}

135

136class EmitAssemblyHelper {

142 llvm::Module *TheModule;

144

145 std::unique_ptr<raw_pwrite_stream> OS;

146

147 Triple TargetTriple;

148

149 TargetIRAnalysis getTargetIRAnalysis() const {

150 if (TM)

151 return TM->getTargetIRAnalysis();

152

153 return TargetIRAnalysis();

154 }

155

156

157

158

159

160

161

162

163

164 void CreateTargetMachine(bool MustCreateTM);

165

166

167

168

169 bool AddEmitPasses(legacy::PassManager &CodeGenPasses, BackendAction Action,

170 raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS);

171

172 std::unique_ptrllvm::ToolOutputFile openOutputFile(StringRef Path) {

173 std::error_code EC;

174 auto F = std::make_uniquellvm::ToolOutputFile(Path, EC,

175 llvm::sys::fs::OF_None);

176 if (EC) {

177 Diags.Report(diag::err_fe_unable_to_open_output) << Path << EC.message();

178 F.reset();

179 }

180 return F;

181 }

182

183 void RunOptimizationPipeline(

184 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,

185 std::unique_ptrllvm::ToolOutputFile &ThinLinkOS, BackendConsumer *BC);

187 std::unique_ptr<raw_pwrite_stream> &OS,

188 std::unique_ptrllvm::ToolOutputFile &DwoOS);

189

190

191

192

193

194

195 bool shouldEmitRegularLTOSummary() const {

196 return CodeGenOpts.PrepareForLTO && !CodeGenOpts.DisableLLVMPasses &&

197 TargetTriple.getVendor() != llvm::Triple::Apple;

198 }

199

200

201

202

203 bool shouldEmitUnifiedLTOModueFlag() const {

204 return CodeGenOpts.UnifiedLTO &&

205 (CodeGenOpts.PrepareForThinLTO || shouldEmitRegularLTOSummary());

206 }

207

208public:

211 : CI(CI), Diags(CI.getDiagnostics()), CodeGenOpts(CI.getCodeGenOpts()),

212 TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),

213 TheModule(M), VFS(std::move(VFS)),

214 TargetTriple(TheModule->getTargetTriple()) {}

215

216 ~EmitAssemblyHelper() {

217 if (CodeGenOpts.DisableFree)

218 BuryPointer(std::move(TM));

219 }

220

221 std::unique_ptr TM;

222

223

224 void emitAssembly(BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS,

226};

227}

228

229static SanitizerCoverageOptions

231 SanitizerCoverageOptions Opts;

232 Opts.CoverageType =

233 static_castSanitizerCoverageOptions::Type\(CGOpts.SanitizeCoverageType);

234 Opts.IndirectCalls = CGOpts.SanitizeCoverageIndirectCalls;

235 Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB;

236 Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp;

237 Opts.TraceDiv = CGOpts.SanitizeCoverageTraceDiv;

238 Opts.TraceGep = CGOpts.SanitizeCoverageTraceGep;

239 Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;

240 Opts.TracePC = CGOpts.SanitizeCoverageTracePC;

241 Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;

242 Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;

243 Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;

244 Opts.InlineBoolFlag = CGOpts.SanitizeCoverageInlineBoolFlag;

245 Opts.PCTable = CGOpts.SanitizeCoveragePCTable;

246 Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;

247 Opts.TraceLoads = CGOpts.SanitizeCoverageTraceLoads;

248 Opts.TraceStores = CGOpts.SanitizeCoverageTraceStores;

249 Opts.CollectControlFlow = CGOpts.SanitizeCoverageControlFlow;

250 return Opts;

251}

252

253static SanitizerBinaryMetadataOptions

255 SanitizerBinaryMetadataOptions Opts;

256 Opts.Covered = CGOpts.SanitizeBinaryMetadataCovered;

257 Opts.Atomics = CGOpts.SanitizeBinaryMetadataAtomics;

258 Opts.UAR = CGOpts.SanitizeBinaryMetadataUAR;

259 return Opts;

260}

261

262

263

264

265

267 if (!CGOpts.SanitizeAddressGlobalsDeadStripping)

268 return false;

269 switch (T.getObjectFormat()) {

270 case Triple::MachO:

271 case Triple::COFF:

272 return true;

273 case Triple::ELF:

274 return !CGOpts.DisableIntegratedAS;

275 case Triple::GOFF:

276 llvm::report_fatal_error("ASan not implemented for GOFF");

277 case Triple::XCOFF:

278 llvm::report_fatal_error("ASan not implemented for XCOFF.");

279 case Triple::Wasm:

280 case Triple::DXContainer:

281 case Triple::SPIRV:

282 case Triple::UnknownObjectFormat:

283 break;

284 }

285 return false;

286}

287

288static std::optionalllvm::CodeModel::Model

290 unsigned CodeModel = llvm::StringSwitch(CodeGenOpts.CodeModel)

291 .Case("tiny", llvm::CodeModel::Tiny)

292 .Case("small", llvm::CodeModel::Small)

293 .Case("kernel", llvm::CodeModel::Kernel)

294 .Case("medium", llvm::CodeModel::Medium)

295 .Case("large", llvm::CodeModel::Large)

296 .Case("default", ~1u)

297 .Default(~0u);

298 assert(CodeModel != ~0u && "invalid code model!");

299 if (CodeModel == ~1u)

300 return std::nullopt;

301 return static_castllvm::CodeModel::Model\(CodeModel);

302}

303

306 return CodeGenFileType::ObjectFile;

308 return CodeGenFileType::Null;

309 else {

311 return CodeGenFileType::AssemblyFile;

312 }

313}

314

318}

319

321 StringRef MainFilename) {

322 if (Args.empty())

323 return std::string{};

324

325 std::string FlatCmdLine;

326 raw_string_ostream OS(FlatCmdLine);

327 bool PrintedOneArg = false;

328 if (!StringRef(Args[0]).contains("-cc1")) {

329 llvm::sys::printArg(OS, "-cc1", true);

330 PrintedOneArg = true;

331 }

332 for (unsigned i = 0; i < Args.size(); i++) {

333 StringRef Arg = Args[i];

334 if (Arg.empty())

335 continue;

336 if (Arg == "-main-file-name" || Arg == "-o") {

337 i++;

338 continue;

339 }

340 if (Arg.starts_with("-object-file-name") || Arg == MainFilename)

341 continue;

342

343 if (Arg.starts_with("-fmessage-length"))

344 continue;

345 if (PrintedOneArg)

346 OS << " ";

347 llvm::sys::printArg(OS, Arg, true);

348 PrintedOneArg = true;

349 }

350 return FlatCmdLine;

351}

352

355 llvm::TargetOptions &Options) {

360 switch (LangOpts.getThreadModel()) {

361 case LangOptions::ThreadModelKind::POSIX:

362 Options.ThreadModel = llvm::ThreadModel::POSIX;

363 break;

364 case LangOptions::ThreadModelKind::Single:

365 Options.ThreadModel = llvm::ThreadModel::Single;

366 break;

367 }

368

369

370 assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" ||

371 CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) &&

372 "Invalid Floating Point ABI!");

373 Options.FloatABIType =

374 llvm::StringSwitchllvm::FloatABI::ABIType(CodeGenOpts.FloatABI)

375 .Case("soft", llvm::FloatABI::Soft)

376 .Case("softfp", llvm::FloatABI::Soft)

377 .Case("hard", llvm::FloatABI::Hard)

378 .Default(llvm::FloatABI::Default);

379

380

381 switch (LangOpts.getDefaultFPContractMode()) {

382 case LangOptions::FPM_Off:

383

384

385 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;

386 break;

387 case LangOptions::FPM_On:

388 case LangOptions::FPM_FastHonorPragmas:

389 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;

390 break;

391 case LangOptions::FPM_Fast:

392 Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;

393 break;

394 }

395

396 Options.BinutilsVersion =

397 llvm::TargetMachine::parseBinutilsVersion(CodeGenOpts.BinutilsVersion);

398 Options.UseInitArray = CodeGenOpts.UseInitArray;

399 Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS;

400

401

402 Options.EABIVersion = TargetOpts.EABIVersion;

403

405 Options.ExceptionModel = llvm::ExceptionHandling::SjLj;

407 Options.ExceptionModel = llvm::ExceptionHandling::WinEH;

409 Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;

411 Options.ExceptionModel = llvm::ExceptionHandling::Wasm;

412

413 Options.NoInfsFPMath = LangOpts.NoHonorInfs;

414 Options.NoNaNsFPMath = LangOpts.NoHonorNaNs;

415 Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;

416 Options.UnsafeFPMath = LangOpts.AllowFPReassoc && LangOpts.AllowRecip &&

417 LangOpts.NoSignedZero && LangOpts.ApproxFunc &&

418 (LangOpts.getDefaultFPContractMode() ==

419 LangOptions::FPModeKind::FPM_Fast ||

420 LangOpts.getDefaultFPContractMode() ==

421 LangOptions::FPModeKind::FPM_FastHonorPragmas);

422 Options.ApproxFuncFPMath = LangOpts.ApproxFunc;

423

424 Options.BBAddrMap = CodeGenOpts.BBAddrMap;

425 Options.BBSections =

426 llvm::StringSwitchllvm::BasicBlockSection(CodeGenOpts.BBSections)

427 .Case("all", llvm::BasicBlockSection::All)

428 .StartsWith("list=", llvm::BasicBlockSection::List)

429 .Case("none", llvm::BasicBlockSection::None)

430 .Default(llvm::BasicBlockSection::None);

431

432 if (Options.BBSections == llvm::BasicBlockSection::List) {

433 ErrorOr<std::unique_ptr> MBOrErr =

434 MemoryBuffer::getFile(CodeGenOpts.BBSections.substr(5));

435 if (!MBOrErr) {

436 Diags.Report(diag::err_fe_unable_to_load_basic_block_sections_file)

437 << MBOrErr.getError().message();

438 return false;

439 }

440 Options.BBSectionsFuncListBuf = std::move(*MBOrErr);

441 }

442

443 Options.EnableMachineFunctionSplitter = CodeGenOpts.SplitMachineFunctions;

444 Options.FunctionSections = CodeGenOpts.FunctionSections;

445 Options.DataSections = CodeGenOpts.DataSections;

446 Options.IgnoreXCOFFVisibility = LangOpts.IgnoreXCOFFVisibility;

447 Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;

448 Options.UniqueBasicBlockSectionNames =

449 CodeGenOpts.UniqueBasicBlockSectionNames;

450 Options.SeparateNamedSections = CodeGenOpts.SeparateNamedSections;

451 Options.TLSSize = CodeGenOpts.TLSSize;

452 Options.EnableTLSDESC = CodeGenOpts.EnableTLSDESC;

453 Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;

454 Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();

455 Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;

457 Options.EmitAddrsig = CodeGenOpts.Addrsig;

458 Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;

459 Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo;

460 Options.EnableAIXExtendedAltivecABI = LangOpts.EnableAIXExtendedAltivecABI;

461 Options.XRayFunctionIndex = CodeGenOpts.XRayFunctionIndex;

462 Options.LoopAlignment = CodeGenOpts.LoopAlignment;

463 Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf;

465 Options.Hotpatch = CodeGenOpts.HotPatch;

466 Options.JMCInstrument = CodeGenOpts.JMCInstrument;

467 Options.XCOFFReadOnlyPointers = CodeGenOpts.XCOFFReadOnlyPointers;

468

469 switch (CodeGenOpts.getSwiftAsyncFramePointer()) {

470 case CodeGenOptions::SwiftAsyncFramePointerKind::Auto:

471 Options.SwiftAsyncFramePointer =

472 SwiftAsyncFramePointerMode::DeploymentBased;

473 break;

474

475 case CodeGenOptions::SwiftAsyncFramePointerKind::Always:

476 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Always;

477 break;

478

479 case CodeGenOptions::SwiftAsyncFramePointerKind::Never:

480 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Never;

481 break;

482 }

483

484 Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;

485 Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind();

486 Options.MCOptions.EmitCompactUnwindNonCanonical =

487 CodeGenOpts.EmitCompactUnwindNonCanonical;

488 Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;

489 Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;

490 Options.MCOptions.MCUseDwarfDirectory =

491 CodeGenOpts.NoDwarfDirectoryAsm

492 ? llvm::MCTargetOptions::DisableDwarfDirectory

493 : llvm::MCTargetOptions::EnableDwarfDirectory;

494 Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;

495 Options.MCOptions.MCIncrementalLinkerCompatible =

496 CodeGenOpts.IncrementalLinkerCompatible;

497 Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;

498 Options.MCOptions.MCNoWarn = CodeGenOpts.NoWarn;

499 Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;

500 Options.MCOptions.Dwarf64 = CodeGenOpts.Dwarf64;

501 Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;

502 Options.MCOptions.Crel = CodeGenOpts.Crel;

503 Options.MCOptions.ImplicitMapSyms = CodeGenOpts.ImplicitMapSyms;

504 Options.MCOptions.X86RelaxRelocations = CodeGenOpts.X86RelaxRelocations;

505 Options.MCOptions.CompressDebugSections =

506 CodeGenOpts.getCompressDebugSections();

507 if (CodeGenOpts.OutputAsmVariant != 3)

508 Options.MCOptions.OutputAsmVariant = CodeGenOpts.OutputAsmVariant;

509 Options.MCOptions.ABIName = TargetOpts.ABI;

510 for (const auto &Entry : HSOpts.UserEntries)

511 if (!Entry.IsFramework &&

512 (Entry.Group == frontend::IncludeDirGroup::Quoted ||

513 Entry.Group == frontend::IncludeDirGroup::Angled ||

514 Entry.Group == frontend::IncludeDirGroup::System))

515 Options.MCOptions.IASSearchPaths.push_back(

516 Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path);

517 Options.MCOptions.Argv0 = CodeGenOpts.Argv0 ? CodeGenOpts.Argv0 : "";

520 Options.MCOptions.AsSecureLogFile = CodeGenOpts.AsSecureLogFile;

521 Options.MCOptions.PPCUseFullRegisterNames =

522 CodeGenOpts.PPCUseFullRegisterNames;

523 Options.MisExpect = CodeGenOpts.MisExpect;

524

525 return true;

526}

527

528static std::optional

532 return std::nullopt;

533

534

535 GCOVOptions Options;

538 llvm::copy(CodeGenOpts.CoverageVersion, std::begin(Options.Version));

539 Options.NoRedZone = CodeGenOpts.DisableRedZone;

542 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;

543 return Options;

544}

545

546static std::optional

550 return std::nullopt;

551 InstrProfOptions Options;

552 Options.NoRedZone = CodeGenOpts.DisableRedZone;

554 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;

555 return Options;

556}

557

560 BackendArgs.push_back("clang");

561 if (!CodeGenOpts.DebugPass.empty()) {

562 BackendArgs.push_back("-debug-pass");

563 BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());

564 }

566 BackendArgs.push_back("-limit-float-precision");

568 }

569

570

571

572 if (BackendArgs.size() == 1)

573 return;

574 BackendArgs.push_back(nullptr);

575

576

577

578 llvm:🆑:ParseCommandLineOptions(BackendArgs.size() - 1,

579 BackendArgs.data());

580}

581

582void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {

583

584 std::string Error;

585 std::string Triple = TheModule->getTargetTriple();

586 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);

587 if (!TheTarget) {

588 if (MustCreateTM)

589 Diags.Report(diag::err_fe_unable_to_create_target) << Error;

590 return;

591 }

592

593 std::optionalllvm::CodeModel::Model CM = getCodeModel(CodeGenOpts);

594 std::string FeaturesStr =

595 llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ",");

597 std::optional OptLevelOrNone =

598 CodeGenOpt::getLevel(CodeGenOpts.OptimizationLevel);

599 assert(OptLevelOrNone && "Invalid optimization level!");

600 CodeGenOptLevel OptLevel = *OptLevelOrNone;

601

602 llvm::TargetOptions Options;

604 return;

605 TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,

606 Options, RM, CM, OptLevel));

608}

609

610bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,

612 raw_pwrite_stream &OS,

613 raw_pwrite_stream *DwoOS) {

614

615 std::unique_ptr TLII(

616 llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));

617 CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));

618

619

620

622

623 if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT,

624 !CodeGenOpts.VerifyModule)) {

625 Diags.Report(diag::err_fe_unable_to_interface_with_target);

626 return false;

627 }

628

629 return true;

630}

631

633 switch (Opts.OptimizationLevel) {

634 default:

635 llvm_unreachable("Invalid optimization level!");

636

637 case 0:

638 return OptimizationLevel::O0;

639

640 case 1:

641 return OptimizationLevel::O1;

642

643 case 2:

644 switch (Opts.OptimizeSize) {

645 default:

646 llvm_unreachable("Invalid optimization level for size!");

647

648 case 0:

649 return OptimizationLevel::O2;

650

651 case 1:

652 return OptimizationLevel::Os;

653

654 case 2:

655 return OptimizationLevel::Oz;

656 }

657

658 case 3:

659 return OptimizationLevel::O3;

660 }

661}

662

664 PassBuilder &PB) {

665

666 if (TargetTriple.getArch() == llvm::Triple::x86_64 ||

667 TargetTriple.isAArch64(64) || TargetTriple.isRISCV())

668 return;

669

670

671 PB.registerOptimizerLastEPCallback(

672 [&](ModulePassManager &MPM, OptimizationLevel Level, ThinOrFullLTOPhase) {

673 if (Level == OptimizationLevel::O0 &&

674 LangOpts.Sanitize.has(SanitizerKind::KCFI))

675 MPM.addPass(createModuleToFunctionPassAdaptor(KCFIPass()));

676 });

677

678

679

680 PB.registerPeepholeEPCallback(

681 [&](FunctionPassManager &FPM, OptimizationLevel Level) {

682 if (Level != OptimizationLevel::O0 &&

683 LangOpts.Sanitize.has(SanitizerKind::KCFI))

684 FPM.addPass(KCFIPass());

685 });

686}

687

690 const LangOptions &LangOpts, PassBuilder &PB) {

691 auto SanitizersCallback = [&](ModulePassManager &MPM, OptimizationLevel Level,

692 ThinOrFullLTOPhase) {

695 MPM.addPass(SanitizerCoveragePass(

698 }

699

701 MPM.addPass(SanitizerBinaryMetadataPass(

704 }

705

706 auto MSanPass = [&](SanitizerMask Mask, bool CompileKernel) {

708 int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins;

710

711 MemorySanitizerOptions options(TrackOrigins, Recover, CompileKernel,

712 CodeGenOpts.SanitizeMemoryParamRetval);

713 MPM.addPass(MemorySanitizerPass(options));

714 if (Level != OptimizationLevel::O0) {

715

716

717

718

719 MPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());

720 FunctionPassManager FPM;

721 FPM.addPass(EarlyCSEPass(true ));

722 FPM.addPass(InstCombinePass());

723 FPM.addPass(JumpThreadingPass());

724 FPM.addPass(GVNPass());

725 FPM.addPass(InstCombinePass());

726 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));

727 }

728 }

729 };

730 MSanPass(SanitizerKind::Memory, false);

731 MSanPass(SanitizerKind::KernelMemory, true);

732

733 if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {

734 MPM.addPass(ModuleThreadSanitizerPass());

735 MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));

736 }

737

738 if (LangOpts.Sanitize.has(SanitizerKind::Type))

739 MPM.addPass(TypeSanitizerPass());

740

741 if (LangOpts.Sanitize.has(SanitizerKind::NumericalStability))

742 MPM.addPass(NumericalStabilitySanitizerPass());

743

744 if (LangOpts.Sanitize.has(SanitizerKind::Realtime))

745 MPM.addPass(RealtimeSanitizerPass());

746

747 auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) {

749 bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts);

750 bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;

751 llvm::AsanDtorKind DestructorKind =

752 CodeGenOpts.getSanitizeAddressDtor();

753 AddressSanitizerOptions Opts;

754 Opts.CompileKernel = CompileKernel;

756 Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;

757 Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();

758 MPM.addPass(AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,

759 DestructorKind));

760 }

761 };

762 ASanPass(SanitizerKind::Address, false);

763 ASanPass(SanitizerKind::KernelAddress, true);

764

765 auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {

768 MPM.addPass(HWAddressSanitizerPass(

769 {CompileKernel, Recover,

770 CodeGenOpts.OptimizationLevel == 0}));

771 }

772 };

773 HWASanPass(SanitizerKind::HWAddress, false);

774 HWASanPass(SanitizerKind::KernelHWAddress, true);

775

776 if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {

777 MPM.addPass(DataFlowSanitizerPass(LangOpts.NoSanitizeFiles));

778 }

779 };

781 PB.registerOptimizerEarlyEPCallback(

782 [SanitizersCallback](ModulePassManager &MPM, OptimizationLevel Level,

783 ThinOrFullLTOPhase Phase) {

784 ModulePassManager NewMPM;

785 SanitizersCallback(NewMPM, Level, Phase);

786 if (!NewMPM.isEmpty()) {

787

788 NewMPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());

789 MPM.addPass(std::move(NewMPM));

790 }

791 });

792 } else {

793

794 PB.registerOptimizerLastEPCallback(SanitizersCallback);

795 }

796

797 if (LowerAllowCheckPass::IsRequested()) {

798

799 PB.registerOptimizerEarlyEPCallback([](ModulePassManager &MPM,

800 OptimizationLevel Level,

801 ThinOrFullLTOPhase Phase) {

802 MPM.addPass(createModuleToFunctionPassAdaptor(LowerAllowCheckPass()));

803 });

804 }

805}

806

807void EmitAssemblyHelper::RunOptimizationPipeline(

808 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,

809 std::unique_ptrllvm::ToolOutputFile &ThinLinkOS, BackendConsumer *BC) {

810 std::optional PGOOpt;

811

813

814 PGOOpt = PGOOptions(

819 CodeGenOpts.DebugInfoForProfiling,

820 false, CodeGenOpts.AtomicProfileUpdate);

822

823 auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse

824 : PGOOptions::NoCSAction;

829 CodeGenOpts.DebugInfoForProfiling);

831

832 PGOOpt = PGOOptions(

836 CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling);

838

840 PGOOptions::NoAction, PGOOptions::NoCSAction,

842 else if (CodeGenOpts.PseudoProbeForProfiling)

843

844 PGOOpt =

845 PGOOptions("", "", "", "", nullptr,

846 PGOOptions::NoAction, PGOOptions::NoCSAction,

848 else if (CodeGenOpts.DebugInfoForProfiling)

849

850 PGOOpt = PGOOptions("", "", "", "", nullptr,

851 PGOOptions::NoAction, PGOOptions::NoCSAction,

853

854

857 "Cannot have both CSProfileUse pass and CSProfileGen pass at "

858 "the same time");

859 if (PGOOpt) {

860 assert(PGOOpt->Action != PGOOptions::IRInstr &&

861 PGOOpt->Action != PGOOptions::SampleUse &&

862 "Cannot run CSProfileGen pass with ProfileGen or SampleUse "

863 " pass");

865 ? getDefaultProfileGenName()

866 : CodeGenOpts.InstrProfileOutput;

867 PGOOpt->CSAction = PGOOptions::CSIRInstr;

868 } else

869 PGOOpt = PGOOptions("",

871 ? getDefaultProfileGenName()

873 "", "", nullptr,

874 PGOOptions::NoAction, PGOOptions::CSIRInstr,

876 }

877 if (TM)

878 TM->setPGOOption(PGOOpt);

879

880 PipelineTuningOptions PTO;

881 PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;

882

883

884 PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;

885 PTO.LoopVectorization = CodeGenOpts.VectorizeLoop;

886 PTO.SLPVectorization = CodeGenOpts.VectorizeSLP;

887 PTO.MergeFunctions = CodeGenOpts.MergeFunctions;

888

889

890 PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;

891 PTO.UnifiedLTO = CodeGenOpts.UnifiedLTO;

892

893 LoopAnalysisManager LAM;

894 FunctionAnalysisManager FAM;

895 CGSCCAnalysisManager CGAM;

896 ModuleAnalysisManager MAM;

897

898 bool DebugPassStructure = CodeGenOpts.DebugPass == "Structure";

899 PassInstrumentationCallbacks PIC;

900 PrintPassOptions PrintPassOpts;

901 PrintPassOpts.Indent = DebugPassStructure;

902 PrintPassOpts.SkipAnalyses = DebugPassStructure;

903 StandardInstrumentations SI(

904 TheModule->getContext(),

905 (CodeGenOpts.DebugPassManager || DebugPassStructure),

906 CodeGenOpts.VerifyEach, PrintPassOpts);

907 SI.registerCallbacks(PIC, &MAM);

908 PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC);

909

910

911 switch (CodeGenOpts.getAssignmentTrackingMode()) {

912 case CodeGenOptions::AssignmentTrackingOpts::Forced:

913 PB.registerPipelineStartEPCallback(

914 [&](ModulePassManager &MPM, OptimizationLevel Level) {

915 MPM.addPass(AssignmentTrackingPass());

916 });

917 break;

918 case CodeGenOptions::AssignmentTrackingOpts::Enabled:

919

920

921 if (!CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.PrepareForLTO &&

922 CodeGenOpts.getDebuggerTuning() != llvm::DebuggerKind::LLDB) {

923 PB.registerPipelineStartEPCallback(

924 [&](ModulePassManager &MPM, OptimizationLevel Level) {

925

926 if (Level != OptimizationLevel::O0)

927 MPM.addPass(AssignmentTrackingPass());

928 });

929 }

930 break;

931 case CodeGenOptions::AssignmentTrackingOpts::Disabled:

932 break;

933 }

934

935

936 DebugifyEachInstrumentation Debugify;

937 DebugInfoPerPass DebugInfoBeforePass;

938 if (CodeGenOpts.EnableDIPreservationVerify) {

939 Debugify.setDebugifyMode(DebugifyMode::OriginalDebugInfo);

940 Debugify.setDebugInfoBeforePass(DebugInfoBeforePass);

941

943 Debugify.setOrigDIVerifyBugsReportFilePath(

945 Debugify.registerCallbacks(PIC, MAM);

946 }

947

948 for (auto &PluginFN : CodeGenOpts.PassPlugins) {

949 auto PassPlugin = PassPlugin::Load(PluginFN);

950 if (PassPlugin) {

951 PassPlugin->registerPassBuilderCallbacks(PB);

952 } else {

953 Diags.Report(diag::err_fe_unable_to_load_plugin)

954 << PluginFN << toString(PassPlugin.takeError());

955 }

956 }

958 PassCallback(PB);

959#define HANDLE_EXTENSION(Ext) \

960 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);

961#include "llvm/Support/Extension.def"

962

963

964

965 std::unique_ptr TLII(

966 llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));

967 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });

968

969

970 PB.registerModuleAnalyses(MAM);

971 PB.registerCGSCCAnalyses(CGAM);

972 PB.registerFunctionAnalyses(FAM);

973 PB.registerLoopAnalyses(LAM);

974 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);

975

976 ModulePassManager MPM;

977

978 if (CodeGenOpts.VerifyModule)

979 MPM.addPass(VerifierPass());

980

981 if (!CodeGenOpts.DisableLLVMPasses) {

982

983

985

986 const bool PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO;

987 const bool PrepareForLTO = CodeGenOpts.PrepareForLTO;

988

989 if (LangOpts.ObjCAutoRefCount) {

990 PB.registerPipelineStartEPCallback(

991 [](ModulePassManager &MPM, OptimizationLevel Level) {

992 if (Level != OptimizationLevel::O0)

993 MPM.addPass(

994 createModuleToFunctionPassAdaptor(ObjCARCExpandPass()));

995 });

996 PB.registerPipelineEarlySimplificationEPCallback(

997 [](ModulePassManager &MPM, OptimizationLevel Level,

998 ThinOrFullLTOPhase) {

999 if (Level != OptimizationLevel::O0)

1000 MPM.addPass(ObjCARCAPElimPass());

1001 });

1002 PB.registerScalarOptimizerLateEPCallback(

1003 [](FunctionPassManager &FPM, OptimizationLevel Level) {

1004 if (Level != OptimizationLevel::O0)

1005 FPM.addPass(ObjCARCOptPass());

1006 });

1007 }

1008

1009

1010

1011

1012 bool IsThinLTOPostLink = !CodeGenOpts.ThinLTOIndexFile.empty();

1013

1014

1015 if (IsThinLTOPostLink)

1016 PB.registerPipelineStartEPCallback(

1017 [](ModulePassManager &MPM, OptimizationLevel Level) {

1018 MPM.addPass(LowerTypeTestsPass(

1019 nullptr,

1020 nullptr,

1021 lowertypetests::DropTestKind::Assume));

1022 });

1023

1024

1025

1026 if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))

1027 PB.registerScalarOptimizerLateEPCallback([this](FunctionPassManager &FPM,

1028 OptimizationLevel Level) {

1029 BoundsCheckingPass::Options Options;

1032 static_assert(SanitizerKind::SO_LocalBounds <=

1033 std::numeric_limits<

1034 decltype(Options.GuardKind)::value_type>::max(),

1035 "Update type of llvm.allow.ubsan.check to represent "

1036 "SanitizerKind::SO_LocalBounds.");

1037 Options.GuardKind = SanitizerKind::SO_LocalBounds;

1038 }

1039 Options.Merge =

1041 if (!CodeGenOpts.SanitizeTrap.has(SanitizerKind::LocalBounds)) {

1042 Options.Rt = {

1043 static_cast(

1044 CodeGenOpts.SanitizeMinimalRuntime),

1045

1046 CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds),

1047 };

1048 }

1049 FPM.addPass(BoundsCheckingPass(Options));

1050 });

1051

1052

1053

1054 if (!IsThinLTOPostLink) {

1055 addSanitizers(TargetTriple, CodeGenOpts, LangOpts, PB);

1056 addKCFIPass(TargetTriple, LangOpts, PB);

1057 }

1058

1059 if (std::optional Options =

1061 PB.registerPipelineStartEPCallback(

1062 [Options](ModulePassManager &MPM, OptimizationLevel Level) {

1063 MPM.addPass(GCOVProfilerPass(*Options));

1064 });

1065 if (std::optional Options =

1067 PB.registerPipelineStartEPCallback(

1068 [Options](ModulePassManager &MPM, OptimizationLevel Level) {

1069 MPM.addPass(InstrProfilingLoweringPass(*Options, false));

1070 });

1071

1072

1073

1075 PB.registerOptimizerLastEPCallback([](ModulePassManager &MPM,

1076 OptimizationLevel Level,

1077 ThinOrFullLTOPhase) {

1078 MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));

1079 MPM.addPass(ModuleMemProfilerPass());

1080 });

1081 }

1082

1083 if (CodeGenOpts.FatLTO) {

1084 MPM.addPass(PB.buildFatLTODefaultPipeline(

1085 Level, PrepareForThinLTO,

1086 PrepareForThinLTO || shouldEmitRegularLTOSummary()));

1087 } else if (PrepareForThinLTO) {

1088 MPM.addPass(PB.buildThinLTOPreLinkDefaultPipeline(Level));

1089 } else if (PrepareForLTO) {

1090 MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(Level));

1091 } else {

1092 MPM.addPass(PB.buildPerModuleDefaultPipeline(Level));

1093 }

1094 }

1095

1096

1097 if (CodeGenOpts.LinkBitcodePostopt)

1099

1100

1101

1102

1103

1104

1106 MPM.addPass(VerifierPass());

1107

1109 CodeGenOpts.FatLTO) {

1110 if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {

1111 if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))

1112 TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",

1113 CodeGenOpts.EnableSplitLTOUnit);

1117 if (!ThinLinkOS)

1118 return;

1119 }

1120 MPM.addPass(ThinLTOBitcodeWriterPass(

1121 *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));

1123 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,

1124 true));

1125 }

1126 } else {

1127

1128

1129 bool EmitLTOSummary = shouldEmitRegularLTOSummary();

1130 if (EmitLTOSummary) {

1131 if (!TheModule->getModuleFlag("ThinLTO") && !CodeGenOpts.UnifiedLTO)

1132 TheModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0));

1133 if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))

1134 TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",

1136 }

1138 MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,

1139 EmitLTOSummary));

1141 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,

1142 EmitLTOSummary));

1143 }

1144 }

1145

1146 if (shouldEmitUnifiedLTOModueFlag())

1147 TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1));

1148 }

1149

1150

1151

1152

1153

1155 MPM.printPipeline(outs(), [&PIC](StringRef ClassName) {

1156 auto PassName = PIC.getPassNameForClassName(ClassName);

1157 return PassName.empty() ? ClassName : PassName;

1158 });

1159 outs() << "\n";

1160 return;

1161 }

1162

1163 if (LangOpts.HIPStdPar && !LangOpts.CUDAIsDevice &&

1164 LangOpts.HIPStdParInterposeAlloc)

1165 MPM.addPass(HipStdParAllocationInterpositionPass());

1166

1167

1168 {

1169 PrettyStackTraceString CrashInfo("Optimizer");

1170 llvm::TimeTraceScope TimeScope("Optimizer");

1171 Timer timer;

1173 timer.init("optimizer", "Optimizer", CI.getTimerGroup());

1175 }

1176 MPM.run(*TheModule, MAM);

1179 }

1180}

1181

1182void EmitAssemblyHelper::RunCodegenPipeline(

1183 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,

1184 std::unique_ptrllvm::ToolOutputFile &DwoOS) {

1185

1186

1187

1188 legacy::PassManager CodeGenPasses;

1189

1190

1191 switch (Action) {

1195 CodeGenPasses.add(

1196 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));

1199 if (!DwoOS)

1200 return;

1201 }

1202 if (!AddEmitPasses(CodeGenPasses, Action, *OS,

1203 DwoOS ? &DwoOS->os() : nullptr))

1204

1205 return;

1206 break;

1207 default:

1208 return;

1209 }

1210

1211

1212

1213

1215 return;

1216 }

1217

1218 {

1219 PrettyStackTraceString CrashInfo("Code generation");

1220 llvm::TimeTraceScope TimeScope("CodeGenPasses");

1221 Timer timer;

1223 timer.init("codegen", "Machine code generation", CI.getTimerGroup());

1225 }

1226 CodeGenPasses.run(*TheModule);

1229 }

1230}

1231

1232void EmitAssemblyHelper::emitAssembly(BackendAction Action,

1233 std::unique_ptr<raw_pwrite_stream> OS,

1236

1238 CreateTargetMachine(RequiresCodeGen);

1239

1240 if (RequiresCodeGen && !TM)

1241 return;

1242 if (TM)

1243 TheModule->setDataLayout(TM->createDataLayout());

1244

1245

1246 cl::PrintOptionValues();

1247

1248 std::unique_ptrllvm::ToolOutputFile ThinLinkOS, DwoOS;

1249 RunOptimizationPipeline(Action, OS, ThinLinkOS, BC);

1250 RunCodegenPipeline(Action, OS, DwoOS);

1251

1252 if (ThinLinkOS)

1253 ThinLinkOS->keep();

1254 if (DwoOS)

1255 DwoOS->keep();

1256}

1257

1258static void

1260 llvm::Module *M, std::unique_ptr<raw_pwrite_stream> OS,

1261 std::string SampleProfile, std::string ProfileRemapping,

1266 DenseMap<StringRef, DenseMap<GlobalValue::GUID, GlobalValueSummary *>>

1267 ModuleToDefinedGVSummaries;

1268 CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

1269

1271

1272

1273

1274

1275 FunctionImporter::ImportIDTable ImportIDs;

1276 FunctionImporter::ImportMapTy ImportList(ImportIDs);

1277 if (!lto::initImportList(*M, *CombinedIndex, ImportList))

1278 return;

1279

1280 auto AddStream = [&](size_t Task, const Twine &ModuleName) {

1281 return std::make_unique(std::move(OS),

1282 CGOpts.ObjectFilenameForDebug);

1283 };

1284 lto::Config Conf;

1285 if (CGOpts.SaveTempsFilePrefix != "") {

1286 if (Error E = Conf.addSaveTemps(CGOpts.SaveTempsFilePrefix + ".",

1287 false)) {

1288 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {

1289 errs() << "Error setting up ThinLTO save-temps: " << EIB.message()

1290 << '\n';

1291 });

1292 }

1293 }

1294 Conf.CPU = TOpts.CPU;

1296 Conf.MAttrs = TOpts.Features;

1297 Conf.RelocModel = CGOpts.RelocationModel;

1298 std::optional OptLevelOrNone =

1299 CodeGenOpt::getLevel(CGOpts.OptimizationLevel);

1300 assert(OptLevelOrNone && "Invalid optimization level!");

1301 Conf.CGOptLevel = *OptLevelOrNone;

1302 Conf.OptLevel = CGOpts.OptimizationLevel;

1304 Conf.SampleProfile = std::move(SampleProfile);

1305 Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;

1306

1307

1308 Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;

1309 Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop;

1310 Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP;

1311

1312

1313 Conf.PTO.CallGraphProfile = !CGOpts.DisableIntegratedAS;

1314

1315

1316 if (CGOpts.hasProfileCSIRInstr()) {

1317 Conf.RunCSIRInstr = true;

1318 Conf.CSIRProfile = std::move(CGOpts.InstrProfileOutput);

1319 } else if (CGOpts.hasProfileCSIRUse()) {

1320 Conf.RunCSIRInstr = false;

1321 Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath);

1322 }

1323

1324 Conf.ProfileRemapping = std::move(ProfileRemapping);

1325 Conf.DebugPassManager = CGOpts.DebugPassManager;

1326 Conf.VerifyEach = CGOpts.VerifyEach;

1327 Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;

1328 Conf.RemarksFilename = CGOpts.OptRecordFile;

1329 Conf.RemarksPasses = CGOpts.OptRecordPasses;

1330 Conf.RemarksFormat = CGOpts.OptRecordFormat;

1331 Conf.SplitDwarfFile = CGOpts.SplitDwarfFile;

1332 Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput;

1333 switch (Action) {

1335 Conf.PreCodeGenModuleHook = [](size_t Task, const llvm::Module &Mod) {

1336 return false;

1337 };

1338 break;

1340 Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {

1341 M->print(*OS, nullptr, CGOpts.EmitLLVMUseLists);

1342 return false;

1343 };

1344 break;

1346 Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {

1347 WriteBitcodeToFile(*M, *OS, CGOpts.EmitLLVMUseLists);

1348 return false;

1349 };

1350 break;

1351 default:

1353 break;

1354 }

1355 if (Error E =

1356 thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,

1357 ModuleToDefinedGVSummaries[M->getModuleIdentifier()],

1358 nullptr, Conf.CodeGenOnly,

1359 nullptr, CGOpts.CmdArgs)) {

1360 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {

1361 errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';

1362 });

1363 }

1364}

1365

1369 std::unique_ptr<raw_pwrite_stream> OS,

1371 llvm::TimeTraceScope TimeScope("Backend");

1374

1375 std::unique_ptrllvm::Module EmptyModule;

1376 if (!CGOpts.ThinLTOIndexFile.empty()) {

1377

1378

1379

1380 std::unique_ptr CombinedIndex;

1381 if (Error E = llvm::getModuleSummaryIndexForFile(

1382 CGOpts.ThinLTOIndexFile,

1383 true)

1384 .moveInto(CombinedIndex)) {

1385 logAllUnhandledErrors(std::move(E), errs(),

1386 "Error loading index file '" +

1387 CGOpts.ThinLTOIndexFile + "': ");

1388 return;

1389 }

1390

1391

1392

1393

1394 if (CombinedIndex) {

1395 if (!CombinedIndex->skipModuleByDistributedBackend()) {

1397 CGOpts.SampleProfileFile, CGOpts.ProfileRemappingFile,

1398 Action);

1399 return;

1400 }

1401

1402

1403

1404

1405

1406

1407 EmptyModule = std::make_uniquellvm::Module("empty", M->getContext());

1408 EmptyModule->setTargetTriple(M->getTargetTriple());

1409 M = EmptyModule.get();

1410 }

1411 }

1412

1413 EmitAssemblyHelper AsmHelper(CI, M, VFS);

1414 AsmHelper.emitAssembly(Action, std::move(OS), BC);

1415

1416

1417

1418 if (AsmHelper.TM) {

1419 std::string DLDesc = M->getDataLayout().getStringRepresentation();

1420 if (DLDesc != TDesc) {

1423 "expected target description '%1'");

1424 Diags.Report(DiagID) << DLDesc << TDesc;

1425 }

1426 }

1427}

1428

1429

1430

1432 llvm::MemoryBufferRef Buf) {

1434 return;

1435 llvm::embedBitcodeInModule(

1439}

1440

1444 return;

1445

1446 for (StringRef OffloadObject : CGOpts.OffloadObjects) {

1447 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> ObjectOrErr =

1448 llvm::MemoryBuffer::getFileOrSTDIN(OffloadObject);

1449 if (ObjectOrErr.getError()) {

1451 "could not open '%0' for embedding");

1452 Diags.Report(DiagID) << OffloadObject;

1453 return;

1454 }

1455

1456 llvm::embedBufferInModule(*M, **ObjectOrErr, ".llvm.offloading",

1457 Align(object::OffloadBinary::getAlignment()));

1458 }

1459}

static bool actionRequiresCodeGen(BackendAction Action)

static void addSanitizers(const Triple &TargetTriple, const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts, PassBuilder &PB)

static std::optional< llvm::CodeModel::Model > getCodeModel(const CodeGenOptions &CodeGenOpts)

static void runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex, llvm::Module *M, std::unique_ptr< raw_pwrite_stream > OS, std::string SampleProfile, std::string ProfileRemapping, BackendAction Action)

static SanitizerBinaryMetadataOptions getSanitizerBinaryMetadataOptions(const CodeGenOptions &CGOpts)

static std::optional< GCOVOptions > getGCOVOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts)

static bool initTargetOptions(const CompilerInstance &CI, DiagnosticsEngine &Diags, llvm::TargetOptions &Options)

static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts, PassBuilder &PB)

static SanitizerCoverageOptions getSancovOptsFromCGOpts(const CodeGenOptions &CGOpts)

static OptimizationLevel mapToLevel(const CodeGenOptions &Opts)

static std::optional< InstrProfOptions > getInstrProfOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts)

static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts)

static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts)

static CodeGenFileType getCodeGenFileType(BackendAction Action)

static std::string flattenClangCommandLine(ArrayRef< std::string > Args, StringRef MainFilename)

Defines the Diagnostic-related interfaces.

Defines the clang::LangOptions interface.

This file provides a pass to link in Modules from a provided BackendConsumer.

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

static bool contains(const std::set< tok::TokenKind > &Terminators, const Token &Tok)

Defines the clang::TargetOptions class.

CodeGenOptions - Track various options which control how the code is optimized and passed to the back...

SanitizerSet SanitizeMergeHandlers

Set of sanitizer checks that can merge handlers (smaller code size at the expense of debuggability).

std::string InstrProfileOutput

Name of the profile file to use as output for -fprofile-instr-generate, -fprofile-generate,...

std::string BinutilsVersion

bool hasProfileIRUse() const

Check if IR level profile use is on.

char CoverageVersion[4]

The version string to put into coverage files.

std::string FloatABI

The ABI to use for passing floating point arguments.

std::string ThinLinkBitcodeFile

Name of a file that can optionally be written with minimized bitcode to be used as input for the Thin...

bool hasProfileCSIRInstr() const

Check if CS IR level profile instrumentation is on.

std::string DebugPass

Enable additional debugging information.

llvm::Reloc::Model RelocationModel

The name of the relocation model to use.

std::string CoverageNotesFile

The filename with path we use for coverage notes files.

std::string ProfileInstrumentUsePath

Name of the profile file to use as input for -fprofile-instr-use.

std::string SampleProfileFile

Name of the profile file to use with -fprofile-sample-use.

uint64_t LargeDataThreshold

The code model-specific large data threshold to use (-mlarge-data-threshold).

std::string MemoryProfileOutput

Name of the profile file to use as output for with -fmemory-profile.

std::vector< std::function< void(llvm::PassBuilder &)> > PassBuilderCallbacks

List of pass builder callbacks.

std::string LimitFloatPrecision

The float precision limit to use, if non-empty.

std::string CodeModel

The code model to use (-mcmodel).

std::string CoverageDataFile

The filename with path we use for coverage data files.

std::vector< std::string > PassPlugins

List of dynamic shared object files to be loaded as pass plugins.

bool hasProfileClangInstr() const

Check if Clang profile instrumenation is on.

std::string StackUsageOutput

Name of the stack usage file (i.e., .su file) if user passes -fstack-usage.

std::vector< std::string > SanitizeCoverageAllowlistFiles

Path to allowlist file specifying which objects (files, functions) should exclusively be instrumented...

std::vector< std::string > SanitizeCoverageIgnorelistFiles

Path to ignorelist file specifying which objects (files, functions) listed for instrumentation by san...

bool hasSanitizeCoverage() const

std::string MainFileName

The user provided name for the "main file", if non-empty.

bool hasProfileIRInstr() const

Check if IR level profile instrumentation is on.

bool hasProfileCSIRUse() const

Check if CSIR profile use is on.

SanitizerSet SanitizeTrap

Set of sanitizer checks that trap rather than diagnose.

std::vector< std::string > SanitizeMetadataIgnorelistFiles

Path to ignorelist file specifying which objects (files, functions) listed for instrumentation by san...

SanitizerSet SanitizeRecover

Set of sanitizer checks that are non-fatal (i.e.

std::string ProfileExcludeFiles

Regexes separated by a semi-colon to filter the files to not instrument.

std::string AsSecureLogFile

The name of a file to use with .secure_log_unique directives.

std::string ProfileRemappingFile

Name of the profile remapping file to apply to the profile data supplied by -fprofile-sample-use or -...

bool hasSanitizeBinaryMetadata() const

std::string ThinLTOIndexFile

Name of the function summary index file to use for ThinLTO function importing.

const char * Argv0

Executable and command-line used to create a given CompilerInvocation.

SanitizerMaskCutoffs SanitizeSkipHotCutoffs

Set of thresholds in a range [0.0, 1.0]: the top hottest code responsible for the given fraction of P...

std::string SplitDwarfFile

The name for the split debug info file used for the DW_AT_[GNU_]dwo_name attribute in the skeleton CU...

std::vector< uint8_t > CmdArgs

List of backend command-line options for -fembed-bitcode.

std::vector< std::string > CommandLineArgs

std::string MemoryProfileUsePath

Name of the profile file to use as input for -fmemory-profile-use.

std::vector< std::string > OffloadObjects

List of filenames passed in using the -fembed-offload-object option.

std::string ProfileFilterFiles

Regexes separated by a semi-colon to filter the files to instrument.

std::string ObjectFilenameForDebug

Output filename used in the COFF debug information.

std::string SplitDwarfOutput

Output filename for the split debug info, not used in the skeleton CU.

std::string DIBugsReportFilePath

The file to use for dumping bug report by Debugify for original debug info.

CompilerInstance - Helper class for managing a single instance of the Clang compiler.

DiagnosticsEngine & getDiagnostics() const

Get the current diagnostics engine.

llvm::TimerGroup & getTimerGroup() const

llvm::Timer & getFrontendTimer() const

TargetOptions & getTargetOpts()

HeaderSearchOptions & getHeaderSearchOpts()

LangOptions & getLangOpts()

CodeGenOptions & getCodeGenOpts()

Concrete class used by the front-end to report problems and issues.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

unsigned getCustomDiagID(Level L, const char(&FormatString)[N])

Return an ID for a diagnostic with the specified format string and level.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

bool hasWasmExceptions() const

bool hasSjLjExceptions() const

SanitizerSet Sanitize

Set of enabled sanitizers.

bool hasDWARFExceptions() const

bool hasSEHExceptions() const

std::vector< std::string > NoSanitizeFiles

Paths to files specifying which objects (files, functions, variables) should not be instrumented.

Options for controlling the target.

std::vector< std::string > Features

The list of target specific features to enable or disable – this should be a list of strings starting...

std::string ABI

If given, the name of the target ABI to use.

std::string CPU

If given, the name of the target CPU to generate code for.

llvm::EABI EABIVersion

The EABI version to use.

Create and return a pass that links in Moduels from a provided BackendConsumer to a given primary Mod...

The JSON file list parser is used to communicate input to InstallAPI.

if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))

void EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts, DiagnosticsEngine &Diags)

void emitBackendOutput(CompilerInstance &CI, StringRef TDesc, llvm::Module *M, BackendAction Action, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::unique_ptr< raw_pwrite_stream > OS, BackendConsumer *BC=nullptr)

llvm:🆑:opt< bool > ClSanitizeGuardChecks

void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)

@ Backend_EmitAssembly

Emit native assembly files.

@ Backend_EmitLL

Emit human-readable LLVM assembly.

@ Backend_EmitBC

Emit LLVM bitcode files.

@ Backend_EmitObj

Emit native object files.

@ Backend_EmitMCNull

Run CodeGen, but don't emit anything.

@ Backend_EmitNothing

Don't emit anything (benchmarking mode)

const FunctionProtoType * T

Diagnostic wrappers for TextAPI types for error reporting.

cl::opt< bool > PrintPipelinePasses

cl::opt< InstrProfCorrelator::ProfCorrelatorKind > ProfileCorrelate

static cl::opt< PGOOptions::ColdFuncOpt > ClPGOColdFuncAttr("pgo-cold-func-opt", cl::init(PGOOptions::ColdFuncOpt::Default), cl::Hidden, cl::desc("Function attribute to apply to cold functions as determined by PGO"), cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default", "Default (no attribute)"), clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize", "Mark cold functions with optsize."), clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize", "Mark cold functions with minsize."), clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone", "Mark cold functions with optnone.")))

static cl::opt< bool > ClSanitizeOnOptimizerEarlyEP("sanitizer-early-opt-ep", cl::Optional, cl::desc("Insert sanitizers on OptimizerEarlyEP."))

bool has(SanitizerMask K) const

Check if a certain (single) sanitizer is enabled.