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:

210 llvm::Module *M,

212 : CI(CI), Diags(CI.getDiagnostics()), CodeGenOpts(CGOpts),

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

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

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

216

217 ~EmitAssemblyHelper() {

218 if (CodeGenOpts.DisableFree)

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

220 }

221

222 std::unique_ptr TM;

223

224

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

227};

228}

229

230static SanitizerCoverageOptions

232 SanitizerCoverageOptions Opts;

233 Opts.CoverageType =

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

235 Opts.IndirectCalls = CGOpts.SanitizeCoverageIndirectCalls;

236 Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB;

237 Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp;

238 Opts.TraceDiv = CGOpts.SanitizeCoverageTraceDiv;

239 Opts.TraceGep = CGOpts.SanitizeCoverageTraceGep;

240 Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;

241 Opts.TracePC = CGOpts.SanitizeCoverageTracePC;

242 Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;

243 Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;

244 Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;

245 Opts.InlineBoolFlag = CGOpts.SanitizeCoverageInlineBoolFlag;

246 Opts.PCTable = CGOpts.SanitizeCoveragePCTable;

247 Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;

248 Opts.TraceLoads = CGOpts.SanitizeCoverageTraceLoads;

249 Opts.TraceStores = CGOpts.SanitizeCoverageTraceStores;

250 Opts.CollectControlFlow = CGOpts.SanitizeCoverageControlFlow;

251 return Opts;

252}

253

254static SanitizerBinaryMetadataOptions

256 SanitizerBinaryMetadataOptions Opts;

257 Opts.Covered = CGOpts.SanitizeBinaryMetadataCovered;

258 Opts.Atomics = CGOpts.SanitizeBinaryMetadataAtomics;

259 Opts.UAR = CGOpts.SanitizeBinaryMetadataUAR;

260 return Opts;

261}

262

263

264

265

266

268 if (!CGOpts.SanitizeAddressGlobalsDeadStripping)

269 return false;

270 switch (T.getObjectFormat()) {

271 case Triple::MachO:

272 case Triple::COFF:

273 return true;

274 case Triple::ELF:

275 return !CGOpts.DisableIntegratedAS;

276 case Triple::GOFF:

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

278 case Triple::XCOFF:

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

280 case Triple::Wasm:

281 case Triple::DXContainer:

282 case Triple::SPIRV:

283 case Triple::UnknownObjectFormat:

284 break;

285 }

286 return false;

287}

288

289static std::optionalllvm::CodeModel::Model

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

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

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

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

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

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

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

298 .Default(~0u);

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

300 if (CodeModel == ~1u)

301 return std::nullopt;

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

303}

304

307 return CodeGenFileType::ObjectFile;

309 return CodeGenFileType::Null;

310 else {

312 return CodeGenFileType::AssemblyFile;

313 }

314}

315

319}

320

322 StringRef MainFilename) {

323 if (Args.empty())

324 return std::string{};

325

326 std::string FlatCmdLine;

327 raw_string_ostream OS(FlatCmdLine);

328 bool PrintedOneArg = false;

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

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

331 PrintedOneArg = true;

332 }

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

334 StringRef Arg = Args[i];

335 if (Arg.empty())

336 continue;

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

338 i++;

339 continue;

340 }

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

342 continue;

343

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

345 continue;

346 if (PrintedOneArg)

347 OS << " ";

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

349 PrintedOneArg = true;

350 }

351 return FlatCmdLine;

352}

353

356 llvm::TargetOptions &Options) {

361 switch (LangOpts.getThreadModel()) {

362 case LangOptions::ThreadModelKind::POSIX:

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

364 break;

365 case LangOptions::ThreadModelKind::Single:

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

367 break;

368 }

369

370

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

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

373 "Invalid Floating Point ABI!");

374 Options.FloatABIType =

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

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

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

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

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

380

381

382 switch (LangOpts.getDefaultFPContractMode()) {

383 case LangOptions::FPM_Off:

384

385

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

387 break;

388 case LangOptions::FPM_On:

389 case LangOptions::FPM_FastHonorPragmas:

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

391 break;

392 case LangOptions::FPM_Fast:

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

394 break;

395 }

