LLVM: lib/Target/ARM/ARMTargetMachine.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

54#include

55#include

56#include

57#include

58

59using namespace llvm;

60

63 cl::desc("Inhibit optimization of S->D register accesses on A15"),

65

68 cl::desc("Run SimplifyCFG after expanding atomic operations"

69 " to make use of cmpxchg flow-based information"),

71

74 cl::desc("Enable ARM load/store optimization pass"),

76

77

80 cl::desc("Enable the global merge pass"));

81

82namespace llvm {

84}

85

116

117static std::unique_ptr createTLOF(const Triple &TT) {

118 if (TT.isOSBinFormatMachO())

119 return std::make_unique();

120 if (TT.isOSWindows())

121 return std::make_unique();

122 return std::make_unique();

123}

124

126 std::optionalReloc::Model RM) {

127 if (!RM)

128

130

132 assert(TT.isOSBinFormatELF() &&

133 "ROPI/RWPI currently only supported for ELF");

134

135

138

139 return *RM;

140}

141

142

143

147 std::optionalReloc::Model RM,

148 std::optionalCodeModel::Model CM,

151 T, TT.computeDataLayout(Options.MCOptions.ABIName), TT, CPU, FS,

156

157

159 if (isTargetHardFloat())

160 this->Options.FloatABIType = FloatABI::Hard;

161 else

162 this->Options.FloatABIType = FloatABI::Soft;

163 }

164

165

168

169 if ((TargetTriple.getEnvironment() == Triple::GNUEABI ||

170 TargetTriple.getEnvironment() == Triple::GNUEABIT64 ||

171 TargetTriple.getEnvironment() == Triple::GNUEABIHF ||

172 TargetTriple.getEnvironment() == Triple::GNUEABIHFT64 ||

173 TargetTriple.getEnvironment() == Triple::MuslEABI ||

174 TargetTriple.getEnvironment() == Triple::MuslEABIHF ||

175 TargetTriple.getEnvironment() == Triple::OpenHOS) &&

176 !(TargetTriple.isOSWindows() || TargetTriple.isOSDarwin()))

177 this->Options.EABIVersion = EABI::GNU;

178 else

179 this->Options.EABIVersion = EABI::EABI5;

180 }

181

182 if (TT.isOSBinFormatMachO()) {

183 this->Options.TrapUnreachable = true;

184 this->Options.NoTrapAfterNoreturn = true;

185 }

186

187

189

191

192

195}

196

198

205

208 Attribute CPUAttr = F.getFnAttribute("target-cpu");

209 Attribute FSAttr = F.getFnAttribute("target-features");

210

211 std::string CPU =

213 std::string FS =

215

216

217

218

219

220

221 bool SoftFloat = F.getFnAttribute("use-soft-float").getValueAsBool();

222

223

224 if (SoftFloat)

225 FS += FS.empty() ? "+soft-float" : ",+soft-float";

226

227

228

229 std::string Key = CPU + FS;

230 if (F.hasMinSize())

231 Key += "+minsize";

232

235 Key += "denormal-fp-math=" + DM.str();

236

238 if (I) {

239

240

241

244 F.hasMinSize(), DM);

245

246 if (I->isThumb() && I->hasARMOps())

247 F.getContext().emitError("Function '" + F.getName() + "' uses ARM "

248 "instructions, but the target does not support ARM mode execution.");

249 }

250

251 return I.get();

252}

253

258

262

264 if (ST.hasFusion())

266 return DAG;

267}

268

272

274 if (ST.hasFusion())

278 return DAG;

279}

280

284 std::optionalReloc::Model RM,

285 std::optionalCodeModel::Model CM,

288

292 std::optionalReloc::Model RM,

293 std::optionalCodeModel::Model CM,

296

297namespace {

298

299

301public:

304

307 }

308

309 void addIRPasses() override;

310 void addCodeGenPrepare() override;

311 bool addPreISel() override;

312 bool addInstSelector() override;

313 bool addIRTranslator() override;

314 bool addLegalizeMachineIR() override;

