1//===-- PPCTargetMachine.cpp - Define TargetMachine for PowerPC -----------===//
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// Top-level implementation for the PowerPC target.
10//
11//===----------------------------------------------------------------------===//
12
13#include "PPCTargetMachine.h"
14#include "MCTargetDesc/PPCMCTargetDesc.h"
15#include "PPC.h"
16#include "PPCMachineFunctionInfo.h"
17#include "PPCMachineScheduler.h"
18#include "PPCMacroFusion.h"
19#include "PPCSubtarget.h"
20#include "PPCTargetObjectFile.h"
21#include "PPCTargetTransformInfo.h"
22#include "TargetInfo/PowerPCTargetInfo.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Analysis/TargetTransformInfo.h"
25#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
26#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
27#include "llvm/CodeGen/GlobalISel/Legalizer.h"
28#include "llvm/CodeGen/GlobalISel/Localizer.h"
29#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
30#include "llvm/CodeGen/MachineScheduler.h"
31#include "llvm/CodeGen/Passes.h"
32#include "llvm/CodeGen/TargetPassConfig.h"
33#include "llvm/IR/Attributes.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/Function.h"
36#include "llvm/InitializePasses.h"
37#include "llvm/MC/TargetRegistry.h"
38#include "llvm/Pass.h"
39#include "llvm/Support/CodeGen.h"
40#include "llvm/Support/CommandLine.h"
41#include "llvm/Support/Compiler.h"
42#include "llvm/Target/TargetLoweringObjectFile.h"
43#include "llvm/Target/TargetOptions.h"
44#include "llvm/TargetParser/Triple.h"
45#include "llvm/Transforms/Scalar.h"
46#include <cassert>
47#include <memory>
48#include <optional>
49#include <string>
50
51using namespace llvm;
52
53
54static cl::opt<bool>
55 EnableBranchCoalescing("enable-ppc-branch-coalesce", cl::Hidden,
56 cl::desc("enable coalescing of duplicate branches for PPC"));
57static cl::
58opt<bool> DisableCTRLoops("disable-ppc-ctrloops", cl::Hidden,
59 cl::desc("Disable CTR loops for PPC"));
60
61static cl::
62opt<bool> DisableInstrFormPrep("disable-ppc-instr-form-prep", cl::Hidden,
63 cl::desc("Disable PPC loop instr form prep"));
64
65static cl::opt<bool>
66VSXFMAMutateEarly("schedule-ppc-vsx-fma-mutation-early",
67 cl::Hidden, cl::desc("Schedule VSX FMA instruction mutation early"));
68
69static cl::
70opt<bool> DisableVSXSwapRemoval("disable-ppc-vsx-swap-removal", cl::Hidden,
71 cl::desc("Disable VSX Swap Removal for PPC"));
72
73static cl::
74opt<bool> DisableMIPeephole("disable-ppc-peephole", cl::Hidden,
75 cl::desc("Disable machine peepholes for PPC"));
76
77static cl::opt<bool>
78EnableGEPOpt("ppc-gep-opt", cl::Hidden,
79 cl::desc("Enable optimizations on complex GEPs"),
80 cl::init(Val: true));
81
82static cl::opt<bool>
83EnablePrefetch("enable-ppc-prefetching",
84 cl::desc("enable software prefetching on PPC"),
85 cl::init(Val: false), cl::Hidden);
86
87static cl::opt<bool>
88EnableExtraTOCRegDeps("enable-ppc-extra-toc-reg-deps",
89 cl::desc("Add extra TOC register dependencies"),
90 cl::init(Val: true), cl::Hidden);
91
92static cl::opt<bool>
93EnableMachineCombinerPass("ppc-machine-combiner",
94 cl::desc("Enable the machine combiner pass"),
95 cl::init(Val: true), cl::Hidden);
96
97static cl::opt<bool>
98 ReduceCRLogical("ppc-reduce-cr-logicals",
99 cl::desc("Expand eligible cr-logical binary ops to branches"),
100 cl::init(Val: true), cl::Hidden);
101
102static cl::opt<bool> EnablePPCGenScalarMASSEntries(
103 "enable-ppc-gen-scalar-mass", cl::init(Val: false),
104 cl::desc("Enable lowering math functions to their corresponding MASS "
105 "(scalar) entries"),
106 cl::Hidden);
107
108static cl::opt<bool>
109 EnableGlobalMerge("ppc-global-merge", cl::Hidden, cl::init(Val: false),
110 cl::desc("Enable the global merge pass"));
111
112static cl::opt<unsigned>
113 GlobalMergeMaxOffset("ppc-global-merge-max-offset", cl::Hidden,
114 cl::init(Val: 0x7fff),
115 cl::desc("Maximum global merge offset"));
116
117extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
118LLVMInitializePowerPCTarget() {
119 // Register the targets
120 RegisterTargetMachine<PPCTargetMachine> A(getThePPC32Target());
121 RegisterTargetMachine<PPCTargetMachine> B(getThePPC32LETarget());
122 RegisterTargetMachine<PPCTargetMachine> C(getThePPC64Target());
123 RegisterTargetMachine<PPCTargetMachine> D(getThePPC64LETarget());
124
125 PassRegistry &PR = *PassRegistry::getPassRegistry();
126#ifndef NDEBUG
127 initializePPCCTRLoopsVerifyPass(PR);
128#endif
129 initializePPCLoopInstrFormPrepPass(PR);
130 initializePPCTOCRegDepsPass(PR);
131 initializePPCEarlyReturnPass(PR);
132 initializePPCVSXWACCCopyPass(PR);
133 initializePPCVSXFMAMutatePass(PR);
134 initializePPCVSXSwapRemovalPass(PR);
135 initializePPCReduceCRLogicalsPass(PR);
136 initializePPCBSelPass(PR);
137 initializePPCBranchCoalescingPass(PR);
138 initializePPCBoolRetToIntPass(PR);
139 initializePPCPreEmitPeepholePass(PR);
140 initializePPCTLSDynamicCallPass(PR);
141 initializePPCMIPeepholePass(PR);
142 initializePPCLowerMASSVEntriesPass(PR);
143 initializePPCGenScalarMASSEntriesPass(PR);
144 initializePPCExpandAtomicPseudoPass(PR);
145 initializeGlobalISel(PR);
146 initializePPCCTRLoopsPass(PR);
147 initializePPCDAGToDAGISelLegacyPass(PR);
148 initializePPCPrepareIFuncsOnAIXPass(PR);
149 initializePPCLinuxAsmPrinterPass(PR);
150 initializePPCAIXAsmPrinterPass(PR);
151}
152
153static std::string computeFSAdditions(StringRef FS, CodeGenOptLevel OL,
154 const Triple &TT) {
155 std::string FullFS = std::string(FS);
156
157 // Make sure 64-bit features are available when CPUname is generic
158 if (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le) {
159 if (!FullFS.empty())
160 FullFS = "+64bit," + FullFS;
161 else
162 FullFS = "+64bit";
163 }
164
165 if (OL >= CodeGenOptLevel::Default) {
166 if (!FullFS.empty())
167 FullFS = "+crbits," + FullFS;
168 else
169 FullFS = "+crbits";
170 }
171
172 if (OL != CodeGenOptLevel::None) {
173 if (!FullFS.empty())
174 FullFS = "+invariant-function-descriptors," + FullFS;
175 else
176 FullFS = "+invariant-function-descriptors";
177 }
178
179 if (TT.isOSAIX()) {
180 if (!FullFS.empty())
181 FullFS = "+aix," + FullFS;
182 else
183 FullFS = "+aix";
184 }
185
186 return FullFS;
187}
188
189static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
190 if (TT.isOSAIX())
191 return std::make_unique<TargetLoweringObjectFileXCOFF>();
192
193 return std::make_unique<PPC64LinuxTargetObjectFile>();
194}
195
196static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT,
197 const TargetOptions &Options) {
198 if (Options.MCOptions.getABIName().starts_with(Prefix: "elfv1"))
199 return PPCTargetMachine::PPC_ABI_ELFv1;
200 else if (Options.MCOptions.getABIName().starts_with(Prefix: "elfv2"))
201 return PPCTargetMachine::PPC_ABI_ELFv2;
202
203 assert(Options.MCOptions.getABIName().empty() &&
204 "Unknown target-abi option!");
205
206 switch (TT.getArch()) {
207 case Triple::ppc64le:
208 return PPCTargetMachine::PPC_ABI_ELFv2;
209 case Triple::ppc64:
210 if (TT.isPPC64ELFv2ABI())
211 return PPCTargetMachine::PPC_ABI_ELFv2;
212 else
213 return PPCTargetMachine::PPC_ABI_ELFv1;
214 default:
215 return PPCTargetMachine::PPC_ABI_UNKNOWN;
216 }
217}
218
219static Reloc::Model getEffectiveRelocModel(const Triple &TT,
220 std::optional<Reloc::Model> RM) {
221 if (TT.isOSAIX() && RM && *RM != Reloc::PIC_)
222 report_fatal_error(reason: "invalid relocation model, AIX only supports PIC",
223 gen_crash_diag: false);
224
225 if (RM)
226 return *RM;
227
228 // Big Endian PPC and AIX default to PIC.
229 if (TT.getArch() == Triple::ppc64 || TT.isOSAIX())
230 return Reloc::PIC_;
231
232 // Rest are static by default.
233 return Reloc::Static;
234}
235
236static CodeModel::Model
237getEffectivePPCCodeModel(const Triple &TT, std::optional<CodeModel::Model> CM,
238 bool JIT) {
239 if (CM) {
240 if (*CM == CodeModel::Tiny)
241 report_fatal_error(reason: "Target does not support the tiny CodeModel", gen_crash_diag: false);
242 if (*CM == CodeModel::Kernel)
243 report_fatal_error(reason: "Target does not support the kernel CodeModel", gen_crash_diag: false);
244 return *CM;
245 }
246
247 if (JIT)
248 return CodeModel::Small;
249 if (TT.isOSAIX())
250 return CodeModel::Small;
251
252 assert(TT.isOSBinFormatELF() && "All remaining PPC OSes are ELF based.");
253
254 if (TT.isArch32Bit())
255 return CodeModel::Small;
256
257 assert(TT.isArch64Bit() && "Unsupported PPC architecture.");
258 return CodeModel::Medium;
259}
260
261
262static ScheduleDAGInstrs *createPPCMachineScheduler(MachineSchedContext *C) {
263 const PPCSubtarget &ST = C->MF->getSubtarget<PPCSubtarget>();
264 ScheduleDAGMILive *DAG = ST.usePPCPreRASchedStrategy()
265 ? createSchedLive<PPCPreRASchedStrategy>(C)
266 : createSchedLive<GenericScheduler>(C);
267 // add DAG Mutations here.
268 if (ST.hasStoreFusion())
269 DAG->addMutation(Mutation: createStoreClusterDAGMutation(TII: DAG->TII, TRI: DAG->TRI));
270 if (ST.hasFusion())
271 DAG->addMutation(Mutation: createPowerPCMacroFusionDAGMutation());
272
273 return DAG;
274}
275
276static ScheduleDAGInstrs *
277createPPCPostMachineScheduler(MachineSchedContext *C) {
278 const PPCSubtarget &ST = C->MF->getSubtarget<PPCSubtarget>();
279 ScheduleDAGMI *DAG = ST.usePPCPostRASchedStrategy()
280 ? createSchedPostRA<PPCPostRASchedStrategy>(C)
281 : createSchedPostRA<PostGenericScheduler>(C);
282 // add DAG Mutations here.
283 if (ST.hasStoreFusion())
284 DAG->addMutation(Mutation: createStoreClusterDAGMutation(TII: DAG->TII, TRI: DAG->TRI));
285 if (ST.hasFusion())
286 DAG->addMutation(Mutation: createPowerPCMacroFusionDAGMutation());
287 return DAG;
288}
289
290// The FeatureString here is a little subtle. We are modifying the feature
291// string with what are (currently) non-function specific overrides as it goes
292// into the CodeGenTargetMachineImpl constructor and then using the stored value
293// in the Subtarget constructor below it.
294PPCTargetMachine::PPCTargetMachine(const Target &T, const Triple &TT,
295 StringRef CPU, StringRef FS,
296 const TargetOptions &Options,
297 std::optional<Reloc::Model> RM,
298 std::optional<CodeModel::Model> CM,
299 CodeGenOptLevel OL, bool JIT)
300 : CodeGenTargetMachineImpl(T,
301 TT.computeDataLayout(ABIName: Options.MCOptions.ABIName),
302 TT, CPU, computeFSAdditions(FS, OL, TT), Options,
303 getEffectiveRelocModel(TT, RM),
304 getEffectivePPCCodeModel(TT, CM, JIT), OL),
305 TLOF(createTLOF(TT: getTargetTriple())),
306 TargetABI(computeTargetABI(TT, Options)),
307 Endianness(TT.isLittleEndian() ? Endian::LITTLE : Endian::BIG) {
308 initAsmInfo();
309}
310
311PPCTargetMachine::~PPCTargetMachine() = default;
312
313const PPCSubtarget *
314PPCTargetMachine::getSubtargetImpl(const Function &F) const {
315 Attribute CPUAttr = F.getFnAttribute(Kind: "target-cpu");
316 Attribute TuneAttr = F.getFnAttribute(Kind: "tune-cpu");
317 Attribute FSAttr = F.getFnAttribute(Kind: "target-features");
318
319 std::string CPU =
320 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
321 std::string TuneCPU =
322 TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
323 std::string FS =
324 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
325
326 // FIXME: This is related to the code below to reset the target options,
327 // we need to know whether or not the soft float flag is set on the
328 // function before we can generate a subtarget. We also need to use
329 // it as a key for the subtarget since that can be the only difference
330 // between two functions.
331 bool SoftFloat = F.getFnAttribute(Kind: "use-soft-float").getValueAsBool();
332 // If the soft float attribute is set on the function turn on the soft float
333 // subtarget feature.
334 if (SoftFloat)
335 FS += FS.empty() ? "-hard-float" : ",-hard-float";
336
337 auto &I = SubtargetMap[CPU + TuneCPU + FS];
338 if (!I) {
339 // This needs to be done before we create a new subtarget since any
340 // creation will depend on the TM and the code generation flags on the
341 // function that reside in TargetOptions.
342 resetTargetOptions(F);
343 I = std::make_unique<PPCSubtarget>(
344 args: TargetTriple, args&: CPU, args&: TuneCPU,
345 // FIXME: It would be good to have the subtarget additions here
346 // not necessary. Anything that turns them on/off (overrides) ends
347 // up being put at the end of the feature string, but the defaults
348 // shouldn't require adding them. Fixing this means pulling Feature64Bit
349 // out of most of the target cpus in the .td file and making it set only
350 // as part of initialization via the TargetTriple.
351 args: computeFSAdditions(FS, OL: getOptLevel(), TT: getTargetTriple()), args: *this);
352 }
353 return I.get();
354}
355
356ScheduleDAGInstrs *
357PPCTargetMachine::createMachineScheduler(MachineSchedContext *C) const {
358 return createPPCMachineScheduler(C);
359}
360
361ScheduleDAGInstrs *
362PPCTargetMachine::createPostMachineScheduler(MachineSchedContext *C) const {
363 return createPPCPostMachineScheduler(C);
364}
365
366//===----------------------------------------------------------------------===//
367// Pass Pipeline Configuration
368//===----------------------------------------------------------------------===//
369
370namespace {
371
372/// PPC Code Generator Pass Configuration Options.
373class PPCPassConfig : public TargetPassConfig {
374public:
375 PPCPassConfig(PPCTargetMachine &TM, PassManagerBase &PM)
376 : TargetPassConfig(TM, PM) {
377 // At any optimization level above -O0 we use the Machine Scheduler and not
378 // the default Post RA List Scheduler.
379 if (TM.getOptLevel() != CodeGenOptLevel::None)
380 substitutePass(StandardID: &PostRASchedulerID, TargetID: &PostMachineSchedulerID);
381 }
382
383 PPCTargetMachine &getPPCTargetMachine() const {
384 return getTM<PPCTargetMachine>();
385 }
386
387 void addIRPasses() override;
388 bool addPreISel() override;
389 bool addILPOpts() override;
390 bool addInstSelector() override;
391 void addMachineSSAOptimization() override;
392 void addPreRegAlloc() override;
393 void addPreSched2() override;
394 void addPreEmitPass() override;
395 void addPreEmitPass2() override;
396 // GlobalISEL
397 bool addIRTranslator() override;
398 bool addLegalizeMachineIR() override;
399 bool addRegBankSelect() override;
400 bool addGlobalInstructionSelect() override;
401};
402
403} // end anonymous namespace
404
405TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) {
406 return new PPCPassConfig(*this, PM);
407}
408
409void PPCPassConfig::addIRPasses() {
410 if (TM->getOptLevel() != CodeGenOptLevel::None)
411 addPass(P: createPPCBoolRetToIntPass());
412 addPass(P: createAtomicExpandLegacyPass());
413
414 // Lower generic MASSV routines to PowerPC subtarget-specific entries.
415 addPass(P: createPPCLowerMASSVEntriesPass());
416
417 // Generate PowerPC target-specific entries for scalar math functions
418 // that are available in IBM MASS (scalar) library.
419 if (TM->getOptLevel() == CodeGenOptLevel::Aggressive &&
420 EnablePPCGenScalarMASSEntries) {
421 TM->Options.PPCGenScalarMASSEntries = EnablePPCGenScalarMASSEntries;
422 addPass(P: createPPCGenScalarMASSEntriesPass());
423 }
424
425 // If explicitly requested, add explicit data prefetch intrinsics.
426 if (EnablePrefetch.getNumOccurrences() > 0)
427 addPass(P: createLoopDataPrefetchPass());
428
429 if (TM->getOptLevel() >= CodeGenOptLevel::Default && EnableGEPOpt) {
430 // Call SeparateConstOffsetFromGEP pass to extract constants within indices
431 // and lower a GEP with multiple indices to either arithmetic operations or
432 // multiple GEPs with single index.
433 addPass(P: createSeparateConstOffsetFromGEPPass(LowerGEP: true));
434 // Call EarlyCSE pass to find and remove subexpressions in the lowered
435 // result.
436 addPass(P: createEarlyCSEPass());
437 // Do loop invariant code motion in case part of the lowered result is
438 // invariant.
439 addPass(P: createLICMPass());
440 }
441
442 if (TM->getTargetTriple().isOSAIX())
443 addPass(P: createPPCPrepareIFuncsOnAIXPass());
444
445 TargetPassConfig::addIRPasses();
446}
447
448bool PPCPassConfig::addPreISel() {
449 // The GlobalMerge pass is intended to be on by default on AIX.
450 // Specifying the command line option overrides the AIX default.
451 if ((EnableGlobalMerge.getNumOccurrences() > 0)
452 ? EnableGlobalMerge
453 : getOptLevel() != CodeGenOptLevel::None)
454 addPass(P: createGlobalMergePass(TM, MaximalOffset: GlobalMergeMaxOffset, OnlyOptimizeForSize: false, MergeExternalByDefault: false, MergeConstantByDefault: true,
455 MergeConstAggressiveByDefault: true));
456
457 if (!DisableInstrFormPrep && getOptLevel() != CodeGenOptLevel::None)
458 addPass(P: createPPCLoopInstrFormPrepPass(TM&: getPPCTargetMachine()));
459
460 if (!DisableCTRLoops && getOptLevel() != CodeGenOptLevel::None)
461 addPass(P: createHardwareLoopsLegacyPass());
462
463 return false;
464}
465
466bool PPCPassConfig::addILPOpts() {
467 addPass(PassID: &EarlyIfConverterLegacyID);
468
469 if (EnableMachineCombinerPass)
470 addPass(PassID: &MachineCombinerID);
471
472 return true;
473}
474
475bool PPCPassConfig::addInstSelector() {
476 // Install an instruction selector.
477 addPass(P: createPPCISelDag(TM&: getPPCTargetMachine(), OL: getOptLevel()));
478
479#ifndef NDEBUG
480 if (!DisableCTRLoops && getOptLevel() != CodeGenOptLevel::None)
481 addPass(createPPCCTRLoopsVerify());
482#endif
483
484 addPass(P: createPPCVSXWACCCopyPass());
485 return false;
486}
487
488void PPCPassConfig::addMachineSSAOptimization() {
489 // Run CTR loops pass before any cfg modification pass to prevent the
490 // canonical form of hardware loop from being destroied.
491 if (!DisableCTRLoops && getOptLevel() != CodeGenOptLevel::None)
492 addPass(P: createPPCCTRLoopsPass());
493
494 // PPCBranchCoalescingPass need to be done before machine sinking
495 // since it merges empty blocks.
496 if (EnableBranchCoalescing && getOptLevel() != CodeGenOptLevel::None)
497 addPass(P: createPPCBranchCoalescingPass());
498 TargetPassConfig::addMachineSSAOptimization();
499 // For little endian, remove where possible the vector swap instructions
500 // introduced at code generation to normalize vector element order.
501 if (TM->getTargetTriple().getArch() == Triple::ppc64le &&
502 !DisableVSXSwapRemoval)
503 addPass(P: createPPCVSXSwapRemovalPass());
504 // Reduce the number of cr-logical ops.
505 if (ReduceCRLogical && getOptLevel() != CodeGenOptLevel::None)
506 addPass(P: createPPCReduceCRLogicalsPass());
507 // Target-specific peephole cleanups performed after instruction
508 // selection.
509 if (!DisableMIPeephole) {
510 addPass(P: createPPCMIPeepholePass());
511 addPass(PassID: &DeadMachineInstructionElimID);
512 }
513}
514
515void PPCPassConfig::addPreRegAlloc() {
516 if (getOptLevel() != CodeGenOptLevel::None) {
517 insertPass(TargetPassID: VSXFMAMutateEarly ? &TwoAddressInstructionPassID
518 : &MachineSchedulerID,
519 InsertedPassID: &PPCVSXFMAMutateID);
520 }
521
522 // FIXME: We probably don't need to run these for -fPIE.
523 if (getPPCTargetMachine().isPositionIndependent()) {
524 // FIXME: LiveVariables should not be necessary here!
525 // PPCTLSDynamicCallPass uses LiveIntervals which previously dependent on
526 // LiveVariables. This (unnecessary) dependency has been removed now,
527 // however a stage-2 clang build fails without LiveVariables computed here.
528 addPass(PassID: &LiveVariablesID);
529 addPass(P: createPPCTLSDynamicCallPass());
530 }
531 if (EnableExtraTOCRegDeps)
532 addPass(P: createPPCTOCRegDepsPass());
533
534 if (getOptLevel() != CodeGenOptLevel::None)
535 addPass(PassID: &MachinePipelinerID);
536}
537
538void PPCPassConfig::addPreSched2() {
539 if (getOptLevel() != CodeGenOptLevel::None)
540 addPass(PassID: &IfConverterID);
541}
542
543void PPCPassConfig::addPreEmitPass() {
544 addPass(P: createPPCPreEmitPeepholePass());
545
546 if (getOptLevel() != CodeGenOptLevel::None)
547 addPass(P: createPPCEarlyReturnPass());
548}
549
550void PPCPassConfig::addPreEmitPass2() {
551 // Schedule the expansion of AMOs at the last possible moment, avoiding the
552 // possibility for other passes to break the requirements for forward
553 // progress in the LL/SC block.
554 addPass(P: createPPCExpandAtomicPseudoPass());
555 // Must run branch selection immediately preceding the asm printer.
556 addPass(P: createPPCBranchSelectionPass());
557}
558
559TargetTransformInfo
560PPCTargetMachine::getTargetTransformInfo(const Function &F) const {
561 return TargetTransformInfo(std::make_unique<PPCTTIImpl>(args: this, args: F));
562}
563
564bool PPCTargetMachine::isLittleEndian() const {
565 assert(Endianness != Endian::NOT_DETECTED &&
566 "Unable to determine endianness");
567 return Endianness == Endian::LITTLE;
568}
569
570MachineFunctionInfo *PPCTargetMachine::createMachineFunctionInfo(
571 BumpPtrAllocator &Allocator, const Function &F,
572 const TargetSubtargetInfo *STI) const {
573 return PPCFunctionInfo::create<PPCFunctionInfo>(Allocator, F, STI);
574}
575
576static MachineSchedRegistry
577PPCPreRASchedRegistry("ppc-prera",
578 "Run PowerPC PreRA specific scheduler",
579 createPPCMachineScheduler);
580
581static MachineSchedRegistry
582PPCPostRASchedRegistry("ppc-postra",
583 "Run PowerPC PostRA specific scheduler",
584 createPPCPostMachineScheduler);
585
586// Global ISEL
587bool PPCPassConfig::addIRTranslator() {
588 addPass(P: new IRTranslator());
589 return false;
590}
591
592bool PPCPassConfig::addLegalizeMachineIR() {
593 addPass(P: new Legalizer());
594 return false;
595}
596
597bool PPCPassConfig::addRegBankSelect() {
598 addPass(P: new RegBankSelect());
599 return false;
600}
601
602bool PPCPassConfig::addGlobalInstructionSelect() {
603 addPass(P: new InstructionSelect(getOptLevel()));
604 return false;
605}
606