396

397 Options.BinutilsVersion =

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

399 Options.UseInitArray = CodeGenOpts.UseInitArray;

400 Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS;

401

402

403 Options.EABIVersion = TargetOpts.EABIVersion;

404

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

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

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

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

413

414 Options.NoInfsFPMath = LangOpts.NoHonorInfs;

415 Options.NoNaNsFPMath = LangOpts.NoHonorNaNs;

416 Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;

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

418 LangOpts.NoSignedZero && LangOpts.ApproxFunc &&

419 (LangOpts.getDefaultFPContractMode() ==

420 LangOptions::FPModeKind::FPM_Fast ||

421 LangOpts.getDefaultFPContractMode() ==

422 LangOptions::FPModeKind::FPM_FastHonorPragmas);

423 Options.ApproxFuncFPMath = LangOpts.ApproxFunc;

424

425 Options.BBAddrMap = CodeGenOpts.BBAddrMap;

426 Options.BBSections =

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

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

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

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

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

432

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

434 ErrorOr<std::unique_ptr> MBOrErr =

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

436 if (!MBOrErr) {

437 Diags.Report(diag::err_fe_unable_to_load_basic_block_sections_file)

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

439 return false;

440 }

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

442 }

443

444 Options.EnableMachineFunctionSplitter = CodeGenOpts.SplitMachineFunctions;

445 Options.FunctionSections = CodeGenOpts.FunctionSections;

446 Options.DataSections = CodeGenOpts.DataSections;

447 Options.IgnoreXCOFFVisibility = LangOpts.IgnoreXCOFFVisibility;

448 Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;

449 Options.UniqueBasicBlockSectionNames =

450 CodeGenOpts.UniqueBasicBlockSectionNames;

451 Options.SeparateNamedSections = CodeGenOpts.SeparateNamedSections;

452 Options.TLSSize = CodeGenOpts.TLSSize;

453 Options.EnableTLSDESC = CodeGenOpts.EnableTLSDESC;

454 Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;

455 Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();

456 Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;

458 Options.EmitAddrsig = CodeGenOpts.Addrsig;

459 Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;

460 Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo;

461 Options.EnableAIXExtendedAltivecABI = LangOpts.EnableAIXExtendedAltivecABI;

462 Options.XRayFunctionIndex = CodeGenOpts.XRayFunctionIndex;

463 Options.LoopAlignment = CodeGenOpts.LoopAlignment;

464 Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf;

466 Options.Hotpatch = CodeGenOpts.HotPatch;

467 Options.JMCInstrument = CodeGenOpts.JMCInstrument;

468 Options.XCOFFReadOnlyPointers = CodeGenOpts.XCOFFReadOnlyPointers;

469

470 switch (CodeGenOpts.getSwiftAsyncFramePointer()) {

471 case CodeGenOptions::SwiftAsyncFramePointerKind::Auto:

472 Options.SwiftAsyncFramePointer =

473 SwiftAsyncFramePointerMode::DeploymentBased;

474 break;

475

476 case CodeGenOptions::SwiftAsyncFramePointerKind::Always:

477 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Always;

478 break;

479

480 case CodeGenOptions::SwiftAsyncFramePointerKind::Never:

481 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Never;

482 break;

483 }

484

485 Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;

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

487 Options.MCOptions.EmitCompactUnwindNonCanonical =

488 CodeGenOpts.EmitCompactUnwindNonCanonical;

489 Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;

490 Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;

491 Options.MCOptions.MCUseDwarfDirectory =

492 CodeGenOpts.NoDwarfDirectoryAsm

493 ? llvm::MCTargetOptions::DisableDwarfDirectory

494 : llvm::MCTargetOptions::EnableDwarfDirectory;

495 Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;

496 Options.MCOptions.MCIncrementalLinkerCompatible =

497 CodeGenOpts.IncrementalLinkerCompatible;

498 Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;

499 Options.MCOptions.MCNoWarn = CodeGenOpts.NoWarn;

500 Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;

501 Options.MCOptions.Dwarf64 = CodeGenOpts.Dwarf64;

502 Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;

503 Options.MCOptions.Crel = CodeGenOpts.Crel;