315 bool addRegBankSelect() override;

316 bool addGlobalInstructionSelect() override;

317 void addPreRegAlloc() override;

318 void addPreSched2() override;

319 void addPreEmitPass() override;

320 void addPreEmitPass2() override;

321

322 std::unique_ptr getCSEConfig() const override;

323};

324

326public:

327 static char ID;

328 ARMExecutionDomainFix() : ExecutionDomainFix(ID, ARM::DPRRegClass) {}

329 StringRef getPassName() const override {

330 return "ARM Execution Domain Fix";

331 }

332};

333char ARMExecutionDomainFix::ID;

334

335}

336

338 "ARM Execution Domain Fix", false, false)

342

344 return new ARMPassConfig(*this, PM);

345}

346

347std::unique_ptr ARMPassConfig::getCSEConfig() const {

349}

350

351void ARMPassConfig::addIRPasses() {

354 else

356

357

358

359

364 const auto &ST = this->TM->getSubtarget<ARMSubtarget>(F);

365 return ST.hasAnyDataBarrier() && !ST.isThumb1Only();

366 }));

367

370

372

373

376

377

380

381

384

385

386 if (TM->getTargetTriple().isOSWindows())

388

389 if (TM->Options.JMCInstrument)

391}

392

393void ARMPassConfig::addCodeGenPrepare() {

397}

398

399bool ARMPassConfig::addPreISel() {

403

404

405

406

407

408 bool OnlyOptimizeForSize =

411

412

413

414

415 bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();

417 MergeExternalByDefault));

418 }

419

423

424

425

426

427

428

429

431 }

432

433 return false;

434}

435

436bool ARMPassConfig::addInstSelector() {

437 addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));

438 return false;

439}

440

441bool ARMPassConfig::addIRTranslator() {

443 return false;

444}

445

446bool ARMPassConfig::addLegalizeMachineIR() {

448 return false;

449}

450

451bool ARMPassConfig::addRegBankSelect() {

453 return false;

454}

455

456bool ARMPassConfig::addGlobalInstructionSelect() {

458 return false;

459}

460

461void ARMPassConfig::addPreRegAlloc() {

465

467

469

472

475 }

476}

477

478void ARMPassConfig::addPreSched2() {

482

483 addPass(new ARMExecutionDomainFix());

485 }

486

487

488

490

491

493

495

496

497

499 return this->TM->getSubtarget<ARMSubtarget>(F).hasMinSize() ||

500 this->TM->getSubtarget<ARMSubtarget>(F).restrictIT();

501 }));

502

505 }));

506 }

508

509

510

514 }

515

519}

520

521void ARMPassConfig::addPreEmitPass() {

523

524

525

526

530 }));

531

532

536 }

537}

538

539void ARMPassConfig::addPreEmitPass2() {

540

541

542

543

545

546

548

549

550

552

553

554

556

557 if (TM->getTargetTriple().isOSWindows()) {

558

560

562 }

563}

564

569

575

584

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()

Definition ARMTargetMachine.cpp:86

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.

This file contains the simple types necessary to represent the attributes associated with functions a...

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_EXTERNAL_VISIBILITY

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.

Interface for Targets to specify which operations they can successfully select and how the others sho...

static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT, const TargetOptions &Options)

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

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")

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

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)

Definition ARMTargetMachine.cpp:289

~ARMBaseTargetMachine() override

bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &, PerFunctionMIParsingState &PFS, SMDiagnostic &Error, SMRange &SourceRange) const override

Parse out the target's MachineFunctionInfo from the YAML reprsentation.

Definition ARMTargetMachine.cpp:576

std::unique_ptr< TargetLoweringObjectFile > TLOF

void reset() override

Reset internal state.

Definition ARMTargetMachine.cpp:585

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.

Definition ARMTargetMachine.cpp:144

MachineFunctionInfo * createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override

Create the target's instance of MachineFunctionInfo.

Definition ARMTargetMachine.cpp:199

