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

1

2

3

4

5

6

7

8

9

10

11

53#include

54#include

55#include

56#include

57

58using namespace llvm;

59

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

64

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

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

70

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

75

76

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

80

81namespace llvm {

83}

84

86

91

112}

113

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

115 if (TT.isOSBinFormatMachO())

116 return std::make_unique();

117 if (TT.isOSWindows())

118 return std::make_unique();

119 return std::make_unique();

120}

121

126

127 if (ABIName.empty())

129

130 if (ABIName == "aapcs16")

136

139}

140

143 bool isLittle) {

145 std::string Ret;

146

147 if (isLittle)

148

149 Ret += "e";

150 else

151

152 Ret += "E";

153

155

156

157 Ret += "-p:32:32";

158

159

160

161 Ret += "-Fi8";

162

163

165 Ret += "-i64:64";

166

167

168

170 Ret += "-f64:32:64";

171

172

173

175 Ret += "-v64:32:64-v128:32:128";

177 Ret += "-v128:64:128";

178

179

180

181 Ret += "-a:0:32";

182

183

184 Ret += "-n32";

185

186

187

189 Ret += "-S128";

191 Ret += "-S64";

192 else

193 Ret += "-S32";

194

195 return Ret;

196}

197

199 std::optionalReloc::Model RM) {

200 if (!RM)

201

203

205 assert(TT.isOSBinFormatELF() &&

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

207

208

211

212 return *RM;

213}

214

215

216

220 std::optionalReloc::Model RM,

221 std::optionalCodeModel::Model CM,

228 TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) {

229

230

234 else

236 }

237

238

241

251 else

253 }

254

255 if (TT.isOSBinFormatMachO()) {

258 }

259

260

262

264

265

268}

269

271

275 return ARMFunctionInfo::create(

277}

278

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

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

283

284 std::string CPU =

286 std::string FS =

288

289

290

291

292

293

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

295

296

297 if (SoftFloat)

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

299

300

301

302 std::string Key = CPU + FS;

303 if (F.hasMinSize())

304 Key += "+minsize";

305

307 if (I) {

308

309

310

313 F.hasMinSize());

314

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

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

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

318 }

319

320 return I.get();

321}

322

326}

327

331 std::optionalReloc::Model RM,

332 std::optionalCodeModel::Model CM,

335

339 std::optionalReloc::Model RM,

340 std::optionalCodeModel::Model CM,

343

344namespace {

345

346

348public:

351

353 return getTM();

354 }

355

359

361 if (ST.hasFusion())

363 return DAG;

364 }

365

369

371 if (ST.hasFusion())

375 return DAG;

376 }

377

378 void addIRPasses() override;

379 void addCodeGenPrepare() override;

380 bool addPreISel() override;

381 bool addInstSelector() override;

382 bool addIRTranslator() override;

383 bool addLegalizeMachineIR() override;

384 bool addRegBankSelect() override;

385 bool addGlobalInstructionSelect() override;

386 void addPreRegAlloc() override;

387 void addPreSched2() override;

388 void addPreEmitPass() override;

389 void addPreEmitPass2() override;

390

391 std::unique_ptr getCSEConfig() const override;

392};

393

395public:

396 static char ID;

398 StringRef getPassName() const override {

399 return "ARM Execution Domain Fix";

400 }

401};

402char ARMExecutionDomainFix::ID;

403

404}

405

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

411

413 return new ARMPassConfig(*this, PM);

414}

415

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

418}

419

420void ARMPassConfig::addIRPasses() {

423 else

425

426

427

428

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

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

435 }));

436

439

441

442

445

446

449

450

453

454

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

457

458 if (TM->Options.JMCInstrument)

460}

461

462void ARMPassConfig::addCodeGenPrepare() {

466}

467

468bool ARMPassConfig::addPreISel() {

472

473

474

475

476

477 bool OnlyOptimizeForSize =

480

481

482

483

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

486 MergeExternalByDefault));

487 }

488

492

493

494

495

496

497

498

500 }

501

502 return false;

503}

504

505bool ARMPassConfig::addInstSelector() {

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

507 return false;

508}

509

510bool ARMPassConfig::addIRTranslator() {

512 return false;

513}

514

515bool ARMPassConfig::addLegalizeMachineIR() {

517 return false;

518}

519

520bool ARMPassConfig::addRegBankSelect() {

522 return false;

523}

524

525bool ARMPassConfig::addGlobalInstructionSelect() {

527 return false;

528}

529

530void ARMPassConfig::addPreRegAlloc() {

534

536

538

541

544 }

545}

546

547void ARMPassConfig::addPreSched2() {

551

552 addPass(new ARMExecutionDomainFix());

554 }

555

556

557

559

561

562

563

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

567 }));

568

571 }));

572 }

574

575

576

580 }

581

585}

586

587void ARMPassConfig::addPreEmitPass() {

589

590

593 }));

594

595

599 }

600}

601

602void ARMPassConfig::addPreEmitPass2() {

603

604

605

607

608

610

611

612

614

615

616

618

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

620

622

624 }

625}

626

630}

631

636}

637

644 return false;

645}

646

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 > 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_EXTERNAL_VISIBILITY void LLVMInitializeARMTarget()

static ARMBaseTargetMachine::ARMABI computeTargetABI(const Triple &TT, StringRef CPU, const TargetOptions &Options)

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

