LLVM 24.0.0git
ARMTargetMachine.cpp
Go to the documentation of this file.
1//===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
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
12#include "ARMTargetMachine.h"
13#include "ARM.h"
14#include "ARMLatencyMutations.h"
16#include "ARMMacroFusion.h"
17#include "ARMSubtarget.h"
18#include "ARMTargetObjectFile.h"
22#include "llvm/ADT/StringRef.h"
35#include "llvm/CodeGen/Passes.h"
37#include "llvm/IR/Attributes.h"
38#include "llvm/IR/CallingConv.h"
39#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/Function.h"
43#include "llvm/IR/InstrTypes.h"
44#include "llvm/IR/Module.h"
46#include "llvm/Pass.h"
57#include "llvm/Transforms/IPO.h"
59#include <cassert>
60#include <memory>
61#include <optional>
62#include <string>
63
64using namespace llvm;
65
66static cl::opt<bool>
67DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden,
68 cl::desc("Inhibit optimization of S->D register accesses on A15"),
69 cl::init(false));
70
71static cl::opt<bool>
72EnableAtomicTidy("arm-atomic-cfg-tidy", cl::Hidden,
73 cl::desc("Run SimplifyCFG after expanding atomic operations"
74 " to make use of cmpxchg flow-based information"),
75 cl::init(true));
76
77static cl::opt<bool>
78EnableARMLoadStoreOpt("arm-load-store-opt", cl::Hidden,
79 cl::desc("Enable ARM load/store optimization pass"),
80 cl::init(true));
81
82// FIXME: Unify control over GlobalMerge.
84EnableGlobalMerge("arm-global-merge", cl::Hidden,
85 cl::desc("Enable the global merge pass"));
86
87namespace llvm {
89}
90
121
122static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
123 if (TT.isOSBinFormatMachO())
124 return std::make_unique<TargetLoweringObjectFileMachO>();
125 if (TT.isOSWindows())
126 return std::make_unique<TargetLoweringObjectFileCOFF>();
127 return std::make_unique<ARMElfTargetObjectFile>();
128}
129
131 std::optional<Reloc::Model> RM) {
132 if (!RM)
133 // Default relocation model on Darwin is PIC.
134 return TT.isOSBinFormatMachO() ? Reloc::PIC_ : Reloc::Static;
135
136 if (*RM == Reloc::ROPI || *RM == Reloc::RWPI || *RM == Reloc::ROPI_RWPI)
137 assert(TT.isOSBinFormatELF() &&
138 "ROPI/RWPI currently only supported for ELF");
139
140 // DynamicNoPIC is only used on darwin.
141 if (*RM == Reloc::DynamicNoPIC && !TT.isOSDarwin())
142 return Reloc::Static;
143
144 return *RM;
145}
146
147/// Create an ARM architecture model.
148///
150 StringRef CPU, StringRef FS,
151 const TargetOptions &Options,
152 std::optional<Reloc::Model> RM,
153 std::optional<CodeModel::Model> CM,
156 T, TT.computeDataLayout(Options.MCOptions.ABIName), TT, CPU, FS,
158 getEffectiveCodeModel(CM, CodeModel::Small), OL),
159 TargetABI(ARM::computeTargetABI(TT, Options.MCOptions.ABIName)),
161
162 // Default to triple-appropriate EABI
163 if (Options.EABIVersion == EABI::Default ||
164 Options.EABIVersion == EABI::Unknown) {
165 // musl is compatible with glibc with regard to EABI version
166 if ((TargetTriple.getEnvironment() == Triple::GNUEABI ||
167 TargetTriple.getEnvironment() == Triple::GNUEABIT64 ||
168 TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
169 TargetTriple.getEnvironment() == Triple::GNUEABIHFT64 ||
170 TargetTriple.getEnvironment() == Triple::MuslEABI ||
171 TargetTriple.getEnvironment() == Triple::MuslEABIHF ||
172 TargetTriple.getEnvironment() == Triple::OpenHOS) &&
173 !(TargetTriple.isOSWindows() || TargetTriple.isOSDarwin()))
174 this->Options.EABIVersion = EABI::GNU;
175 else
176 this->Options.EABIVersion = EABI::EABI5;
177 }
178
179 if (TT.isOSBinFormatMachO()) {
180 this->Options.TrapUnreachable = true;
181 this->Options.NoTrapAfterNoreturn = true;
182 }
183
184 // ARM supports the debug entry values.
186
187 initAsmInfo();
188
189 // ARM supports the MachineOutliner.
190 setMachineOutliner(true);
192}
193
195
197 BumpPtrAllocator &Allocator, const Function &F,
198 const TargetSubtargetInfo *STI) const {
199 const auto *ARMSTI = static_cast<const ARMSubtarget *>(STI);
200 bool FPRegsUnavailable = !ARMSTI->hasFPRegs() || ARMSTI->isThumb1Only();
201 if (FPRegsUnavailable) {
202 const StringRef FPRegsUnavailableMsg =
203 ", but floating-point registers are unavailable";
204 const ARMTargetLowering *TLI = ARMSTI->getTargetLowering();
205
206 if (TLI->getEffectiveCallingConv(F.getCallingConv(), F.isVarArg()) ==
208 F.getContext().diagnose(DiagnosticInfoUnsupported(
209 F, Twine("calling convention is hard-float") + FPRegsUnavailableMsg,
210 DiagnosticLocation(F.getSubprogram())));
211 } else {
212 for (const Instruction &I : instructions(F)) {
213 const auto *CB = dyn_cast<CallBase>(&I);
214 if (!CB || CB->isInlineAsm() ||
215 (CB->getCalledFunction() && CB->getCalledFunction()->isIntrinsic()))
216 continue;
217 if (TLI->getEffectiveCallingConv(CB->getCallingConv(),
218 CB->getFunctionType()->isVarArg()) ==
220 const Function *Callee = CB->getCalledFunction();
221 F.getContext().diagnose(DiagnosticInfoUnsupported(
222 F,
223 (Callee ? Twine("'") + F.getName() + "' calls '" +
224 Callee->getName() + "', which"
225 : Twine("'") + F.getName() +
226 "' makes an indirect call that") +
227 " expects a hard-float calling convention" +
228 FPRegsUnavailableMsg,
229 CB->getDebugLoc()));
230 }
231 }
232 }
233 }
234 return ARMFunctionInfo::create<ARMFunctionInfo>(Allocator, F, ARMSTI);
235}
236
238 // An explicit "float-abi" module flag always wins, even for AAPCS16.
239 if (auto *Val = dyn_cast_or_null<MDString>(M.getModuleFlag("float-abi")))
240 return *FloatABI::parseABIType(Val->getString());
241
242 // With no explicit ABI, an explicit -target-abi=aapcs16 forces hard float
243 // even on triples whose default float ABI is soft (the triple default only
244 // detects AAPCS16 when it is the triple's own default ABI).
246 return FloatABI::Hard;
247 // Otherwise fall back to the ABI implied by the target triple.
248 return M.getTargetTriple().getDefaultFloatABI();
249}
250
252 // Consistency of "target-abi" and -target-abi is validated elsewhere.
253 if (const auto *MD = cast_or_null<MDString>(M.getModuleFlag("target-abi")))
254 return ARM::computeTargetABI(TargetTriple, MD->getString());
255 return TargetABI;
256}
257
258const ARMSubtarget *
260 Attribute CPUAttr = F.getFnAttribute("target-cpu");
261 Attribute FSAttr = F.getFnAttribute("target-features");
262
263 std::string CPU =
264 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
265 std::string FS =
266 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
267
268 // FIXME: This is related to the code below to reset the target options,
269 // we need to know whether or not the soft float flag is set on the
270 // function before we can generate a subtarget. We also need to use
271 // it as a key for the subtarget since that can be the only difference
272 // between two functions.
273 bool SoftFloat = F.getFnAttribute("use-soft-float").getValueAsBool();
274 // If the soft float attribute is set on the function turn on the soft float
275 // subtarget feature.
276 if (SoftFloat)
277 FS += FS.empty() ? "+soft-float" : ",+soft-float";
278
279 // Use the optminsize to identify the subtarget, but don't use it in the
280 // feature string.
281 std::string Key = CPU + FS;
282 if (F.hasMinSize())
283 Key += "+minsize";
284
285 DenormalMode DM = F.getDenormalFPEnv().DefaultMode;
286 if (DM != DenormalMode::getIEEE())
287 Key += "denormal-fp-math=" + DM.str();
288
289 FloatABI::ABIType FloatABI = getFloatABI(*F.getParent());
290 // It is legal to have FloatABI::Hard with +soft-float for targets with SIMD
291 // registers, but no floating-point hardware (mve+nofp)
292 Key += FloatABI == FloatABI::Hard ? "+hard-float-abi" : "+soft-float-abi";
293
294 ARM::ARMABI ABI = getEffectiveABI(*F.getParent());
295 Key += "+abi=" + std::to_string((int)ABI);
296
297 auto &I = SubtargetMap[Key];
298 if (!I) {
299 I = std::make_unique<ARMSubtarget>(TargetTriple, CPU, FS, *this, isLittle,
300 FloatABI, ABI, F.hasMinSize(), DM);
301
302 if (!I->isThumb() && !I->hasARMOps())
303 F.getContext().emitError("Function '" + F.getName() + "' uses ARM "
304 "instructions, but the target does not support ARM mode execution.");
305 }
306
307 return I.get();
308}
309
312 return TargetTransformInfo(std::make_unique<ARMTTIImpl>(this, F));
313}
314
318 // add DAG Mutations here.
319 const ARMSubtarget &ST = C->MF->getSubtarget<ARMSubtarget>();
320 if (ST.hasFusion())
322 return DAG;
323}
324
328 // add DAG Mutations here.
329 const ARMSubtarget &ST = C->MF->getSubtarget<ARMSubtarget>();
330 if (ST.hasFusion())
332 if (auto Mutation = createARMLatencyMutations(ST, C->AA))
333 DAG->addMutation(std::move(Mutation));
334 return DAG;
335}
336
338 StringRef CPU, StringRef FS,
339 const TargetOptions &Options,
340 std::optional<Reloc::Model> RM,
341 std::optional<CodeModel::Model> CM,
342 CodeGenOptLevel OL, bool JIT)
343 : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {}
344
346 StringRef CPU, StringRef FS,
347 const TargetOptions &Options,
348 std::optional<Reloc::Model> RM,
349 std::optional<CodeModel::Model> CM,
350 CodeGenOptLevel OL, bool JIT)
351 : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {}
352
353namespace {
354
355/// ARM Code Generator Pass Configuration Options.
356class ARMPassConfig : public TargetPassConfig {
357public:
358 ARMPassConfig(ARMBaseTargetMachine &TM, PassManagerBase &PM)
359 : TargetPassConfig(TM, PM) {}
360
361 ARMBaseTargetMachine &getARMTargetMachine() const {
363 }
364
365 void addIRPasses() override;
366 void addCodeGenPrepare() override;
367 bool addPreISel() override;
368 bool addInstSelector() override;
369 bool addIRTranslator() override;
370 bool addLegalizeMachineIR() override;
371 bool addRegBankSelect() override;
372 bool addGlobalInstructionSelect() override;
373 void addPreRegAlloc() override;
374 void addPreSched2() override;
375 void addPreEmitPass() override;
376 void addPreEmitPass2() override;
377
378 std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
379};
380
381class ARMExecutionDomainFix : public ExecutionDomainFix {
382public:
383 static char ID;
384 ARMExecutionDomainFix() : ExecutionDomainFix(ID, ARM::DPRRegClass) {}
385 StringRef getPassName() const override {
386 return "ARM Execution Domain Fix";
387 }
388};
389char ARMExecutionDomainFix::ID;
390
391} // end anonymous namespace
392
393INITIALIZE_PASS_BEGIN(ARMExecutionDomainFix, "arm-execution-domain-fix",
394 "ARM Execution Domain Fix", false, false)
396INITIALIZE_PASS_END(ARMExecutionDomainFix, "arm-execution-domain-fix",
397 "ARM Execution Domain Fix", false, false)
398
400#define GET_PASS_REGISTRY "ARMPassRegistry.def"
402}
403
405 return new ARMPassConfig(*this, PM);
406}
407
408std::unique_ptr<CSEConfigBase> ARMPassConfig::getCSEConfig() const {
409 return getStandardCSEConfigForOpt(TM->getOptLevel());
410}
411
412void ARMPassConfig::addIRPasses() {
413 if (TM->Options.ThreadModel == ThreadModel::Single)
414 addPass(createLowerAtomicPass());
415 else
417
418 // Cmpxchg instructions are often used with a subsequent comparison to
419 // determine whether it succeeded. We can exploit existing control-flow in
420 // ldrex/strex loops to simplify this, but it needs tidying up.
421 if (TM->getOptLevel() != CodeGenOptLevel::None && EnableAtomicTidy)
423 SimplifyCFGOptions().hoistCommonInsts(true).sinkCommonInsts(true),
424 [this](const Function &F) {
425 const auto &ST = this->TM->getSubtarget<ARMSubtarget>(F);
426 return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
427 }));
428
431
433
434 // Run the parallel DSP pass.
435 if (getOptLevel() == CodeGenOptLevel::Aggressive)
436 addPass(createARMParallelDSPPass());
437
438 // Match complex arithmetic patterns
439 if (TM->getOptLevel() >= CodeGenOptLevel::Default)
441
442 // Match interleaved memory accesses to ldN/stN intrinsics.
443 if (TM->getOptLevel() != CodeGenOptLevel::None)
445
446 // Add Control Flow Guard checks.
447 if (TM->getTargetTriple().isOSWindows())
448 addPass(createCFGuardPass());
449
450 if (TM->Options.JMCInstrument)
451 addPass(createJMCInstrumenterPass());
452}
453
454void ARMPassConfig::addCodeGenPrepare() {
455 if (getOptLevel() != CodeGenOptLevel::None)
458}
459
460bool ARMPassConfig::addPreISel() {
461 if ((TM->getOptLevel() != CodeGenOptLevel::None &&
464 // FIXME: This is using the thumb1 only constant value for
465 // maximal global offset for merging globals. We may want
466 // to look into using the old value for non-thumb1 code of
467 // 4095 based on the TargetMachine, but this starts to become
468 // tricky when doing code gen per function.
469 bool OnlyOptimizeForSize =
470 (TM->getOptLevel() < CodeGenOptLevel::Aggressive) &&
472 // Merging of extern globals is enabled by default on non-Mach-O as we
473 // expect it to be generally either beneficial or harmless. On Mach-O it
474 // is disabled as we emit the .subsections_via_symbols directive which
475 // means that merging extern globals is not safe.
476 bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();
477 addPass(createGlobalMergePass(TM, 127, OnlyOptimizeForSize,
478 MergeExternalByDefault));
479 }
480
481 if (TM->getOptLevel() != CodeGenOptLevel::None) {
484 // FIXME: IR passes can delete address-taken basic blocks, deleting
485 // corresponding blockaddresses. ARMConstantPoolConstant holds references to
486 // address-taken basic blocks which can be invalidated if the function
487 // containing the blockaddress has already been codegen'd and the basic
488 // block is removed. Work around this by forcing all IR passes to run before
489 // any ISel takes place. We should have a more principled way of handling
490 // this. See D99707 for more details.
491 addPass(createBarrierNoopPass());
492 }
493
494 return false;
495}
496
497bool ARMPassConfig::addInstSelector() {
498 addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
499 return false;
500}
501
502bool ARMPassConfig::addIRTranslator() {
503 addPass(new IRTranslatorLegacy(getOptLevel()));
504 return false;
505}
506
507bool ARMPassConfig::addLegalizeMachineIR() {
508 addPass(new LegalizerLegacy());
509 return false;
510}
511
512bool ARMPassConfig::addRegBankSelect() {
513 addPass(new RegBankSelectLegacy());
514 return false;
515}
516
517bool ARMPassConfig::addGlobalInstructionSelect() {
518 addPass(new InstructionSelectLegacy(getOptLevel()));
519 return false;
520}
521
522void ARMPassConfig::addPreRegAlloc() {
523 if (getOptLevel() != CodeGenOptLevel::None) {
524 if (getOptLevel() == CodeGenOptLevel::Aggressive)
525 addPass(&MachinePipelinerID);
526
528
529 addPass(createMLxExpansionPass());
530
532 addPass(createARMLoadStoreOptLegacyPass(/* pre-register alloc */ true));
533
535 addPass(createA15SDOptimizerPass());
536 }
537}
538
539void ARMPassConfig::addPreSched2() {
540 if (getOptLevel() != CodeGenOptLevel::None) {
543
544 addPass(new ARMExecutionDomainFix());
546 }
547
548 // Expand some pseudo instructions into multiple instructions to allow
549 // proper scheduling.
550 addPass(createARMExpandPseudoPass());
551
552 // Emit KCFI checks for indirect calls.
553 addPass(createKCFIPass());
554
555 if (getOptLevel() != CodeGenOptLevel::None) {
556 // When optimising for size, always run the Thumb2SizeReduction pass before
557 // IfConversion. Otherwise, check whether IT blocks are restricted
558 // (e.g. in v8, IfConversion depends on Thumb instruction widths)
559 addPass(createThumb2SizeReductionPass([this](const Function &F) {
560 return this->TM->getSubtarget<ARMSubtarget>(F).hasMinSize() ||
561 this->TM->getSubtarget<ARMSubtarget>(F).restrictIT();
562 }));
563
564 addPass(createIfConverter([](const MachineFunction &MF) {
565 return !MF.getSubtarget<ARMSubtarget>().isThumb1Only();
566 }));
567 }
568 addPass(createThumb2ITBlockPass());
569
570 // Add both scheduling passes to give the subtarget an opportunity to pick
571 // between them.
572 if (getOptLevel() != CodeGenOptLevel::None) {
573 addPass(&PostMachineSchedulerID);
574 addPass(&PostRASchedulerID);
575 }
576
577 addPass(createMVEVPTBlockPass());
578 addPass(createARMIndirectThunks());
579 addPass(createARMSLSHardeningPass());
580}
581
582void ARMPassConfig::addPreEmitPass() {
584
585 // Unpack bundles for:
586 // - Thumb2: Constant island pass requires unbundled instructions
587 // - KCFI: KCFI_CHECK pseudo instructions need to be unbundled for AsmPrinter
589 return MF.getSubtarget<ARMSubtarget>().isThumb2() ||
590 MF.getFunction().getParent()->getModuleFlag("kcfi");
591 }));
592
593 // Don't optimize barriers or block placement at -O0.
594 if (getOptLevel() != CodeGenOptLevel::None) {
597 }
598}
599
600void ARMPassConfig::addPreEmitPass2() {
601
602 // Inserts fixup instructions before unsafe AES operations. Instructions may
603 // be inserted at the start of blocks and at within blocks so this pass has to
604 // come before those below.
606 // Inserts BTIs at the start of functions and indirectly-called basic blocks,
607 // so passes cannot add to the start of basic blocks once this has run.
609 // Inserts Constant Islands. Block sizes cannot be increased after this point,
610 // as this may push the branch ranges and load offsets of accessing constant
611 // pools out of range..
613 // Finalises Low-Overhead Loops. This replaces pseudo instructions with real
614 // instructions, but the pseudos all have conservative sizes so that block
615 // sizes will only be decreased by this pass.
617
618 if (TM->getTargetTriple().isOSWindows()) {
619 // Identify valid longjmp targets for Windows Control Flow Guard.
620 addPass(createCFGuardLongjmpPass());
621 // Identify valid eh continuation targets for Windows EHCont Guard.
623 }
624}
625
630
633 const auto *MFI = MF.getInfo<ARMFunctionInfo>();
634 return new yaml::ARMFunctionInfo(*MFI);
635}
636
639 SMDiagnostic &Error, SMRange &SourceRange) const {
640 const auto &YamlMFI = static_cast<const yaml::ARMFunctionInfo &>(MFI);
641 MachineFunction &MF = PFS.MF;
642 MF.getInfo<ARMFunctionInfo>()->initializeBaseYamlFields(YamlMFI);
643 return false;
644}
645
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 std::unique_ptr< TargetLoweringObjectFile > createTLOF(const Triple &TT)
static Reloc::Model getEffectiveRelocModel()
static cl::opt< bool > DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden, cl::desc("Inhibit optimization of S->D register accesses on A15"), cl::init(false))
static cl::opt< cl::boolOrDefault > EnableGlobalMerge("arm-global-merge", cl::Hidden, cl::desc("Enable the global merge pass"))
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTarget()
static cl::opt< bool > EnableARMLoadStoreOpt("arm-load-store-opt", cl::Hidden, cl::desc("Enable ARM load/store optimization pass"), cl::init(true))
static cl::opt< bool > EnableAtomicTidy("arm-atomic-cfg-tidy", cl::Hidden, cl::desc("Run SimplifyCFG after expanding atomic operations" " to make use of cmpxchg flow-based information"), cl::init(true))
This file a TargetTransformInfoImplBase conforming object specific to the ARM target machine.
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for continuously CSEing during GISel passes.
This file describes how to lower LLVM calls to machine code calls.
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
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.
Module.h This file contains the declarations for the Module class.
Interface for Targets to specify which operations they can successfully select and how the others sho...
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT, const TargetOptions &Options)
PowerPC VSX FMA Mutation
if(PassOpts->AAPipeline)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
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()
ARMBETargetMachine(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 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 ...
std::unique_ptr< TargetLoweringObjectFile > TLOF
ARM::ARMABI getEffectiveABI(const Module &M) const
Returns the ABI in effect for M: the "target-abi" module flag if present, otherwise the legacy -targe...
void reset() override
Reset internal state.
ARMBaseTargetMachine(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)
Create an ARM architecture model.
MachineFunctionInfo * createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override
Create the target's instance of MachineFunctionInfo.
yaml::MachineFunctionInfo * createDefaultFuncInfoYAML() const override
Allocate and return a default initialized instance of the YAML representation for the MachineFunction...
const ARMSubtarget * getSubtargetImpl() const =delete
FloatABI::ABIType getFloatABI(const Module &M) const
Returns the floating-point ABI in effect for M: the "float-abi" module flag if present,...
ScheduleDAGInstrs * createMachineScheduler(MachineSchedContext *C) const override
Create an instance of ScheduleDAGInstrs to be run within the standard MachineScheduler pass for this ...
StringMap< std::unique_ptr< ARMSubtarget > > SubtargetMap
void registerPassBuilderCallbacks(PassBuilder &PB) override
Allow the target to modify the pass pipeline.
TargetTransformInfo getTargetTransformInfo(const Function &F) const override
Return a TargetTransformInfo for a given function.
ScheduleDAGInstrs * createPostMachineScheduler(MachineSchedContext *C) const override
Similar to createMachineScheduler but used when postRA machine scheduling is enabled.
yaml::MachineFunctionInfo * convertFuncInfoToYAML(const MachineFunction &MF) const override
Allocate and initialize an instance of the YAML representation of the MachineFunctionInfo.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
ARMLETargetMachine(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 isThumb1Only() const
CallingConv::ID getEffectiveCallingConv(CallingConv::ID CC, bool isVarArg) const
getEffectiveCallingConv - Get the effective calling convention, taking into account presence of float...
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)
Diagnostic information for unsupported feature in backend.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Module * getParent()
Get the module that this global value is contained inside of...
This pass is responsible for selecting generic machine instructions to target-specific instructions.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Definition Module.cpp:358
This class provides access to building LLVM's passes.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
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.
A global registry used in conjunction with static constructors to make pluggable components (like tar...
Definition Registry.h:116
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...
void addMutation(std::unique_ptr< ScheduleDAGMutation > Mutation)
Add a postprocessing step to the DAG builder.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
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 setSupportsDefaultOutlining(bool Enable)
std::unique_ptr< const MCSubtargetInfo > STI
TargetOptions Options
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...
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
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
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,...
Define some predicates that are used for node matching.
Definition ARMEHABI.h:25
LLVM_ABI LLVM_READONLY ARMABI computeTargetABI(const Triple &TT, StringRef ABIName="")
@ ARM_AAPCS_VFP
Same as ARM_AAPCS, but uses hard floating point ABI.
std::optional< ABIType > parseABIType(StringRef S)
Parse the string spelling used by the "float-abi" IR module flag into an ABIType.
Definition CodeGen.h:117
@ DynamicNoPIC
Definition CodeGen.h:26
@ ARM
Windows AXP64.
Definition MCAsmInfo.h:50
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.
void initializeARMConstantIslandsPass(PassRegistry &)
LLVM_ABI FunctionPass * createCFGSimplificationPass(SimplifyCFGOptions Options=SimplifyCFGOptions(), std::function< bool(const Function &)> Ftor=nullptr)
FunctionPass * createMVETPAndVPTOptimisationsPass()
createMVETPAndVPTOptimisationsPass
Pass * createMVELaneInterleavingPass()
LLVM_ABI ModulePass * createJMCInstrumenterPass()
JMC instrument pass.
FunctionPass * createARMOptimizeBarriersPass()
createARMOptimizeBarriersPass - Returns an instance of the remove double barriers pass.
LLVM_ABI FunctionPass * createIfConverter(std::function< bool(const MachineFunction &)> Ftor)
LLVM_ABI FunctionPass * createTypePromotionLegacyPass()
Create IR Type Promotion pass.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
void initializeMVETailPredicationPass(PassRegistry &)
void initializeMVELaneInterleavingPass(PassRegistry &)
Pass * createMVEGatherScatterLoweringPass()
LLVM_ABI FunctionPass * createEHContGuardTargetsLegacy()
Creates Windows EH Continuation Guard target identification pass.
Target & getTheThumbBETarget()
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...
auto cast_or_null(const Y &Val)
Definition Casting.h:714
LLVM_ABI char & PostRASchedulerID
PostRAScheduler - This pass performs post register allocation scheduling.
LLVM_ABI Pass * createLowerAtomicPass()
FunctionPass * createARMISelDag(ARMBaseTargetMachine &TM, CodeGenOptLevel OptLevel)
createARMISelDag - This pass converts a legalized DAG into a ARM-specific DAG, ready for instruction ...
LLVM_ABI std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)
Definition CSEInfo.cpp:85
FunctionPass * createARMLowOverheadLoopsPass()
LLVM_ABI char & PostMachineSchedulerID
PostMachineScheduler - This pass schedules machine instructions postRA.
void initializeARMPreAllocLoadStoreOptLegacyPass(PassRegistry &)
FunctionPass * createARMBranchTargetsPass()
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
LLVM_ABI void initializeMachineKCFILegacyPass(PassRegistry &)
LLVM_ABI FunctionPass * createUnpackMachineBundlesLegacy(std::function< bool(const MachineFunction &)> Ftor)
static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM)
std::unique_ptr< ScheduleDAGMutation > createARMLatencyMutations(const ARMSubtarget &ST, AAResults *AA)
CodeModel::Model getEffectiveCodeModel(std::optional< CodeModel::Model > CM, CodeModel::Model Default)
Helper method for getting the code model, returning Default if CM does not have a value.
ScheduleDAGMI * createSchedPostRA(MachineSchedContext *C)
Create a generic scheduler with no vreg liveness or DAG mutation passes.
void initializeARMBranchTargetsPass(PassRegistry &)
Pass * createMVETailPredicationPass()
LLVM_ABI FunctionPass * createKCFIPass()
Lowers KCFI operand bundles for indirect calls.
Definition KCFI.cpp:75
LLVM_ABI FunctionPass * createComplexDeinterleavingPass(const TargetMachine *TM)
This pass implements generation of target-specific intrinsics to support handling of complex number a...
FunctionPass * createARMBlockPlacementPass()
std::unique_ptr< ScheduleDAGMutation > createARMMacroFusionDAGMutation()
Note that you have to add: DAG.addMutation(createARMMacroFusionDAGMutation()); to ARMTargetMachine::c...
void initializeARMParallelDSPPass(PassRegistry &)
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:149
@ Default
-O2, -Os, -Oz
Definition CodeGen.h:152
FunctionPass * createARMLoadStoreOptLegacyPass(bool PreAlloc=false)
Returns an instance of the load / store optimization pass.
LLVM_ABI FunctionPass * createCFGuardLongjmpPass()
Creates CFGuard longjmp target identification pass.
void initializeARMExpandPseudoPass(PassRegistry &)
FunctionPass * createA15SDOptimizerPass()
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
void initializeARMSLSHardeningPass(PassRegistry &)
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 initializeARMAsmPrinterPass(PassRegistry &)
LLVM_ABI FunctionPass * createCFGuardPass()
Insert Control Flow Guard checks on indirect function calls.
Definition CFGuard.cpp:316
void initializeARMLoadStoreOptLegacyPass(PassRegistry &)
LLVM_ABI char & MachinePipelinerID
This pass performs software pipelining on machine instructions.
LLVM_ABI ModulePass * createBarrierNoopPass()
createBarrierNoopPass - This pass is purely a module pass barrier in a pass manager.
FunctionPass * createARMSLSHardeningPass()
FunctionPass * createARMConstantIslandPass()
createARMConstantIslandPass - returns an instance of the constpool island pass.
void initializeARMLowOverheadLoopsPass(PassRegistry &)
void initializeMVETPAndVPTOptimisationsPass(PassRegistry &)
void initializeARMExecutionDomainFixPass(PassRegistry &)
void initializeThumb2SizeReducePass(PassRegistry &)
FunctionPass * createThumb2ITBlockPass()
createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks insertion pass.
void initializeMVEGatherScatterLoweringPass(PassRegistry &)
FunctionPass * createARMExpandPseudoPass()
createARMExpandPseudoPass - returns an instance of the pseudo instruction expansion pass.
FunctionPass * createARMIndirectThunks()
void initializeARMFixCortexA57AES1742098Pass(PassRegistry &)
FunctionPass * createARMFixCortexA57AES1742098Pass()
Pass * createARMParallelDSPPass()
LLVM_ABI FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:390
FunctionPass * createThumb2SizeReductionPass(std::function< bool(const Function &)> Ftor=nullptr)
createThumb2SizeReductionPass - Returns an instance of the Thumb2 size reduction pass.
Target & getTheARMLETarget()
LLVM_ABI FunctionPass * createBreakFalseDepsLegacyPass()
Creates Break False Dependencies pass.
void initializeMVEVPTBlockPass(PassRegistry &)
void initializeARMDAGToDAGISelLegacyPass(PassRegistry &)
FunctionPass * createMLxExpansionPass()
void initializeARMBlockPlacementPass(PassRegistry &)
LLVM_ABI FunctionPass * createHardwareLoopsLegacyPass()
Create Hardware Loop pass.
Target & getTheARMBETarget()
Target & getTheThumbLETarget()
FunctionPass * createMVEVPTBlockPass()
createMVEVPTBlock - Returns an instance of the MVE VPT block insertion pass.
Represent subnormal handling kind for floating point instruction inputs and outputs.
static constexpr DenormalMode getIEEE()
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.