yaml::MachineFunctionInfo * createDefaultFuncInfoYAML() const override

Allocate and return a default initialized instance of the YAML representation for the MachineFunction...

Definition ARMTargetMachine.cpp:566

TargetPassConfig * createPassConfig(PassManagerBase &PM) override

Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...

Definition ARMTargetMachine.cpp:343

const ARMSubtarget * getSubtargetImpl() const =delete

ScheduleDAGInstrs * createMachineScheduler(MachineSchedContext *C) const override

Create an instance of ScheduleDAGInstrs to be run within the standard MachineScheduler pass for this ...

Definition ARMTargetMachine.cpp:260

StringMap< std::unique_ptr< ARMSubtarget > > SubtargetMap

bool isLittleEndian() const

TargetTransformInfo getTargetTransformInfo(const Function &F) const override

Return a TargetTransformInfo for a given function.

Definition ARMTargetMachine.cpp:255

ScheduleDAGInstrs * createPostMachineScheduler(MachineSchedContext *C) const override

Similar to createMachineScheduler but used when postRA machine scheduling is enabled.

Definition ARMTargetMachine.cpp:270

yaml::MachineFunctionInfo * convertFuncInfoToYAML(const MachineFunction &MF) const override

Allocate and initialize an instance of the YAML representation of the MachineFunctionInfo.

Definition ARMTargetMachine.cpp:571

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)

Definition ARMTargetMachine.cpp:281

Functions, function parameters, and return types can have attributes to indicate how they should be t...

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.

CodeGenTargetMachineImpl(const Target &T, StringRef DataLayoutString, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOptLevel OL)

Lightweight error class with error context and mandatory checking.

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...

Metadata * getModuleFlag(StringRef Key) const

Return the corresponding value if Key appears in module flags, otherwise return null.

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...

Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...

Represents a range in source code.

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.

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

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

void resetTargetOptions(const Function &F) const

Reset the target options based on the function's attributes.

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.

PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...

Define some predicates that are used for node matching.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ C

The default llvm calling convention, compatible with C.

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.

void initializeMVETailPredicationPass(PassRegistry &)

void initializeMVELaneInterleavingPass(PassRegistry &)

Pass * createMVEGatherScatterLoweringPass()

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...

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)

FunctionPass * createARMLowOverheadLoopsPass()

FunctionPass * createARMLoadStoreOptimizationPass(bool PreAlloc=false)

Returns an instance of the load / store optimization pass.

LLVM_ABI char & PostMachineSchedulerID

PostMachineScheduler - This pass schedules machine instructions postRA.

FunctionPass * createARMBranchTargetsPass()

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.

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.

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.

LLVM_ABI void initializeKCFIPass(PassRegistry &)

void initializeARMAsmPrinterPass(PassRegistry &)

LLVM_ABI FunctionPass * createBreakFalseDeps()

Creates Break False Dependencies pass.

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.

LLVM_ABI FunctionPass * createUnpackMachineBundles(std::function< bool(const MachineFunction &)> Ftor)

void initializeARMLowOverheadLoopsPass(PassRegistry &)

FunctionPass * createCFGuardCheckPass()

Insert Control FLow Guard checks on indirect function calls.

void initializeMVETPAndVPTOptimisationsPass(PassRegistry &)

void initializeARMExecutionDomainFixPass(PassRegistry &)

LLVM_ABI FunctionPass * createEHContGuardTargetsPass()

Creates Windows EH Continuation Guard target identification pass.

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.

FunctionPass * createThumb2SizeReductionPass(std::function< bool(const Function &)> Ftor=nullptr)

createThumb2SizeReductionPass - Returns an instance of the Thumb2 size reduction pass.

Target & getTheARMLETarget()

void initializeMVEVPTBlockPass(PassRegistry &)

void initializeARMDAGToDAGISelLegacyPass(PassRegistry &)

FunctionPass * createMLxExpansionPass()

void initializeARMLoadStoreOptPass(PassRegistry &)

void initializeARMPreAllocLoadStoreOptPass(PassRegistry &)

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.