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"
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"
54#include <memory>
55#include <optional>
56#include <string>
57
58using namespace llvm;
59
60static cl::opt<bool> EnableCCMP("aarch64-enable-ccmp",
61 cl::desc("Enable the CCMP formation pass"),
62 cl::init(true), cl::Hidden);
63
64static cl::opt<bool>
65 EnableCondBrTuning("aarch64-enable-cond-br-tune",
66 cl::desc("Enable the conditional branch tuning pass"),
67 cl::init(true), cl::Hidden);
68
70 "aarch64-enable-copy-propagation",
71 cl::desc("Enable the copy propagation with AArch64 copy instr"),
72 cl::init(true), cl::Hidden);
73
74static cl::opt<bool> EnableMCR("aarch64-enable-mcr",
75 cl::desc("Enable the machine combiner pass"),
76 cl::init(true), cl::Hidden);
77
78static cl::opt<bool> EnableStPairSuppress("aarch64-enable-stp-suppress",
79 cl::desc("Suppress STP for AArch64"),
80 cl::init(true), cl::Hidden);
81
83 "aarch64-enable-simd-scalar",
84 cl::desc("Enable use of AdvSIMD scalar integer instructions"),
85 cl::init(false), cl::Hidden);
86
87static cl::opt<bool>
88 EnablePromoteConstant("aarch64-enable-promote-const",
89 cl::desc("Enable the promote constant pass"),
90 cl::init(true), cl::Hidden);
91
93 "aarch64-enable-collect-loh",
94 cl::desc("Enable the pass that emits the linker optimization hints (LOH)"),
95 cl::init(true), cl::Hidden);
96
97static cl::opt<bool>
98 EnableDeadRegisterElimination("aarch64-enable-dead-defs", cl::Hidden,
99 cl::desc("Enable the pass that removes dead"
100 " definitions and replaces stores to"
101 " them with stores to the zero"
102 " register"),
103 cl::init(true));
104
106 "aarch64-enable-copyelim",
107 cl::desc("Enable the redundant copy elimination pass"), cl::init(true),
108 cl::Hidden);
109
110static cl::opt<bool> EnableLoadStoreOpt("aarch64-enable-ldst-opt",
111 cl::desc("Enable the load/store pair"
112 " optimization pass"),
113 cl::init(true), cl::Hidden);
114
116 "aarch64-enable-atomic-cfg-tidy", cl::Hidden,
117 cl::desc("Run SimplifyCFG after expanding atomic operations"
118 " to make use of cmpxchg flow-based information"),
119 cl::init(true));
120
121static cl::opt<bool>
122EnableEarlyIfConversion("aarch64-enable-early-ifcvt", cl::Hidden,
123 cl::desc("Run early if-conversion"),
124 cl::init(true));
125
126static cl::opt<bool>
127 EnableCondOpt("aarch64-enable-condopt",
128 cl::desc("Enable the condition optimizer pass"),
129 cl::init(true), cl::Hidden);
130
131static cl::opt<bool>
132 EnableGEPOpt("aarch64-enable-gep-opt", cl::Hidden,
133 cl::desc("Enable optimizations on complex GEPs"),
134 cl::init(false));
135
136static cl::opt<bool>
137 EnableSelectOpt("aarch64-select-opt", cl::Hidden,
138 cl::desc("Enable select to branch optimizations"),
139 cl::init(true));
140
141static cl::opt<bool>
142 BranchRelaxation("aarch64-enable-branch-relax", cl::Hidden, cl::init(true),
143 cl::desc("Relax out of range conditional branches"));
144
146 "aarch64-enable-compress-jump-tables", cl::Hidden, cl::init(true),
147 cl::desc("Use smallest entry possible for jump tables"));
148
149// FIXME: Unify control over GlobalMerge.
151 EnableGlobalMerge("aarch64-enable-global-merge", cl::Hidden,
152 cl::desc("Enable the global merge pass"));
153
154static cl::opt<bool>
155 EnableLoopDataPrefetch("aarch64-enable-loop-data-prefetch", cl::Hidden,
156 cl::desc("Enable the loop data prefetch pass"),
157 cl::init(true));
158
160 "aarch64-enable-global-isel-at-O", cl::Hidden,
161 cl::desc("Enable GlobalISel at or below an opt level (-1 to disable)"),
162 cl::init(0));
163
164static cl::opt<bool>
165 EnableSVEIntrinsicOpts("aarch64-enable-sve-intrinsic-opts", cl::Hidden,
166 cl::desc("Enable SVE intrinsic opts"),
167 cl::init(true));
168
169static cl::opt<bool>
170 EnableSMEPeepholeOpt("enable-aarch64-sme-peephole-opt", cl::init(true),
172 cl::desc("Perform SME peephole optimization"));
173
174static cl::opt<bool> EnableFalkorHWPFFix("aarch64-enable-falkor-hwpf-fix",
175 cl::init(true), cl::Hidden);
176
177static cl::opt<bool>
178 EnableBranchTargets("aarch64-enable-branch-targets", cl::Hidden,
179 cl::desc("Enable the AArch64 branch target pass"),
180 cl::init(true));
181
183 "aarch64-sve-vector-bits-max",
184 cl::desc("Assume SVE vector registers are at most this big, "
185 "with zero meaning no maximum size is assumed."),
186 cl::init(0), cl::Hidden);
187
189 "aarch64-sve-vector-bits-min",
190 cl::desc("Assume SVE vector registers are at least this big, "
191 "with zero meaning no minimum size is assumed."),
192 cl::init(0), cl::Hidden);
193
195 "force-streaming",
196 cl::desc("Force the use of streaming code for all functions"),
197 cl::init(false), cl::Hidden);
198
200 "force-streaming-compatible",
201 cl::desc("Force the use of streaming-compatible code for all functions"),
202 cl::init(false), cl::Hidden);
203
205
207 "aarch64-enable-gisel-ldst-prelegal",
208 cl::desc("Enable GlobalISel's pre-legalizer load/store optimization pass"),
209 cl::init(true), cl::Hidden);
210
212 "aarch64-enable-gisel-ldst-postlegal",
213 cl::desc("Enable GlobalISel's post-legalizer load/store optimization pass"),
214 cl::init(false), cl::Hidden);
215
216static cl::opt<bool>
217 EnableSinkFold("aarch64-enable-sink-fold",
218 cl::desc("Enable sinking and folding of instruction copies"),
219 cl::init(true), cl::Hidden);
220
221static cl::opt<bool>
222 EnableMachinePipeliner("aarch64-enable-pipeliner",
223 cl::desc("Enable Machine Pipeliner for AArch64"),
224 cl::init(false), cl::Hidden);
225
227 // Register the target.
271}
272
274
275//===----------------------------------------------------------------------===//
276// AArch64 Lowering public interface.
277//===----------------------------------------------------------------------===//
278static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
279 if (TT.isOSBinFormatMachO())
280 return std::make_unique<AArch64_MachoTargetObjectFile>();
281 if (TT.isOSBinFormatCOFF())
282 return std::make_unique<AArch64_COFFTargetObjectFile>();
283
284 return std::make_unique<AArch64_ELFTargetObjectFile>();
285}
286
287// Helper function to build a DataLayout string
288static std::string computeDataLayout(const Triple &TT,
290 bool LittleEndian) {
291 if (TT.isOSBinFormatMachO()) {
292 if (TT.getArch() == Triple::aarch64_32)
293 return "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
294 "n32:64-S128-Fn32";
295 return "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-"
296 "Fn32";
297 }
298 if (TT.isOSBinFormatCOFF())
299 return "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:"
300 "128-n32:64-S128-Fn32";
301 std::string Endian = LittleEndian ? "e" : "E";
302 std::string Ptr32 = TT.getEnvironment() == Triple::GNUILP32 ? "-p:32:32" : "";
303 return Endian + "-m:e" + Ptr32 +
304 "-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-"
305 "n32:64-S128-Fn32";
306}
307
309 if (CPU.empty() && TT.isArm64e())
310 return "apple-a12";
311 return CPU;
312}
313
315 std::optional<Reloc::Model> RM) {
316 // AArch64 Darwin and Windows are always PIC.
317 if (TT.isOSDarwin() || TT.isOSWindows())
318 return Reloc::PIC_;
319 // On ELF platforms the default static relocation model has a smart enough
320 // linker to cope with referencing external symbols defined in a shared
321 // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
322 if (!RM || *RM == Reloc::DynamicNoPIC)
323 return Reloc::Static;
324 return *RM;
325}
326
327static CodeModel::Model
329 std::optional<CodeModel::Model> CM, bool JIT) {
330 if (CM) {
331 if (*CM != CodeModel::Small && *CM != CodeModel::Tiny &&
332 *CM != CodeModel::Large) {
334 "Only small, tiny and large code models are allowed on AArch64");
335 } else if (*CM == CodeModel::Tiny && !TT.isOSBinFormatELF())
336 report_fatal_error("tiny code model is only supported on ELF");
337 return *CM;
338 }
339 // The default MCJIT memory managers make no guarantees about where they can
340 // find an executable page; JITed code needs to be able to refer to globals
341 // no matter how far away they are.
342 // We should set the CodeModel::Small for Windows ARM64 in JIT mode,
343 // since with large code model LLVM generating 4 MOV instructions, and
344 // Windows doesn't support relocating these long branch (4 MOVs).
345 if (JIT && !TT.isOSWindows())
346 return CodeModel::Large;
347 return CodeModel::Small;
348}
349
350/// Create an AArch64 architecture model.
351///
353 StringRef CPU, StringRef FS,
354 const TargetOptions &Options,
355 std::optional<Reloc::Model> RM,
356 std::optional<CodeModel::Model> CM,
357 CodeGenOptLevel OL, bool JIT,
358 bool LittleEndian)
360 T, computeDataLayout(TT, Options.MCOptions, LittleEndian), TT,
361 computeDefaultCPU(TT, CPU), FS, Options,
363 getEffectiveAArch64CodeModel(TT, CM, JIT), OL),
364 TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian) {
365 initAsmInfo();
366
367 if (TT.isOSBinFormatMachO()) {
368 this->Options.TrapUnreachable = true;
369 this->Options.NoTrapAfterNoreturn = true;
370 }
371
372 if (getMCAsmInfo()->usesWindowsCFI()) {
373 // Unwinding can get confused if the last instruction in an
374 // exception-handling region (function, funclet, try block, etc.)
375 // is a call.
376 //
377 // FIXME: We could elide the trap if the next instruction would be in
378 // the same region anyway.
379 this->Options.TrapUnreachable = true;
380 }
381
382 if (this->Options.TLSSize == 0) // default
383 this->Options.TLSSize = 24;
384 if ((getCodeModel() == CodeModel::Small ||
386 this->Options.TLSSize > 32)
387 // for the small (and kernel) code model, the maximum TLS size is 4GiB
388 this->Options.TLSSize = 32;
389 else if (getCodeModel() == CodeModel::Tiny && this->Options.TLSSize > 24)
390 // for the tiny code model, the maximum TLS size is 1MiB (< 16MiB)
391 this->Options.TLSSize = 24;
392
393 // Enable GlobalISel at or below EnableGlobalISelAt0, unless this is
394 // MachO/CodeModel::Large, which GlobalISel does not support.
395 if (static_cast<int>(getOptLevel()) <= EnableGlobalISelAtO &&
396 TT.getArch() != Triple::aarch64_32 &&
397 TT.getEnvironment() != Triple::GNUILP32 &&
398 !(getCodeModel() == CodeModel::Large && TT.isOSBinFormatMachO())) {
399 setGlobalISel(true);
401 }
402
403 // AArch64 supports the MachineOutliner.
404 setMachineOutliner(true);
405
406 // AArch64 supports default outlining behaviour.
408
409 // AArch64 supports the debug entry values.
411
412 // AArch64 supports fixing up the DWARF unwind information.
413 if (!getMCAsmInfo()->usesWindowsCFI())
414 setCFIFixup(true);
415}
416
418
419const AArch64Subtarget *
421 Attribute CPUAttr = F.getFnAttribute("target-cpu");
422 Attribute TuneAttr = F.getFnAttribute("tune-cpu");
423 Attribute FSAttr = F.getFnAttribute("target-features");
424
425 StringRef CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString() : TargetCPU;
426 StringRef TuneCPU = TuneAttr.isValid() ? TuneAttr.getValueAsString() : CPU;
427 StringRef FS = FSAttr.isValid() ? FSAttr.getValueAsString() : TargetFS;
428 bool HasMinSize = F.hasMinSize();
429
430 bool IsStreaming = ForceStreaming ||
431 F.hasFnAttribute("aarch64_pstate_sm_enabled") ||
432 F.hasFnAttribute("aarch64_pstate_sm_body");
433 bool IsStreamingCompatible = ForceStreamingCompatible ||
434 F.hasFnAttribute("aarch64_pstate_sm_compatible");
435
436 unsigned MinSVEVectorSize = 0;
437 unsigned MaxSVEVectorSize = 0;
438 if (F.hasFnAttribute(Attribute::VScaleRange)) {
439 ConstantRange CR = getVScaleRange(&F, 64);
440 MinSVEVectorSize = CR.getUnsignedMin().getZExtValue() * 128;
441 MaxSVEVectorSize = CR.getUnsignedMax().getZExtValue() * 128;
442 } else {
443 MinSVEVectorSize = SVEVectorBitsMinOpt;
444 MaxSVEVectorSize = SVEVectorBitsMaxOpt;
445 }
446
447 assert(MinSVEVectorSize % 128 == 0 &&
448 "SVE requires vector length in multiples of 128!");
449 assert(MaxSVEVectorSize % 128 == 0 &&
450 "SVE requires vector length in multiples of 128!");
451 assert((MaxSVEVectorSize >= MinSVEVectorSize || MaxSVEVectorSize == 0) &&
452 "Minimum SVE vector size should not be larger than its maximum!");
453
454 // Sanitize user input in case of no asserts
455 if (MaxSVEVectorSize != 0) {
456 MinSVEVectorSize = std::min(MinSVEVectorSize, MaxSVEVectorSize);
457 MaxSVEVectorSize = std::max(MinSVEVectorSize, MaxSVEVectorSize);
458 }
459
461 raw_svector_ostream(Key) << "SVEMin" << MinSVEVectorSize << "SVEMax"
462 << MaxSVEVectorSize << "IsStreaming=" << IsStreaming
463 << "IsStreamingCompatible=" << IsStreamingCompatible
464 << CPU << TuneCPU << FS
465 << "HasMinSize=" << HasMinSize;
466
467 auto &I = SubtargetMap[Key];
468 if (!I) {
469 // This needs to be done before we create a new subtarget since any
470 // creation will depend on the TM and the code generation flags on the
471 // function that reside in TargetOptions.
473 I = std::make_unique<AArch64Subtarget>(
474 TargetTriple, CPU, TuneCPU, FS, *this, isLittle, MinSVEVectorSize,
475 MaxSVEVectorSize, IsStreaming, IsStreamingCompatible, HasMinSize);
476 }
477
478 assert((!IsStreaming || I->hasSME()) && "Expected SME to be available");
479
480 return I.get();
481}
482
483void AArch64leTargetMachine::anchor() { }
484
486 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
487 const TargetOptions &Options, std::optional<Reloc::Model> RM,
488 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
489 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
490
491void AArch64beTargetMachine::anchor() { }
492
494 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
495 const TargetOptions &Options, std::optional<Reloc::Model> RM,
496 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
497 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
498
499namespace {
500
501/// AArch64 Code Generator Pass Configuration Options.
502class AArch64PassConfig : public TargetPassConfig {
503public:
504 AArch64PassConfig(AArch64TargetMachine &TM, PassManagerBase &PM)
505 : TargetPassConfig(TM, PM) {
506 if (TM.getOptLevel() != CodeGenOptLevel::None)
507 substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
508 setEnableSinkAndFold(EnableSinkFold);
509 }
510
511 AArch64TargetMachine &getAArch64TargetMachine() const {
512 return getTM<AArch64TargetMachine>();
513 }
514
516 createMachineScheduler(MachineSchedContext *C) const override {
517 const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
519 DAG->addMutation(createLoadClusterDAGMutation(DAG->TII, DAG->TRI));
520 DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
521 if (ST.hasFusion())
522 DAG->addMutation(createAArch64MacroFusionDAGMutation());
523 return DAG;
524 }
525
527 createPostMachineScheduler(MachineSchedContext *C) const override {
528 const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
529 ScheduleDAGMI *DAG =
530 new ScheduleDAGMI(C, std::make_unique<AArch64PostRASchedStrategy>(C),
531 /* RemoveKillFlags=*/true);
532 if (ST.hasFusion()) {
533 // Run the Macro Fusion after RA again since literals are expanded from
534 // pseudos then (v. addPreSched2()).
535 DAG->addMutation(createAArch64MacroFusionDAGMutation());
536 return DAG;
537 }
538
539 return DAG;
540 }
541
542 void addIRPasses() override;
543 bool addPreISel() override;
544 void addCodeGenPrepare() override;
545 bool addInstSelector() override;
546 bool addIRTranslator() override;
547 void addPreLegalizeMachineIR() override;
548 bool addLegalizeMachineIR() override;
549 void addPreRegBankSelect() override;
550 bool addRegBankSelect() override;
551 bool addGlobalInstructionSelect() override;
552 void addMachineSSAOptimization() override;
553 bool addILPOpts() override;
554 void addPreRegAlloc() override;
555 void addPostRegAlloc() override;
556 void addPreSched2() override;
557 void addPreEmitPass() override;
558 void addPostBBSections() override;
559 void addPreEmitPass2() override;
560 bool addRegAssignAndRewriteOptimized() override;
561
562 std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
563};
564
565} // end anonymous namespace
566
568
570 [=](LoopPassManager &LPM, OptimizationLevel Level) {
572 });
573 if (getTargetTriple().isOSWindows())
577 });
578}
579
582 return TargetTransformInfo(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
657 // Expand any functions marked with SME attributes which require special
658 // changes for the calling convention or that require the lazy-saving
659 // mechanism specified in the SME ABI.
660 addPass(createSMEABIPass());
661
662 // Add Control Flow Guard checks.
663 if (TM->getTargetTriple().isOSWindows()) {
664 if (TM->getTargetTriple().isWindowsArm64EC())
666 else
667 addPass(createCFGuardCheckPass());
668 }
669
670 if (TM->Options.JMCInstrument)
671 addPass(createJMCInstrumenterPass());
672}
673
674// Pass Pipeline Configuration
675bool AArch64PassConfig::addPreISel() {
676 // Run promote constant before global merge, so that the promoted constants
677 // get a chance to be merged
678 if (TM->getOptLevel() != CodeGenOptLevel::None && EnablePromoteConstant)
680 // FIXME: On AArch64, this depends on the type.
681 // Basically, the addressable offsets are up to 4095 * Ty.getSizeInBytes().
682 // and the offset has to be a multiple of the related size in bytes.
683 if ((TM->getOptLevel() != CodeGenOptLevel::None &&
686 bool OnlyOptimizeForSize =
687 (TM->getOptLevel() < CodeGenOptLevel::Aggressive) &&
689
690 // Merging of extern globals is enabled by default on non-Mach-O as we
691 // expect it to be generally either beneficial or harmless. On Mach-O it
692 // is disabled as we emit the .subsections_via_symbols directive which
693 // means that merging extern globals is not safe.
694 bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();
695
696 // FIXME: extern global merging is only enabled when we optimise for size
697 // because there are some regressions with it also enabled for performance.
698 if (!OnlyOptimizeForSize)
699 MergeExternalByDefault = false;
700
701 addPass(createGlobalMergePass(TM, 4095, OnlyOptimizeForSize,
702 MergeExternalByDefault));
703 }
704
705 return false;
706}
707
708void AArch64PassConfig::addCodeGenPrepare() {
709 if (getOptLevel() != CodeGenOptLevel::None)
712}
713
714bool AArch64PassConfig::addInstSelector() {
715 addPass(createAArch64ISelDag(getAArch64TargetMachine(), getOptLevel()));
716
717 // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
718 // references to _TLS_MODULE_BASE_ as possible.
719 if (TM->getTargetTriple().isOSBinFormatELF() &&
720 getOptLevel() != CodeGenOptLevel::None)
722
723 return false;
724}
725
726bool AArch64PassConfig::addIRTranslator() {
727 addPass(new IRTranslator(getOptLevel()));
728 return false;
729}
730
731void AArch64PassConfig::addPreLegalizeMachineIR() {
732 if (getOptLevel() == CodeGenOptLevel::None) {
734 addPass(new Localizer());
735 } else {
737 addPass(new Localizer());
739 addPass(new LoadStoreOpt());
740 }
741}
742
743bool AArch64PassConfig::addLegalizeMachineIR() {
744 addPass(new Legalizer());
745 return false;
746}
747
748void AArch64PassConfig::addPreRegBankSelect() {
749 bool IsOptNone = getOptLevel() == CodeGenOptLevel::None;
750 if (!IsOptNone) {
751 addPass(createAArch64PostLegalizerCombiner(IsOptNone));
753 addPass(new LoadStoreOpt());
754 }
756}
757
758bool AArch64PassConfig::addRegBankSelect() {
759 addPass(new RegBankSelect());
760 return false;
761}
762
763bool AArch64PassConfig::addGlobalInstructionSelect() {
764 addPass(new InstructionSelect(getOptLevel()));
765 if (getOptLevel() != CodeGenOptLevel::None)
767 return false;
768}
769
770void AArch64PassConfig::addMachineSSAOptimization() {
771 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableSMEPeepholeOpt)
772 addPass(createSMEPeepholeOptPass());
773
774 // Run default MachineSSAOptimization first.
776
777 if (TM->getOptLevel() != CodeGenOptLevel::None)
779}
780
781bool AArch64PassConfig::addILPOpts() {
782 if (EnableCondOpt)
784 if (EnableCCMP)
786 if (EnableMCR)
787 addPass(&MachineCombinerID);
789 addPass(createAArch64CondBrTuning());
791 addPass(&EarlyIfConverterLegacyID);
795 if (TM->getOptLevel() != CodeGenOptLevel::None)
797 return true;
798}
799
800void AArch64PassConfig::addPreRegAlloc() {
801 // Change dead register definitions to refer to the zero register.
802 if (TM->getOptLevel() != CodeGenOptLevel::None &&
805
806 // Use AdvSIMD scalar instructions whenever profitable.
807 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableAdvSIMDScalar) {
809 // The AdvSIMD pass may produce copies that can be rewritten to
810 // be register coalescer friendly.
812 }
813 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableMachinePipeliner)
814 addPass(&MachinePipelinerID);
815}
816
817void AArch64PassConfig::addPostRegAlloc() {
818 // Remove redundant copy instructions.
819 if (TM->getOptLevel() != CodeGenOptLevel::None &&
822
823 if (TM->getOptLevel() != CodeGenOptLevel::None && usingDefaultRegAlloc())
824 // Improve performance for some FP/SIMD code for A57.
826}
827
828void AArch64PassConfig::addPreSched2() {
829 // Lower homogeneous frame instructions
832 // Expand some pseudo instructions to allow proper scheduling.
834 // Use load/store pair instructions when possible.
835 if (TM->getOptLevel() != CodeGenOptLevel::None) {
838 }
839 // Emit KCFI checks for indirect calls.
840 addPass(createKCFIPass());
841
842 // The AArch64SpeculationHardeningPass destroys dominator tree and natural
843 // loop info, which is needed for the FalkorHWPFFixPass and also later on.
844 // Therefore, run the AArch64SpeculationHardeningPass before the
845 // FalkorHWPFFixPass to avoid recomputing dominator tree and natural loop
846 // info.
848
849 if (TM->getOptLevel() != CodeGenOptLevel::None) {
851 addPass(createFalkorHWPFFixPass());
852 }
853}
854
855void AArch64PassConfig::addPreEmitPass() {
856 // Machine Block Placement might have created new opportunities when run
857 // at O3, where the Tail Duplication Threshold is set to 4 instructions.
858 // Run the load/store optimizer once more.
859 if (TM->getOptLevel() >= CodeGenOptLevel::Aggressive && EnableLoadStoreOpt)
861
862 if (TM->getOptLevel() >= CodeGenOptLevel::Aggressive &&
865
866 addPass(createAArch64A53Fix835769());
867
868 if (TM->getTargetTriple().isOSWindows()) {
869 // Identify valid longjmp targets for Windows Control Flow Guard.
870 addPass(createCFGuardLongjmpPass());
871 // Identify valid eh continuation targets for Windows EHCont Guard.
873 }
874
875 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCollectLOH &&
876 TM->getTargetTriple().isOSBinFormatMachO())
878}
879
880void AArch64PassConfig::addPostBBSections() {
885 // Relax conditional branch instructions if they're otherwise out of
886 // range of their destination.
887 if (BranchRelaxation)
888 addPass(&BranchRelaxationPassID);
889
890 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCompressJumpTables)
892}
893
894void AArch64PassConfig::addPreEmitPass2() {
895 // SVE bundles move prefixes with destructive operations. BLR_RVMARKER pseudo
896 // instructions are lowered to bundles as well.
897 addPass(createUnpackMachineBundles(nullptr));
898}
899
900bool AArch64PassConfig::addRegAssignAndRewriteOptimized() {
903}
904
906 BumpPtrAllocator &Allocator, const Function &F,
907 const TargetSubtargetInfo *STI) const {
908 return AArch64FunctionInfo::create<AArch64FunctionInfo>(
909 Allocator, F, static_cast<const AArch64Subtarget *>(STI));
910}
911
914 return new yaml::AArch64FunctionInfo();
915}
916
919 const auto *MFI = MF.getInfo<AArch64FunctionInfo>();
920 return new yaml::AArch64FunctionInfo(*MFI);
921}
922
925 SMDiagnostic &Error, SMRange &SourceRange) const {
926 const auto &YamlMFI = static_cast<const yaml::AArch64FunctionInfo &>(MFI);
927 MachineFunction &MF = PFS.MF;
928 MF.getInfo<AArch64FunctionInfo>()->initializeBaseYamlFields(YamlMFI);
929 return false;
930}
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 > 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)
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 > 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))
static cl::opt< bool > EnableSMEPeepholeOpt("enable-aarch64-sme-peephole-opt", cl::init(true), cl::Hidden, cl::desc("Perform SME peephole optimization"))
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 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
Provides analysis for continuously CSEing during GISel passes.
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:128
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())
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 ...
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.
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:1520
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:208
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
implements a set of functionality in the TargetMachine class for targets that make use of the indepen...
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 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...
This class provides access to building LLVM's passes.
Definition: PassBuilder.h:105
void registerPipelineEarlySimplificationEPCallback(const std::function< void(ModulePassManager &, OptimizationLevel, ThinOrFullLTOPhase)> &C)
Register a callback for a default optimizer pipeline extension point.
Definition: PassBuilder.h:482
void registerLateLoopOptimizationsEPCallback(const std::function< void(LoopPassManager &, OptimizationLevel)> &C)
Register a callback for a default optimizer pipeline extension point.
Definition: PassBuilder.h:421
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t< is_detected< HasRunOnLoopT, PassT >::value > addPass(PassT &&Pass)
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Definition: PassManager.h:195
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:51
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
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
const Triple & getTargetTriple() const
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:50
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.
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()
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 & PostMachineSchedulerID
PostMachineScheduler - This pass schedules machine instructions postRA.
char & PeepholeOptimizerLegacyID
PeepholeOptimizer - This pass performs peephole optimizations - like extension and comparison elimina...
Pass * createLICMPass()
Definition: LICM.cpp:381
ScheduleDAGMILive * createGenericSchedLive(MachineSchedContext *C)
Create the standard converging machine scheduler.
Target & getTheAArch64leTarget()
FunctionPass * createAArch64DeadRegisterDefinitions()
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:76
ModulePass * createJMCInstrumenterPass()
JMC instrument pass.
char & MachineCombinerID
This pass performs instruction combining using trace metrics to estimate critical-path and resource d...
static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM)
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:61
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 * 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 initializeSMEPeepholeOptPass(PassRegistry &)
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)
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 &)
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:1944
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.