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