LLVM 22.0.0git
AArch64TargetMachine.cpp
Go to the documentation of this file.
1//===-- AArch64TargetMachine.cpp - Define TargetMachine for AArch64 -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//
10//===----------------------------------------------------------------------===//
11
13#include "AArch64.h"
16#include "AArch64MacroFusion.h"
17#include "AArch64Subtarget.h"
34#include "llvm/CodeGen/Passes.h"
37#include "llvm/IR/Attributes.h"
38#include "llvm/IR/Function.h"
40#include "llvm/MC/MCAsmInfo.h"
43#include "llvm/Pass.h"
55#include <memory>
56#include <optional>
57#include <string>
58
59using namespace llvm;
60
61static cl::opt<bool> EnableCCMP("aarch64-enable-ccmp",
62 cl::desc("Enable the CCMP formation pass"),
63 cl::init(true), cl::Hidden);
64
65static cl::opt<bool>
66 EnableCondBrTuning("aarch64-enable-cond-br-tune",
67 cl::desc("Enable the conditional branch tuning pass"),
68 cl::init(true), cl::Hidden);
69
71 "aarch64-enable-copy-propagation",
72 cl::desc("Enable the copy propagation with AArch64 copy instr"),
73 cl::init(true), cl::Hidden);
74
75static cl::opt<bool> EnableMCR("aarch64-enable-mcr",
76 cl::desc("Enable the machine combiner pass"),
77 cl::init(true), cl::Hidden);
78
79static cl::opt<bool> EnableStPairSuppress("aarch64-enable-stp-suppress",
80 cl::desc("Suppress STP for AArch64"),
81 cl::init(true), cl::Hidden);
82
84 "aarch64-enable-simd-scalar",
85 cl::desc("Enable use of AdvSIMD scalar integer instructions"),
86 cl::init(false), cl::Hidden);
87
88static cl::opt<bool>
89 EnablePromoteConstant("aarch64-enable-promote-const",
90 cl::desc("Enable the promote constant pass"),
91 cl::init(true), cl::Hidden);
92
94 "aarch64-enable-collect-loh",
95 cl::desc("Enable the pass that emits the linker optimization hints (LOH)"),
96 cl::init(true), cl::Hidden);
97
98static cl::opt<bool>
99 EnableDeadRegisterElimination("aarch64-enable-dead-defs", cl::Hidden,
100 cl::desc("Enable the pass that removes dead"
101 " definitions and replaces stores to"
102 " them with stores to the zero"
103 " register"),
104 cl::init(true));
105
107 "aarch64-enable-copyelim",
108 cl::desc("Enable the redundant copy elimination pass"), cl::init(true),
109 cl::Hidden);
110
111static cl::opt<bool> EnableLoadStoreOpt("aarch64-enable-ldst-opt",
112 cl::desc("Enable the load/store pair"
113 " optimization pass"),
114 cl::init(true), cl::Hidden);
115
117 "aarch64-enable-atomic-cfg-tidy", cl::Hidden,
118 cl::desc("Run SimplifyCFG after expanding atomic operations"
119 " to make use of cmpxchg flow-based information"),
120 cl::init(true));
121
122static cl::opt<bool>
123EnableEarlyIfConversion("aarch64-enable-early-ifcvt", cl::Hidden,
124 cl::desc("Run early if-conversion"),
125 cl::init(true));
126
127static cl::opt<bool>
128 EnableCondOpt("aarch64-enable-condopt",
129 cl::desc("Enable the condition optimizer pass"),
130 cl::init(true), cl::Hidden);
131
132static cl::opt<bool>
133 EnableGEPOpt("aarch64-enable-gep-opt", cl::Hidden,
134 cl::desc("Enable optimizations on complex GEPs"),
135 cl::init(false));
136
137static cl::opt<bool>
138 EnableSelectOpt("aarch64-select-opt", cl::Hidden,
139 cl::desc("Enable select to branch optimizations"),
140 cl::init(true));
141
142static cl::opt<bool>
143 BranchRelaxation("aarch64-enable-branch-relax", cl::Hidden, cl::init(true),
144 cl::desc("Relax out of range conditional branches"));
145
147 "aarch64-enable-compress-jump-tables", cl::Hidden, cl::init(true),
148 cl::desc("Use smallest entry possible for jump tables"));
149
150// FIXME: Unify control over GlobalMerge.
152 EnableGlobalMerge("aarch64-enable-global-merge", cl::Hidden,
153 cl::desc("Enable the global merge pass"));
154
155static cl::opt<bool>
156 EnableLoopDataPrefetch("aarch64-enable-loop-data-prefetch", cl::Hidden,
157 cl::desc("Enable the loop data prefetch pass"),
158 cl::init(true));
159
161 "aarch64-enable-global-isel-at-O", cl::Hidden,
162 cl::desc("Enable GlobalISel at or below an opt level (-1 to disable)"),
163 cl::init(0));
164
165static cl::opt<bool>
166 EnableSVEIntrinsicOpts("aarch64-enable-sve-intrinsic-opts", cl::Hidden,
167 cl::desc("Enable SVE intrinsic opts"),
168 cl::init(true));
169
170static cl::opt<bool>
171 EnableSMEPeepholeOpt("enable-aarch64-sme-peephole-opt", cl::init(true),
173 cl::desc("Perform SME peephole optimization"));
174
175static cl::opt<bool> EnableFalkorHWPFFix("aarch64-enable-falkor-hwpf-fix",
176 cl::init(true), cl::Hidden);
177
178static cl::opt<bool>
179 EnableBranchTargets("aarch64-enable-branch-targets", cl::Hidden,
180 cl::desc("Enable the AArch64 branch target pass"),
181 cl::init(true));
182
184 "aarch64-sve-vector-bits-max",
185 cl::desc("Assume SVE vector registers are at most this big, "
186 "with zero meaning no maximum size is assumed."),
187 cl::init(0), cl::Hidden);
188
190 "aarch64-sve-vector-bits-min",
191 cl::desc("Assume SVE vector registers are at least this big, "
192 "with zero meaning no minimum size is assumed."),
193 cl::init(0), cl::Hidden);
194
196 "force-streaming",
197 cl::desc("Force the use of streaming code for all functions"),
198 cl::init(false), cl::Hidden);
199
201 "force-streaming-compatible",
202 cl::desc("Force the use of streaming-compatible code for all functions"),
203 cl::init(false), cl::Hidden);
204
206
208 "aarch64-enable-gisel-ldst-prelegal",
209 cl::desc("Enable GlobalISel's pre-legalizer load/store optimization pass"),
210 cl::init(true), cl::Hidden);
211
213 "aarch64-enable-gisel-ldst-postlegal",
214 cl::desc("Enable GlobalISel's post-legalizer load/store optimization pass"),
215 cl::init(false), cl::Hidden);
216
217static cl::opt<bool>
218 EnableSinkFold("aarch64-enable-sink-fold",
219 cl::desc("Enable sinking and folding of instruction copies"),
220 cl::init(true), cl::Hidden);
221
222static cl::opt<bool>
223 EnableMachinePipeliner("aarch64-enable-pipeliner",
224 cl::desc("Enable Machine Pipeliner for AArch64"),
225 cl::init(false), cl::Hidden);
226
227static cl::opt<bool>
228 EnableNewSMEABILowering("aarch64-new-sme-abi",
229 cl::desc("Enable new lowering for the SME ABI"),
230 cl::init(false), cl::Hidden);
231
234 // Register the target.
240 auto &PR = *PassRegistry::getPassRegistry();
282}
283
285
286//===----------------------------------------------------------------------===//
287// AArch64 Lowering public interface.
288//===----------------------------------------------------------------------===//
289static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
290 if (TT.isOSBinFormatMachO())
291 return std::make_unique<AArch64_MachoTargetObjectFile>();
292 if (TT.isOSBinFormatCOFF())
293 return std::make_unique<AArch64_COFFTargetObjectFile>();
294
295 return std::make_unique<AArch64_ELFTargetObjectFile>();
296}
297
299 if (CPU.empty() && TT.isArm64e())
300 return "apple-a12";
301 return CPU;
302}
303
305 std::optional<Reloc::Model> RM) {
306 // AArch64 Darwin and Windows are always PIC.
307 if (TT.isOSDarwin() || TT.isOSWindows())
308 return Reloc::PIC_;
309 // On ELF platforms the default static relocation model has a smart enough
310 // linker to cope with referencing external symbols defined in a shared
311 // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
312 if (!RM || *RM == Reloc::DynamicNoPIC)
313 return Reloc::Static;
314 return *RM;
315}
316
317static CodeModel::Model
319 std::optional<CodeModel::Model> CM, bool JIT) {
320 if (CM) {
321 if (*CM != CodeModel::Small && *CM != CodeModel::Tiny &&
322 *CM != CodeModel::Large) {
324 "Only small, tiny and large code models are allowed on AArch64");
325 } else if (*CM == CodeModel::Tiny && !TT.isOSBinFormatELF()) {
326 report_fatal_error("tiny code model is only supported on ELF");
327 }
328 return *CM;
329 }
330 // The default MCJIT memory managers make no guarantees about where they can
331 // find an executable page; JITed code needs to be able to refer to globals
332 // no matter how far away they are.
333 // We should set the CodeModel::Small for Windows ARM64 in JIT mode,
334 // since with large code model LLVM generating 4 MOV instructions, and
335 // Windows doesn't support relocating these long branch (4 MOVs).
336 if (JIT && !TT.isOSWindows())
337 return CodeModel::Large;
338 return CodeModel::Small;
339}
340
341/// Create an AArch64 architecture model.
342///
344 StringRef CPU, StringRef FS,
345 const TargetOptions &Options,
346 std::optional<Reloc::Model> RM,
347 std::optional<CodeModel::Model> CM,
348 CodeGenOptLevel OL, bool JIT,
349 bool LittleEndian)
350 : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT,
351 computeDefaultCPU(TT, CPU), FS, Options,
353 getEffectiveAArch64CodeModel(TT, CM, JIT), OL),
354 TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian),
355 UseNewSMEABILowering(EnableNewSMEABILowering) {
356 initAsmInfo();
357
358 if (TT.isOSBinFormatMachO()) {
359 this->Options.TrapUnreachable = true;
360 this->Options.NoTrapAfterNoreturn = true;
361 }
362
363 if (getMCAsmInfo()->usesWindowsCFI()) {
364 // Unwinding can get confused if the last instruction in an
365 // exception-handling region (function, funclet, try block, etc.)
366 // is a call.
367 //
368 // FIXME: We could elide the trap if the next instruction would be in
369 // the same region anyway.
370 this->Options.TrapUnreachable = true;
371 }
372
373 if (this->Options.TLSSize == 0) // default
374 this->Options.TLSSize = 24;
375 if ((getCodeModel() == CodeModel::Small ||
377 this->Options.TLSSize > 32)
378 // for the small (and kernel) code model, the maximum TLS size is 4GiB
379 this->Options.TLSSize = 32;
380 else if (getCodeModel() == CodeModel::Tiny && this->Options.TLSSize > 24)
381 // for the tiny code model, the maximum TLS size is 1MiB (< 16MiB)
382 this->Options.TLSSize = 24;
383
384 // Enable GlobalISel at or below EnableGlobalISelAt0, unless this is
385 // MachO/CodeModel::Large, which GlobalISel does not support.
386 if (static_cast<int>(getOptLevel()) <= EnableGlobalISelAtO &&
387 TT.getArch() != Triple::aarch64_32 &&
388 TT.getEnvironment() != Triple::GNUILP32 &&
389 !(getCodeModel() == CodeModel::Large && TT.isOSBinFormatMachO())) {
390 setGlobalISel(true);
392 }
393
394 // AArch64 supports the MachineOutliner.
395 setMachineOutliner(true);
396
397 // AArch64 supports default outlining behaviour.
399
400 // AArch64 supports the debug entry values.
402
403 // AArch64 supports fixing up the DWARF unwind information.
404 if (!getMCAsmInfo()->usesWindowsCFI())
405 setCFIFixup(true);
406}
407
409
410const AArch64Subtarget *
412 Attribute CPUAttr = F.getFnAttribute("target-cpu");
413 Attribute TuneAttr = F.getFnAttribute("tune-cpu");
414 Attribute FSAttr = F.getFnAttribute("target-features");
415
416 StringRef CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString() : TargetCPU;
417 StringRef TuneCPU = TuneAttr.isValid() ? TuneAttr.getValueAsString() : CPU;
418 StringRef FS = FSAttr.isValid() ? FSAttr.getValueAsString() : TargetFS;
419 bool HasMinSize = F.hasMinSize();
420
421 bool IsStreaming = ForceStreaming ||
422 F.hasFnAttribute("aarch64_pstate_sm_enabled") ||
423 F.hasFnAttribute("aarch64_pstate_sm_body");
424 bool IsStreamingCompatible = ForceStreamingCompatible ||
425 F.hasFnAttribute("aarch64_pstate_sm_compatible");
426
427 unsigned MinSVEVectorSize = 0;
428 unsigned MaxSVEVectorSize = 0;
429 if (F.hasFnAttribute(Attribute::VScaleRange)) {
430 ConstantRange CR = getVScaleRange(&F, 64);
431 MinSVEVectorSize = CR.getUnsignedMin().getZExtValue() * 128;
432 MaxSVEVectorSize = CR.getUnsignedMax().getZExtValue() * 128;
433 } else {
434 MinSVEVectorSize = SVEVectorBitsMinOpt;
435 MaxSVEVectorSize = SVEVectorBitsMaxOpt;
436 }
437
438 assert(MinSVEVectorSize % 128 == 0 &&
439 "SVE requires vector length in multiples of 128!");
440 assert(MaxSVEVectorSize % 128 == 0 &&
441 "SVE requires vector length in multiples of 128!");
442 assert((MaxSVEVectorSize >= MinSVEVectorSize || MaxSVEVectorSize == 0) &&
443 "Minimum SVE vector size should not be larger than its maximum!");
444
445 // Sanitize user input in case of no asserts
446 if (MaxSVEVectorSize != 0) {
447 MinSVEVectorSize = std::min(MinSVEVectorSize, MaxSVEVectorSize);
448 MaxSVEVectorSize = std::max(MinSVEVectorSize, MaxSVEVectorSize);
449 }
450
452 raw_svector_ostream(Key) << "SVEMin" << MinSVEVectorSize << "SVEMax"
453 << MaxSVEVectorSize << "IsStreaming=" << IsStreaming
454 << "IsStreamingCompatible=" << IsStreamingCompatible
455 << CPU << TuneCPU << FS
456 << "HasMinSize=" << HasMinSize;
457
458 auto &I = SubtargetMap[Key];
459 if (!I) {
460 // This needs to be done before we create a new subtarget since any
461 // creation will depend on the TM and the code generation flags on the
462 // function that reside in TargetOptions.
464 I = std::make_unique<AArch64Subtarget>(
465 TargetTriple, CPU, TuneCPU, FS, *this, isLittle, MinSVEVectorSize,
466 MaxSVEVectorSize, IsStreaming, IsStreamingCompatible, HasMinSize);
467 }
468
469 if (IsStreaming && !I->hasSME())
470 reportFatalUsageError("streaming SVE functions require SME");
471
472 return I.get();
473}
474
477 const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
479 DAG->addMutation(createLoadClusterDAGMutation(DAG->TII, DAG->TRI));
480 DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
481 if (ST.hasFusion())
482 DAG->addMutation(createAArch64MacroFusionDAGMutation());
483 return DAG;
484}
485
488 const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
490 if (ST.hasFusion()) {
491 // Run the Macro Fusion after RA again since literals are expanded from
492 // pseudos then (v. addPreSched2()).
493 DAG->addMutation(createAArch64MacroFusionDAGMutation());
494 return DAG;
495 }
496
497 return DAG;
498}
499
501 const SmallPtrSetImpl<MachineInstr *> &MIs) const {
502 if (MIs.empty())
503 return 0;
504 auto *MI = *MIs.begin();
505 auto *FuncInfo = MI->getMF()->getInfo<AArch64FunctionInfo>();
506 return FuncInfo->clearLinkerOptimizationHints(MIs);
507}
508
509void AArch64leTargetMachine::anchor() { }
510
512 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
513 const TargetOptions &Options, std::optional<Reloc::Model> RM,
514 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
515 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
516
517void AArch64beTargetMachine::anchor() { }
518
520 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
521 const TargetOptions &Options, std::optional<Reloc::Model> RM,
522 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
523 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
524
525namespace {
526
527/// AArch64 Code Generator Pass Configuration Options.
528class AArch64PassConfig : public TargetPassConfig {
529public:
530 AArch64PassConfig(AArch64TargetMachine &TM, PassManagerBase &PM)
531 : TargetPassConfig(TM, PM) {
532 if (TM.getOptLevel() != CodeGenOptLevel::None)
533 substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
534 setEnableSinkAndFold(EnableSinkFold);
535 }
536
537 AArch64TargetMachine &getAArch64TargetMachine() const {
539 }
540
541 void addIRPasses() override;
542 bool addPreISel() override;
543 void addCodeGenPrepare() override;
544 bool addInstSelector() override;
545 bool addIRTranslator() override;
546 void addPreLegalizeMachineIR() override;
547 bool addLegalizeMachineIR() override;
548 void addPreRegBankSelect() override;
549 bool addRegBankSelect() override;
550 bool addGlobalInstructionSelect() override;
551 void addMachineSSAOptimization() override;
552 bool addILPOpts() override;
553 void addPreRegAlloc() override;
554 void addPostRegAlloc() override;
555 void addPreSched2() override;
556 void addPreEmitPass() override;
557 void addPostBBSections() override;
558 void addPreEmitPass2() override;
559 bool addRegAssignAndRewriteOptimized() override;
560
561 std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
562};
563
564} // end anonymous namespace
565
567
568 PB.registerLateLoopOptimizationsEPCallback(
569 [=](LoopPassManager &LPM, OptimizationLevel Level) {
570 if (Level != OptimizationLevel::O0)
571 LPM.addPass(LoopIdiomVectorizePass());
572 });
573 if (getTargetTriple().isOSWindows())
574 PB.registerPipelineEarlySimplificationEPCallback(
577 });
578}
579
582 return TargetTransformInfo(std::make_unique<AArch64TTIImpl>(this, F));
583}
584
586 return new AArch64PassConfig(*this, PM);
587}
588
589std::unique_ptr<CSEConfigBase> AArch64PassConfig::getCSEConfig() const {
590 return getStandardCSEConfigForOpt(TM->getOptLevel());
591}
592
593void AArch64PassConfig::addIRPasses() {
594 // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
595 // ourselves.
597
598 // Expand any SVE vector library calls that we can't code generate directly.
600 TM->getOptLevel() != CodeGenOptLevel::None)
602
603 // Cmpxchg instructions are often used with a subsequent comparison to
604 // determine whether it succeeded. We can exploit existing control-flow in
605 // ldrex/strex loops to simplify this, but it needs tidying up.
606 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableAtomicTidy)
608 .forwardSwitchCondToPhi(true)
609 .convertSwitchRangeToICmp(true)
610 .convertSwitchToLookupTable(true)
611 .needCanonicalLoops(false)
612 .hoistCommonInsts(true)
613 .sinkCommonInsts(true)));
614
615 // Run LoopDataPrefetch
616 //
617 // Run this before LSR to remove the multiplies involved in computing the
618 // pointer values N iterations ahead.
619 if (TM->getOptLevel() != CodeGenOptLevel::None) {
624 }
625
626 if (EnableGEPOpt) {
627 // Call SeparateConstOffsetFromGEP pass to extract constants within indices
628 // and lower a GEP with multiple indices to either arithmetic operations or
629 // multiple GEPs with single index.
631 // Call EarlyCSE pass to find and remove subexpressions in the lowered
632 // result.
633 addPass(createEarlyCSEPass());
634 // Do loop invariant code motion in case part of the lowered result is
635 // invariant.
636 addPass(createLICMPass());
637 }
638
640
641 if (getOptLevel() == CodeGenOptLevel::Aggressive && EnableSelectOpt)
642 addPass(createSelectOptimizePass());
643
645 /*IsOptNone=*/TM->getOptLevel() == CodeGenOptLevel::None));
646
647 // Match complex arithmetic patterns
648 if (TM->getOptLevel() >= CodeGenOptLevel::Default)
650
651 // Match interleaved memory accesses to ldN/stN intrinsics.
652 if (TM->getOptLevel() != CodeGenOptLevel::None) {
655 }
656
658 // Expand any functions marked with SME attributes which require special
659 // changes for the calling convention or that require the lazy-saving
660 // mechanism specified in the SME ABI.
661 addPass(createSMEABIPass());
662 }
663
664 // Add Control Flow Guard checks.
665 if (TM->getTargetTriple().isOSWindows()) {
666 if (TM->getTargetTriple().isWindowsArm64EC())
668 else
669 addPass(createCFGuardCheckPass());
670 }
671
672 if (TM->Options.JMCInstrument)
673 addPass(createJMCInstrumenterPass());
674}
675
676// Pass Pipeline Configuration
677bool AArch64PassConfig::addPreISel() {
678 // Run promote constant before global merge, so that the promoted constants
679 // get a chance to be merged
680 if (TM->getOptLevel() != CodeGenOptLevel::None && EnablePromoteConstant)
682 // FIXME: On AArch64, this depends on the type.
683 // Basically, the addressable offsets are up to 4095 * Ty.getSizeInBytes().
684 // and the offset has to be a multiple of the related size in bytes.
685 if ((TM->getOptLevel() != CodeGenOptLevel::None &&
688 bool OnlyOptimizeForSize =
689 (TM->getOptLevel() < CodeGenOptLevel::Aggressive) &&
691
692 // Merging of extern globals is enabled by default on non-Mach-O as we
693 // expect it to be generally either beneficial or harmless. On Mach-O it
694 // is disabled as we emit the .subsections_via_symbols directive which
695 // means that merging extern globals is not safe.
696 bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();
697
698 // FIXME: extern global merging is only enabled when we optimise for size
699 // because there are some regressions with it also enabled for performance.
700 if (!OnlyOptimizeForSize)
701 MergeExternalByDefault = false;
702
703 addPass(createGlobalMergePass(TM, 4095, OnlyOptimizeForSize,
704 MergeExternalByDefault));
705 }
706
707 return false;
708}
709
710void AArch64PassConfig::addCodeGenPrepare() {
711 if (getOptLevel() != CodeGenOptLevel::None)
714}
715
716bool AArch64PassConfig::addInstSelector() {
717 addPass(createAArch64ISelDag(getAArch64TargetMachine(), getOptLevel()));
718
719 // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
720 // references to _TLS_MODULE_BASE_ as possible.
721 if (TM->getTargetTriple().isOSBinFormatELF() &&
722 getOptLevel() != CodeGenOptLevel::None)
724
725 return false;
726}
727
728bool AArch64PassConfig::addIRTranslator() {
729 addPass(new IRTranslator(getOptLevel()));
730 return false;
731}
732
733void AArch64PassConfig::addPreLegalizeMachineIR() {
734 if (getOptLevel() == CodeGenOptLevel::None) {
736 addPass(new Localizer());
737 } else {
739 addPass(new Localizer());
741 addPass(new LoadStoreOpt());
742 }
743}
744
745bool AArch64PassConfig::addLegalizeMachineIR() {
746 addPass(new Legalizer());
747 return false;
748}
749
750void AArch64PassConfig::addPreRegBankSelect() {
751 bool IsOptNone = getOptLevel() == CodeGenOptLevel::None;
752 if (!IsOptNone) {
753 addPass(createAArch64PostLegalizerCombiner(IsOptNone));
755 addPass(new LoadStoreOpt());
756 }
758}
759
760bool AArch64PassConfig::addRegBankSelect() {
761 addPass(new RegBankSelect());
762 return false;
763}
764
765bool AArch64PassConfig::addGlobalInstructionSelect() {
766 addPass(new InstructionSelect(getOptLevel()));
767 if (getOptLevel() != CodeGenOptLevel::None)
769 return false;
770}
771
772void AArch64PassConfig::addMachineSSAOptimization() {
773 if (EnableNewSMEABILowering && TM->getOptLevel() != CodeGenOptLevel::None)
774 addPass(createMachineSMEABIPass());
775
776 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableSMEPeepholeOpt)
777 addPass(createSMEPeepholeOptPass());
778
779 // Run default MachineSSAOptimization first.
781
782 if (TM->getOptLevel() != CodeGenOptLevel::None)
784}
785
786bool AArch64PassConfig::addILPOpts() {
787 if (EnableCondOpt)
789 if (EnableCCMP)
791 if (EnableMCR)
792 addPass(&MachineCombinerID);
794 addPass(createAArch64CondBrTuning());
796 addPass(&EarlyIfConverterLegacyID);
800 if (TM->getOptLevel() != CodeGenOptLevel::None)
802 return true;
803}
804
805void AArch64PassConfig::addPreRegAlloc() {
806 if (TM->getOptLevel() == CodeGenOptLevel::None && EnableNewSMEABILowering)
807 addPass(createMachineSMEABIPass());
808
809 // Change dead register definitions to refer to the zero register.
810 if (TM->getOptLevel() != CodeGenOptLevel::None &&
813
814 // Use AdvSIMD scalar instructions whenever profitable.
815 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableAdvSIMDScalar) {
817 // The AdvSIMD pass may produce copies that can be rewritten to
818 // be register coalescer friendly.
820 }
821 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableMachinePipeliner)
822 addPass(&MachinePipelinerID);
823}
824
825void AArch64PassConfig::addPostRegAlloc() {
826 // Remove redundant copy instructions.
827 if (TM->getOptLevel() != CodeGenOptLevel::None &&
830
831 if (TM->getOptLevel() != CodeGenOptLevel::None && usingDefaultRegAlloc())
832 // Improve performance for some FP/SIMD code for A57.
834}
835
836void AArch64PassConfig::addPreSched2() {
837 // Lower homogeneous frame instructions
840 // Expand some pseudo instructions to allow proper scheduling.
842 // Use load/store pair instructions when possible.
843 if (TM->getOptLevel() != CodeGenOptLevel::None) {
846 }
847 // Emit KCFI checks for indirect calls.
848 addPass(createKCFIPass());
849
850 // The AArch64SpeculationHardeningPass destroys dominator tree and natural
851 // loop info, which is needed for the FalkorHWPFFixPass and also later on.
852 // Therefore, run the AArch64SpeculationHardeningPass before the
853 // FalkorHWPFFixPass to avoid recomputing dominator tree and natural loop
854 // info.
856
857 if (TM->getOptLevel() != CodeGenOptLevel::None) {
859 addPass(createFalkorHWPFFixPass());
860 }
861}
862
863void AArch64PassConfig::addPreEmitPass() {
864 // Machine Block Placement might have created new opportunities when run
865 // at O3, where the Tail Duplication Threshold is set to 4 instructions.
866 // Run the load/store optimizer once more.
867 if (TM->getOptLevel() >= CodeGenOptLevel::Aggressive && EnableLoadStoreOpt)
869
870 if (TM->getOptLevel() >= CodeGenOptLevel::Aggressive &&
873
874 addPass(createAArch64A53Fix835769());
875
876 if (TM->getTargetTriple().isOSWindows()) {
877 // Identify valid longjmp targets for Windows Control Flow Guard.
878 addPass(createCFGuardLongjmpPass());
879 // Identify valid eh continuation targets for Windows EHCont Guard.
881 }
882
883 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCollectLOH &&
884 TM->getTargetTriple().isOSBinFormatMachO())
886}
887
888void AArch64PassConfig::addPostBBSections() {
893 // Relax conditional branch instructions if they're otherwise out of
894 // range of their destination.
896 addPass(&BranchRelaxationPassID);
897
898 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCompressJumpTables)
900}
901
902void AArch64PassConfig::addPreEmitPass2() {
903 // SVE bundles move prefixes with destructive operations. BLR_RVMARKER pseudo
904 // instructions are lowered to bundles as well.
905 addPass(createUnpackMachineBundles(nullptr));
906}
907
908bool AArch64PassConfig::addRegAssignAndRewriteOptimized() {
911}
912
919
924
927 const auto *MFI = MF.getInfo<AArch64FunctionInfo>();
928 return new yaml::AArch64FunctionInfo(*MFI);
929}
930
933 SMDiagnostic &Error, SMRange &SourceRange) const {
934 const auto &YamlMFI = static_cast<const yaml::AArch64FunctionInfo &>(MFI);
935 MachineFunction &MF = PFS.MF;
936 MF.getInfo<AArch64FunctionInfo>()->initializeBaseYamlFields(YamlMFI);
937 return false;
938}
cl::opt< bool > EnableHomogeneousPrologEpilog("homogeneous-prolog-epilog", cl::Hidden, cl::desc("Emit homogeneous prologue and epilogue for the size " "optimization (default = off)"))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< bool > EnableBranchTargets("aarch64-enable-branch-targets", cl::Hidden, cl::desc("Enable the AArch64 branch target pass"), cl::init(true))
static cl::opt< bool > EnableSVEIntrinsicOpts("aarch64-enable-sve-intrinsic-opts", cl::Hidden, cl::desc("Enable SVE intrinsic opts"), cl::init(true))
static cl::opt< bool > EnableAArch64CopyPropagation("aarch64-enable-copy-propagation", cl::desc("Enable the copy propagation with AArch64 copy instr"), cl::init(true), cl::Hidden)
static cl::opt< bool > BranchRelaxation("aarch64-enable-branch-relax", cl::Hidden, cl::init(true), cl::desc("Relax out of range conditional branches"))
static cl::opt< bool > EnablePromoteConstant("aarch64-enable-promote-const", cl::desc("Enable the promote constant pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableCondBrTuning("aarch64-enable-cond-br-tune", cl::desc("Enable the conditional branch tuning pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableSinkFold("aarch64-enable-sink-fold", cl::desc("Enable sinking and folding of instruction copies"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableDeadRegisterElimination("aarch64-enable-dead-defs", cl::Hidden, cl::desc("Enable the pass that removes dead" " definitions and replaces stores to" " them with stores to the zero" " register"), cl::init(true))
static cl::opt< bool > EnableGEPOpt("aarch64-enable-gep-opt", cl::Hidden, cl::desc("Enable optimizations on complex GEPs"), cl::init(false))
static cl::opt< bool > EnableSelectOpt("aarch64-select-opt", cl::Hidden, cl::desc("Enable select to branch optimizations"), cl::init(true))
static cl::opt< bool > EnableLoadStoreOpt("aarch64-enable-ldst-opt", cl::desc("Enable the load/store pair" " optimization pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableGISelLoadStoreOptPostLegal("aarch64-enable-gisel-ldst-postlegal", cl::desc("Enable GlobalISel's post-legalizer load/store optimization pass"), cl::init(false), cl::Hidden)
static StringRef computeDefaultCPU(const Triple &TT, StringRef CPU)
static cl::opt< unsigned > SVEVectorBitsMinOpt("aarch64-sve-vector-bits-min", cl::desc("Assume SVE vector registers are at least this big, " "with zero meaning no minimum size is assumed."), cl::init(0), cl::Hidden)
static cl::opt< bool > EnableMCR("aarch64-enable-mcr", cl::desc("Enable the machine combiner pass"), cl::init(true), cl::Hidden)
static cl::opt< cl::boolOrDefault > EnableGlobalMerge("aarch64-enable-global-merge", cl::Hidden, cl::desc("Enable the global merge pass"))
static cl::opt< bool > EnableStPairSuppress("aarch64-enable-stp-suppress", cl::desc("Suppress STP for AArch64"), cl::init(true), cl::Hidden)
static CodeModel::Model getEffectiveAArch64CodeModel(const Triple &TT, std::optional< CodeModel::Model > CM, bool JIT)
static cl::opt< bool > EnableCondOpt("aarch64-enable-condopt", cl::desc("Enable the condition optimizer pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > ForceStreaming("force-streaming", cl::desc("Force the use of streaming code for all functions"), cl::init(false), cl::Hidden)
static cl::opt< bool > EnableCollectLOH("aarch64-enable-collect-loh", cl::desc("Enable the pass that emits the linker optimization hints (LOH)"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableGISelLoadStoreOptPreLegal("aarch64-enable-gisel-ldst-prelegal", cl::desc("Enable GlobalISel's pre-legalizer load/store optimization pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableRedundantCopyElimination("aarch64-enable-copyelim", cl::desc("Enable the redundant copy elimination pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableNewSMEABILowering("aarch64-new-sme-abi", cl::desc("Enable new lowering for the SME ABI"), cl::init(false), cl::Hidden)
static cl::opt< bool > EnableAtomicTidy("aarch64-enable-atomic-cfg-tidy", cl::Hidden, cl::desc("Run SimplifyCFG after expanding atomic operations" " to make use of cmpxchg flow-based information"), cl::init(true))
static cl::opt< bool > EnableAdvSIMDScalar("aarch64-enable-simd-scalar", cl::desc("Enable use of AdvSIMD scalar integer instructions"), cl::init(false), cl::Hidden)
static cl::opt< int > EnableGlobalISelAtO("aarch64-enable-global-isel-at-O", cl::Hidden, cl::desc("Enable GlobalISel at or below an opt level (-1 to disable)"), cl::init(0))
static cl::opt< bool > EnableLoopDataPrefetch("aarch64-enable-loop-data-prefetch", cl::Hidden, cl::desc("Enable the loop data prefetch pass"), cl::init(true))
static cl::opt< bool > EnableSMEPeepholeOpt("enable-aarch64-sme-peephole-opt", cl::init(true), cl::Hidden, cl::desc("Perform SME peephole optimization"))
static cl::opt< bool > EnableEarlyIfConversion("aarch64-enable-early-ifcvt", cl::Hidden, cl::desc("Run early if-conversion"), cl::init(true))
static cl::opt< bool > EnableMachinePipeliner("aarch64-enable-pipeliner", cl::desc("Enable Machine Pipeliner for AArch64"), cl::init(false), cl::Hidden)
static cl::opt< bool > EnableFalkorHWPFFix("aarch64-enable-falkor-hwpf-fix", cl::init(true), cl::Hidden)
static cl::opt< unsigned > SVEVectorBitsMaxOpt("aarch64-sve-vector-bits-max", cl::desc("Assume SVE vector registers are at most this big, " "with zero meaning no maximum size is assumed."), cl::init(0), cl::Hidden)
static cl::opt< bool > ForceStreamingCompatible("force-streaming-compatible", cl::desc("Force the use of streaming-compatible code for all functions"), cl::init(false), cl::Hidden)
static std::unique_ptr< TargetLoweringObjectFile > createTLOF(const Triple &TT)
static cl::opt< bool > EnableCompressJumpTables("aarch64-enable-compress-jump-tables", cl::Hidden, cl::init(true), cl::desc("Use smallest entry possible for jump tables"))
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target()
static cl::opt< bool > EnableCCMP("aarch64-enable-ccmp", cl::desc("Enable the CCMP formation pass"), cl::init(true), cl::Hidden)
This file a TargetTransformInfoImplBase conforming object specific to the AArch64 target machine.
This file contains the simple types necessary to represent the attributes associated with functions a...
Provides analysis for continuously CSEing during GISel passes.
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
DXIL Legalizer
static cl::opt< bool > EnableGlobalMerge("enable-global-merge", cl::Hidden, cl::desc("Enable the global merge pass"), cl::init(true))
IRTranslator LLVM IR MI
This file declares the IRTranslator pass.
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
#define T
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
This file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
static std::unique_ptr< TargetLoweringObjectFile > createTLOF()
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
size_t clearLinkerOptimizationHints(const SmallPtrSetImpl< MachineInstr * > &MIs)
size_t clearLinkerOptimizationHints(const SmallPtrSetImpl< MachineInstr * > &MIs) const override
Remove all Linker Optimization Hints (LOH) associated with instructions in MIs and.
StringMap< std::unique_ptr< AArch64Subtarget > > SubtargetMap
MachineFunctionInfo * createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override
Create the target's instance of MachineFunctionInfo.
void registerPassBuilderCallbacks(PassBuilder &PB) override
Allow the target to modify the pass pipeline.
const AArch64Subtarget * getSubtargetImpl() const =delete
yaml::MachineFunctionInfo * createDefaultFuncInfoYAML() const override
Allocate and return a default initialized instance of the YAML representation for the MachineFunction...
ScheduleDAGInstrs * createPostMachineScheduler(MachineSchedContext *C) const override
Similar to createMachineScheduler but used when postRA machine scheduling is enabled.
std::unique_ptr< TargetLoweringObjectFile > TLOF
yaml::MachineFunctionInfo * convertFuncInfoToYAML(const MachineFunction &MF) const override
Allocate and initialize an instance of the YAML representation of the MachineFunctionInfo.
bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &, PerFunctionMIParsingState &PFS, SMDiagnostic &Error, SMRange &SourceRange) const override
Parse out the target's MachineFunctionInfo from the YAML reprsentation.
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
void reset() override
Reset internal state.
AArch64TargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT, bool IsLittleEndian)
Create an AArch64 architecture model.
ScheduleDAGInstrs * createMachineScheduler(MachineSchedContext *C) const override
Create an instance of ScheduleDAGInstrs to be run within the standard MachineScheduler pass for this ...
TargetTransformInfo getTargetTransformInfo(const Function &F) const override
Return a TargetTransformInfo for a given function.
AArch64beTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT)
AArch64leTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT)
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1540
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:69
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:223
CodeGenTargetMachineImpl(const Target &T, StringRef DataLayoutString, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOptLevel OL)
This class represents a range of values.
LLVM_ABI APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
LLVM_ABI APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
This pass is responsible for selecting generic machine instructions to target-specific instructions.
This pass implements the localization mechanism described at the top of this file.
Definition Localizer.h:43
Pass to replace calls to ifuncs with indirect calls.
Definition LowerIFunc.h:19
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
static LLVM_ABI const OptimizationLevel O0
Disable as many optimizations as possible.
This class provides access to building LLVM's passes.
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This pass implements the reg bank selector pass used in the GlobalISel pipeline.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition SourceMgr.h:282
Represents a range in source code.
Definition SMLoc.h:48
A ScheduleDAG for scheduling lists of MachineInstr.
ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules machine instructions while...
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
void setSupportsDebugEntryValues(bool Enable)
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
const Triple & getTargetTriple() const
void setMachineOutliner(bool Enable)
void setCFIFixup(bool Enable)
void setSupportsDefaultOutlining(bool Enable)
void setGlobalISelAbort(GlobalISelAbortMode Mode)
std::unique_ptr< const MCSubtargetInfo > STI
void setGlobalISel(bool Enable)
TargetOptions Options
CodeModel::Model getCodeModel() const
Returns the code model.
void resetTargetOptions(const Function &F) const
Reset the target options based on the function's attributes.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
unsigned TLSSize
Bit size of immediate TLS offsets (0 == use the default).
unsigned NoTrapAfterNoreturn
Do not emit a trap instruction for 'unreachable' IR instructions behind noreturn calls,...
unsigned TrapUnreachable
Emit target-specific trap instruction for 'unreachable' IR instructions.
Target-Independent Code Generator Pass Configuration Options.
virtual void addCodeGenPrepare()
Add pass to prepare the LLVM IR for code generation.
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
virtual void addMachineSSAOptimization()
addMachineSSAOptimization - Add standard passes that optimize machine instructions in SSA form.
virtual bool addRegAssignAndRewriteOptimized()
TargetSubtargetInfo - Generic base class for all target subtargets.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
A raw_ostream that writes to an SmallVector or SmallString.
Interfaces for registering analysis passes, producing common pass manager configurations,...
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ DynamicNoPIC
Definition CodeGen.h:25
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
ScheduleDAGMILive * createSchedLive(MachineSchedContext *C)
Create the standard converging machine scheduler.
FunctionPass * createAArch64PreLegalizerCombiner()
void initializeLDTLSCleanupPass(PassRegistry &)
LLVM_ABI FunctionPass * createCFGSimplificationPass(SimplifyCFGOptions Options=SimplifyCFGOptions(), std::function< bool(const Function &)> Ftor=nullptr)
FunctionPass * createSMEABIPass()
void initializeAArch64A57FPLoadBalancingPass(PassRegistry &)
void initializeMachineSMEABIPass(PassRegistry &)
FunctionPass * createAArch64PostSelectOptimize()
LLVM_ABI ModulePass * createJMCInstrumenterPass()
JMC instrument pass.
void initializeAArch64SpeculationHardeningPass(PassRegistry &)
void initializeAArch64PostLegalizerLoweringPass(PassRegistry &)
FunctionPass * createAArch64RedundantCopyEliminationPass()
FunctionPass * createAArch64StackTaggingPreRAPass()
LLVM_ABI FunctionPass * createTypePromotionLegacyPass()
Create IR Type Promotion pass.
FunctionPass * createMachineSMEABIPass()
void initializeAArch64PostLegalizerCombinerPass(PassRegistry &)
FunctionPass * createAArch64MIPeepholeOptPass()
void initializeAArch64AdvSIMDScalarPass(PassRegistry &)
void initializeAArch64PostCoalescerPass(PassRegistry &)
LLVM_ABI FunctionPass * createSelectOptimizePass()
This pass converts conditional moves to conditional jumps when profitable.
LLVM_ABI Pass * createGlobalMergePass(const TargetMachine *TM, unsigned MaximalOffset, bool OnlyOptimizeForSize=false, bool MergeExternalByDefault=false, bool MergeConstantByDefault=false, bool MergeConstAggressiveByDefault=false)
GlobalMerge - This pass merges internal (by default) globals into structs to enable reuse of a base p...
FunctionPass * createAArch64PostCoalescerPass()
void initializeAArch64PromoteConstantPass(PassRegistry &)
FunctionPass * createFalkorMarkStridedAccessesPass()
Target & getTheAArch64beTarget()
FunctionPass * createAArch64PointerAuthPass()
FunctionPass * createFalkorHWPFFixPass()
LLVM_ABI char & PostRASchedulerID
PostRAScheduler - This pass performs post register allocation scheduling.
FunctionPass * createAArch64O0PreLegalizerCombiner()
FunctionPass * createAArch64A57FPLoadBalancing()
FunctionPass * createAArch64CondBrTuning()
LLVM_ABI std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)
Definition CSEInfo.cpp:89
void initializeAArch64Arm64ECCallLoweringPass(PassRegistry &)
void initializeSMEABIPass(PassRegistry &)
LLVM_ABI char & PostMachineSchedulerID
PostMachineScheduler - This pass schedules machine instructions postRA.
LLVM_ABI char & PeepholeOptimizerLegacyID
PeepholeOptimizer - This pass performs peephole optimizations - like extension and comparison elimina...
LLVM_ABI Pass * createLICMPass()
Definition LICM.cpp:384
Target & getTheAArch64leTarget()
FunctionPass * createAArch64DeadRegisterDefinitions()
LLVM_ABI char & EarlyIfConverterLegacyID
EarlyIfConverter - This pass performs if-conversion on SSA form by inserting cmov instructions.
FunctionPass * createSMEPeepholeOptPass()
FunctionPass * createAArch64PostLegalizerLowering()
ThinOrFullLTOPhase
This enumerates the LLVM full LTO or ThinLTO optimization phases.
Definition Pass.h:77
PassManager< Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, LPMUpdater & > LoopPassManager
The Loop pass manager.
LLVM_ABI char & MachineCombinerID
This pass performs instruction combining using trace metrics to estimate critical-path and resource d...
void initializeAArch64AsmPrinterPass(PassRegistry &)
static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM)
FunctionPass * createAArch64CompressJumpTablesPass()
Target & getTheAArch64_32Target()
FunctionPass * createAArch64ConditionalCompares()
ScheduleDAGMI * createSchedPostRA(MachineSchedContext *C)
Create a generic scheduler with no vreg liveness or DAG mutation passes.
LLVM_ABI char & BranchRelaxationPassID
BranchRelaxation - This pass replaces branches that need to jump further than is supported by a branc...
void initializeFalkorMarkStridedAccessesLegacyPass(PassRegistry &)
void initializeAArch64ExpandPseudoPass(PassRegistry &)
void initializeAArch64DeadRegisterDefinitionsPass(PassRegistry &)
void initializeAArch64StackTaggingPass(PassRegistry &)
FunctionPass * createAArch64ExpandPseudoPass()
Returns an instance of the pseudo instruction expansion pass.
LLVM_ABI FunctionPass * createKCFIPass()
Lowers KCFI operand bundles for indirect calls.
Definition KCFI.cpp:61
std::unique_ptr< ScheduleDAGMutation > createAArch64MacroFusionDAGMutation()
Note that you have to add: DAG.addMutation(createAArch64MacroFusionDAGMutation()); to AArch64TargetMa...
LLVM_ABI FunctionPass * createComplexDeinterleavingPass(const TargetMachine *TM)
This pass implements generation of target-specific intrinsics to support handling of complex number a...
PassManager< Module > ModulePassManager
Convenience typedef for a pass manager over modules.
ModulePass * createAArch64Arm64ECCallLoweringPass()
LLVM_ABI std::unique_ptr< ScheduleDAGMutation > createStoreClusterDAGMutation(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, bool ReorderWhileClustering=false)
If ReorderWhileClustering is set to true, no attempt will be made to reduce reordering due to store c...
LLVM_ABI FunctionPass * createLoopDataPrefetchPass()
FunctionPass * createAArch64SIMDInstrOptPass()
Returns an instance of the high cost ASIMD instruction replacement optimization pass.
void initializeSMEPeepholeOptPass(PassRegistry &)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
FunctionPass * createAArch64StorePairSuppressPass()
FunctionPass * createAArch64ConditionOptimizerPass()
ModulePass * createSVEIntrinsicOptsPass()
void initializeAArch64CompressJumpTablesPass(PassRegistry &)
void initializeAArch64SLSHardeningPass(PassRegistry &)
FunctionPass * createAArch64CollectLOHPass()
LLVM_ABI ConstantRange getVScaleRange(const Function *F, unsigned BitWidth)
Determine the possible constant range of vscale with the given bit width, based on the vscale_range f...
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
@ Default
-O2, -Os
Definition CodeGen.h:85
FunctionPass * createAArch64LoadStoreOptimizationPass()
createAArch64LoadStoreOptimizationPass - returns an instance of the load / store optimization pass.
void initializeAArch64StackTaggingPreRAPass(PassRegistry &)
LLVM_ABI FunctionPass * createCFGuardLongjmpPass()
Creates CFGuard longjmp target identification pass.
void initializeAArch64PreLegalizerCombinerPass(PassRegistry &)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Target & getTheARM64_32Target()
FunctionPass * createAArch64PostLegalizerCombiner(bool IsOptNone)
void initializeAArch64StorePairSuppressPass(PassRegistry &)
void initializeAArch64LowerHomogeneousPrologEpilogPass(PassRegistry &)
LLVM_ABI FunctionPass * createSeparateConstOffsetFromGEPPass(bool LowerGEP=false)
LLVM_ABI FunctionPass * createInterleavedAccessPass()
InterleavedAccess Pass - This pass identifies and matches interleaved memory accesses to target speci...
LLVM_ABI void initializeGlobalISel(PassRegistry &)
Initialize all passes linked into the GlobalISel library.
LLVM_ABI void initializeKCFIPass(PassRegistry &)
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
void initializeAArch64CondBrTuningPass(PassRegistry &)
LLVM_ABI char & MachinePipelinerID
This pass performs software pipelining on machine instructions.
void initializeAArch64MIPeepholeOptPass(PassRegistry &)
FunctionPass * createAArch64SLSHardeningPass()
FunctionPass * createAArch64BranchTargetsPass()
Target & getTheARM64Target()
LLVM_ABI std::unique_ptr< ScheduleDAGMutation > createLoadClusterDAGMutation(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, bool ReorderWhileClustering=false)
If ReorderWhileClustering is set to true, no attempt will be made to reduce reordering due to store c...
void initializeFalkorHWPFFixPass(PassRegistry &)
LLVM_ABI FunctionPass * createUnpackMachineBundles(std::function< bool(const MachineFunction &)> Ftor)
void initializeAArch64BranchTargetsPass(PassRegistry &)
FunctionPass * createCFGuardCheckPass()
Insert Control FLow Guard checks on indirect function calls.
Definition CFGuard.cpp:317
void initializeAArch64A53Fix835769Pass(PassRegistry &)
LLVM_ABI FunctionPass * createEHContGuardTargetsPass()
Creates Windows EH Continuation Guard target identification pass.
ModulePass * createAArch64LowerHomogeneousPrologEpilogPass()
void initializeAArch64LoadStoreOptPass(PassRegistry &)
void initializeAArch64SIMDInstrOptPass(PassRegistry &)
void initializeAArch64PostSelectOptimizePass(PassRegistry &)
void initializeAArch64CollectLOHPass(PassRegistry &)
FunctionPass * createAArch64StackTaggingPass(bool IsOptNone)
void initializeAArch64O0PreLegalizerCombinerPass(PassRegistry &)
void initializeAArch64ConditionOptimizerPass(PassRegistry &)
void initializeAArch64ConditionalComparesPass(PassRegistry &)
LLVM_ABI FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
FunctionPass * createAArch64CleanupLocalDynamicTLSPass()
ModulePass * createAArch64PromoteConstantPass()
LLVM_ABI FunctionPass * createEarlyCSEPass(bool UseMemorySSA=false)
LLVM_ABI MachineFunctionPass * createMachineCopyPropagationPass(bool UseCopyInstr)
FunctionPass * createAArch64AdvSIMDScalar()
void initializeAArch64DAGToDAGISelLegacyPass(PassRegistry &)
FunctionPass * createAArch64SpeculationHardeningPass()
Returns an instance of the pseudo instruction expansion pass.
void initializeSVEIntrinsicOptsPass(PassRegistry &)
void initializeAArch64PointerAuthPass(PassRegistry &)
void initializeAArch64RedundantCopyEliminationPass(PassRegistry &)
LLVM_ABI FunctionPass * createInterleavedLoadCombinePass()
InterleavedLoadCombines Pass - This pass identifies interleaved loads and combines them into wide loa...
FunctionPass * createAArch64A53Fix835769()
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:180
MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...
static FuncInfoTy * create(BumpPtrAllocator &Allocator, const Function &F, const SubtargetTy *STI)
Factory function: default behavior is to call new using the supplied allocator.
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
RegisterTargetMachine - Helper template for registering a target machine implementation,...
Targets should override this in a way that mirrors the implementation of llvm::MachineFunctionInfo.