LLVM 18.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"
53#include <memory>
54#include <optional>
55#include <string>
56
57using namespace llvm;
58
59static cl::opt<bool> EnableCCMP("aarch64-enable-ccmp",
60 cl::desc("Enable the CCMP formation pass"),
61 cl::init(true), cl::Hidden);
62
63static cl::opt<bool>
64 EnableCondBrTuning("aarch64-enable-cond-br-tune",
65 cl::desc("Enable the conditional branch tuning pass"),
66 cl::init(true), cl::Hidden);
67
69 "aarch64-enable-copy-propagation",
70 cl::desc("Enable the copy propagation with AArch64 copy instr"),
71 cl::init(true), cl::Hidden);
72
73static cl::opt<bool> EnableMCR("aarch64-enable-mcr",
74 cl::desc("Enable the machine combiner pass"),
75 cl::init(true), cl::Hidden);
76
77static cl::opt<bool> EnableStPairSuppress("aarch64-enable-stp-suppress",
78 cl::desc("Suppress STP for AArch64"),
79 cl::init(true), cl::Hidden);
80
82 "aarch64-enable-simd-scalar",
83 cl::desc("Enable use of AdvSIMD scalar integer instructions"),
84 cl::init(false), cl::Hidden);
85
86static cl::opt<bool>
87 EnablePromoteConstant("aarch64-enable-promote-const",
88 cl::desc("Enable the promote constant pass"),
89 cl::init(true), cl::Hidden);
90
92 "aarch64-enable-collect-loh",
93 cl::desc("Enable the pass that emits the linker optimization hints (LOH)"),
94 cl::init(true), cl::Hidden);
95
96static cl::opt<bool>
97 EnableDeadRegisterElimination("aarch64-enable-dead-defs", cl::Hidden,
98 cl::desc("Enable the pass that removes dead"
99 " definitons and replaces stores to"
100 " them with stores to the zero"
101 " register"),
102 cl::init(true));
103
105 "aarch64-enable-copyelim",
106 cl::desc("Enable the redundant copy elimination pass"), cl::init(true),
107 cl::Hidden);
108
109static cl::opt<bool> EnableLoadStoreOpt("aarch64-enable-ldst-opt",
110 cl::desc("Enable the load/store pair"
111 " optimization pass"),
112 cl::init(true), cl::Hidden);
113
115 "aarch64-enable-atomic-cfg-tidy", cl::Hidden,
116 cl::desc("Run SimplifyCFG after expanding atomic operations"
117 " to make use of cmpxchg flow-based information"),
118 cl::init(true));
119
120static cl::opt<bool>
121EnableEarlyIfConversion("aarch64-enable-early-ifcvt", cl::Hidden,
122 cl::desc("Run early if-conversion"),
123 cl::init(true));
124
125static cl::opt<bool>
126 EnableCondOpt("aarch64-enable-condopt",
127 cl::desc("Enable the condition optimizer pass"),
128 cl::init(true), cl::Hidden);
129
130static cl::opt<bool>
131 EnableGEPOpt("aarch64-enable-gep-opt", cl::Hidden,
132 cl::desc("Enable optimizations on complex GEPs"),
133 cl::init(false));
134
135static cl::opt<bool>
136 EnableSelectOpt("aarch64-select-opt", cl::Hidden,
137 cl::desc("Enable select to branch optimizations"),
138 cl::init(true));
139
140static cl::opt<bool>
141 BranchRelaxation("aarch64-enable-branch-relax", cl::Hidden, cl::init(true),
142 cl::desc("Relax out of range conditional branches"));
143
145 "aarch64-enable-compress-jump-tables", cl::Hidden, cl::init(true),
146 cl::desc("Use smallest entry possible for jump tables"));
147
148// FIXME: Unify control over GlobalMerge.
150 EnableGlobalMerge("aarch64-enable-global-merge", cl::Hidden,
151 cl::desc("Enable the global merge pass"));
152
153static cl::opt<bool>
154 EnableLoopDataPrefetch("aarch64-enable-loop-data-prefetch", cl::Hidden,
155 cl::desc("Enable the loop data prefetch pass"),
156 cl::init(true));
157
159 "aarch64-enable-global-isel-at-O", cl::Hidden,
160 cl::desc("Enable GlobalISel at or below an opt level (-1 to disable)"),
161 cl::init(0));
162
163static cl::opt<bool>
164 EnableSVEIntrinsicOpts("aarch64-enable-sve-intrinsic-opts", cl::Hidden,
165 cl::desc("Enable SVE intrinsic opts"),
166 cl::init(true));
167
168static cl::opt<bool> EnableFalkorHWPFFix("aarch64-enable-falkor-hwpf-fix",
169 cl::init(true), cl::Hidden);
170
171static cl::opt<bool>
172 EnableBranchTargets("aarch64-enable-branch-targets", cl::Hidden,
173 cl::desc("Enable the AArch64 branch target pass"),
174 cl::init(true));
175
177 "aarch64-sve-vector-bits-max",
178 cl::desc("Assume SVE vector registers are at most this big, "
179 "with zero meaning no maximum size is assumed."),
180 cl::init(0), cl::Hidden);
181
183 "aarch64-sve-vector-bits-min",
184 cl::desc("Assume SVE vector registers are at least this big, "
185 "with zero meaning no minimum size is assumed."),
186 cl::init(0), cl::Hidden);
187
189
191 "aarch64-enable-gisel-ldst-prelegal",
192 cl::desc("Enable GlobalISel's pre-legalizer load/store optimization pass"),
193 cl::init(true), cl::Hidden);
194
196 "aarch64-enable-gisel-ldst-postlegal",
197 cl::desc("Enable GlobalISel's post-legalizer load/store optimization pass"),
198 cl::init(false), cl::Hidden);
199
200static cl::opt<bool>
201 EnableSinkFold("aarch64-enable-sink-fold",
202 cl::desc("Enable sinking and folding of instruction copies"),
203 cl::init(false), cl::Hidden);
204
206 // Register the target.
249}
250
251//===----------------------------------------------------------------------===//
252// AArch64 Lowering public interface.
253//===----------------------------------------------------------------------===//
254static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
255 if (TT.isOSBinFormatMachO())
256 return std::make_unique<AArch64_MachoTargetObjectFile>();
257 if (TT.isOSBinFormatCOFF())
258 return std::make_unique<AArch64_COFFTargetObjectFile>();
259
260 return std::make_unique<AArch64_ELFTargetObjectFile>();
261}
262
263// Helper function to build a DataLayout string
264static std::string computeDataLayout(const Triple &TT,
266 bool LittleEndian) {
267 if (TT.isOSBinFormatMachO()) {
268 if (TT.getArch() == Triple::aarch64_32)
269 return "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128";
270 return "e-m:o-i64:64-i128:128-n32:64-S128";
271 }
272 if (TT.isOSBinFormatCOFF())
273 return "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128";
274 std::string Endian = LittleEndian ? "e" : "E";
275 std::string Ptr32 = TT.getEnvironment() == Triple::GNUILP32 ? "-p:32:32" : "";
276 return Endian + "-m:e" + Ptr32 +
277 "-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128";
278}
279
281 if (CPU.empty() && TT.isArm64e())
282 return "apple-a12";
283 return CPU;
284}
285
287 std::optional<Reloc::Model> RM) {
288 // AArch64 Darwin and Windows are always PIC.
289 if (TT.isOSDarwin() || TT.isOSWindows())
290 return Reloc::PIC_;
291 // On ELF platforms the default static relocation model has a smart enough
292 // linker to cope with referencing external symbols defined in a shared
293 // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
294 if (!RM || *RM == Reloc::DynamicNoPIC)
295 return Reloc::Static;
296 return *RM;
297}
298
299static CodeModel::Model
301 std::optional<CodeModel::Model> CM, bool JIT) {
302 if (CM) {
303 if (*CM != CodeModel::Small && *CM != CodeModel::Tiny &&
304 *CM != CodeModel::Large) {
306 "Only small, tiny and large code models are allowed on AArch64");
307 } else if (*CM == CodeModel::Tiny && !TT.isOSBinFormatELF())
308 report_fatal_error("tiny code model is only supported on ELF");
309 return *CM;
310 }
311 // The default MCJIT memory managers make no guarantees about where they can
312 // find an executable page; JITed code needs to be able to refer to globals
313 // no matter how far away they are.
314 // We should set the CodeModel::Small for Windows ARM64 in JIT mode,
315 // since with large code model LLVM generating 4 MOV instructions, and
316 // Windows doesn't support relocating these long branch (4 MOVs).
317 if (JIT && !TT.isOSWindows())
318 return CodeModel::Large;
319 return CodeModel::Small;
320}
321
322/// Create an AArch64 architecture model.
323///
325 StringRef CPU, StringRef FS,
326 const TargetOptions &Options,
327 std::optional<Reloc::Model> RM,
328 std::optional<CodeModel::Model> CM,
329 CodeGenOptLevel OL, bool JIT,
330 bool LittleEndian)
332 computeDataLayout(TT, Options.MCOptions, LittleEndian),
333 TT, computeDefaultCPU(TT, CPU), FS, Options,
335 getEffectiveAArch64CodeModel(TT, CM, JIT), OL),
336 TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian) {
337 initAsmInfo();
338
339 if (TT.isOSBinFormatMachO()) {
340 this->Options.TrapUnreachable = true;
341 this->Options.NoTrapAfterNoreturn = true;
342 }
343
344 if (getMCAsmInfo()->usesWindowsCFI()) {
345 // Unwinding can get confused if the last instruction in an
346 // exception-handling region (function, funclet, try block, etc.)
347 // is a call.
348 //
349 // FIXME: We could elide the trap if the next instruction would be in
350 // the same region anyway.
351 this->Options.TrapUnreachable = true;
352 }
353
354 if (this->Options.TLSSize == 0) // default
355 this->Options.TLSSize = 24;
356 if ((getCodeModel() == CodeModel::Small ||
358 this->Options.TLSSize > 32)
359 // for the small (and kernel) code model, the maximum TLS size is 4GiB
360 this->Options.TLSSize = 32;
361 else if (getCodeModel() == CodeModel::Tiny && this->Options.TLSSize > 24)
362 // for the tiny code model, the maximum TLS size is 1MiB (< 16MiB)
363 this->Options.TLSSize = 24;
364
365 // Enable GlobalISel at or below EnableGlobalISelAt0, unless this is
366 // MachO/CodeModel::Large, which GlobalISel does not support.
367 if (static_cast<int>(getOptLevel()) <= EnableGlobalISelAtO &&
368 TT.getArch() != Triple::aarch64_32 &&
369 TT.getEnvironment() != Triple::GNUILP32 &&
370 !(getCodeModel() == CodeModel::Large && TT.isOSBinFormatMachO())) {
371 setGlobalISel(true);
373 }
374
375 // AArch64 supports the MachineOutliner.
376 setMachineOutliner(true);
377
378 // AArch64 supports default outlining behaviour.
380
381 // AArch64 supports the debug entry values.
383
384 // AArch64 supports fixing up the DWARF unwind information.
385 if (!getMCAsmInfo()->usesWindowsCFI())
386 setCFIFixup(true);
387}
388
390
391const AArch64Subtarget *
393 Attribute CPUAttr = F.getFnAttribute("target-cpu");
394 Attribute TuneAttr = F.getFnAttribute("tune-cpu");
395 Attribute FSAttr = F.getFnAttribute("target-features");
396
397 StringRef CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString() : TargetCPU;
398 StringRef TuneCPU = TuneAttr.isValid() ? TuneAttr.getValueAsString() : CPU;
399 StringRef FS = FSAttr.isValid() ? FSAttr.getValueAsString() : TargetFS;
400
401 bool StreamingSVEMode = F.hasFnAttribute("aarch64_pstate_sm_enabled") ||
402 F.hasFnAttribute("aarch64_pstate_sm_body");
403 bool StreamingCompatibleSVEMode =
404 F.hasFnAttribute("aarch64_pstate_sm_compatible");
405
406 unsigned MinSVEVectorSize = 0;
407 unsigned MaxSVEVectorSize = 0;
408 if (F.hasFnAttribute(Attribute::VScaleRange)) {
409 ConstantRange CR = getVScaleRange(&F, 64);
410 MinSVEVectorSize = CR.getUnsignedMin().getZExtValue() * 128;
411 MaxSVEVectorSize = CR.getUnsignedMax().getZExtValue() * 128;
412 } else {
413 MinSVEVectorSize = SVEVectorBitsMinOpt;
414 MaxSVEVectorSize = SVEVectorBitsMaxOpt;
415 }
416
417 assert(MinSVEVectorSize % 128 == 0 &&
418 "SVE requires vector length in multiples of 128!");
419 assert(MaxSVEVectorSize % 128 == 0 &&
420 "SVE requires vector length in multiples of 128!");
421 assert((MaxSVEVectorSize >= MinSVEVectorSize || MaxSVEVectorSize == 0) &&
422 "Minimum SVE vector size should not be larger than its maximum!");
423
424 // Sanitize user input in case of no asserts
425 if (MaxSVEVectorSize != 0) {
426 MinSVEVectorSize = std::min(MinSVEVectorSize, MaxSVEVectorSize);
427 MaxSVEVectorSize = std::max(MinSVEVectorSize, MaxSVEVectorSize);
428 }
429
431 raw_svector_ostream(Key) << "SVEMin" << MinSVEVectorSize << "SVEMax"
432 << MaxSVEVectorSize
433 << "StreamingSVEMode=" << StreamingSVEMode
434 << "StreamingCompatibleSVEMode="
435 << StreamingCompatibleSVEMode << CPU << TuneCPU
436 << FS;
437
438 auto &I = SubtargetMap[Key];
439 if (!I) {
440 // This needs to be done before we create a new subtarget since any
441 // creation will depend on the TM and the code generation flags on the
442 // function that reside in TargetOptions.
444 I = std::make_unique<AArch64Subtarget>(
445 TargetTriple, CPU, TuneCPU, FS, *this, isLittle, MinSVEVectorSize,
446 MaxSVEVectorSize, StreamingSVEMode, StreamingCompatibleSVEMode);
447 }
448
449 assert((!StreamingSVEMode || I->hasSME()) &&
450 "Expected SME to be available");
451
452 return I.get();
453}
454
455void AArch64leTargetMachine::anchor() { }
456
458 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
459 const TargetOptions &Options, std::optional<Reloc::Model> RM,
460 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
461 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
462
463void AArch64beTargetMachine::anchor() { }
464
466 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
467 const TargetOptions &Options, std::optional<Reloc::Model> RM,
468 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
469 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
470
471namespace {
472
473/// AArch64 Code Generator Pass Configuration Options.
474class AArch64PassConfig : public TargetPassConfig {
475public:
476 AArch64PassConfig(AArch64TargetMachine &TM, PassManagerBase &PM)
477 : TargetPassConfig(TM, PM) {
478 if (TM.getOptLevel() != CodeGenOptLevel::None)
479 substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
480 setEnableSinkAndFold(EnableSinkFold);
481 }
482
483 AArch64TargetMachine &getAArch64TargetMachine() const {
484 return getTM<AArch64TargetMachine>();
485 }
486
488 createMachineScheduler(MachineSchedContext *C) const override {
489 const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
491 DAG->addMutation(createLoadClusterDAGMutation(DAG->TII, DAG->TRI));
492 DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
493 if (ST.hasFusion())
494 DAG->addMutation(createAArch64MacroFusionDAGMutation());
495 return DAG;
496 }
497
499 createPostMachineScheduler(MachineSchedContext *C) const override {
500 const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
501 ScheduleDAGMI *DAG =
502 new ScheduleDAGMI(C, std::make_unique<AArch64PostRASchedStrategy>(C),
503 /* RemoveKillFlags=*/true);
504 if (ST.hasFusion()) {
505 // Run the Macro Fusion after RA again since literals are expanded from
506 // pseudos then (v. addPreSched2()).
507 DAG->addMutation(createAArch64MacroFusionDAGMutation());
508 return DAG;
509 }
510
511 return DAG;
512 }
513
514 void addIRPasses() override;
515 bool addPreISel() override;
516 void addCodeGenPrepare() override;
517 bool addInstSelector() override;
518 bool addIRTranslator() override;
519 void addPreLegalizeMachineIR() override;
520 bool addLegalizeMachineIR() override;
521 void addPreRegBankSelect() override;
522 bool addRegBankSelect() override;
523 bool addGlobalInstructionSelect() override;
524 void addMachineSSAOptimization() override;
525 bool addILPOpts() override;
526 void addPreRegAlloc() override;
527 void addPostRegAlloc() override;
528 void addPreSched2() override;
529 void addPreEmitPass() override;
530 void addPostBBSections() override;
531 void addPreEmitPass2() override;
532
533 std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
534};
535
536} // end anonymous namespace
537
540 return TargetTransformInfo(AArch64TTIImpl(this, F));
541}
542
544 return new AArch64PassConfig(*this, PM);
545}
546
547std::unique_ptr<CSEConfigBase> AArch64PassConfig::getCSEConfig() const {
548 return getStandardCSEConfigForOpt(TM->getOptLevel());
549}
550
551void AArch64PassConfig::addIRPasses() {
552 // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
553 // ourselves.
554 addPass(createAtomicExpandPass());
555
556 // Expand any SVE vector library calls that we can't code generate directly.
558 TM->getOptLevel() == CodeGenOptLevel::Aggressive)
560
561 // Cmpxchg instructions are often used with a subsequent comparison to
562 // determine whether it succeeded. We can exploit existing control-flow in
563 // ldrex/strex loops to simplify this, but it needs tidying up.
564 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableAtomicTidy)
566 .forwardSwitchCondToPhi(true)
567 .convertSwitchRangeToICmp(true)
568 .convertSwitchToLookupTable(true)
569 .needCanonicalLoops(false)
570 .hoistCommonInsts(true)
571 .sinkCommonInsts(true)));
572
573 // Run LoopDataPrefetch
574 //
575 // Run this before LSR to remove the multiplies involved in computing the
576 // pointer values N iterations ahead.
577 if (TM->getOptLevel() != CodeGenOptLevel::None) {
582 }
583
584 if (TM->getOptLevel() == CodeGenOptLevel::Aggressive && EnableGEPOpt) {
585 // Call SeparateConstOffsetFromGEP pass to extract constants within indices
586 // and lower a GEP with multiple indices to either arithmetic operations or
587 // multiple GEPs with single index.
589 // Call EarlyCSE pass to find and remove subexpressions in the lowered
590 // result.
591 addPass(createEarlyCSEPass());
592 // Do loop invariant code motion in case part of the lowered result is
593 // invariant.
594 addPass(createLICMPass());
595 }
596
598
599 if (getOptLevel() == CodeGenOptLevel::Aggressive && EnableSelectOpt)
600 addPass(createSelectOptimizePass());
601
604 /*IsOptNone=*/TM->getOptLevel() == CodeGenOptLevel::None));
605
606 // Match complex arithmetic patterns
607 if (TM->getOptLevel() >= CodeGenOptLevel::Default)
609
610 // Match interleaved memory accesses to ldN/stN intrinsics.
611 if (TM->getOptLevel() != CodeGenOptLevel::None) {
614 }
615
616 // Expand any functions marked with SME attributes which require special
617 // changes for the calling convention or that require the lazy-saving
618 // mechanism specified in the SME ABI.
619 addPass(createSMEABIPass());
620
621 // Add Control Flow Guard checks.
622 if (TM->getTargetTriple().isOSWindows())
623 addPass(createCFGuardCheckPass());
624
625 if (TM->Options.JMCInstrument)
626 addPass(createJMCInstrumenterPass());
627}
628
629// Pass Pipeline Configuration
630bool AArch64PassConfig::addPreISel() {
631 // Run promote constant before global merge, so that the promoted constants
632 // get a chance to be merged
633 if (TM->getOptLevel() != CodeGenOptLevel::None && EnablePromoteConstant)
635 // FIXME: On AArch64, this depends on the type.
636 // Basically, the addressable offsets are up to 4095 * Ty.getSizeInBytes().
637 // and the offset has to be a multiple of the related size in bytes.
638 if ((TM->getOptLevel() != CodeGenOptLevel::None &&
641 bool OnlyOptimizeForSize =
642 (TM->getOptLevel() < CodeGenOptLevel::Aggressive) &&
644
645 // Merging of extern globals is enabled by default on non-Mach-O as we
646 // expect it to be generally either beneficial or harmless. On Mach-O it
647 // is disabled as we emit the .subsections_via_symbols directive which
648 // means that merging extern globals is not safe.
649 bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();
650
651 // FIXME: extern global merging is only enabled when we optimise for size
652 // because there are some regressions with it also enabled for performance.
653 if (!OnlyOptimizeForSize)
654 MergeExternalByDefault = false;
655
656 addPass(createGlobalMergePass(TM, 4095, OnlyOptimizeForSize,
657 MergeExternalByDefault));
658 }
659
660 return false;
661}
662
663void AArch64PassConfig::addCodeGenPrepare() {
664 if (getOptLevel() != CodeGenOptLevel::None)
667}
668
669bool AArch64PassConfig::addInstSelector() {
670 addPass(createAArch64ISelDag(getAArch64TargetMachine(), getOptLevel()));
671
672 // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
673 // references to _TLS_MODULE_BASE_ as possible.
674 if (TM->getTargetTriple().isOSBinFormatELF() &&
675 getOptLevel() != CodeGenOptLevel::None)
677
678 return false;
679}
680
681bool AArch64PassConfig::addIRTranslator() {
682 addPass(new IRTranslator(getOptLevel()));
683 return false;
684}
685
686void AArch64PassConfig::addPreLegalizeMachineIR() {
687 if (getOptLevel() == CodeGenOptLevel::None) {
689 addPass(new Localizer());
690 } else {
692 addPass(new Localizer());
694 addPass(new LoadStoreOpt());
695 }
696}
697
698bool AArch64PassConfig::addLegalizeMachineIR() {
699 addPass(new Legalizer());
700 return false;
701}
702
703void AArch64PassConfig::addPreRegBankSelect() {
704 bool IsOptNone = getOptLevel() == CodeGenOptLevel::None;
705 if (!IsOptNone) {
706 addPass(createAArch64PostLegalizerCombiner(IsOptNone));
708 addPass(new LoadStoreOpt());
709 }
711}
712
713bool AArch64PassConfig::addRegBankSelect() {
714 addPass(new RegBankSelect());
715 return false;
716}
717
718bool AArch64PassConfig::addGlobalInstructionSelect() {
719 addPass(new InstructionSelect(getOptLevel()));
720 if (getOptLevel() != CodeGenOptLevel::None)
722 return false;
723}
724
725void AArch64PassConfig::addMachineSSAOptimization() {
726 // Run default MachineSSAOptimization first.
728
729 if (TM->getOptLevel() != CodeGenOptLevel::None)
731}
732
733bool AArch64PassConfig::addILPOpts() {
734 if (EnableCondOpt)
736 if (EnableCCMP)
738 if (EnableMCR)
739 addPass(&MachineCombinerID);
741 addPass(createAArch64CondBrTuning());
743 addPass(&EarlyIfConverterID);
747 if (TM->getOptLevel() != CodeGenOptLevel::None)
749 return true;
750}
751
752void AArch64PassConfig::addPreRegAlloc() {
753 // Change dead register definitions to refer to the zero register.
754 if (TM->getOptLevel() != CodeGenOptLevel::None &&
757
758 // Use AdvSIMD scalar instructions whenever profitable.
759 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableAdvSIMDScalar) {
761 // The AdvSIMD pass may produce copies that can be rewritten to
762 // be register coalescer friendly.
763 addPass(&PeepholeOptimizerID);
764 }
765}
766
767void AArch64PassConfig::addPostRegAlloc() {
768 // Remove redundant copy instructions.
769 if (TM->getOptLevel() != CodeGenOptLevel::None &&
772
773 if (TM->getOptLevel() != CodeGenOptLevel::None && usingDefaultRegAlloc())
774 // Improve performance for some FP/SIMD code for A57.
776}
777
778void AArch64PassConfig::addPreSched2() {
779 // Lower homogeneous frame instructions
782 // Expand some pseudo instructions to allow proper scheduling.
784 // Use load/store pair instructions when possible.
785 if (TM->getOptLevel() != CodeGenOptLevel::None) {
788 }
789 // Emit KCFI checks for indirect calls.
790 addPass(createKCFIPass());
791
792 // The AArch64SpeculationHardeningPass destroys dominator tree and natural
793 // loop info, which is needed for the FalkorHWPFFixPass and also later on.
794 // Therefore, run the AArch64SpeculationHardeningPass before the
795 // FalkorHWPFFixPass to avoid recomputing dominator tree and natural loop
796 // info.
798
801
802 if (TM->getOptLevel() != CodeGenOptLevel::None) {
804 addPass(createFalkorHWPFFixPass());
805 }
806}
807
808void AArch64PassConfig::addPreEmitPass() {
809 // Machine Block Placement might have created new opportunities when run
810 // at O3, where the Tail Duplication Threshold is set to 4 instructions.
811 // Run the load/store optimizer once more.
812 if (TM->getOptLevel() >= CodeGenOptLevel::Aggressive && EnableLoadStoreOpt)
814
815 if (TM->getOptLevel() >= CodeGenOptLevel::Aggressive &&
818
819 addPass(createAArch64A53Fix835769());
820
821 if (TM->getTargetTriple().isOSWindows()) {
822 // Identify valid longjmp targets for Windows Control Flow Guard.
823 addPass(createCFGuardLongjmpPass());
824 // Identify valid eh continuation targets for Windows EHCont Guard.
826 }
827
828 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCollectLOH &&
829 TM->getTargetTriple().isOSBinFormatMachO())
831}
832
833void AArch64PassConfig::addPostBBSections() {
837 // Relax conditional branch instructions if they're otherwise out of
838 // range of their destination.
839 if (BranchRelaxation)
840 addPass(&BranchRelaxationPassID);
841
842 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCompressJumpTables)
844}
845
846void AArch64PassConfig::addPreEmitPass2() {
847 // SVE bundles move prefixes with destructive operations. BLR_RVMARKER pseudo
848 // instructions are lowered to bundles as well.
849 addPass(createUnpackMachineBundles(nullptr));
850}
851
853 BumpPtrAllocator &Allocator, const Function &F,
854 const TargetSubtargetInfo *STI) const {
855 return AArch64FunctionInfo::create<AArch64FunctionInfo>(
856 Allocator, F, static_cast<const AArch64Subtarget *>(STI));
857}
858
861 return new yaml::AArch64FunctionInfo();
862}
863
866 const auto *MFI = MF.getInfo<AArch64FunctionInfo>();
867 return new yaml::AArch64FunctionInfo(*MFI);
868}
869
872 SMDiagnostic &Error, SMRange &SourceRange) const {
873 const auto &YamlMFI = static_cast<const yaml::AArch64FunctionInfo &>(MFI);
874 MachineFunction &MF = PFS.MF;
875 MF.getInfo<AArch64FunctionInfo>()->initializeBaseYamlFields(YamlMFI);
876 return false;
877}
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 > 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 > 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 > EnableSinkFold("aarch64-enable-sink-fold", cl::desc("Enable sinking and folding of instruction copies"), cl::init(false), cl::Hidden)
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 > 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 > 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:135
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")
const char LLVMTargetMachineRef TM
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.
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:1485
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:318
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:184
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...
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
void setSupportsDebugEntryValues(bool Enable)
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
Definition: TargetMachine.h:97
void setMachineOutliner(bool Enable)
void setCFIFixup(bool Enable)
void setSupportsDefaultOutlining(bool Enable)
void setGlobalISelAbort(GlobalISelAbortMode Mode)
std::string TargetFS
Definition: TargetMachine.h:99
std::string TargetCPU
Definition: TargetMachine.h:98
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.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
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.
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:672
@ 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:445
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:53
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 &)
FunctionPass * createSelectOptimizePass()
This pass converts conditional moves to conditional jumps when profitable.
FunctionPass * createAtomicExpandPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
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()
std::unique_ptr< ScheduleDAGMutation > createStoreClusterDAGMutation(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
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:370
ScheduleDAGMILive * createGenericSchedLive(MachineSchedContext *C)
Create the standard converging machine scheduler.
Target & getTheAArch64leTarget()
FunctionPass * createAArch64DeadRegisterDefinitions()
FunctionPass * createAArch64PostLegalizerLowering()
ModulePass * createJMCInstrumenterPass()
JMC instrument pass.
FunctionPass * createAArch64IndirectThunks()
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 initializeAArch64DAGToDAGISelPass(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 * createAArch64GlobalsTaggingPass()
std::unique_ptr< ScheduleDAGMutation > createLoadClusterDAGMutation(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
Pass * createGlobalMergePass(const TargetMachine *TM, unsigned MaximalOffset, bool OnlyOptimizeForSize=false, bool MergeExternalByDefault=false)
GlobalMerge - This pass merges internal (by default) globals into structs to enable reuse of a base p...
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:156
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,...
void initializeAArch64MIPeepholeOptPass(PassRegistry &)
FunctionPass * createAArch64SLSHardeningPass()
FunctionPass * createAArch64BranchTargetsPass()
Target & getTheARM64Target()
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:306
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 * 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()
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.