504 Options.MCOptions.ImplicitMapSyms = CodeGenOpts.ImplicitMapSyms;

505 Options.MCOptions.X86RelaxRelocations = CodeGenOpts.X86RelaxRelocations;

506 Options.MCOptions.CompressDebugSections =

507 CodeGenOpts.getCompressDebugSections();

508 if (CodeGenOpts.OutputAsmVariant != 3)

509 Options.MCOptions.OutputAsmVariant = CodeGenOpts.OutputAsmVariant;

510 Options.MCOptions.ABIName = TargetOpts.ABI;

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

512 if (!Entry.IsFramework &&

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

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

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

516 Options.MCOptions.IASSearchPaths.push_back(

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

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

521 Options.MCOptions.AsSecureLogFile = CodeGenOpts.AsSecureLogFile;

522 Options.MCOptions.PPCUseFullRegisterNames =

523 CodeGenOpts.PPCUseFullRegisterNames;

524 Options.MisExpect = CodeGenOpts.MisExpect;

525

526 return true;

527}

528

529static std::optional

533 return std::nullopt;

534

535

536 GCOVOptions Options;

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

540 Options.NoRedZone = CodeGenOpts.DisableRedZone;

543 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;

544 return Options;

545}

546

547static std::optional

551 return std::nullopt;

552 InstrProfOptions Options;

553 Options.NoRedZone = CodeGenOpts.DisableRedZone;

555 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;

556 return Options;

557}

558

561 BackendArgs.push_back("clang");

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

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

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

565 }

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

569 }

570

571

572

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

574 return;

575 BackendArgs.push_back(nullptr);

576

577

578

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

580 BackendArgs.data());

581}

582

583void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {

584

585 std::string Error;

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

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

588 if (!TheTarget) {

589 if (MustCreateTM)

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

591 return;

592 }

593

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

595 std::string FeaturesStr =

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

598 std::optional OptLevelOrNone =

599 CodeGenOpt::getLevel(CodeGenOpts.OptimizationLevel);

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

601 CodeGenOptLevel OptLevel = *OptLevelOrNone;

602

603 llvm::TargetOptions Options;

605 return;

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

607 Options, RM, CM, OptLevel));

609}

610

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

613 raw_pwrite_stream &OS,

614 raw_pwrite_stream *DwoOS) {

615

616 std::unique_ptr TLII(

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

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

619

620

621

623

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

625 !CodeGenOpts.VerifyModule)) {

626 Diags.Report(diag::err_fe_unable_to_interface_with_target);

627 return false;

628 }

629

630 return true;

631}

632

634 switch (Opts.OptimizationLevel) {

635 default:

636 llvm_unreachable("Invalid optimization level!");

637

638 case 0:

639 return OptimizationLevel::O0;

640

641 case 1:

642 return OptimizationLevel::O1;

643

644 case 2:

645 switch (Opts.OptimizeSize) {

646 default:

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

648

649 case 0:

650 return OptimizationLevel::O2;

651

652 case 1:

653 return OptimizationLevel::Os;

654

655 case 2:

656 return OptimizationLevel::Oz;

657 }

658

659 case 3:

660 return OptimizationLevel::O3;

661 }

662}

663

665 PassBuilder &PB) {

666

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

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

669 return;

670

671

672 PB.registerOptimizerLastEPCallback(

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

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

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

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

677 });

678

679

680

681 PB.registerPeepholeEPCallback(

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

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

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

685 FPM.addPass(KCFIPass());

686 });

687}

688

691 const LangOptions &LangOpts, PassBuilder &PB) {

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

693 ThinOrFullLTOPhase) {

696 MPM.addPass(SanitizerCoveragePass(

699 }

700

702 MPM.addPass(SanitizerBinaryMetadataPass(

705 }

706

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

709 int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins;

711

712 MemorySanitizerOptions options(TrackOrigins, Recover, CompileKernel,

713 CodeGenOpts.SanitizeMemoryParamRetval);

714 MPM.addPass(MemorySanitizerPass(options));

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

716

717

718

719

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

721 FunctionPassManager FPM;

722 FPM.addPass(EarlyCSEPass(true ));

723 FPM.addPass(InstCombinePass());

724 FPM.addPass(JumpThreadingPass());

725 FPM.addPass(GVNPass());

726 FPM.addPass(InstCombinePass());

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

728 }

729 }

730 };

