LLVM 20.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"
22#include "llvm/ADT/STLExtras.h"
36#include "llvm/CodeGen/Passes.h"
39#include "llvm/IR/Attributes.h"
40#include "llvm/IR/Function.h"
42#include "llvm/MC/MCAsmInfo.h"
45#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 " definitons 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> EnableFalkorHWPFFix("aarch64-enable-falkor-hwpf-fix",
171 cl::init(true), cl::Hidden);
172
173static cl::opt<bool>
174 EnableBranchTargets("aarch64-enable-branch-targets", cl::Hidden,
175 cl::desc("Enable the AArch64 branch target pass"),
176 cl::init(true));
177
179 "aarch64-sve-vector-bits-max",
180 cl::desc("Assume SVE vector registers are at most this big, "
181 "with zero meaning no maximum size is assumed."),
182 cl::init(0), cl::Hidden);
183
185 "aarch64-sve-vector-bits-min",
186 cl::desc("Assume SVE vector registers are at least this big, "
187 "with zero meaning no minimum size is assumed."),
188 cl::init(0), cl::Hidden);
189
191 "force-streaming",
192 cl::desc("Force the use of streaming code for all functions"),
193 cl::init(false), cl::Hidden);
194
196 "force-streaming-compatible",
197 cl::desc("Force the use of streaming-compatible code for all functions"),
198 cl::init(false), cl::Hidden);
199
201
203 "aarch64-enable-gisel-ldst-prelegal",
204 cl::desc("Enable GlobalISel's pre-legalizer load/store optimization pass"),
205 cl::init(true), cl::Hidden);
206
208 "aarch64-enable-gisel-ldst-postlegal",
209 cl::desc("Enable GlobalISel's post-legalizer load/store optimization pass"),
210 cl::init(false), cl::Hidden);
211
212static cl::opt<bool>
213 EnableSinkFold("aarch64-enable-sink-fold",
214 cl::desc("Enable sinking and folding of instruction copies"),
215 cl::init(true), cl::Hidden);
216
217static cl::opt<bool>
218 EnableMachinePipeliner("aarch64-enable-pipeliner",
219 cl::desc("Enable Machine Pipeliner for AArch64"),
220 cl::init(false), cl::Hidden);
221
223 // Register the target.
267}
268
269//===----------------------------------------------------------------------===//
270// AArch64 Lowering public interface.
271//===----------------------------------------------------------------------===//
272static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
273 if (TT.isOSBinFormatMachO())
274 return std::make_unique<AArch64_MachoTargetObjectFile>();
275 if (TT.isOSBinFormatCOFF())
276 return std::make_unique<AArch64_COFFTargetObjectFile>();
277
278 return std::make_unique<AArch64_ELFTargetObjectFile>();
279}
280
281// Helper function to build a DataLayout string
282static std::string computeDataLayout(const Triple &TT,
284 bool LittleEndian) {
285 if (TT.isOSBinFormatMachO()) {
286 if (TT.getArch() == Triple::aarch64_32)
287 return "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32";
288 return "e-m:o-i64:64-i128:128-n32:64-S128-Fn32";
289 }
290 if (TT.isOSBinFormatCOFF())
291 return "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32";
292 std::string Endian = LittleEndian ? "e" : "E";
293 std::string Ptr32 = TT.getEnvironment() == Triple::GNUILP32 ? "-p:32:32" : "";
294 return Endian + "-m:e" + Ptr32 +
295 "-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32";
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 return *CM;
328 }
329 // The default MCJIT memory managers make no guarantees about where they can
330 // find an executable page; JITed code needs to be able to refer to globals
331 // no matter how far away they are.
332 // We should set the CodeModel::Small for Windows ARM64 in JIT mode,
333 // since with large code model LLVM generating 4 MOV instructions, and
334 // Windows doesn't support relocating these long branch (4 MOVs).
335 if (JIT && !TT.isOSWindows())
336 return CodeModel::Large;
337 return CodeModel::Small;
338}
339
340/// Create an AArch64 architecture model.
341///
343 StringRef CPU, StringRef FS,
344 const TargetOptions &Options,
345 std::optional<Reloc::Model> RM,
346 std::optional<CodeModel::Model> CM,
347 CodeGenOptLevel OL, bool JIT,
348 bool LittleEndian)
350 computeDataLayout(TT, Options.MCOptions, LittleEndian),
351 TT, computeDefaultCPU(TT, CPU), FS, Options,
353 getEffectiveAArch64CodeModel(TT, CM, JIT), OL),
354 TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian) {
355 initAsmInfo();
356
357 if (TT.isOSBinFormatMachO()) {
358 this->Options.TrapUnreachable = true;
359 this->Options.NoTrapAfterNoreturn = true;
360 }
361
362 if (getMCAsmInfo()->usesWindowsCFI()) {
363 // Unwinding can get confused if the last instruction in an
364 // exception-handling region (function, funclet, try block, etc.)
365 // is a call.
366 //
367 // FIXME: We could elide the trap if the next instruction would be in
368 // the same region anyway.
369 this->Options.TrapUnreachable = true;
370 }
371
372 if (this->Options.TLSSize == 0) // default
373 this->Options.TLSSize = 24;
374 if ((getCodeModel() == CodeModel::Small ||
376 this->Options.TLSSize > 32)
377 // for the small (and kernel) code model, the maximum TLS size is 4GiB
378 this->Options.TLSSize = 32;
379 else if (getCodeModel() == CodeModel::Tiny && this->Options.TLSSize > 24)
380 // for the tiny code model, the maximum TLS size is 1MiB (< 16MiB)
381 this->Options.TLSSize = 24;
382
383 // Enable GlobalISel at or below EnableGlobalISelAt0, unless this is
384 // MachO/CodeModel::Large, which GlobalISel does not support.
385 if (static_cast<int>(getOptLevel()) <= EnableGlobalISelAtO &&
386 TT.getArch() != Triple::aarch64_32 &&
387 TT.getEnvironment() != Triple::GNUILP32 &&
388 !(getCodeModel() == CodeModel::Large && TT.isOSBinFormatMachO())) {
389 setGlobalISel(true);
391 }
392
393 // AArch64 supports the MachineOutliner.
394 setMachineOutliner(true);
395
396 // AArch64 supports default outlining behaviour.
398
399 // AArch64 supports the debug entry values.
401
402 // AArch64 supports fixing up the DWARF unwind information.
403 if (!getMCAsmInfo()->usesWindowsCFI())
404 setCFIFixup(true);
405}
406
408
409const AArch64Subtarget *
411 Attribute CPUAttr = F.getFnAttribute("target-cpu");
412 Attribute TuneAttr = F.getFnAttribute("tune-cpu");
413 Attribute FSAttr = F.getFnAttribute("target-features");
414
415 StringRef CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString() : TargetCPU;
416 StringRef TuneCPU = TuneAttr.isValid() ? TuneAttr.getValueAsString() : CPU;
417 StringRef FS = FSAttr.isValid() ? FSAttr.getValueAsString() : TargetFS;
418 bool HasMinSize = F.hasMinSize();
419
420 bool IsStreaming = ForceStreaming ||
421 F.hasFnAttribute("aarch64_pstate_sm_enabled") ||
422 F.hasFnAttribute("aarch64_pstate_sm_body");
423 bool IsStreamingCompatible = ForceStreamingCompatible ||
424 F.hasFnAttribute("aarch64_pstate_sm_compatible");
425
426 unsigned MinSVEVectorSize = 0;
427 unsigned MaxSVEVectorSize = 0;
428 if (F.hasFnAttribute(Attribute::VScaleRange)) {
429 ConstantRange CR = getVScaleRange(&F, 64);
430 MinSVEVectorSize = CR.getUnsignedMin().getZExtValue() * 128;
431 MaxSVEVectorSize = CR.getUnsignedMax().getZExtValue() * 128;
432 } else {
433 MinSVEVectorSize = SVEVectorBitsMinOpt;
434 MaxSVEVectorSize = SVEVectorBitsMaxOpt;
435 }
436
437 assert(MinSVEVectorSize % 128 == 0 &&
438 "SVE requires vector length in multiples of 128!");
439 assert(MaxSVEVectorSize % 128 == 0 &&
440 "SVE requires vector length in multiples of 128!");
441 assert((MaxSVEVectorSize >= MinSVEVectorSize || MaxSVEVectorSize == 0) &&
442 "Minimum SVE vector size should not be larger than its maximum!");
443
444 // Sanitize user input in case of no asserts
445 if (MaxSVEVectorSize != 0) {
446 MinSVEVectorSize = std::min(MinSVEVectorSize, MaxSVEVectorSize);
447 MaxSVEVectorSize = std::max(MinSVEVectorSize, MaxSVEVectorSize);
448 }
449
451 raw_svector_ostream(Key) << "SVEMin" << MinSVEVectorSize << "SVEMax"
452 << MaxSVEVectorSize << "IsStreaming=" << IsStreaming
453 << "IsStreamingCompatible=" << IsStreamingCompatible
454 << CPU << TuneCPU << FS
455 << "HasMinSize=" << HasMinSize;
456
457 auto &I = SubtargetMap[Key];
458 if (!I) {
459 // This needs to be done before we create a new subtarget since any
460 // creation will depend on the TM and the code generation flags on the
461 // function that reside in TargetOptions.
463 I = std::make_unique<AArch64Subtarget>(
464 TargetTriple, CPU, TuneCPU, FS, *this, isLittle, MinSVEVectorSize,
465 MaxSVEVectorSize, IsStreaming, IsStreamingCompatible, HasMinSize);
466 }
467
468 assert((!IsStreaming || I->hasSME()) && "Expected SME to be available");
469
470 return I.get();
471}
472
473void AArch64leTargetMachine::anchor() { }
474
476 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
477 const TargetOptions &Options, std::optional<Reloc::Model> RM,
478 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
479 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
480
481void AArch64beTargetMachine::anchor() { }
482
484 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
485 const TargetOptions &Options, std::optional<Reloc::Model> RM,
486 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
487 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
488
489namespace {
490
491/// AArch64 Code Generator Pass Configuration Options.
492class AArch64PassConfig : public TargetPassConfig {
493public:
494 AArch64PassConfig(AArch64TargetMachine &TM, PassManagerBase &PM)
495 : TargetPassConfig(TM, PM) {
496 if (TM.getOptLevel() != CodeGenOptLevel::None)
497 substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
498 setEnableSinkAndFold(EnableSinkFold);
499 }
500
501 AArch64TargetMachine &getAArch64TargetMachine() const {
502 return getTM<AArch64TargetMachine>();
503 }
504
506 createMachineScheduler(MachineSchedContext *C) const override {
507 const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
509 DAG->addMutation(createLoadClusterDAGMutation(DAG->TII, DAG->TRI));
510 DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
511 if (ST.hasFusion())
512 DAG->addMutation(createAArch64MacroFusionDAGMutation());
513 return DAG;
514 }
515
517 createPostMachineScheduler(MachineSchedContext *C) const override {
518 const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
519 ScheduleDAGMI *DAG =
520 new ScheduleDAGMI(C, std::make_unique<AArch64PostRASchedStrategy>(C),
521 /* RemoveKillFlags=*/true);
522 if (ST.hasFusion()) {
523 // Run the Macro Fusion after RA again since literals are expanded from
524 // pseudos then (v. addPreSched2()).
525 DAG->addMutation(createAArch64MacroFusionDAGMutation());
526 return DAG;
527 }
528
529 return DAG;
530 }
531
532 void addIRPasses() override;
533 bool addPreISel() override;
534 void addCodeGenPrepare() override;
535 bool addInstSelector() override;
536 bool addIRTranslator() override;
537 void addPreLegalizeMachineIR() override;
538 bool addLegalizeMachineIR() override;
539 void addPreRegBankSelect() override;
540 bool addRegBankSelect() override;
541 bool addGlobalInstructionSelect() override;
542 void addMachineSSAOptimization() override;
543 bool addILPOpts() override;
544 void addPreRegAlloc() override;
545 void addPostRegAlloc() override;
546 void addPreSched2() override;
547 void addPreEmitPass() override;
548 void addPostBBSections() override;
549 void addPreEmitPass2() override;
550 bool addRegAssignAndRewriteOptimized() override;
551
552 std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
553};
554
555} // end anonymous namespace
556
558
560 [=](LoopPassManager &LPM, OptimizationLevel Level) {
562 });
563}
564
567 return TargetTransformInfo(AArch64TTIImpl(this, F));
568}
569
571 return new AArch64PassConfig(*this, PM);
572}
573
574std::unique_ptr<CSEConfigBase> AArch64PassConfig::getCSEConfig() const {
575 return getStandardCSEConfigForOpt(TM->getOptLevel());
576}
577
578void AArch64PassConfig::addIRPasses() {
579 // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
580 // ourselves.
582
583 // Expand any SVE vector library calls that we can't code generate directly.
585 TM->getOptLevel() == CodeGenOptLevel::Aggressive)
587
588 // Cmpxchg instructions are often used with a subsequent comparison to
589 // determine whether it succeeded. We can exploit existing control-flow in
590 // ldrex/strex loops to simplify this, but it needs tidying up.
591 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableAtomicTidy)
593 .forwardSwitchCondToPhi(true)
594 .convertSwitchRangeToICmp(true)
595 .convertSwitchToLookupTable(true)
596 .needCanonicalLoops(false)
597 .hoistCommonInsts(true)
598 .sinkCommonInsts(true)));
599
600 // Run LoopDataPrefetch
601 //
602 // Run this before LSR to remove the multiplies involved in computing the
603 // pointer values N iterations ahead.
604 if (TM->getOptLevel() != CodeGenOptLevel::None) {
609 }
610
611 if (EnableGEPOpt) {
612 // Call SeparateConstOffsetFromGEP pass to extract constants within indices
613 // and lower a GEP with multiple indices to either arithmetic operations or
614 // multiple GEPs with single index.
616 // Call EarlyCSE pass to find and remove subexpressions in the lowered
617 // result.
618 addPass(createEarlyCSEPass());
619 // Do loop invariant code motion in case part of the lowered result is
620 // invariant.
621 addPass(createLICMPass());
622 }
623
625
626 if (getOptLevel() == CodeGenOptLevel::Aggressive && EnableSelectOpt)
627 addPass(createSelectOptimizePass());
628
631 /*IsOptNone=*/TM->getOptLevel() == CodeGenOptLevel::None));
632
633 // Match complex arithmetic patterns
634 if (TM->getOptLevel() >= CodeGenOptLevel::Default)
636
637 // Match interleaved memory accesses to ldN/stN intrinsics.
638 if (TM->getOptLevel() != CodeGenOptLevel::None) {
641 }
642
643 // Expand any functions marked with SME attributes which require special
644 // changes for the calling convention or that require the lazy-saving
645 // mechanism specified in the SME ABI.
646 addPass(createSMEABIPass());
647
648 // Add Control Flow Guard checks.
649 if (TM->getTargetTriple().isOSWindows()) {
650 if (TM->getTargetTriple().isWindowsArm64EC())
652 else
653 addPass(createCFGuardCheckPass());
654 }
655
656 if (TM->Options.JMCInstrument)
657 addPass(createJMCInstrumenterPass());
658}
659
660// Pass Pipeline Configuration
661bool AArch64PassConfig::addPreISel() {
662 // Run promote constant before global merge, so that the promoted constants
663 // get a chance to be merged
664 if (TM->getOptLevel() != CodeGenOptLevel::None && EnablePromoteConstant)
666 // FIXME: On AArch64, this depends on the type.
667 // Basically, the addressable offsets are up to 4095 * Ty.getSizeInBytes().
668 // and the offset has to be a multiple of the related size in bytes.
669 if ((TM->getOptLevel() != CodeGenOptLevel::None &&
672 bool OnlyOptimizeForSize =
673 (TM->getOptLevel() < CodeGenOptLevel::Aggressive) &&
675
676 // Merging of extern globals is enabled by default on non-Mach-O as we
677 // expect it to be generally either beneficial or harmless. On Mach-O it
678 // is disabled as we emit the .subsections_via_symbols directive which
679 // means that merging extern globals is not safe.
680 bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();
681
682 // FIXME: extern global merging is only enabled when we optimise for size
683 // because there are some regressions with it also enabled for performance.
684 if (!OnlyOptimizeForSize)
685 MergeExternalByDefault = false;
686
687 addPass(createGlobalMergePass(TM, 4095, OnlyOptimizeForSize,
688 MergeExternalByDefault));
689 }
690
691 return false;
692}
693
694void AArch64PassConfig::addCodeGenPrepare() {
695 if (getOptLevel() != CodeGenOptLevel::None)
698}
699
700bool AArch64PassConfig::addInstSelector() {
701 addPass(createAArch64ISelDag(getAArch64TargetMachine(), getOptLevel()));
702
703 // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
704 // references to _TLS_MODULE_BASE_ as possible.
705 if (TM->getTargetTriple().isOSBinFormatELF() &&
706 getOptLevel() != CodeGenOptLevel::None)
708
709 return false;
710}
711
712bool AArch64PassConfig::addIRTranslator() {
713 addPass(new IRTranslator(getOptLevel()));
714 return false;
715}
716
717void AArch64PassConfig::addPreLegalizeMachineIR() {
718 if (getOptLevel() == CodeGenOptLevel::None) {
720 addPass(new Localizer());
721 } else {
723 addPass(new Localizer());
725 addPass(new LoadStoreOpt());
726 }
727}
728
729bool AArch64PassConfig::addLegalizeMachineIR() {
730 addPass(new Legalizer());
731 return false;
732}
733
734void AArch64PassConfig::addPreRegBankSelect() {
735 bool IsOptNone = getOptLevel() == CodeGenOptLevel::None;
736 if (!IsOptNone) {
737 addPass(createAArch64PostLegalizerCombiner(IsOptNone));
739 addPass(new LoadStoreOpt());
740 }
742}
743
744bool AArch64PassConfig::addRegBankSelect() {
745 addPass(new RegBankSelect());
746 return false;
747}
748
749bool AArch64PassConfig::addGlobalInstructionSelect() {
750 addPass(new InstructionSelect(getOptLevel()));
751 if (getOptLevel() != CodeGenOptLevel::None)
753 return false;
754}
755
756void AArch64PassConfig::addMachineSSAOptimization() {
757 // Run default MachineSSAOptimization first.
759
760 if (TM->getOptLevel() != CodeGenOptLevel::None)
762}
763
764bool AArch64PassConfig::addILPOpts() {
765 if (EnableCondOpt)
767 if (EnableCCMP)
769 if (EnableMCR)
770 addPass(&MachineCombinerID);
772 addPass(createAArch64CondBrTuning());
774 addPass(&EarlyIfConverterID);
778 if (TM->getOptLevel() != CodeGenOptLevel::None)
780 return true;
781}
782
783void AArch64PassConfig::addPreRegAlloc() {
784 // Change dead register definitions to refer to the zero register.
785 if (TM->getOptLevel() != CodeGenOptLevel::None &&
788
789 // Use AdvSIMD scalar instructions whenever profitable.
790 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableAdvSIMDScalar) {
792 // The AdvSIMD pass may produce copies that can be rewritten to
793 // be register coalescer friendly.
794 addPass(&PeepholeOptimizerID);
795 }
796 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableMachinePipeliner)
797 addPass(&MachinePipelinerID);
798}
799
800void AArch64PassConfig::addPostRegAlloc() {
801 // Remove redundant copy instructions.
802 if (TM->getOptLevel() != CodeGenOptLevel::None &&
805
806 if (TM->getOptLevel() != CodeGenOptLevel::None && usingDefaultRegAlloc())
807 // Improve performance for some FP/SIMD code for A57.
809}
810
811void AArch64PassConfig::addPreSched2() {
812 // Lower homogeneous frame instructions
815 // Expand some pseudo instructions to allow proper scheduling.
817 // Use load/store pair instructions when possible.
818 if (TM->getOptLevel() != CodeGenOptLevel::None) {
821 }
822 // Emit KCFI checks for indirect calls.
823 addPass(createKCFIPass());
824
825 // The AArch64SpeculationHardeningPass destroys dominator tree and natural
826 // loop info, which is needed for the FalkorHWPFFixPass and also later on.
827 // Therefore, run the AArch64SpeculationHardeningPass before the
828 // FalkorHWPFFixPass to avoid recomputing dominator tree and natural loop
829 // info.
831
832 if (TM->getOptLevel() != CodeGenOptLevel::None) {
834 addPass(createFalkorHWPFFixPass());
835 }
836}
837
838void AArch64PassConfig::addPreEmitPass() {
839 // Machine Block Placement might have created new opportunities when run
840 // at O3, where the Tail Duplication Threshold is set to 4 instructions.
841 // Run the load/store optimizer once more.
842 if (TM->getOptLevel() >= CodeGenOptLevel::Aggressive && EnableLoadStoreOpt)
844
845 if (TM->getOptLevel() >= CodeGenOptLevel::Aggressive &&
848
849 addPass(createAArch64A53Fix835769());
850
851 if (TM->getTargetTriple().isOSWindows()) {
852 // Identify valid longjmp targets for Windows Control Flow Guard.
853 addPass(createCFGuardLongjmpPass());
854 // Identify valid eh continuation targets for Windows EHCont Guard.
856 }
857
858 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCollectLOH &&
859 TM->getTargetTriple().isOSBinFormatMachO())
861}
862
863void AArch64PassConfig::addPostBBSections() {
868 // Relax conditional branch instructions if they're otherwise out of
869 // range of their destination.
870 if (BranchRelaxation)
871 addPass(&BranchRelaxationPassID);
872
873 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCompressJumpTables)
875}
876
877void AArch64PassConfig::addPreEmitPass2() {
878 // SVE bundles move prefixes with destructive operations. BLR_RVMARKER pseudo
879 // instructions are lowered to bundles as well.
880 addPass(createUnpackMachineBundles(nullptr));
881}
882
883bool AArch64PassConfig::addRegAssignAndRewriteOptimized() {
886}
887
889 BumpPtrAllocator &Allocator, const Function &F,
890 const TargetSubtargetInfo *STI) const {
891 return AArch64FunctionInfo::create<AArch64FunctionInfo>(
892 Allocator, F, static_cast<const AArch64Subtarget *>(STI));
893}
894
897 return new yaml::AArch64FunctionInfo();
898}
899
902 const auto *MFI = MF.getInfo<AArch64FunctionInfo>();
903 return new yaml::AArch64FunctionInfo(*MFI);
904}
905
908 SMDiagnostic &Error, SMRange &SourceRange) const {
909 const auto &YamlMFI = static_cast<const yaml::AArch64FunctionInfo &>(MFI);
910 MachineFunction &MF = PFS.MF;
911 MF.getInfo<AArch64FunctionInfo>()->initializeBaseYamlFields(YamlMFI);
912 return false;
913}
cl::opt< bool > EnableHomogeneousPrologEpilog("homogeneous-prolog-epilog", cl::Hidden, cl::desc("Emit homogeneous prologue and epilogue for the size " "optimization (default = off)"))
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 > 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)
cl::opt< bool > EnableHomogeneousPrologEpilog
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 > EnableDeadRegisterElimination("aarch64-enable-dead-defs", cl::Hidden, cl::desc("Enable the pass that removes dead" " definitons and replaces stores to" " them with stores to the zero" " register"), cl::init(true))
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 > 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))
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target()
static cl::opt< bool > EnableEarlyIfConversion("aarch64-enable-early-ifcvt", cl::Hidden, cl::desc("Run early if-conversion"), cl::init(true))
static Reloc::Model getEffectiveRelocModel(const Triple &TT, std::optional< Reloc::Model > RM)
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 cl::opt< bool > EnableCompressJumpTables("aarch64-enable-compress-jump-tables", cl::Hidden, cl::init(true), cl::desc("Use smallest entry possible for jump tables"))
static cl::opt< bool > EnableCCMP("aarch64-enable-ccmp", cl::desc("Enable the CCMP formation pass"), cl::init(true), cl::Hidden)
This file a TargetTransformInfo::Concept conforming object specific to the AArch64 target machine.
This file contains the simple types necessary to represent the attributes associated with functions a...
basic Basic Alias true
Contains definition of the base CFIFixup pass.
Provides analysis for continuously CSEing during GISel passes.
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:131
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static cl::opt< bool > EnableGlobalMerge("enable-global-merge", cl::Hidden, cl::desc("Enable the global merge pass"), cl::init(true))
This file declares the IRTranslator pass.
static LVOptions Options
Definition: LVOptions.cpp:25
static std::string computeDataLayout()
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
Basic Register Allocator
This file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
endianness Endian
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...
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...
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 ...
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.
TargetTransformInfo getTargetTransformInfo(const Function &F) const override
Get a TargetTransformInfo implementation for the target.
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:1498
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:392
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:203
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
This class represents a range of values.
Definition: ConstantRange.h:47
APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
This pass is responsible for selecting generic machine instructions to target-specific instructions.
This class describes a target machine that is implemented with the LLVM target-independent code gener...
This pass implements the localization mechanism described at the top of this file.
Definition: Localizer.h:43
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
This class provides access to building LLVM's passes.
Definition: PassBuilder.h:106
void registerLateLoopOptimizationsEPCallback(const std::function< void(LoopPassManager &, OptimizationLevel)> &C)
Register a callback for a default optimizer pipeline extension point.
Definition: PassBuilder.h:420
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t< is_detected< HasRunOnLoopT, PassT >::value > addPass(PassT &&Pass)
static 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.
Definition: RegBankSelect.h:91
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:281
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...
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:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
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.
Definition: TargetMachine.h:96
void setMachineOutliner(bool Enable)
void setCFIFixup(bool Enable)
void setSupportsDefaultOutlining(bool Enable)
void setGlobalISelAbort(GlobalISelAbortMode Mode)
std::string TargetFS
Definition: TargetMachine.h:98
std::string TargetCPU
Definition: TargetMachine.h:97
std::unique_ptr< const MCSubtargetInfo > STI
void setGlobalISel(bool Enable)
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:44
@ aarch64_32
Definition: Triple.h:53
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.
Definition: raw_ostream.h:691
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)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
FunctionPass * createAArch64PreLegalizerCombiner()
void initializeLDTLSCleanupPass(PassRegistry &)
FunctionPass * createCFGSimplificationPass(SimplifyCFGOptions Options=SimplifyCFGOptions(), std::function< bool(const Function &)> Ftor=nullptr)
FunctionPass * createSMEABIPass()
Definition: SMEABIPass.cpp:54
void initializeAArch64A57FPLoadBalancingPass(PassRegistry &)
FunctionPass * createAArch64PostSelectOptimize()
void initializeAArch64SpeculationHardeningPass(PassRegistry &)
void initializeAArch64PostLegalizerLoweringPass(PassRegistry &)
FunctionPass * createAArch64RedundantCopyEliminationPass()
FunctionPass * createAArch64StackTaggingPreRAPass()
FunctionPass * createTypePromotionLegacyPass()
Create IR Type Promotion pass.
void initializeAArch64PostLegalizerCombinerPass(PassRegistry &)
FunctionPass * createAArch64MIPeepholeOptPass()
void initializeAArch64AdvSIMDScalarPass(PassRegistry &)
void initializeAArch64PostCoalescerPass(PassRegistry &)
FunctionPass * createSelectOptimizePass()
This pass converts conditional moves to conditional jumps when profitable.
FunctionPass * createAArch64PostCoalescerPass()
void initializeAArch64GlobalsTaggingPass(PassRegistry &)
void initializeAArch64PromoteConstantPass(PassRegistry &)
FunctionPass * createFalkorMarkStridedAccessesPass()
Target & getTheAArch64beTarget()
FunctionPass * createAArch64PointerAuthPass()
FunctionPass * createFalkorHWPFFixPass()
char & PostRASchedulerID
PostRAScheduler - This pass performs post register allocation scheduling.
FunctionPass * createAArch64O0PreLegalizerCombiner()
FunctionPass * createAArch64A57FPLoadBalancing()
FunctionPass * createAArch64CondBrTuning()
std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)
Definition: CSEInfo.cpp:79
void initializeSMEABIPass(PassRegistry &)
char & PeepholeOptimizerID
PeepholeOptimizer - This pass performs peephole optimizations - like extension and comparison elimina...
char & PostMachineSchedulerID
PostMachineScheduler - This pass schedules machine instructions postRA.
Pass * createLICMPass()
Definition: LICM.cpp:381
ScheduleDAGMILive * createGenericSchedLive(MachineSchedContext *C)
Create the standard converging machine scheduler.
Target & getTheAArch64leTarget()
FunctionPass * createAArch64DeadRegisterDefinitions()
FunctionPass * createAArch64PostLegalizerLowering()
ModulePass * createJMCInstrumenterPass()
JMC instrument pass.
char & MachineCombinerID
This pass performs instruction combining using trace metrics to estimate critical-path and resource d...
FunctionPass * createAArch64CompressJumpTablesPass()
Target & getTheAArch64_32Target()
FunctionPass * createAArch64ConditionalCompares()
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.
FunctionPass * createKCFIPass()
Lowers KCFI operand bundles for indirect calls.
Definition: KCFI.cpp:62
std::unique_ptr< ScheduleDAGMutation > createAArch64MacroFusionDAGMutation()
Note that you have to add: DAG.addMutation(createAArch64MacroFusionDAGMutation()); to AArch64PassConf...
FunctionPass * createComplexDeinterleavingPass(const TargetMachine *TM)
This pass implements generation of target-specific intrinsics to support handling of complex number a...
ModulePass * createAArch64GlobalsTaggingPass()
ModulePass * createAArch64Arm64ECCallLoweringPass()
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...
FunctionPass * createLoopDataPrefetchPass()
FunctionPass * createAArch64SIMDInstrOptPass()
Returns an instance of the high cost ASIMD instruction replacement optimization pass.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
FunctionPass * createAArch64StorePairSuppressPass()
FunctionPass * createAArch64ConditionOptimizerPass()
ModulePass * createSVEIntrinsicOptsPass()
void initializeAArch64CompressJumpTablesPass(PassRegistry &)
void initializeAArch64SLSHardeningPass(PassRegistry &)
FunctionPass * createAArch64CollectLOHPass()
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...
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
FunctionPass * createAArch64LoadStoreOptimizationPass()
createAArch64LoadStoreOptimizationPass - returns an instance of the load / store optimization pass.
void initializeAArch64StackTaggingPreRAPass(PassRegistry &)
void initializeAArch64PreLegalizerCombinerPass(PassRegistry &)
Target & getTheARM64_32Target()
FunctionPass * createCFGuardLongjmpPass()
Creates CFGuard longjmp target identification pass.
FunctionPass * createAArch64PostLegalizerCombiner(bool IsOptNone)
void initializeAArch64StorePairSuppressPass(PassRegistry &)
void initializeAArch64LowerHomogeneousPrologEpilogPass(PassRegistry &)
FunctionPass * createSeparateConstOffsetFromGEPPass(bool LowerGEP=false)
char & EarlyIfConverterID
EarlyIfConverter - This pass performs if-conversion on SSA form by inserting cmov instructions.
FunctionPass * createInterleavedAccessPass()
InterleavedAccess Pass - This pass identifies and matches interleaved memory accesses to target speci...
void initializeGlobalISel(PassRegistry &)
Initialize all passes linked into the GlobalISel library.
Definition: GlobalISel.cpp:17
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
char & MachinePipelinerID
This pass performs software pipelining on machine instructions.
void initializeAArch64MIPeepholeOptPass(PassRegistry &)
FunctionPass * createAArch64SLSHardeningPass()
FunctionPass * createAArch64BranchTargetsPass()
Target & getTheARM64Target()
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 &)
FunctionPass * createUnpackMachineBundles(std::function< bool(const MachineFunction &)> Ftor)
void initializeKCFIPass(PassRegistry &)
void initializeAArch64BranchTargetsPass(PassRegistry &)
FunctionPass * createCFGuardCheckPass()
Insert Control FLow Guard checks on indirect function calls.
Definition: CFGuard.cpp:314
void initializeAArch64A53Fix835769Pass(PassRegistry &)
ModulePass * createAArch64LowerHomogeneousPrologEpilogPass()
void initializeAArch64LoadStoreOptPass(PassRegistry &)
void initializeAArch64SIMDInstrOptPass(PassRegistry &)
void initializeAArch64PostSelectOptimizePass(PassRegistry &)
void initializeAArch64CollectLOHPass(PassRegistry &)
Pass * createGlobalMergePass(const TargetMachine *TM, unsigned MaximalOffset, bool OnlyOptimizeForSize=false, bool MergeExternalByDefault=false, bool MergeConstantByDefault=false)
GlobalMerge - This pass merges internal (by default) globals into structs to enable reuse of a base p...
FunctionPass * createAArch64StackTaggingPass(bool IsOptNone)
void initializeAArch64O0PreLegalizerCombinerPass(PassRegistry &)
void initializeAArch64ConditionOptimizerPass(PassRegistry &)
void initializeAArch64ConditionalComparesPass(PassRegistry &)
FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
FunctionPass * createAArch64CleanupLocalDynamicTLSPass()
FunctionPass * createEHContGuardCatchretPass()
Creates EHContGuard catchret target identification pass.
ModulePass * createAArch64PromoteConstantPass()
FunctionPass * createEarlyCSEPass(bool UseMemorySSA=false)
Definition: EarlyCSE.cpp:1932
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 &)
FunctionPass * createInterleavedLoadCombinePass()
InterleavedLoadCombines Pass - This pass identifies interleaved loads and combines them into wide loa...
FunctionPass * createAArch64A53Fix835769()
MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...
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.