LLVM 24.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"
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"
56#include <memory>
57
58using namespace llvm;
59
60static cl::opt<bool> EnableCCMP("aarch64-enable-ccmp",
61 cl::desc("Enable the CCMP formation pass"),
62 cl::init(true), cl::Hidden);
63
64static cl::opt<bool>
65 EnableCondBrTuning("aarch64-enable-cond-br-tune",
66 cl::desc("Enable the conditional branch tuning pass"),
67 cl::init(true), cl::Hidden);
68
70 "aarch64-enable-copy-propagation",
71 cl::desc("Enable the copy propagation with AArch64 copy instr"),
72 cl::init(true), cl::Hidden);
73
74static cl::opt<bool> EnableMCR("aarch64-enable-mcr",
75 cl::desc("Enable the machine combiner pass"),
76 cl::init(true), cl::Hidden);
77
78static cl::opt<bool> EnableStPairSuppress("aarch64-enable-stp-suppress",
79 cl::desc("Suppress STP for AArch64"),
80 cl::init(true), cl::Hidden);
81
83 "aarch64-enable-simd-scalar",
84 cl::desc("Enable use of AdvSIMD scalar integer instructions"),
85 cl::init(false), cl::Hidden);
86
87static cl::opt<bool>
88 EnablePromoteConstant("aarch64-enable-promote-const",
89 cl::desc("Enable the promote constant pass"),
90 cl::init(true), cl::Hidden);
91
93 "aarch64-enable-collect-loh",
94 cl::desc("Enable the pass that emits the linker optimization hints (LOH)"),
95 cl::init(true), cl::Hidden);
96
97static cl::opt<bool>
98 EnableDeadRegisterElimination("aarch64-enable-dead-defs", cl::Hidden,
99 cl::desc("Enable the pass that removes dead"
100 " definitions and replaces stores to"
101 " them with stores to the zero"
102 " register"),
103 cl::init(true));
104
106 "aarch64-enable-copyelim",
107 cl::desc("Enable the redundant copy elimination pass"), cl::init(true),
108 cl::Hidden);
109
110static cl::opt<bool> EnableLoadStoreOpt("aarch64-enable-ldst-opt",
111 cl::desc("Enable the load/store pair"
112 " optimization pass"),
113 cl::init(true), cl::Hidden);
114
116 "aarch64-enable-atomic-cfg-tidy", cl::Hidden,
117 cl::desc("Run SimplifyCFG after expanding atomic operations"
118 " to make use of cmpxchg flow-based information"),
119 cl::init(true));
120
121static cl::opt<bool>
122EnableEarlyIfConversion("aarch64-enable-early-ifcvt", cl::Hidden,
123 cl::desc("Run early if-conversion"),
124 cl::init(true));
125
126static cl::opt<bool>
127 EnableCondOpt("aarch64-enable-condopt",
128 cl::desc("Enable the condition optimizer pass"),
129 cl::init(true), cl::Hidden);
130
131static cl::opt<bool>
132 EnableGEPOpt("aarch64-enable-gep-opt", cl::Hidden,
133 cl::desc("Enable optimizations on complex GEPs"),
134 cl::init(false));
135
136static cl::opt<bool>
137 EnableSelectOpt("aarch64-select-opt", cl::Hidden,
138 cl::desc("Enable select to branch optimizations"),
139 cl::init(true));
140
141static cl::opt<bool>
142 BranchRelaxation("aarch64-enable-branch-relax", cl::Hidden, cl::init(true),
143 cl::desc("Relax out of range conditional branches"));
144
146 "aarch64-enable-compress-jump-tables", cl::Hidden, cl::init(true),
147 cl::desc("Use smallest entry possible for jump tables"));
148
149// FIXME: Unify control over GlobalMerge.
151 EnableGlobalMerge("aarch64-enable-global-merge", cl::Hidden,
152 cl::desc("Enable the global merge pass"));
153
154static cl::opt<bool>
155 EnableLoopDataPrefetch("aarch64-enable-loop-data-prefetch", cl::Hidden,
156 cl::desc("Enable the loop data prefetch pass"),
157 cl::init(true));
158
160 "aarch64-enable-global-isel-at-O", cl::Hidden,
161 cl::desc("Enable GlobalISel at or below an opt level (-1 to disable)"),
162 cl::init(0));
163
164static cl::opt<bool>
165 EnableSMEPeepholeOpt("enable-aarch64-sme-peephole-opt", cl::init(true),
167 cl::desc("Perform SME peephole optimization"));
168
169static cl::opt<bool> EnableFalkorHWPFFix("aarch64-enable-falkor-hwpf-fix",
170 cl::init(true), cl::Hidden);
171
172static cl::opt<bool>
173 EnableBranchTargets("aarch64-enable-branch-targets", cl::Hidden,
174 cl::desc("Enable the AArch64 branch target pass"),
175 cl::init(true));
176
178 "aarch64-sve-vector-bits-max",
179 cl::desc("Assume SVE vector registers are at most this big, "
180 "with zero meaning no maximum size is assumed."),
181 cl::init(0), cl::Hidden);
182
184 "aarch64-sve-vector-bits-min",
185 cl::desc("Assume SVE vector registers are at least this big, "
186 "with zero meaning no minimum size is assumed."),
187 cl::init(0), cl::Hidden);
188
190 "force-streaming",
191 cl::desc("Force the use of streaming code for all functions"),
192 cl::init(false), cl::Hidden);
193
195 "force-streaming-compatible",
196 cl::desc("Force the use of streaming-compatible code for all functions"),
197 cl::init(false), cl::Hidden);
198
200
202 "aarch64-enable-gisel-ldst-prelegal",
203 cl::desc("Enable GlobalISel's pre-legalizer load/store optimization pass"),
204 cl::init(true), cl::Hidden);
205
207 "aarch64-enable-gisel-ldst-postlegal",
208 cl::desc("Enable GlobalISel's post-legalizer load/store optimization pass"),
209 cl::init(false), cl::Hidden);
210
211static cl::opt<bool>
212 EnableSinkFold("aarch64-enable-sink-fold",
213 cl::desc("Enable sinking and folding of instruction copies"),
214 cl::init(true), cl::Hidden);
215
216static cl::opt<bool>
217 EnableMachinePipeliner("aarch64-enable-pipeliner",
218 cl::desc("Enable Machine Pipeliner for AArch64"),
219 cl::init(false), cl::Hidden);
220
222 "aarch64-srlt-mitigate-sr2r",
223 cl::desc("Enable SUBREG_TO_REG mitigation by adding 'implicit-def' for "
224 "super-regs when using Subreg Liveness Tracking"),
225 cl::init(true), cl::Hidden);
226
228 "aarch64-enable-sve-shuffle-opts",
229 cl::desc("Enable pattern matching of shuffles that could make use of SVE "
230 "instructions like tbl or the bottom/top variants"),
231 cl::init(true), cl::Hidden);
232
235 // Register the target.
241 auto &PR = *PassRegistry::getPassRegistry();
286}
287
289 const bool GlobalISelFlag = getCGPassBuilderOption().EnableGlobalISelOption ==
291
293 (static_cast<unsigned>(getOptLevel()) >
294 static_cast<unsigned>(EnableGlobalISelAtO) &&
295 !GlobalISelFlag);
296}
297
299
300//===----------------------------------------------------------------------===//
301// AArch64 Lowering public interface.
302//===----------------------------------------------------------------------===//
303static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
304 if (TT.isOSBinFormatMachO())
305 return std::make_unique<AArch64_MachoTargetObjectFile>();
306 if (TT.isOSBinFormatCOFF())
307 return std::make_unique<AArch64_COFFTargetObjectFile>();
308
309 return std::make_unique<AArch64_ELFTargetObjectFile>();
310}
311
313 if (CPU.empty() && TT.isArm64e())
314 return "apple-a12";
315 return CPU;
316}
317
319 std::optional<Reloc::Model> RM) {
320 // AArch64 Darwin and Windows are always PIC.
321 if (TT.isOSDarwin() || TT.isOSWindows())
322 return Reloc::PIC_;
323 // On ELF platforms the default static relocation model has a smart enough
324 // linker to cope with referencing external symbols defined in a shared
325 // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
326 if (!RM || *RM == Reloc::DynamicNoPIC)
327 return Reloc::Static;
328 return *RM;
329}
330
331static CodeModel::Model
333 std::optional<CodeModel::Model> CM, bool JIT) {
334 if (CM) {
335 if (*CM != CodeModel::Small && *CM != CodeModel::Tiny &&
336 *CM != CodeModel::Large) {
338 "Only small, tiny and large code models are allowed on AArch64");
339 } else if (*CM == CodeModel::Tiny && !TT.isOSBinFormatELF()) {
340 report_fatal_error("tiny code model is only supported on ELF");
341 }
342 return *CM;
343 }
344 // The default MCJIT memory managers make no guarantees about where they can
345 // find an executable page; JITed code needs to be able to refer to globals
346 // no matter how far away they are.
347 // We should set the CodeModel::Small for Windows ARM64 in JIT mode,
348 // since with large code model LLVM generating 4 MOV instructions, and
349 // Windows doesn't support relocating these long branch (4 MOVs).
350 if (JIT && !TT.isOSWindows())
351 return CodeModel::Large;
352 return CodeModel::Small;
353}
354
355/// Create an AArch64 architecture model.
356///
358 StringRef CPU, StringRef FS,
359 const TargetOptions &Options,
360 std::optional<Reloc::Model> RM,
361 std::optional<CodeModel::Model> CM,
362 CodeGenOptLevel OL, bool JIT,
363 bool LittleEndian)
364 : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT,
365 computeDefaultCPU(TT, CPU), FS, Options,
367 getEffectiveAArch64CodeModel(TT, CM, JIT), OL),
368 TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian) {
369 initAsmInfo();
370
371 if (TT.isOSBinFormatMachO()) {
372 this->Options.TrapUnreachable = true;
373 this->Options.NoTrapAfterNoreturn = true;
374 }
375
376 if (getMCAsmInfo().usesWindowsCFI()) {
377 // Unwinding can get confused if the last instruction in an
378 // exception-handling region (function, funclet, try block, etc.)
379 // is a call.
380 //
381 // FIXME: We could elide the trap if the next instruction would be in
382 // the same region anyway.
383 this->Options.TrapUnreachable = true;
384 }
385
386 if (this->Options.TLSSize == 0) // default
387 this->Options.TLSSize = 24;
388 if ((getCodeModel() == CodeModel::Small ||
390 this->Options.TLSSize > 32)
391 // for the small (and kernel) code model, the maximum TLS size is 4GiB
392 this->Options.TLSSize = 32;
393 else if (getCodeModel() == CodeModel::Tiny && this->Options.TLSSize > 24)
394 // for the tiny code model, the maximum TLS size is 1MiB (< 16MiB)
395 this->Options.TLSSize = 24;
396
397 const bool TargetSupportsGISel =
398 TT.getArch() != Triple::aarch64_32 &&
399 TT.getEnvironment() != Triple::GNUILP32 &&
400 !(getCodeModel() == CodeModel::Large && TT.isOSBinFormatMachO());
401
402 const bool GlobalISelFlag = getCGPassBuilderOption().EnableGlobalISelOption ==
404
405 // Enable GlobalISel at or below EnableGlobalISelAt0, unless this is
406 // MachO/CodeModel::Large, which GlobalISel does not support.
407 if (TargetSupportsGISel && EnableGlobalISelAtO != -1 &&
408 (static_cast<int>(getOptLevel()) <= EnableGlobalISelAtO ||
409 (!GlobalISelFlag && !Options.EnableGlobalISel))) {
410 setGlobalISel(true);
412 }
413
415
416 // AArch64 supports the MachineOutliner.
417 setMachineOutliner(true);
418
419 // AArch64 supports default outlining behaviour.
421
422 // AArch64 supports the debug entry values.
424
425 // AArch64 supports fixing up the DWARF unwind information.
426 if (!getMCAsmInfo().usesWindowsCFI())
427 setCFIFixup(true);
428}
429
433
435
436const AArch64Subtarget *
438 Attribute CPUAttr = F.getFnAttribute("target-cpu");
439 Attribute TuneAttr = F.getFnAttribute("tune-cpu");
440 Attribute FSAttr = F.getFnAttribute("target-features");
441
442 StringRef CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString() : TargetCPU;
443 StringRef TuneCPU = TuneAttr.isValid() ? TuneAttr.getValueAsString() : CPU;
444 StringRef FS = FSAttr.isValid() ? FSAttr.getValueAsString() : TargetFS;
445 bool HasMinSize = F.hasMinSize();
446
447 bool IsStreaming = ForceStreaming ||
448 F.hasFnAttribute("aarch64_pstate_sm_enabled") ||
449 F.hasFnAttribute("aarch64_pstate_sm_body");
450 bool IsStreamingCompatible = ForceStreamingCompatible ||
451 F.hasFnAttribute("aarch64_pstate_sm_compatible");
452
453 unsigned MinSVEVectorSize = 0;
454 unsigned MaxSVEVectorSize = 0;
455 if (F.hasFnAttribute(Attribute::VScaleRange)) {
456 ConstantRange CR = getVScaleRange(&F, 64);
457 MinSVEVectorSize = CR.getUnsignedMin().getZExtValue() * 128;
458 MaxSVEVectorSize = CR.getUnsignedMax().getZExtValue() * 128;
459 } else {
460 MinSVEVectorSize = SVEVectorBitsMinOpt;
461 MaxSVEVectorSize = SVEVectorBitsMaxOpt;
462 }
463
464 assert(MinSVEVectorSize % 128 == 0 &&
465 "SVE requires vector length in multiples of 128!");
466 assert(MaxSVEVectorSize % 128 == 0 &&
467 "SVE requires vector length in multiples of 128!");
468 assert((MaxSVEVectorSize >= MinSVEVectorSize || MaxSVEVectorSize == 0) &&
469 "Minimum SVE vector size should not be larger than its maximum!");
470
471 // Sanitize user input in case of no asserts
472 if (MaxSVEVectorSize != 0) {
473 MinSVEVectorSize = std::min(MinSVEVectorSize, MaxSVEVectorSize);
474 MaxSVEVectorSize = std::max(MinSVEVectorSize, MaxSVEVectorSize);
475 }
476
478 // This lookup is hot during repeated TTI queries, so build the key directly
479 // instead of formatting through raw_svector_ostream.
480 Key += "SVEMin";
481 Key += utostr(MinSVEVectorSize);
482 Key += "SVEMax";
483 Key += utostr(MaxSVEVectorSize);
484 Key += "IsStreaming=";
485 Key += utostr(IsStreaming);
486 Key += "IsStreamingCompatible=";
487 Key += utostr(IsStreamingCompatible);
488 Key += CPU;
489 Key += TuneCPU;
490 Key += FS;
491 Key += "HasMinSize=";
492 Key += utostr(HasMinSize);
493
494 auto &I = SubtargetMap[Key];
495 if (!I) {
496 I = std::make_unique<AArch64Subtarget>(
497 TargetTriple, CPU, TuneCPU, FS, *this, isLittle, MinSVEVectorSize,
498 MaxSVEVectorSize, IsStreaming, IsStreamingCompatible, HasMinSize,
500 }
501
502 if (IsStreaming && !I->hasSME())
503 reportFatalUsageError("streaming SVE functions require SME");
504
505 return I.get();
506}
507
508// Encourage placing FORM_TRANSPOSED_REG immediately before the instruction that
509// uses/consumes it. This ensures its def has a short live range, which means
510// we're more likely to allocate registers its operands first (which works best
511// for the hints in AArch64RegisterInfo::getRegAllocationHints).
513 const TargetInstrInfo &TII, const TargetSubtargetInfo &TSI,
514 const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
515 return !FirstMI ||
516 FirstMI->getOpcode() == AArch64::FORM_TRANSPOSED_REG_TUPLE_X2_PSEUDO ||
517 FirstMI->getOpcode() == AArch64::FORM_TRANSPOSED_REG_TUPLE_X4_PSEUDO;
518}
519
522 const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
524 DAG->addMutation(createLoadClusterDAGMutation(DAG->TII, DAG->TRI));
525 DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
526 if (ST.hasFusion())
527 DAG->addMutation(createAArch64MacroFusionDAGMutation());
528 if (ST.hasSME() && ST.isStreaming())
529 DAG->addMutation(createMacroFusionDAGMutation(
531 return DAG;
532}
533
536 const AArch64Subtarget &ST = C->MF->getSubtarget<AArch64Subtarget>();
538 if (ST.hasFusion()) {
539 // Run the Macro Fusion after RA again since literals are expanded from
540 // pseudos then (v. addPreSched2()).
541 DAG->addMutation(createAArch64MacroFusionDAGMutation());
542 return DAG;
543 }
544
545 return DAG;
546}
547
549 const SmallPtrSetImpl<MachineInstr *> &MIs) const {
550 if (MIs.empty())
551 return 0;
552 auto *MI = *MIs.begin();
553 auto *FuncInfo = MI->getMF()->getInfo<AArch64FunctionInfo>();
554 return FuncInfo->clearLinkerOptimizationHints(MIs);
555}
556
557void AArch64leTargetMachine::anchor() { }
558
560 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
561 const TargetOptions &Options, std::optional<Reloc::Model> RM,
562 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
563 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
564
565void AArch64beTargetMachine::anchor() { }
566
568 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
569 const TargetOptions &Options, std::optional<Reloc::Model> RM,
570 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
571 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
572
573namespace {
574
575/// AArch64 Code Generator Pass Configuration Options.
576class AArch64PassConfig : public TargetPassConfig {
577public:
578 AArch64PassConfig(AArch64TargetMachine &TM, PassManagerBase &PM)
579 : TargetPassConfig(TM, PM) {
581 substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
582 setEnableSinkAndFold(EnableSinkFold);
583 }
584
585 AArch64TargetMachine &getAArch64TargetMachine() const {
587 }
588
589 void addIRPasses() override;
590 bool addPreISel() override;
591 void addCodeGenPrepare() override;
592 bool addInstSelector() override;
593 bool addIRTranslator() override;
594 void addPreLegalizeMachineIR() override;
595 bool addLegalizeMachineIR() override;
596 void addPreRegBankSelect() override;
597 bool addRegBankSelect() override;
598 bool addGlobalInstructionSelect() override;
599 void addMachineSSAOptimization() override;
600 bool addILPOpts() override;
601 void addPreRegAlloc() override;
602 void addPostRewrite() override;
603 void addPostRegAlloc() override;
604 void addPreSched2() override;
605 void addPreEmitPass() override;
606 void addPostBBSections() override;
607 void addPreEmitPass2() override;
608 bool addRegAssignAndRewriteOptimized() override;
609
610 std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
611};
612
613} // end anonymous namespace
614
616#define GET_PASS_REGISTRY "AArch64PassRegistry.def"
618
619 PB.registerLateLoopOptimizationsEPCallback(
620 [=](LoopPassManager &LPM, OptimizationLevel Level) {
621 if (Level != OptimizationLevel::O0)
622 LPM.addPass(LoopIdiomVectorizePass());
623 });
624 if (getTargetTriple().isOSWindows())
625 PB.registerPipelineEarlySimplificationEPCallback(
628 });
629}
630
633 return TargetTransformInfo(std::make_unique<AArch64TTIImpl>(this, F));
634}
635
637 return new AArch64PassConfig(*this, PM);
638}
639
640std::unique_ptr<CSEConfigBase> AArch64PassConfig::getCSEConfig() const {
641 return getStandardCSEConfigForOpt(TM->getOptLevel());
642}
643
644void AArch64PassConfig::addIRPasses() {
645 // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
646 // ourselves.
648
649 // Cmpxchg instructions are often used with a subsequent comparison to
650 // determine whether it succeeded. We can exploit existing control-flow in
651 // ldrex/strex loops to simplify this, but it needs tidying up.
652 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableAtomicTidy)
654 .forwardSwitchCondToPhi(true)
655 .convertSwitchRangeToICmp(true)
656 .convertSwitchToLookupTable(true)
657 .needCanonicalLoops(false)
658 .hoistCommonInsts(true)
659 .sinkCommonInsts(true)));
660
661 // Run LoopDataPrefetch
662 //
663 // Run this before LSR to remove the multiplies involved in computing the
664 // pointer values N iterations ahead.
665 if (TM->getOptLevel() != CodeGenOptLevel::None) {
670 }
671
672 if (EnableGEPOpt) {
673 // Call SeparateConstOffsetFromGEP pass to extract constants within indices
674 // and lower a GEP with multiple indices to either arithmetic operations or
675 // multiple GEPs with single index.
677 // Call EarlyCSE pass to find and remove subexpressions in the lowered
678 // result.
679 addPass(createEarlyCSEPass());
680 // Do loop invariant code motion in case part of the lowered result is
681 // invariant.
682 addPass(createLICMPass());
683 }
684
686
687 if (getOptLevel() == CodeGenOptLevel::Aggressive && EnableSelectOpt)
688 addPass(createSelectOptimizePass());
689
691 /*IsOptNone=*/TM->getOptLevel() == CodeGenOptLevel::None));
692
693 // Try to use tbl in place of other shuffling operations if doing so would
694 // reduce the total number of instructions. Shuffle masks for big endian may
695 // be different, so require a little endian target.
696 if (TM->createDataLayout().isLittleEndian() &&
698 addPass(createSVEShuffleOptsPass());
699
700 // Match complex arithmetic patterns
701 if (TM->getOptLevel() >= CodeGenOptLevel::Default)
703
704 // Match interleaved memory accesses to ldN/stN intrinsics.
705 if (TM->getOptLevel() != CodeGenOptLevel::None) {
708 }
709
710 // Add Control Flow Guard checks.
711 if (TM->getTargetTriple().isOSWindows()) {
712 if (TM->getTargetTriple().isWindowsArm64EC())
714 else
715 addPass(createCFGuardPass());
716 }
717
718 if (TM->Options.JMCInstrument)
719 addPass(createJMCInstrumenterPass());
720}
721
722// Pass Pipeline Configuration
723bool AArch64PassConfig::addPreISel() {
724 // Run promote constant before global merge, so that the promoted constants
725 // get a chance to be merged
726 if (TM->getOptLevel() != CodeGenOptLevel::None && EnablePromoteConstant)
728 // FIXME: On AArch64, this depends on the type.
729 // Basically, the addressable offsets are up to 4095 * Ty.getSizeInBytes().
730 // and the offset has to be a multiple of the related size in bytes.
731 if ((TM->getOptLevel() != CodeGenOptLevel::None &&
734 bool OnlyOptimizeForSize =
735 (TM->getOptLevel() < CodeGenOptLevel::Aggressive) &&
737
738 // Merging of extern globals is enabled by default on non-Mach-O as we
739 // expect it to be generally either beneficial or harmless. On Mach-O it
740 // is disabled as we emit the .subsections_via_symbols directive which
741 // means that merging extern globals is not safe.
742 bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();
743 addPass(createGlobalMergePass(TM, 4095, OnlyOptimizeForSize,
744 MergeExternalByDefault));
745 }
746
747 return false;
748}
749
750void AArch64PassConfig::addCodeGenPrepare() {
751 if (getOptLevel() != CodeGenOptLevel::None)
754}
755
756bool AArch64PassConfig::addInstSelector() {
757 addPass(createAArch64ISelDag(getAArch64TargetMachine(), getOptLevel()));
758
759 // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
760 // references to _TLS_MODULE_BASE_ as possible.
761 if (TM->getTargetTriple().isOSBinFormatELF() &&
762 getOptLevel() != CodeGenOptLevel::None)
764
765 return false;
766}
767
768bool AArch64PassConfig::addIRTranslator() {
769 addPass(new IRTranslator(getOptLevel()));
770 return false;
771}
772
773void AArch64PassConfig::addPreLegalizeMachineIR() {
774 if (getAArch64TargetMachine().isGlobalISelOptNone()) {
776 addPass(new Localizer());
777 } else {
779 addPass(new Localizer());
781 addPass(new LoadStoreOpt());
782 }
783}
784
785bool AArch64PassConfig::addLegalizeMachineIR() {
786 addPass(new Legalizer());
787 return false;
788}
789
790void AArch64PassConfig::addPreRegBankSelect() {
791 const bool IsGlobalISelOptNone =
792 getAArch64TargetMachine().isGlobalISelOptNone();
793 if (!IsGlobalISelOptNone) {
794 addPass(createAArch64PostLegalizerCombinerLegacy(IsGlobalISelOptNone));
796 addPass(new LoadStoreOpt());
797 }
799}
800
801bool AArch64PassConfig::addRegBankSelect() {
802 addPass(new RegBankSelect());
803 return false;
804}
805
806bool AArch64PassConfig::addGlobalInstructionSelect() {
807 addPass(new InstructionSelect(getOptLevel()));
808 if (!getAArch64TargetMachine().isGlobalISelOptNone())
810 return false;
811}
812
813void AArch64PassConfig::addMachineSSAOptimization() {
814 if (TM->getOptLevel() != CodeGenOptLevel::None)
815 addPass(createMachineSMEABIPass(TM->getOptLevel()));
816
817 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableSMEPeepholeOpt)
818 addPass(createSMEPeepholeOptPass());
819
820 // Run default MachineSSAOptimization first.
822
823 if (TM->getOptLevel() != CodeGenOptLevel::None) {
826 }
827}
828
829bool AArch64PassConfig::addILPOpts() {
830 if (EnableCondOpt)
832 if (EnableCCMP)
834 if (EnableMCR)
835 addPass(&MachineCombinerID);
837 addPass(createAArch64CondBrTuning());
839 addPass(&EarlyIfConverterLegacyID);
843 if (TM->getOptLevel() != CodeGenOptLevel::None)
845 return true;
846}
847
848void AArch64PassConfig::addPreRegAlloc() {
849 if (TM->getOptLevel() == CodeGenOptLevel::None)
851
852 // Change dead register definitions to refer to the zero register.
853 if (TM->getOptLevel() != CodeGenOptLevel::None &&
856
857 // Use AdvSIMD scalar instructions whenever profitable.
858 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableAdvSIMDScalar) {
860 // The AdvSIMD pass may produce copies that can be rewritten to
861 // be register coalescer friendly.
863 }
864 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableMachinePipeliner)
865 addPass(&MachinePipelinerID);
866}
867
868void AArch64PassConfig::addPostRewrite() {
871}
872
873void AArch64PassConfig::addPostRegAlloc() {
874 // Remove redundant copy instructions.
875 if (TM->getOptLevel() != CodeGenOptLevel::None &&
878
879 if (TM->getOptLevel() != CodeGenOptLevel::None && usingDefaultRegAlloc())
880 // Improve performance for some FP/SIMD code for A57.
882}
883
884void AArch64PassConfig::addPreSched2() {
885 // Lower homogeneous frame instructions
888 // Expand some pseudo instructions to allow proper scheduling.
890 // Use load/store pair instructions when possible.
891 if (TM->getOptLevel() != CodeGenOptLevel::None) {
894 }
895 // Emit KCFI checks for indirect calls.
896 addPass(createKCFIPass());
897
898 // The AArch64SpeculationHardeningPass destroys dominator tree and natural
899 // loop info, which is needed for the FalkorHWPFFixPass and also later on.
900 // Therefore, run the AArch64SpeculationHardeningPass before the
901 // FalkorHWPFFixPass to avoid recomputing dominator tree and natural loop
902 // info.
904
905 if (TM->getOptLevel() != CodeGenOptLevel::None) {
907 addPass(createFalkorHWPFFixPass());
908 }
909}
910
911void AArch64PassConfig::addPreEmitPass() {
912 // Machine Block Placement might have created new opportunities when run
913 // at O3, where the Tail Duplication Threshold is set to 4 instructions.
914 // Run the load/store optimizer once more.
915 if (TM->getOptLevel() >= CodeGenOptLevel::Aggressive && EnableLoadStoreOpt)
917
918 if (TM->getOptLevel() >= CodeGenOptLevel::Aggressive &&
921 if (TM->getOptLevel() != CodeGenOptLevel::None)
923
925
926 if (TM->getTargetTriple().isOSWindows()) {
927 // Identify valid longjmp targets for Windows Control Flow Guard.
928 addPass(createCFGuardLongjmpPass());
929 // Identify valid eh continuation targets for Windows EHCont Guard.
931 }
932
933 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCollectLOH &&
934 TM->getTargetTriple().isOSBinFormatMachO())
936
937 // Apply code layout optimizations. Run late so detection reflects the
938 // final MI stream.
939 if (getOptLevel() != CodeGenOptLevel::None)
941}
942
943void AArch64PassConfig::addPostBBSections() {
948 // Relax conditional branch instructions if they're otherwise out of
949 // range of their destination.
951 addPass(&BranchRelaxationPassID);
952
953 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCompressJumpTables)
955}
956
957void AArch64PassConfig::addPreEmitPass2() {
958 // Insert pseudo probe annotation for callsite profiling
959 addPass(createPseudoProbeInserter());
960
961 // SVE bundles move prefixes with destructive operations. BLR_RVMARKER pseudo
962 // instructions are lowered to bundles as well.
963 addPass(createUnpackMachineBundlesLegacy(nullptr));
964}
965
966bool AArch64PassConfig::addRegAssignAndRewriteOptimized() {
969}
970
977
982
985 const auto *MFI = MF.getInfo<AArch64FunctionInfo>();
986 return new yaml::AArch64FunctionInfo(*MFI);
987}
988
991 SMDiagnostic &Error, SMRange &SourceRange) const {
992 const auto &YamlMFI = static_cast<const yaml::AArch64FunctionInfo &>(MFI);
993 MachineFunction &MF = PFS.MF;
994 MF.getInfo<AArch64FunctionInfo>()->initializeBaseYamlFields(YamlMFI);
995 return false;
996}
cl::opt< bool > EnableHomogeneousPrologEpilog("homogeneous-prolog-epilog", cl::Hidden, cl::desc("Emit homogeneous prologue and epilogue for the size " "optimization (default = off)"))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< bool > EnableBranchTargets("aarch64-enable-branch-targets", cl::Hidden, cl::desc("Enable the AArch64 branch target pass"), cl::init(true))
static cl::opt< bool > EnableAArch64CopyPropagation("aarch64-enable-copy-propagation", cl::desc("Enable the copy propagation with AArch64 copy instr"), cl::init(true), cl::Hidden)
static cl::opt< bool > BranchRelaxation("aarch64-enable-branch-relax", cl::Hidden, cl::init(true), cl::desc("Relax out of range conditional branches"))
static cl::opt< bool > EnablePromoteConstant("aarch64-enable-promote-const", cl::desc("Enable the promote constant pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableCondBrTuning("aarch64-enable-cond-br-tune", cl::desc("Enable the conditional branch tuning pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableSinkFold("aarch64-enable-sink-fold", cl::desc("Enable sinking and folding of instruction copies"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableDeadRegisterElimination("aarch64-enable-dead-defs", cl::Hidden, cl::desc("Enable the pass that removes dead" " definitions and replaces stores to" " them with stores to the zero" " register"), cl::init(true))
static cl::opt< bool > EnableGEPOpt("aarch64-enable-gep-opt", cl::Hidden, cl::desc("Enable optimizations on complex GEPs"), cl::init(false))
static cl::opt< bool > EnableSelectOpt("aarch64-select-opt", cl::Hidden, cl::desc("Enable select to branch optimizations"), cl::init(true))
static cl::opt< bool > EnableLoadStoreOpt("aarch64-enable-ldst-opt", cl::desc("Enable the load/store pair" " optimization pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableGISelLoadStoreOptPostLegal("aarch64-enable-gisel-ldst-postlegal", cl::desc("Enable GlobalISel's post-legalizer load/store optimization pass"), cl::init(false), cl::Hidden)
static StringRef computeDefaultCPU(const Triple &TT, StringRef CPU)
static cl::opt< unsigned > SVEVectorBitsMinOpt("aarch64-sve-vector-bits-min", cl::desc("Assume SVE vector registers are at least this big, " "with zero meaning no minimum size is assumed."), cl::init(0), cl::Hidden)
static cl::opt< bool > EnableMCR("aarch64-enable-mcr", cl::desc("Enable the machine combiner pass"), cl::init(true), cl::Hidden)
static cl::opt< cl::boolOrDefault > EnableGlobalMerge("aarch64-enable-global-merge", cl::Hidden, cl::desc("Enable the global merge pass"))
static cl::opt< bool > EnableStPairSuppress("aarch64-enable-stp-suppress", cl::desc("Suppress STP for AArch64"), cl::init(true), cl::Hidden)
static bool scheduleFormTransposedTupleAdjacentToUsers(const TargetInstrInfo &TII, const TargetSubtargetInfo &TSI, const MachineInstr *FirstMI, const MachineInstr &SecondMI)
static CodeModel::Model getEffectiveAArch64CodeModel(const Triple &TT, std::optional< CodeModel::Model > CM, bool JIT)
static cl::opt< bool > EnableCondOpt("aarch64-enable-condopt", cl::desc("Enable the condition optimizer pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > ForceStreaming("force-streaming", cl::desc("Force the use of streaming code for all functions"), cl::init(false), cl::Hidden)
static cl::opt< bool > EnableCollectLOH("aarch64-enable-collect-loh", cl::desc("Enable the pass that emits the linker optimization hints (LOH)"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableGISelLoadStoreOptPreLegal("aarch64-enable-gisel-ldst-prelegal", cl::desc("Enable GlobalISel's pre-legalizer load/store optimization pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableRedundantCopyElimination("aarch64-enable-copyelim", cl::desc("Enable the redundant copy elimination pass"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableAtomicTidy("aarch64-enable-atomic-cfg-tidy", cl::Hidden, cl::desc("Run SimplifyCFG after expanding atomic operations" " to make use of cmpxchg flow-based information"), cl::init(true))
static cl::opt< bool > EnableAdvSIMDScalar("aarch64-enable-simd-scalar", cl::desc("Enable use of AdvSIMD scalar integer instructions"), cl::init(false), cl::Hidden)
static cl::opt< int > EnableGlobalISelAtO("aarch64-enable-global-isel-at-O", cl::Hidden, cl::desc("Enable GlobalISel at or below an opt level (-1 to disable)"), cl::init(0))
static cl::opt< bool > EnableLoopDataPrefetch("aarch64-enable-loop-data-prefetch", cl::Hidden, cl::desc("Enable the loop data prefetch pass"), cl::init(true))
static cl::opt< bool > EnableSMEPeepholeOpt("enable-aarch64-sme-peephole-opt", cl::init(true), cl::Hidden, cl::desc("Perform SME peephole optimization"))
static cl::opt< bool > EnableEarlyIfConversion("aarch64-enable-early-ifcvt", cl::Hidden, cl::desc("Run early if-conversion"), cl::init(true))
static cl::opt< bool > EnableSRLTSubregToRegMitigation("aarch64-srlt-mitigate-sr2r", cl::desc("Enable SUBREG_TO_REG mitigation by adding 'implicit-def' for " "super-regs when using Subreg Liveness Tracking"), cl::init(true), cl::Hidden)
static cl::opt< bool > EnableMachinePipeliner("aarch64-enable-pipeliner", cl::desc("Enable Machine Pipeliner for AArch64"), cl::init(false), cl::Hidden)
static cl::opt< bool > EnableFalkorHWPFFix("aarch64-enable-falkor-hwpf-fix", cl::init(true), cl::Hidden)
static cl::opt< bool > EnableSVEShuffleOpt("aarch64-enable-sve-shuffle-opts", cl::desc("Enable pattern matching of shuffles that could make use of SVE " "instructions like tbl or the bottom/top variants"), cl::init(true), cl::Hidden)
static cl::opt< unsigned > SVEVectorBitsMaxOpt("aarch64-sve-vector-bits-max", cl::desc("Assume SVE vector registers are at most this big, " "with zero meaning no maximum size is assumed."), cl::init(0), cl::Hidden)
static cl::opt< bool > ForceStreamingCompatible("force-streaming-compatible", cl::desc("Force the use of streaming-compatible code for all functions"), cl::init(false), cl::Hidden)
static std::unique_ptr< TargetLoweringObjectFile > createTLOF(const Triple &TT)
static cl::opt< bool > EnableCompressJumpTables("aarch64-enable-compress-jump-tables", cl::Hidden, cl::init(true), cl::desc("Use smallest entry possible for jump tables"))
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target()
static cl::opt< bool > EnableCCMP("aarch64-enable-ccmp", cl::desc("Enable the CCMP formation pass"), cl::init(true), cl::Hidden)
This file a TargetTransformInfoImplBase conforming object specific to the AArch64 target machine.
static Reloc::Model getEffectiveRelocModel()
This file contains the simple types necessary to represent the attributes associated with functions a...
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
Provides analysis for continuously CSEing during GISel passes.
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
DXIL Legalizer
static cl::opt< bool > EnableGlobalMerge("enable-global-merge", cl::Hidden, cl::desc("Enable the global merge pass"), cl::init(true))
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
This file declares the IRTranslator pass.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
This file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
This file contains some functions that are useful when dealing with strings.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
static std::unique_ptr< TargetLoweringObjectFile > createTLOF()
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
size_t clearLinkerOptimizationHints(const SmallPtrSetImpl< MachineInstr * > &MIs)
size_t clearLinkerOptimizationHints(const SmallPtrSetImpl< MachineInstr * > &MIs) const override
Remove all Linker Optimization Hints (LOH) associated with instructions in MIs and.
StringMap< std::unique_ptr< AArch64Subtarget > > SubtargetMap
MachineFunctionInfo * createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override
Create the target's instance of MachineFunctionInfo.
void registerPassBuilderCallbacks(PassBuilder &PB) override
Allow the target to modify the pass pipeline.
const AArch64Subtarget * getSubtargetImpl() const =delete
yaml::MachineFunctionInfo * createDefaultFuncInfoYAML() const override
Allocate and return a default initialized instance of the YAML representation for the MachineFunction...
ScheduleDAGInstrs * createPostMachineScheduler(MachineSchedContext *C) const override
Similar to createMachineScheduler but used when postRA machine scheduling is enabled.
unsigned getEnableGlobalISelAtO() const
Returns the optimisation level that enables GlobalISel.
std::unique_ptr< TargetLoweringObjectFile > TLOF
yaml::MachineFunctionInfo * convertFuncInfoToYAML(const MachineFunction &MF) const override
Allocate and initialize an instance of the YAML representation of the MachineFunctionInfo.
bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &, PerFunctionMIParsingState &PFS, SMDiagnostic &Error, SMRange &SourceRange) const override
Parse out the target's MachineFunctionInfo from the YAML reprsentation.
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
bool isGlobalISelOptNone() const
This function checks whether the opt level is explicitly set to none, or whether GlobalISel was enabl...
void reset() override
Reset internal state.
AArch64TargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT, bool IsLittleEndian)
Create an AArch64 architecture model.
ScheduleDAGInstrs * createMachineScheduler(MachineSchedContext *C) const override
Create an instance of ScheduleDAGInstrs to be run within the standard MachineScheduler pass for this ...
TargetTransformInfo getTargetTransformInfo(const Function &F) const override
Return a TargetTransformInfo for a given function.
AArch64beTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT)
AArch64leTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT)
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1565
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
CodeGenTargetMachineImpl(const Target &T, StringRef DataLayoutString, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOptLevel OL)
This class represents a range of values.
LLVM_ABI APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
LLVM_ABI APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
This pass is responsible for selecting generic machine instructions to target-specific instructions.
static void setUseExtended(bool Enable)
This pass implements the localization mechanism described at the top of this file.
Definition Localizer.h:43
Pass to replace calls to ifuncs with indirect calls.
Definition LowerIFunc.h:19
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
This class provides access to building LLVM's passes.
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This pass implements the reg bank selector pass used in the GlobalISel pipeline.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition SourceMgr.h:308
Represents a range in source code.
Definition SMLoc.h:47
A ScheduleDAG for scheduling lists of MachineInstr.
ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules machine instructions while...
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
TargetInstrInfo - Interface to description of machine instruction set.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
void setSupportsDebugEntryValues(bool Enable)
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
const Triple & getTargetTriple() const
void setMachineOutliner(bool Enable)
void setCFIFixup(bool Enable)
void setSupportsDefaultOutlining(bool Enable)
void setGlobalISelAbort(GlobalISelAbortMode Mode)
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
std::unique_ptr< const MCSubtargetInfo > STI
void setGlobalISel(bool Enable)
TargetOptions Options
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned TLSSize
Bit size of immediate TLS offsets (0 == use the default).
unsigned NoTrapAfterNoreturn
Do not emit a trap instruction for 'unreachable' IR instructions behind noreturn calls,...
unsigned TrapUnreachable
Emit target-specific trap instruction for 'unreachable' IR instructions.
Target-Independent Code Generator Pass Configuration Options.
virtual void addCodeGenPrepare()
Add pass to prepare the LLVM IR for code generation.
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
virtual void addMachineSSAOptimization()
addMachineSSAOptimization - Add standard passes that optimize machine instructions in SSA form.
virtual bool addRegAssignAndRewriteOptimized()
TargetSubtargetInfo - Generic base class for all target subtargets.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
Interfaces for registering analysis passes, producing common pass manager configurations,...
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ DynamicNoPIC
Definition CodeGen.h:25
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
ScheduleDAGMILive * createSchedLive(MachineSchedContext *C)
Create the standard converging machine scheduler.
FunctionPass * createAArch64PreLegalizerCombiner()
void initializeLDTLSCleanupPass(PassRegistry &)
LLVM_ABI FunctionPass * createCFGSimplificationPass(SimplifyCFGOptions Options=SimplifyCFGOptions(), std::function< bool(const Function &)> Ftor=nullptr)
void initializeMachineSMEABIPass(PassRegistry &)
FunctionPass * createAArch64PostSelectOptimize()
void initializeAArch64PTrueCoalescingLegacyPass(PassRegistry &)
FunctionPass * createAArch64ConditionOptimizerLegacyPass()
void initializeAArch64A53Fix835769LegacyPass(PassRegistry &)
LLVM_ABI ModulePass * createJMCInstrumenterPass()
JMC instrument pass.
void initializeAArch64SpeculationHardeningPass(PassRegistry &)
FunctionPass * createAArch64RedundantCopyEliminationPass()
LLVM_ABI std::unique_ptr< ScheduleDAGMutation > createMacroFusionDAGMutation(ArrayRef< MacroFusionPredTy > Predicates, bool BranchOnly=false)
Create a DAG scheduling mutation to pair instructions back to back for instructions that benefit acco...
LLVM_ABI FunctionPass * createTypePromotionLegacyPass()
Create IR Type Promotion pass.
void initializeAArch64StackTaggingPreRALegacyPass(PassRegistry &)
FunctionPass * createMachineSMEABIPass(CodeGenOptLevel)
LLVM_ABI FunctionPass * createSelectOptimizePass()
This pass converts conditional moves to conditional jumps when profitable.
FunctionPass * createAArch64A53Fix835769LegacyPass()
LLVM_ABI Pass * createGlobalMergePass(const TargetMachine *TM, unsigned MaximalOffset, bool OnlyOptimizeForSize=false, bool MergeExternalByDefault=false, bool MergeConstantByDefault=false, bool MergeConstAggressiveByDefault=false)
GlobalMerge - This pass merges internal (by default) globals into structs to enable reuse of a base p...
void initializeAArch64BranchTargetsLegacyPass(PassRegistry &)
LLVM_ABI FunctionPass * createPseudoProbeInserter()
This pass inserts pseudo probe annotation for callsite profiling.
FunctionPass * createAArch64PostCoalescerPass()
void initializeAArch64PromoteConstantPass(PassRegistry &)
FunctionPass * createFalkorMarkStridedAccessesPass()
Target & getTheAArch64beTarget()
FunctionPass * createAArch64PointerAuthPass()
FunctionPass * createFalkorHWPFFixPass()
LLVM_ABI char & PostRASchedulerID
PostRAScheduler - This pass performs post register allocation scheduling.
std::string utostr(uint64_t X, bool isNeg=false)
FunctionPass * createAArch64O0PreLegalizerCombiner()
FunctionPass * createAArch64SLSHardeningLegacyPass()
@ O0
Disable as many optimizations as possible.
void initializeAArch64CollectLOHLegacyPass(PassRegistry &)
void initializeAArch64PostLegalizerCombinerLegacyPass(PassRegistry &)
FunctionPass * createAArch64PostLegalizerCombinerLegacy(bool IsOptNone)
FunctionPass * createAArch64LoadStoreOptLegacyPass()
createAArch64LoadStoreOptimizationPass - returns an instance of the load / store optimization pass.
FunctionPass * createAArch64CondBrTuning()
LLVM_ABI std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)
Definition CSEInfo.cpp:85
void initializeAArch64Arm64ECCallLoweringPass(PassRegistry &)
void initializeAArch64SIMDInstrOptLegacyPass(PassRegistry &)
LLVM_ABI char & PostMachineSchedulerID
PostMachineScheduler - This pass schedules machine instructions postRA.
LLVM_ABI char & PeepholeOptimizerLegacyID
PeepholeOptimizer - This pass performs peephole optimizations - like extension and comparison elimina...
LLVM_ABI Pass * createLICMPass()
Definition LICM.cpp:392
FunctionPass * createAArch64A57FPLoadBalancingLegacyPass()
Target & getTheAArch64leTarget()
FunctionPass * createAArch64DeadRegisterDefinitions()
LLVM_ABI char & EarlyIfConverterLegacyID
EarlyIfConverter - This pass performs if-conversion on SSA form by inserting cmov instructions.
void initializeAArch64RedundantCondBranchLegacyPass(PassRegistry &)
void initializeAArch64PostSelectOptimizeLegacyPass(PassRegistry &)
FunctionPass * createSMEPeepholeOptPass()
FunctionPass * createAArch64PostLegalizerLowering()
ThinOrFullLTOPhase
This enumerates the LLVM full LTO or ThinLTO optimization phases.
Definition Pass.h:77
FunctionPass * createAArch64StackTaggingPreRALegacyPass()
void initializeAArch64CodeLayoutOptPass(PassRegistry &)
FunctionPass * createAArch64PTrueCoalescingLegacyPass()
LLVM_ABI void initializeMachineKCFILegacyPass(PassRegistry &)
PassManager< Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, LPMUpdater & > LoopPassManager
The Loop pass manager.
LLVM_ABI char & MachineCombinerID
This pass performs instruction combining using trace metrics to estimate critical-path and resource d...
void initializeAArch64AsmPrinterPass(PassRegistry &)
FunctionPass * createAArch64MIPeepholeOptLegacyPass()
LLVM_ABI FunctionPass * createUnpackMachineBundlesLegacy(std::function< bool(const MachineFunction &)> Ftor)
static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM)
void initializeAArch64AdvSIMDScalarLegacyPass(PassRegistry &)
FunctionPass * createAArch64CompressJumpTablesPass()
Target & getTheAArch64_32Target()
FunctionPass * createAArch64ConditionalCompares()
FunctionPass * createAArch64ExpandPseudoLegacyPass()
Returns an instance of the pseudo instruction expansion pass.
void initializeAArch64PointerAuthLegacyPass(PassRegistry &)
ScheduleDAGMI * createSchedPostRA(MachineSchedContext *C)
Create a generic scheduler with no vreg liveness or DAG mutation passes.
LLVM_ABI char & BranchRelaxationPassID
BranchRelaxation - This pass replaces branches that need to jump further than is supported by a branc...
void initializeFalkorMarkStridedAccessesLegacyPass(PassRegistry &)
void initializeAArch64StackTaggingPass(PassRegistry &)
void initializeAArch64PostLegalizerLoweringLegacyPass(PassRegistry &)
LLVM_ABI FunctionPass * createKCFIPass()
Lowers KCFI operand bundles for indirect calls.
Definition KCFI.cpp:75
std::unique_ptr< ScheduleDAGMutation > createAArch64MacroFusionDAGMutation()
Note that you have to add: DAG.addMutation(createAArch64MacroFusionDAGMutation()); to AArch64TargetMa...
LLVM_ABI FunctionPass * createComplexDeinterleavingPass(const TargetMachine *TM)
This pass implements generation of target-specific intrinsics to support handling of complex number a...
PassManager< Module > ModulePassManager
Convenience typedef for a pass manager over modules.
ModulePass * createAArch64Arm64ECCallLoweringPass()
void initializeAArch64ConditionOptimizerLegacyPass(PassRegistry &)
LLVM_ABI std::unique_ptr< ScheduleDAGMutation > createStoreClusterDAGMutation(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, bool ReorderWhileClustering=false)
If ReorderWhileClustering is set to true, no attempt will be made to reduce reordering due to store c...
LLVM_ABI FunctionPass * createLoopDataPrefetchPass()
FunctionPass * createAArch64SIMDInstrOptPass()
Returns an instance of the high cost ASIMD instruction replacement optimization pass.
void initializeSMEPeepholeOptPass(PassRegistry &)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
FunctionPass * createAArch64StorePairSuppressPass()
void initializeAArch64PostCoalescerLegacyPass(PassRegistry &)
FunctionPass * createAArch64CollectLOHPass()
LLVM_ABI ConstantRange getVScaleRange(const Function *F, unsigned BitWidth)
Determine the possible constant range of vscale with the given bit width, based on the vscale_range f...
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
@ Default
-O2, -Os, -Oz
Definition CodeGen.h:85
LLVM_ABI FunctionPass * createCFGuardLongjmpPass()
Creates CFGuard longjmp target identification pass.
void initializeAArch64SLSHardeningLegacyPass(PassRegistry &)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Target & getTheARM64_32Target()
void initializeAArch64StorePairSuppressPass(PassRegistry &)
LLVM_ABI FunctionPass * createSeparateConstOffsetFromGEPPass(bool LowerGEP=false)
LLVM_ABI FunctionPass * createInterleavedAccessPass()
InterleavedAccess Pass - This pass identifies and matches interleaved memory accesses to target speci...
LLVM_ABI void initializeGlobalISel(PassRegistry &)
Initialize all passes linked into the GlobalISel library.
void initializeAArch64PreLegalizerCombinerLegacyPass(PassRegistry &)
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
void initializeSVEShuffleOptsPass(PassRegistry &)
void initializeAArch64LowerHomogeneousPrologEpilogLegacyPass(PassRegistry &)
LLVM_ABI FunctionPass * createCFGuardPass()
Insert Control Flow Guard checks on indirect function calls.
Definition CFGuard.cpp:316
void initializeAArch64CondBrTuningPass(PassRegistry &)
LLVM_ABI char & MachinePipelinerID
This pass performs software pipelining on machine instructions.
void initializeAArch64A57FPLoadBalancingLegacyPass(PassRegistry &)
FunctionPass * createAArch64BranchTargetsPass()
Target & getTheARM64Target()
LLVM_ABI std::unique_ptr< ScheduleDAGMutation > createLoadClusterDAGMutation(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, bool ReorderWhileClustering=false)
If ReorderWhileClustering is set to true, no attempt will be made to reduce reordering due to store c...
void initializeFalkorHWPFFixPass(PassRegistry &)
void initializeAArch64ExpandPseudoLegacyPass(PassRegistry &)
LLVM_ABI FunctionPass * createEHContGuardTargetsPass()
Creates Windows EH Continuation Guard target identification pass.
ModulePass * createAArch64LowerHomogeneousPrologEpilogPass()
void initializeAArch64SRLTDefineSuperRegsLegacyPass(PassRegistry &)
FunctionPass * createAArch64SRLTDefineSuperRegsLegacyPass()
FunctionPass * createAArch64StackTaggingPass(bool IsOptNone)
LLVM_ABI FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
FunctionPass * createAArch64CleanupLocalDynamicTLSPass()
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:390
ModulePass * createAArch64PromoteConstantPass()
void initializeAArch64CompressJumpTablesLegacyPass(PassRegistry &)
LLVM_ABI FunctionPass * createEarlyCSEPass(bool UseMemorySSA=false)
LLVM_ABI MachineFunctionPass * createMachineCopyPropagationPass(bool UseCopyInstr)
void initializeAArch64RedundantCopyEliminationLegacyPass(PassRegistry &)
Pass * createSVEShuffleOptsPass()
FunctionPass * createAArch64CodeLayoutOptPass()
FunctionPass * createAArch64AdvSIMDScalar()
FunctionPass * createAArch64RedundantCondBranchPass()
void initializeAArch64DAGToDAGISelLegacyPass(PassRegistry &)
FunctionPass * createAArch64SpeculationHardeningPass()
Returns an instance of the pseudo instruction expansion pass.
void initializeAArch64MIPeepholeOptLegacyPass(PassRegistry &)
void initializeAArch64DeadRegisterDefinitionsLegacyPass(PassRegistry &)
void initializeAArch64ConditionalComparesLegacyPass(PassRegistry &)
void initializeAArch64O0PreLegalizerCombinerLegacyPass(PassRegistry &)
LLVM_ABI FunctionPass * createInterleavedLoadCombinePass()
InterleavedLoadCombines Pass - This pass identifies interleaved loads and combines them into wide loa...
void initializeAArch64LoadStoreOptLegacyPass(PassRegistry &)
LLVM_ABI CGPassBuilderOption getCGPassBuilderOption()
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
cl::boolOrDefault EnableGlobalISelOption
MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...
static FuncInfoTy * create(BumpPtrAllocator &Allocator, const Function &F, const SubtargetTy *STI)
Factory function: default behavior is to call new using the supplied allocator.
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
RegisterTargetMachine - Helper template for registering a target machine implementation,...
Targets should override this in a way that mirrors the implementation of llvm::MachineFunctionInfo.