731 MSanPass(SanitizerKind::Memory, false);

732 MSanPass(SanitizerKind::KernelMemory, true);

733

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

735 MPM.addPass(ModuleThreadSanitizerPass());

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

737 }

738

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

740 MPM.addPass(TypeSanitizerPass());

741

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

743 MPM.addPass(NumericalStabilitySanitizerPass());

744

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

746 MPM.addPass(RealtimeSanitizerPass());

747

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

750 bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts);

751 bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;

752 llvm::AsanDtorKind DestructorKind =

753 CodeGenOpts.getSanitizeAddressDtor();

754 AddressSanitizerOptions Opts;

755 Opts.CompileKernel = CompileKernel;

757 Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;

758 Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();

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

760 DestructorKind));

761 }

762 };

763 ASanPass(SanitizerKind::Address, false);

764 ASanPass(SanitizerKind::KernelAddress, true);

765

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

769 MPM.addPass(HWAddressSanitizerPass(

770 {CompileKernel, Recover,

771 CodeGenOpts.OptimizationLevel == 0}));

772 }

773 };

774 HWASanPass(SanitizerKind::HWAddress, false);

775 HWASanPass(SanitizerKind::KernelHWAddress, true);

776

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

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

779 }

780 };

782 PB.registerOptimizerEarlyEPCallback(

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

784 ThinOrFullLTOPhase Phase) {

785 ModulePassManager NewMPM;

786 SanitizersCallback(NewMPM, Level, Phase);

787 if (!NewMPM.isEmpty()) {

788

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

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

791 }

792 });

793 } else {

794

795 PB.registerOptimizerLastEPCallback(SanitizersCallback);

796 }

797

798 if (LowerAllowCheckPass::IsRequested()) {

799

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

801 OptimizationLevel Level,

802 ThinOrFullLTOPhase Phase) {

803 LowerAllowCheckPass::Options Opts;

804 MPM.addPass(createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts)));

805 });

806 }

807}

808

809void EmitAssemblyHelper::RunOptimizationPipeline(

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

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

812 std::optional PGOOpt;

813

815

816 PGOOpt = PGOOptions(

821 CodeGenOpts.DebugInfoForProfiling,

822 false, CodeGenOpts.AtomicProfileUpdate);

824

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

826 : PGOOptions::NoCSAction;

831 CodeGenOpts.DebugInfoForProfiling);

833

834 PGOOpt = PGOOptions(

838 CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling);

840

842 PGOOptions::NoAction, PGOOptions::NoCSAction,

844 else if (CodeGenOpts.PseudoProbeForProfiling)

845

846 PGOOpt =

847 PGOOptions("", "", "", "", nullptr,

848 PGOOptions::NoAction, PGOOptions::NoCSAction,

850 else if (CodeGenOpts.DebugInfoForProfiling)

851

852 PGOOpt = PGOOptions("", "", "", "", nullptr,

853 PGOOptions::NoAction, PGOOptions::NoCSAction,

855

856

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

860 "the same time");

861 if (PGOOpt) {

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

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

864 "Cannot run CSProfileGen pass with ProfileGen or SampleUse "

865 " pass");

867 ? getDefaultProfileGenName()

868 : CodeGenOpts.InstrProfileOutput;

869 PGOOpt->CSAction = PGOOptions::CSIRInstr;

870 } else

871 PGOOpt = PGOOptions("",

873 ? getDefaultProfileGenName()

875 "", "", nullptr,

876 PGOOptions::NoAction, PGOOptions::CSIRInstr,

878 }

879 if (TM)

880 TM->setPGOOption(PGOOpt);

881

882 PipelineTuningOptions PTO;

883 PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;

884

885

886 PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;

887 PTO.LoopVectorization = CodeGenOpts.VectorizeLoop;

888 PTO.SLPVectorization = CodeGenOpts.VectorizeSLP;

889 PTO.MergeFunctions = CodeGenOpts.MergeFunctions;

890

891