static Reloc::Model getEffectiveRelocModel(const Triple &TT, std::optional< Reloc::Model > RM)

This file a TargetTransformInfo::Concept 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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

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 GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

static cl::opt< bool > EnableGlobalMerge("enable-global-merge", cl::Hidden, cl::desc("Enable the global merge pass"), cl::init(true))

This file declares the IRTranslator pass.

static std::string computeDataLayout()

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

static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")

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

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

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)

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

bool isTargetHardFloat() const

void reset() override

Reset internal state.

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

StringMap< std::unique_ptr< ARMSubtarget > > SubtargetMap

TargetTransformInfo getTargetTransformInfo(const Function &F) const override

Get a TargetTransformInfo implementation for the target.

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, bool isLittle)

Create an ARM architecture model.

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)

StringRef getValueAsString() const

Return the attribute's value as a string.

bool isValid() const

Return true if the attribute is any kind of attribute.

Allocate memory in an ever growing pool, as if by bump-pointer.

implements a set of functionality in the TargetMachine class for targets that make use of the indepen...

static const char * getManglingComponent(const Triple &T)

Lightweight error class with error context and mandatory checking.

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.

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...

static PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

This class provides the reaching def analysis.

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.

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

void setSupportsDebugEntryValues(bool Enable)

Triple TargetTriple

Triple string, CPU name, and target feature strings the TargetMachine instance is created with.

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.

FloatABI::ABIType FloatABIType

FloatABIType - This setting is set by -float-abi=xxx option is specfied on the command line.

EABI EABIVersion

EABIVersion - This flag specifies the EABI version.

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

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.

EnvironmentType getEnvironment() const

Get the parsed environment type of this triple.

bool isOSWindows() const

Tests whether the OS is Windows.

bool isOSDarwin() const

Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).

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

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU)

@ C

The default llvm calling convention, compatible with C.

unsigned ID

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

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

void initializeARMConstantIslandsPass(PassRegistry &)

FunctionPass * createCFGSimplificationPass(SimplifyCFGOptions Options=SimplifyCFGOptions(), std::function< bool(const Function &)> Ftor=nullptr)

FunctionPass * createMVETPAndVPTOptimisationsPass()

createMVETPAndVPTOptimisationsPass

Pass * createMVELaneInterleavingPass()

FunctionPass * createARMOptimizeBarriersPass()

createARMOptimizeBarriersPass - Returns an instance of the remove double barriers pass.

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

FunctionPass * createTypePromotionLegacyPass()

Create IR Type Promotion pass.

void initializeMVETailPredicationPass(PassRegistry &)

void initializeMVELaneInterleavingPass(PassRegistry &)

Pass * createMVEGatherScatterLoweringPass()

Target & getTheThumbBETarget()

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

char & PostRASchedulerID

PostRAScheduler - This pass performs post register allocation scheduling.

FunctionPass * createARMISelDag(ARMBaseTargetMachine &TM, CodeGenOptLevel OptLevel)

createARMISelDag - This pass converts a legalized DAG into a ARM-specific DAG, ready for instruction ...

std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)

FunctionPass * createARMLowOverheadLoopsPass()

FunctionPass * createARMLoadStoreOptimizationPass(bool PreAlloc=false)

Returns an instance of the load / store optimization pass.

char & PostMachineSchedulerID

PostMachineScheduler - This pass schedules machine instructions postRA.

ScheduleDAGMILive * createGenericSchedLive(MachineSchedContext *C)

Create the standard converging machine scheduler.

FunctionPass * createARMBranchTargetsPass()

ModulePass * createJMCInstrumenterPass()

JMC instrument pass.

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.

void initializeARMBranchTargetsPass(PassRegistry &)

Pass * createMVETailPredicationPass()

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 ARMPassConfig::crea...

Pass * createLowerAtomicPass()

void initializeARMParallelDSPPass(PassRegistry &)

CodeGenOptLevel

Code generation optimization level.

void initializeARMExpandPseudoPass(PassRegistry &)

FunctionPass * createA15SDOptimizerPass()

FunctionPass * createCFGuardLongjmpPass()

Creates CFGuard longjmp target identification pass.

void initializeARMSLSHardeningPass(PassRegistry &)

FunctionPass * createInterleavedAccessPass()

InterleavedAccess Pass - This pass identifies and matches interleaved memory accesses to target speci...

void initializeGlobalISel(PassRegistry &)

Initialize all passes linked into the GlobalISel library.

ScheduleDAGMI * createGenericSchedPostRA(MachineSchedContext *C)

Create a generic scheduler with no vreg liveness or DAG mutation passes.

FunctionPass * createBreakFalseDeps()

Creates Break False Dependencies pass.

char & MachinePipelinerID

This pass performs software pipelining on machine instructions.

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.

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

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

FunctionPass * createAtomicExpandLegacyPass()

AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...

FunctionPass * createEHContGuardCatchretPass()

Creates EHContGuard catchret target identification pass.

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

FunctionPass * createHardwareLoopsLegacyPass()

Create Hardware Loop pass.

Target & getTheARMBETarget()

Target & getTheThumbLETarget()

FunctionPass * createMVEVPTBlockPass()

createMVEVPTBlock - Returns an instance of the MVE VPT block insertion pass.

MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...

MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...

RegisterTargetMachine - Helper template for registering a target machine implementation,...

Targets should override this in a way that mirrors the implementation of llvm::MachineFunctionInfo.