ARMTargetMachine.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  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. #include "ARMTargetMachine.h"
  12. #include "ARM.h"
  13. #include "ARMMachineFunctionInfo.h"
  14. #include "ARMMacroFusion.h"
  15. #include "ARMSubtarget.h"
  16. #include "ARMTargetObjectFile.h"
  17. #include "ARMTargetTransformInfo.h"
  18. #include "MCTargetDesc/ARMMCTargetDesc.h"
  19. #include "TargetInfo/ARMTargetInfo.h"
  20. #include "llvm/ADT/STLExtras.h"
  21. #include "llvm/ADT/StringRef.h"
  22. #include "llvm/ADT/Triple.h"
  23. #include "llvm/Analysis/TargetTransformInfo.h"
  24. #include "llvm/CodeGen/ExecutionDomainFix.h"
  25. #include "llvm/CodeGen/GlobalISel/CSEInfo.h"
  26. #include "llvm/CodeGen/GlobalISel/CallLowering.h"
  27. #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
  28. #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
  29. #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
  30. #include "llvm/CodeGen/GlobalISel/Legalizer.h"
  31. #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
  32. #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
  33. #include "llvm/CodeGen/MachineFunction.h"
  34. #include "llvm/CodeGen/MachineScheduler.h"
  35. #include "llvm/CodeGen/Passes.h"
  36. #include "llvm/CodeGen/RegisterBankInfo.h"
  37. #include "llvm/CodeGen/TargetPassConfig.h"
  38. #include "llvm/IR/Attributes.h"
  39. #include "llvm/IR/DataLayout.h"
  40. #include "llvm/IR/Function.h"
  41. #include "llvm/MC/TargetRegistry.h"
  42. #include "llvm/Pass.h"
  43. #include "llvm/Support/ARMTargetParser.h"
  44. #include "llvm/Support/CodeGen.h"
  45. #include "llvm/Support/CommandLine.h"
  46. #include "llvm/Support/ErrorHandling.h"
  47. #include "llvm/Support/TargetParser.h"
  48. #include "llvm/Target/TargetLoweringObjectFile.h"
  49. #include "llvm/Target/TargetOptions.h"
  50. #include "llvm/Transforms/CFGuard.h"
  51. #include "llvm/Transforms/IPO.h"
  52. #include "llvm/Transforms/Scalar.h"
  53. #include <cassert>
  54. #include <memory>
  55. #include <optional>
  56. #include <string>
  57. using namespace llvm;
  58. static cl::opt<bool>
  59. DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden,
  60. cl::desc("Inhibit optimization of S->D register accesses on A15"),
  61. cl::init(false));
  62. static cl::opt<bool>
  63. EnableAtomicTidy("arm-atomic-cfg-tidy", cl::Hidden,
  64. cl::desc("Run SimplifyCFG after expanding atomic operations"
  65. " to make use of cmpxchg flow-based information"),
  66. cl::init(true));
  67. static cl::opt<bool>
  68. EnableARMLoadStoreOpt("arm-load-store-opt", cl::Hidden,
  69. cl::desc("Enable ARM load/store optimization pass"),
  70. cl::init(true));
  71. // FIXME: Unify control over GlobalMerge.
  72. static cl::opt<cl::boolOrDefault>
  73. EnableGlobalMerge("arm-global-merge", cl::Hidden,
  74. cl::desc("Enable the global merge pass"));
  75. namespace llvm {
  76. void initializeARMExecutionDomainFixPass(PassRegistry&);
  77. }
  78. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTarget() {
  79. // Register the target.
  80. RegisterTargetMachine<ARMLETargetMachine> X(getTheARMLETarget());
  81. RegisterTargetMachine<ARMLETargetMachine> A(getTheThumbLETarget());
  82. RegisterTargetMachine<ARMBETargetMachine> Y(getTheARMBETarget());
  83. RegisterTargetMachine<ARMBETargetMachine> B(getTheThumbBETarget());
  84. PassRegistry &Registry = *PassRegistry::getPassRegistry();
  85. initializeGlobalISel(Registry);
  86. initializeARMLoadStoreOptPass(Registry);
  87. initializeARMPreAllocLoadStoreOptPass(Registry);
  88. initializeARMParallelDSPPass(Registry);
  89. initializeARMBranchTargetsPass(Registry);
  90. initializeARMConstantIslandsPass(Registry);
  91. initializeARMExecutionDomainFixPass(Registry);
  92. initializeARMExpandPseudoPass(Registry);
  93. initializeThumb2SizeReducePass(Registry);
  94. initializeMVEVPTBlockPass(Registry);
  95. initializeMVETPAndVPTOptimisationsPass(Registry);
  96. initializeMVETailPredicationPass(Registry);
  97. initializeARMLowOverheadLoopsPass(Registry);
  98. initializeARMBlockPlacementPass(Registry);
  99. initializeMVEGatherScatterLoweringPass(Registry);
  100. initializeARMSLSHardeningPass(Registry);
  101. initializeMVELaneInterleavingPass(Registry);
  102. initializeARMFixCortexA57AES1742098Pass(Registry);
  103. initializeARMDAGToDAGISelPass(Registry);
  104. }
  105. static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
  106. if (TT.isOSBinFormatMachO())
  107. return std::make_unique<TargetLoweringObjectFileMachO>();
  108. if (TT.isOSWindows())
  109. return std::make_unique<TargetLoweringObjectFileCOFF>();
  110. return std::make_unique<ARMElfTargetObjectFile>();
  111. }
  112. static ARMBaseTargetMachine::ARMABI
  113. computeTargetABI(const Triple &TT, StringRef CPU,
  114. const TargetOptions &Options) {
  115. StringRef ABIName = Options.MCOptions.getABIName();
  116. if (ABIName.empty())
  117. ABIName = ARM::computeDefaultTargetABI(TT, CPU);
  118. if (ABIName == "aapcs16")
  119. return ARMBaseTargetMachine::ARM_ABI_AAPCS16;
  120. else if (ABIName.startswith("aapcs"))
  121. return ARMBaseTargetMachine::ARM_ABI_AAPCS;
  122. else if (ABIName.startswith("apcs"))
  123. return ARMBaseTargetMachine::ARM_ABI_APCS;
  124. llvm_unreachable("Unhandled/unknown ABI Name!");
  125. return ARMBaseTargetMachine::ARM_ABI_UNKNOWN;
  126. }
  127. static std::string computeDataLayout(const Triple &TT, StringRef CPU,
  128. const TargetOptions &Options,
  129. bool isLittle) {
  130. auto ABI = computeTargetABI(TT, CPU, Options);
  131. std::string Ret;
  132. if (isLittle)
  133. // Little endian.
  134. Ret += "e";
  135. else
  136. // Big endian.
  137. Ret += "E";
  138. Ret += DataLayout::getManglingComponent(TT);
  139. // Pointers are 32 bits and aligned to 32 bits.
  140. Ret += "-p:32:32";
  141. // Function pointers are aligned to 8 bits (because the LSB stores the
  142. // ARM/Thumb state).
  143. Ret += "-Fi8";
  144. // ABIs other than APCS have 64 bit integers with natural alignment.
  145. if (ABI != ARMBaseTargetMachine::ARM_ABI_APCS)
  146. Ret += "-i64:64";
  147. // We have 64 bits floats. The APCS ABI requires them to be aligned to 32
  148. // bits, others to 64 bits. We always try to align to 64 bits.
  149. if (ABI == ARMBaseTargetMachine::ARM_ABI_APCS)
  150. Ret += "-f64:32:64";
  151. // We have 128 and 64 bit vectors. The APCS ABI aligns them to 32 bits, others
  152. // to 64. We always ty to give them natural alignment.
  153. if (ABI == ARMBaseTargetMachine::ARM_ABI_APCS)
  154. Ret += "-v64:32:64-v128:32:128";
  155. else if (ABI != ARMBaseTargetMachine::ARM_ABI_AAPCS16)
  156. Ret += "-v128:64:128";
  157. // Try to align aggregates to 32 bits (the default is 64 bits, which has no
  158. // particular hardware support on 32-bit ARM).
  159. Ret += "-a:0:32";
  160. // Integer registers are 32 bits.
  161. Ret += "-n32";
  162. // The stack is 128 bit aligned on NaCl, 64 bit aligned on AAPCS and 32 bit
  163. // aligned everywhere else.
  164. if (TT.isOSNaCl() || ABI == ARMBaseTargetMachine::ARM_ABI_AAPCS16)
  165. Ret += "-S128";
  166. else if (ABI == ARMBaseTargetMachine::ARM_ABI_AAPCS)
  167. Ret += "-S64";
  168. else
  169. Ret += "-S32";
  170. return Ret;
  171. }
  172. static Reloc::Model getEffectiveRelocModel(const Triple &TT,
  173. std::optional<Reloc::Model> RM) {
  174. if (!RM)
  175. // Default relocation model on Darwin is PIC.
  176. return TT.isOSBinFormatMachO() ? Reloc::PIC_ : Reloc::Static;
  177. if (*RM == Reloc::ROPI || *RM == Reloc::RWPI || *RM == Reloc::ROPI_RWPI)
  178. assert(TT.isOSBinFormatELF() &&
  179. "ROPI/RWPI currently only supported for ELF");
  180. // DynamicNoPIC is only used on darwin.
  181. if (*RM == Reloc::DynamicNoPIC && !TT.isOSDarwin())
  182. return Reloc::Static;
  183. return *RM;
  184. }
  185. /// Create an ARM architecture model.
  186. ///
  187. ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,
  188. StringRef CPU, StringRef FS,
  189. const TargetOptions &Options,
  190. std::optional<Reloc::Model> RM,
  191. std::optional<CodeModel::Model> CM,
  192. CodeGenOpt::Level OL, bool isLittle)
  193. : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT,
  194. CPU, FS, Options, getEffectiveRelocModel(TT, RM),
  195. getEffectiveCodeModel(CM, CodeModel::Small), OL),
  196. TargetABI(computeTargetABI(TT, CPU, Options)),
  197. TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) {
  198. // Default to triple-appropriate float ABI
  199. if (Options.FloatABIType == FloatABI::Default) {
  200. if (isTargetHardFloat())
  201. this->Options.FloatABIType = FloatABI::Hard;
  202. else
  203. this->Options.FloatABIType = FloatABI::Soft;
  204. }
  205. // Default to triple-appropriate EABI
  206. if (Options.EABIVersion == EABI::Default ||
  207. Options.EABIVersion == EABI::Unknown) {
  208. // musl is compatible with glibc with regard to EABI version
  209. if ((TargetTriple.getEnvironment() == Triple::GNUEABI ||
  210. TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
  211. TargetTriple.getEnvironment() == Triple::MuslEABI ||
  212. TargetTriple.getEnvironment() == Triple::MuslEABIHF) &&
  213. !(TargetTriple.isOSWindows() || TargetTriple.isOSDarwin()))
  214. this->Options.EABIVersion = EABI::GNU;
  215. else
  216. this->Options.EABIVersion = EABI::EABI5;
  217. }
  218. if (TT.isOSBinFormatMachO()) {
  219. this->Options.TrapUnreachable = true;
  220. this->Options.NoTrapAfterNoreturn = true;
  221. }
  222. // ARM supports the debug entry values.
  223. setSupportsDebugEntryValues(true);
  224. initAsmInfo();
  225. // ARM supports the MachineOutliner.
  226. setMachineOutliner(true);
  227. setSupportsDefaultOutlining(true);
  228. }
  229. ARMBaseTargetMachine::~ARMBaseTargetMachine() = default;
  230. MachineFunctionInfo *ARMBaseTargetMachine::createMachineFunctionInfo(
  231. BumpPtrAllocator &Allocator, const Function &F,
  232. const TargetSubtargetInfo *STI) const {
  233. return ARMFunctionInfo::create<ARMFunctionInfo>(
  234. Allocator, F, static_cast<const ARMSubtarget *>(STI));
  235. }
  236. const ARMSubtarget *
  237. ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {
  238. Attribute CPUAttr = F.getFnAttribute("target-cpu");
  239. Attribute FSAttr = F.getFnAttribute("target-features");
  240. std::string CPU =
  241. CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
  242. std::string FS =
  243. FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
  244. // FIXME: This is related to the code below to reset the target options,
  245. // we need to know whether or not the soft float flag is set on the
  246. // function before we can generate a subtarget. We also need to use
  247. // it as a key for the subtarget since that can be the only difference
  248. // between two functions.
  249. bool SoftFloat = F.getFnAttribute("use-soft-float").getValueAsBool();
  250. // If the soft float attribute is set on the function turn on the soft float
  251. // subtarget feature.
  252. if (SoftFloat)
  253. FS += FS.empty() ? "+soft-float" : ",+soft-float";
  254. // Use the optminsize to identify the subtarget, but don't use it in the
  255. // feature string.
  256. std::string Key = CPU + FS;
  257. if (F.hasMinSize())
  258. Key += "+minsize";
  259. auto &I = SubtargetMap[Key];
  260. if (!I) {
  261. // This needs to be done before we create a new subtarget since any
  262. // creation will depend on the TM and the code generation flags on the
  263. // function that reside in TargetOptions.
  264. resetTargetOptions(F);
  265. I = std::make_unique<ARMSubtarget>(TargetTriple, CPU, FS, *this, isLittle,
  266. F.hasMinSize());
  267. if (!I->isThumb() && !I->hasARMOps())
  268. F.getContext().emitError("Function '" + F.getName() + "' uses ARM "
  269. "instructions, but the target does not support ARM mode execution.");
  270. }
  271. return I.get();
  272. }
  273. TargetTransformInfo
  274. ARMBaseTargetMachine::getTargetTransformInfo(const Function &F) const {
  275. return TargetTransformInfo(ARMTTIImpl(this, F));
  276. }
  277. ARMLETargetMachine::ARMLETargetMachine(const Target &T, const Triple &TT,
  278. StringRef CPU, StringRef FS,
  279. const TargetOptions &Options,
  280. std::optional<Reloc::Model> RM,
  281. std::optional<CodeModel::Model> CM,
  282. CodeGenOpt::Level OL, bool JIT)
  283. : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
  284. ARMBETargetMachine::ARMBETargetMachine(const Target &T, const Triple &TT,
  285. StringRef CPU, StringRef FS,
  286. const TargetOptions &Options,
  287. std::optional<Reloc::Model> RM,
  288. std::optional<CodeModel::Model> CM,
  289. CodeGenOpt::Level OL, bool JIT)
  290. : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
  291. namespace {
  292. /// ARM Code Generator Pass Configuration Options.
  293. class ARMPassConfig : public TargetPassConfig {
  294. public:
  295. ARMPassConfig(ARMBaseTargetMachine &TM, PassManagerBase &PM)
  296. : TargetPassConfig(TM, PM) {}
  297. ARMBaseTargetMachine &getARMTargetMachine() const {
  298. return getTM<ARMBaseTargetMachine>();
  299. }
  300. ScheduleDAGInstrs *
  301. createMachineScheduler(MachineSchedContext *C) const override {
  302. ScheduleDAGMILive *DAG = createGenericSchedLive(C);
  303. // add DAG Mutations here.
  304. const ARMSubtarget &ST = C->MF->getSubtarget<ARMSubtarget>();
  305. if (ST.hasFusion())
  306. DAG->addMutation(createARMMacroFusionDAGMutation());
  307. return DAG;
  308. }
  309. ScheduleDAGInstrs *
  310. createPostMachineScheduler(MachineSchedContext *C) const override {
  311. ScheduleDAGMI *DAG = createGenericSchedPostRA(C);
  312. // add DAG Mutations here.
  313. const ARMSubtarget &ST = C->MF->getSubtarget<ARMSubtarget>();
  314. if (ST.hasFusion())
  315. DAG->addMutation(createARMMacroFusionDAGMutation());
  316. return DAG;
  317. }
  318. void addIRPasses() override;
  319. void addCodeGenPrepare() override;
  320. bool addPreISel() override;
  321. bool addInstSelector() override;
  322. bool addIRTranslator() override;
  323. bool addLegalizeMachineIR() override;
  324. bool addRegBankSelect() override;
  325. bool addGlobalInstructionSelect() override;
  326. void addPreRegAlloc() override;
  327. void addPreSched2() override;
  328. void addPreEmitPass() override;
  329. void addPreEmitPass2() override;
  330. std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
  331. };
  332. class ARMExecutionDomainFix : public ExecutionDomainFix {
  333. public:
  334. static char ID;
  335. ARMExecutionDomainFix() : ExecutionDomainFix(ID, ARM::DPRRegClass) {}
  336. StringRef getPassName() const override {
  337. return "ARM Execution Domain Fix";
  338. }
  339. };
  340. char ARMExecutionDomainFix::ID;
  341. } // end anonymous namespace
  342. INITIALIZE_PASS_BEGIN(ARMExecutionDomainFix, "arm-execution-domain-fix",
  343. "ARM Execution Domain Fix", false, false)
  344. INITIALIZE_PASS_DEPENDENCY(ReachingDefAnalysis)
  345. INITIALIZE_PASS_END(ARMExecutionDomainFix, "arm-execution-domain-fix",
  346. "ARM Execution Domain Fix", false, false)
  347. TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
  348. return new ARMPassConfig(*this, PM);
  349. }
  350. std::unique_ptr<CSEConfigBase> ARMPassConfig::getCSEConfig() const {
  351. return getStandardCSEConfigForOpt(TM->getOptLevel());
  352. }
  353. void ARMPassConfig::addIRPasses() {
  354. if (TM->Options.ThreadModel == ThreadModel::Single)
  355. addPass(createLowerAtomicPass());
  356. else
  357. addPass(createAtomicExpandPass());
  358. // Cmpxchg instructions are often used with a subsequent comparison to
  359. // determine whether it succeeded. We can exploit existing control-flow in
  360. // ldrex/strex loops to simplify this, but it needs tidying up.
  361. if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
  362. addPass(createCFGSimplificationPass(
  363. SimplifyCFGOptions().hoistCommonInsts(true).sinkCommonInsts(true),
  364. [this](const Function &F) {
  365. const auto &ST = this->TM->getSubtarget<ARMSubtarget>(F);
  366. return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
  367. }));
  368. addPass(createMVEGatherScatterLoweringPass());
  369. addPass(createMVELaneInterleavingPass());
  370. TargetPassConfig::addIRPasses();
  371. // Run the parallel DSP pass.
  372. if (getOptLevel() == CodeGenOpt::Aggressive)
  373. addPass(createARMParallelDSPPass());
  374. // Match complex arithmetic patterns
  375. if (TM->getOptLevel() >= CodeGenOpt::Default)
  376. addPass(createComplexDeinterleavingPass(TM));
  377. // Match interleaved memory accesses to ldN/stN intrinsics.
  378. if (TM->getOptLevel() != CodeGenOpt::None)
  379. addPass(createInterleavedAccessPass());
  380. // Add Control Flow Guard checks.
  381. if (TM->getTargetTriple().isOSWindows())
  382. addPass(createCFGuardCheckPass());
  383. if (TM->Options.JMCInstrument)
  384. addPass(createJMCInstrumenterPass());
  385. }
  386. void ARMPassConfig::addCodeGenPrepare() {
  387. if (getOptLevel() != CodeGenOpt::None)
  388. addPass(createTypePromotionLegacyPass());
  389. TargetPassConfig::addCodeGenPrepare();
  390. }
  391. bool ARMPassConfig::addPreISel() {
  392. if ((TM->getOptLevel() != CodeGenOpt::None &&
  393. EnableGlobalMerge == cl::BOU_UNSET) ||
  394. EnableGlobalMerge == cl::BOU_TRUE) {
  395. // FIXME: This is using the thumb1 only constant value for
  396. // maximal global offset for merging globals. We may want
  397. // to look into using the old value for non-thumb1 code of
  398. // 4095 based on the TargetMachine, but this starts to become
  399. // tricky when doing code gen per function.
  400. bool OnlyOptimizeForSize = (TM->getOptLevel() < CodeGenOpt::Aggressive) &&
  401. (EnableGlobalMerge == cl::BOU_UNSET);
  402. // Merging of extern globals is enabled by default on non-Mach-O as we
  403. // expect it to be generally either beneficial or harmless. On Mach-O it
  404. // is disabled as we emit the .subsections_via_symbols directive which
  405. // means that merging extern globals is not safe.
  406. bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();
  407. addPass(createGlobalMergePass(TM, 127, OnlyOptimizeForSize,
  408. MergeExternalByDefault));
  409. }
  410. if (TM->getOptLevel() != CodeGenOpt::None) {
  411. addPass(createHardwareLoopsPass());
  412. addPass(createMVETailPredicationPass());
  413. // FIXME: IR passes can delete address-taken basic blocks, deleting
  414. // corresponding blockaddresses. ARMConstantPoolConstant holds references to
  415. // address-taken basic blocks which can be invalidated if the function
  416. // containing the blockaddress has already been codegen'd and the basic
  417. // block is removed. Work around this by forcing all IR passes to run before
  418. // any ISel takes place. We should have a more principled way of handling
  419. // this. See D99707 for more details.
  420. addPass(createBarrierNoopPass());
  421. }
  422. return false;
  423. }
  424. bool ARMPassConfig::addInstSelector() {
  425. addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
  426. return false;
  427. }
  428. bool ARMPassConfig::addIRTranslator() {
  429. addPass(new IRTranslator(getOptLevel()));
  430. return false;
  431. }
  432. bool ARMPassConfig::addLegalizeMachineIR() {
  433. addPass(new Legalizer());
  434. return false;
  435. }
  436. bool ARMPassConfig::addRegBankSelect() {
  437. addPass(new RegBankSelect());
  438. return false;
  439. }
  440. bool ARMPassConfig::addGlobalInstructionSelect() {
  441. addPass(new InstructionSelect(getOptLevel()));
  442. return false;
  443. }
  444. void ARMPassConfig::addPreRegAlloc() {
  445. if (getOptLevel() != CodeGenOpt::None) {
  446. if (getOptLevel() == CodeGenOpt::Aggressive)
  447. addPass(&MachinePipelinerID);
  448. addPass(createMVETPAndVPTOptimisationsPass());
  449. addPass(createMLxExpansionPass());
  450. if (EnableARMLoadStoreOpt)
  451. addPass(createARMLoadStoreOptimizationPass(/* pre-register alloc */ true));
  452. if (!DisableA15SDOptimization)
  453. addPass(createA15SDOptimizerPass());
  454. }
  455. }
  456. void ARMPassConfig::addPreSched2() {
  457. if (getOptLevel() != CodeGenOpt::None) {
  458. if (EnableARMLoadStoreOpt)
  459. addPass(createARMLoadStoreOptimizationPass());
  460. addPass(new ARMExecutionDomainFix());
  461. addPass(createBreakFalseDeps());
  462. }
  463. // Expand some pseudo instructions into multiple instructions to allow
  464. // proper scheduling.
  465. addPass(createARMExpandPseudoPass());
  466. if (getOptLevel() != CodeGenOpt::None) {
  467. // When optimising for size, always run the Thumb2SizeReduction pass before
  468. // IfConversion. Otherwise, check whether IT blocks are restricted
  469. // (e.g. in v8, IfConversion depends on Thumb instruction widths)
  470. addPass(createThumb2SizeReductionPass([this](const Function &F) {
  471. return this->TM->getSubtarget<ARMSubtarget>(F).hasMinSize() ||
  472. this->TM->getSubtarget<ARMSubtarget>(F).restrictIT();
  473. }));
  474. addPass(createIfConverter([](const MachineFunction &MF) {
  475. return !MF.getSubtarget<ARMSubtarget>().isThumb1Only();
  476. }));
  477. }
  478. addPass(createThumb2ITBlockPass());
  479. // Add both scheduling passes to give the subtarget an opportunity to pick
  480. // between them.
  481. if (getOptLevel() != CodeGenOpt::None) {
  482. addPass(&PostMachineSchedulerID);
  483. addPass(&PostRASchedulerID);
  484. }
  485. addPass(createMVEVPTBlockPass());
  486. addPass(createARMIndirectThunks());
  487. addPass(createARMSLSHardeningPass());
  488. }
  489. void ARMPassConfig::addPreEmitPass() {
  490. addPass(createThumb2SizeReductionPass());
  491. // Constant island pass work on unbundled instructions.
  492. addPass(createUnpackMachineBundles([](const MachineFunction &MF) {
  493. return MF.getSubtarget<ARMSubtarget>().isThumb2();
  494. }));
  495. // Don't optimize barriers or block placement at -O0.
  496. if (getOptLevel() != CodeGenOpt::None) {
  497. addPass(createARMBlockPlacementPass());
  498. addPass(createARMOptimizeBarriersPass());
  499. }
  500. }
  501. void ARMPassConfig::addPreEmitPass2() {
  502. // Inserts fixup instructions before unsafe AES operations. Instructions may
  503. // be inserted at the start of blocks and at within blocks so this pass has to
  504. // come before those below.
  505. addPass(createARMFixCortexA57AES1742098Pass());
  506. // Inserts BTIs at the start of functions and indirectly-called basic blocks,
  507. // so passes cannot add to the start of basic blocks once this has run.
  508. addPass(createARMBranchTargetsPass());
  509. // Inserts Constant Islands. Block sizes cannot be increased after this point,
  510. // as this may push the branch ranges and load offsets of accessing constant
  511. // pools out of range..
  512. addPass(createARMConstantIslandPass());
  513. // Finalises Low-Overhead Loops. This replaces pseudo instructions with real
  514. // instructions, but the pseudos all have conservative sizes so that block
  515. // sizes will only be decreased by this pass.
  516. addPass(createARMLowOverheadLoopsPass());
  517. if (TM->getTargetTriple().isOSWindows()) {
  518. // Identify valid longjmp targets for Windows Control Flow Guard.
  519. addPass(createCFGuardLongjmpPass());
  520. // Identify valid eh continuation targets for Windows EHCont Guard.
  521. addPass(createEHContGuardCatchretPass());
  522. }
  523. }