892 PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;

893 PTO.UnifiedLTO = CodeGenOpts.UnifiedLTO;

894

895 LoopAnalysisManager LAM;

896 FunctionAnalysisManager FAM;

897 CGSCCAnalysisManager CGAM;

898 ModuleAnalysisManager MAM;

899

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

901 PassInstrumentationCallbacks PIC;

902 PrintPassOptions PrintPassOpts;

903 PrintPassOpts.Indent = DebugPassStructure;

904 PrintPassOpts.SkipAnalyses = DebugPassStructure;

905 StandardInstrumentations SI(

906 TheModule->getContext(),

907 (CodeGenOpts.DebugPassManager || DebugPassStructure),

908 CodeGenOpts.VerifyEach, PrintPassOpts);

909 SI.registerCallbacks(PIC, &MAM);

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

911

912

913 switch (CodeGenOpts.getAssignmentTrackingMode()) {

914 case CodeGenOptions::AssignmentTrackingOpts::Forced:

915 PB.registerPipelineStartEPCallback(

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

917 MPM.addPass(AssignmentTrackingPass());

918 });

919 break;

920 case CodeGenOptions::AssignmentTrackingOpts::Enabled:

921

922

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

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

925 PB.registerPipelineStartEPCallback(

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

927

928 if (Level != OptimizationLevel::O0)

929 MPM.addPass(AssignmentTrackingPass());

930 });

931 }

932 break;

933 case CodeGenOptions::AssignmentTrackingOpts::Disabled:

934 break;

935 }

936

937

938 DebugifyEachInstrumentation Debugify;

939 DebugInfoPerPass DebugInfoBeforePass;

940 if (CodeGenOpts.EnableDIPreservationVerify) {

941 Debugify.setDebugifyMode(DebugifyMode::OriginalDebugInfo);

942 Debugify.setDebugInfoBeforePass(DebugInfoBeforePass);

943

945 Debugify.setOrigDIVerifyBugsReportFilePath(

947 Debugify.registerCallbacks(PIC, MAM);

948 }

949

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

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

952 if (PassPlugin) {

953 PassPlugin->registerPassBuilderCallbacks(PB);

954 } else {

955 Diags.Report(diag::err_fe_unable_to_load_plugin)

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

957 }

958 }

960 PassCallback(PB);

961#define HANDLE_EXTENSION(Ext) \

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

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

964

965

966

967 std::unique_ptr TLII(

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

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

970

971

972 PB.registerModuleAnalyses(MAM);

973 PB.registerCGSCCAnalyses(CGAM);

974 PB.registerFunctionAnalyses(FAM);

975 PB.registerLoopAnalyses(LAM);

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

977

978 ModulePassManager MPM;

979

980 if (CodeGenOpts.VerifyModule)

981 MPM.addPass(VerifierPass());

982

983 if (!CodeGenOpts.DisableLLVMPasses) {

984

985

987

988 const bool PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO;

989 const bool PrepareForLTO = CodeGenOpts.PrepareForLTO;

990

991 if (LangOpts.ObjCAutoRefCount) {

992 PB.registerPipelineStartEPCallback(

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

994 if (Level != OptimizationLevel::O0)

995 MPM.addPass(

996 createModuleToFunctionPassAdaptor(ObjCARCExpandPass()));

997 });

998 PB.registerPipelineEarlySimplificationEPCallback(

999 [](ModulePassManager &MPM, OptimizationLevel Level,

1000 ThinOrFullLTOPhase) {

1001 if (Level != OptimizationLevel::O0)

1002 MPM.addPass(ObjCARCAPElimPass());

1003 });

1004 PB.registerScalarOptimizerLateEPCallback(

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

1006 if (Level != OptimizationLevel::O0)

1007 FPM.addPass(ObjCARCOptPass());

1008 });

1009 }

1010

1011

1012

1013

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

1015

1016

1017 if (IsThinLTOPostLink)

1018 PB.registerPipelineStartEPCallback(

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

1020 MPM.addPass(LowerTypeTestsPass(

1021 nullptr,

1022 nullptr,

1023 lowertypetests::DropTestKind::Assume));

1024 });

1025

1026

1027

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

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

1030 OptimizationLevel Level) {

1031 BoundsCheckingPass::Options Options;

1034 static_assert(SanitizerKind::SO_LocalBounds <=

1035 std::numeric_limits<

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

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

1038 "SanitizerKind::SO_LocalBounds.");

1039 Options.GuardKind = SanitizerKind::SO_LocalBounds;

1040 }

1041 Options.Merge =

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

1044 Options.Rt = {

1045 static_cast(

1046 CodeGenOpts.SanitizeMinimalRuntime),

1047

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

1049 };

1050 }

1051 FPM.addPass(BoundsCheckingPass(Options));

1052 });

1053

1054

1055

1056 if (!IsThinLTOPostLink) {

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

1058 addKCFIPass(TargetTriple, LangOpts, PB);

1059 }

1060

1061 if (std::optional Options =

1063 PB.registerPipelineStartEPCallback(

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

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

1066 });

1067 if (std::optional Options =

1069 PB.registerPipelineStartEPCallback(

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

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

1072 });

1073

1074

1075

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

1078 OptimizationLevel Level,

1079 ThinOrFullLTOPhase) {

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

1081 MPM.addPass(ModuleMemProfilerPass());

1082 });

1083 }

1084

1085 if (CodeGenOpts.FatLTO) {

1086 MPM.addPass(PB.buildFatLTODefaultPipeline(

1087 Level, PrepareForThinLTO,

1088 PrepareForThinLTO || shouldEmitRegularLTOSummary()));

1089 } else if (PrepareForThinLTO) {

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

1091 } else if (PrepareForLTO) {

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

1093 } else {

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

1095 }

1096 }

1097

1098

1099 if (CodeGenOpts.LinkBitcodePostopt)

1101

1102

1103

1104

1105

1106

1108 MPM.addPass(VerifierPass());

1109

1111 CodeGenOpts.FatLTO) {

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

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

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

1115 CodeGenOpts.EnableSplitLTOUnit);

1119 if (!ThinLinkOS)

1120 return;

1121 }

1122 MPM.addPass(ThinLTOBitcodeWriterPass(

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

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

1126 true));

1127 }

1128 } else {

1129

1130

1131 bool EmitLTOSummary = shouldEmitRegularLTOSummary();

1132 if (EmitLTOSummary) {

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

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

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

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

1138 }

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

1141 EmitLTOSummary));

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

1144 EmitLTOSummary));

1145 }

1146 }

1147

1148 if (shouldEmitUnifiedLTOModueFlag())

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

1150 }

1151

1152

1153

1154

1155

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

1158 auto PassName = PIC.getPassNameForClassName(ClassName);

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

1160 });

1161 outs() << "\n";

1162 return;

1163 }

1164

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

1166 LangOpts.HIPStdParInterposeAlloc)

1167 MPM.addPass(HipStdParAllocationInterpositionPass());

1168

1169

1170 {

1171 PrettyStackTraceString CrashInfo("Optimizer");

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

1173 Timer timer;

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

1177 }

1178 MPM.run(*TheModule, MAM);

1181 }

1182}

1183

1184void EmitAssemblyHelper::RunCodegenPipeline(

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

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

1187

1188

1189

1190 legacy::PassManager CodeGenPasses;

1191

1192

1193 switch (Action) {

1197 CodeGenPasses.add(

1198 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));

1201 if (!DwoOS)

1202 return;

1203 }

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

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

1206

1207 return;

1208 break;

1209 default:

1210 return;

1211 }

1212

1213

1214

1215

1217 return;

1218 }

1219

1220 {

1221 PrettyStackTraceString CrashInfo("Code generation");

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

1223 Timer timer;

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

1227 }

1228 CodeGenPasses.run(*TheModule);

1231 }

1232}

1233

1234void EmitAssemblyHelper::emitAssembly(BackendAction Action,

1235 std::unique_ptr<raw_pwrite_stream> OS,

1238

1240 CreateTargetMachine(RequiresCodeGen);

1241

1242 if (RequiresCodeGen && !TM)

1243 return;

1244 if (TM)

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

1246

1247

1248 cl::PrintOptionValues();

1249

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

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

1252 RunCodegenPipeline(Action, OS, DwoOS);

1253

1254 if (ThinLinkOS)

1255 ThinLinkOS->keep();

1256 if (DwoOS)

1257 DwoOS->keep();

1258}

1259

1260static void

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

1263 std::string SampleProfile, std::string ProfileRemapping,

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

1269 ModuleToDefinedGVSummaries;

1270 CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

1271

1273

1274

1275

1276

1277 FunctionImporter::ImportIDTable ImportIDs;

1278 FunctionImporter::ImportMapTy ImportList(ImportIDs);

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

1280 return;

1281

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

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

1284 CGOpts.ObjectFilenameForDebug);

1285 };

1286 lto::Config Conf;

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

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

1289 false)) {

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

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

1292 << '\n';

1293 });

1294 }

1295 }

1296 Conf.CPU = TOpts.CPU;

1298 Conf.MAttrs = TOpts.Features;

1299 Conf.RelocModel = CGOpts.RelocationModel;

1300 std::optional OptLevelOrNone =

1301 CodeGenOpt::getLevel(CGOpts.OptimizationLevel);

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

1303 Conf.CGOptLevel = *OptLevelOrNone;

1304 Conf.OptLevel = CGOpts.OptimizationLevel;

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

1307 Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;

1308

1309

1310 Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;

1311 Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop;

1312 Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP;

1313

1314

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

1316

1317

1318 if (CGOpts.hasProfileCSIRInstr()) {

1319 Conf.RunCSIRInstr = true;

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

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

1322 Conf.RunCSIRInstr = false;

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

1324 }

1325

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

1327 Conf.DebugPassManager = CGOpts.DebugPassManager;

1328 Conf.VerifyEach = CGOpts.VerifyEach;

1329 Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;

1330 Conf.RemarksFilename = CGOpts.OptRecordFile;

1331 Conf.RemarksPasses = CGOpts.OptRecordPasses;

1332 Conf.RemarksFormat = CGOpts.OptRecordFormat;

1333 Conf.SplitDwarfFile = CGOpts.SplitDwarfFile;

1334 Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput;

1335 switch (Action) {

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

1338 return false;

1339 };

1340 break;

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

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

1344 return false;

1345 };

1346 break;

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

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

1350 return false;

1351 };

1352 break;

1353 default:

1355 break;

1356 }

1357 if (Error E =

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

1359 ModuleToDefinedGVSummaries[M->getModuleIdentifier()],

1360 nullptr, Conf.CodeGenOnly,

1361 nullptr, CGOpts.CmdArgs)) {

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

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

1364 });

1365 }

1366}

1367

1369 StringRef TDesc, llvm::Module *M,

1372 std::unique_ptr<raw_pwrite_stream> OS,

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

1376

1377 std::unique_ptrllvm::Module EmptyModule;

1379

1380

1381

1382 std::unique_ptr CombinedIndex;

1383 if (Error E = llvm::getModuleSummaryIndexForFile(

1385 true)

1386 .moveInto(CombinedIndex)) {

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

1388 "Error loading index file '" +

1390 return;

1391 }

1392

1393

1394

1395

1396 if (CombinedIndex) {

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

1400 Action);

1401 return;

1402 }

1403

1404

1405

1406

1407

1408

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

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

1411 M = EmptyModule.get();

1412 }

1413 }

1414

1415 EmitAssemblyHelper AsmHelper(CI, CGOpts, M, VFS);

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

1417

1418

1419

1420 if (AsmHelper.TM) {

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

1422 if (DLDesc != TDesc) {

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

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

1427 }

1428 }

1429}

1430

1431

1432

1434 llvm::MemoryBufferRef Buf) {

1436 return;

1437 llvm::embedBitcodeInModule(

1441}

1442

1446 return;

1447

1448 for (StringRef OffloadObject : CGOpts.OffloadObjects) {

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

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

1451 if (ObjectOrErr.getError()) {

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

1454 Diags.Report(DiagID) << OffloadObject;

1455 return;

1456 }

1457

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

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

1460 }

1461}

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)

llvm:🆑:opt< bool > ClSanitizeGuardChecks

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

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.