ARMSubtarget.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. //===-- ARMSubtarget.h - Define Subtarget for the ARM ----------*- C++ -*--===//
  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. // This file declares the ARM specific subclass of TargetSubtargetInfo.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H
  13. #define LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H
  14. #include "ARMBaseInstrInfo.h"
  15. #include "ARMBaseRegisterInfo.h"
  16. #include "ARMConstantPoolValue.h"
  17. #include "ARMFrameLowering.h"
  18. #include "ARMISelLowering.h"
  19. #include "ARMMachineFunctionInfo.h"
  20. #include "ARMSelectionDAGInfo.h"
  21. #include "llvm/ADT/Triple.h"
  22. #include "llvm/Analysis/TargetTransformInfo.h"
  23. #include "llvm/CodeGen/GlobalISel/CallLowering.h"
  24. #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
  25. #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
  26. #include "llvm/CodeGen/MachineFunction.h"
  27. #include "llvm/CodeGen/RegisterBankInfo.h"
  28. #include "llvm/CodeGen/TargetSubtargetInfo.h"
  29. #include "llvm/MC/MCInstrItineraries.h"
  30. #include "llvm/MC/MCSchedule.h"
  31. #include "llvm/Target/TargetMachine.h"
  32. #include "llvm/Target/TargetOptions.h"
  33. #include <memory>
  34. #include <string>
  35. #define GET_SUBTARGETINFO_HEADER
  36. #include "ARMGenSubtargetInfo.inc"
  37. namespace llvm {
  38. class ARMBaseTargetMachine;
  39. class GlobalValue;
  40. class StringRef;
  41. class ARMSubtarget : public ARMGenSubtargetInfo {
  42. protected:
  43. enum ARMProcFamilyEnum {
  44. Others,
  45. CortexA12,
  46. CortexA15,
  47. CortexA17,
  48. CortexA32,
  49. CortexA35,
  50. CortexA5,
  51. CortexA53,
  52. CortexA55,
  53. CortexA57,
  54. CortexA7,
  55. CortexA72,
  56. CortexA73,
  57. CortexA75,
  58. CortexA76,
  59. CortexA77,
  60. CortexA78,
  61. CortexA78C,
  62. CortexA710,
  63. CortexA8,
  64. CortexA9,
  65. CortexM3,
  66. CortexM7,
  67. CortexR4,
  68. CortexR4F,
  69. CortexR5,
  70. CortexR52,
  71. CortexR7,
  72. CortexX1,
  73. CortexX1C,
  74. Exynos,
  75. Krait,
  76. Kryo,
  77. NeoverseN1,
  78. NeoverseN2,
  79. NeoverseV1,
  80. Swift
  81. };
  82. enum ARMProcClassEnum {
  83. None,
  84. AClass,
  85. MClass,
  86. RClass
  87. };
  88. enum ARMArchEnum {
  89. ARMv4,
  90. ARMv4t,
  91. ARMv5,
  92. ARMv5t,
  93. ARMv5te,
  94. ARMv5tej,
  95. ARMv6,
  96. ARMv6k,
  97. ARMv6kz,
  98. ARMv6m,
  99. ARMv6sm,
  100. ARMv6t2,
  101. ARMv7a,
  102. ARMv7em,
  103. ARMv7m,
  104. ARMv7r,
  105. ARMv7ve,
  106. ARMv81a,
  107. ARMv82a,
  108. ARMv83a,
  109. ARMv84a,
  110. ARMv85a,
  111. ARMv86a,
  112. ARMv87a,
  113. ARMv88a,
  114. ARMv89a,
  115. ARMv8a,
  116. ARMv8mBaseline,
  117. ARMv8mMainline,
  118. ARMv8r,
  119. ARMv81mMainline,
  120. ARMv9a,
  121. ARMv91a,
  122. ARMv92a,
  123. ARMv93a,
  124. ARMv94a,
  125. };
  126. public:
  127. /// What kind of timing do load multiple/store multiple instructions have.
  128. enum ARMLdStMultipleTiming {
  129. /// Can load/store 2 registers/cycle.
  130. DoubleIssue,
  131. /// Can load/store 2 registers/cycle, but needs an extra cycle if the access
  132. /// is not 64-bit aligned.
  133. DoubleIssueCheckUnalignedAccess,
  134. /// Can load/store 1 register/cycle.
  135. SingleIssue,
  136. /// Can load/store 1 register/cycle, but needs an extra cycle for address
  137. /// computation and potentially also for register writeback.
  138. SingleIssuePlusExtras,
  139. };
  140. protected:
  141. // Bool members corresponding to the SubtargetFeatures defined in tablegen
  142. #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
  143. bool ATTRIBUTE = DEFAULT;
  144. #include "ARMGenSubtargetInfo.inc"
  145. /// ARMProcFamily - ARM processor family: Cortex-A8, Cortex-A9, and others.
  146. ARMProcFamilyEnum ARMProcFamily = Others;
  147. /// ARMProcClass - ARM processor class: None, AClass, RClass or MClass.
  148. ARMProcClassEnum ARMProcClass = None;
  149. /// ARMArch - ARM architecture
  150. ARMArchEnum ARMArch = ARMv4t;
  151. /// UseMulOps - True if non-microcoded fused integer multiply-add and
  152. /// multiply-subtract instructions should be used.
  153. bool UseMulOps = false;
  154. /// SupportsTailCall - True if the OS supports tail call. The dynamic linker
  155. /// must be able to synthesize call stubs for interworking between ARM and
  156. /// Thumb.
  157. bool SupportsTailCall = false;
  158. /// RestrictIT - If true, the subtarget disallows generation of complex IT
  159. /// blocks.
  160. bool RestrictIT = false;
  161. /// UseSjLjEH - If true, the target uses SjLj exception handling (e.g. iOS).
  162. bool UseSjLjEH = false;
  163. /// stackAlignment - The minimum alignment known to hold of the stack frame on
  164. /// entry to the function and which must be maintained by every function.
  165. Align stackAlignment = Align(4);
  166. /// CPUString - String name of used CPU.
  167. std::string CPUString;
  168. unsigned MaxInterleaveFactor = 1;
  169. /// Clearance before partial register updates (in number of instructions)
  170. unsigned PartialUpdateClearance = 0;
  171. /// What kind of timing do load multiple/store multiple have (double issue,
  172. /// single issue etc).
  173. ARMLdStMultipleTiming LdStMultipleTiming = SingleIssue;
  174. /// The adjustment that we need to apply to get the operand latency from the
  175. /// operand cycle returned by the itinerary data for pre-ISel operands.
  176. int PreISelOperandLatencyAdjustment = 2;
  177. /// What alignment is preferred for loop bodies, in log2(bytes).
  178. unsigned PrefLoopLogAlignment = 0;
  179. /// The cost factor for MVE instructions, representing the multiple beats an
  180. // instruction can take. The default is 2, (set in initSubtargetFeatures so
  181. // that we can use subtarget features less than 2).
  182. unsigned MVEVectorCostFactor = 0;
  183. /// OptMinSize - True if we're optimising for minimum code size, equal to
  184. /// the function attribute.
  185. bool OptMinSize = false;
  186. /// IsLittle - The target is Little Endian
  187. bool IsLittle;
  188. /// TargetTriple - What processor and OS we're targeting.
  189. Triple TargetTriple;
  190. /// SchedModel - Processor specific instruction costs.
  191. MCSchedModel SchedModel;
  192. /// Selected instruction itineraries (one entry per itinerary class.)
  193. InstrItineraryData InstrItins;
  194. /// Options passed via command line that could influence the target
  195. const TargetOptions &Options;
  196. const ARMBaseTargetMachine &TM;
  197. public:
  198. /// This constructor initializes the data members to match that
  199. /// of the specified triple.
  200. ///
  201. ARMSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
  202. const ARMBaseTargetMachine &TM, bool IsLittle,
  203. bool MinSize = false);
  204. /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size
  205. /// that still makes it profitable to inline the call.
  206. unsigned getMaxInlineSizeThreshold() const {
  207. return 64;
  208. }
  209. /// getMaxMemcpyTPInlineSizeThreshold - Returns the maximum size
  210. /// that still makes it profitable to inline a llvm.memcpy as a Tail
  211. /// Predicated loop.
  212. /// This threshold should only be used for constant size inputs.
  213. unsigned getMaxMemcpyTPInlineSizeThreshold() const { return 128; }
  214. /// ParseSubtargetFeatures - Parses features string setting specified
  215. /// subtarget options. Definition of function is auto generated by tblgen.
  216. void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
  217. /// initializeSubtargetDependencies - Initializes using a CPU and feature string
  218. /// so that we can use initializer lists for subtarget initialization.
  219. ARMSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
  220. const ARMSelectionDAGInfo *getSelectionDAGInfo() const override {
  221. return &TSInfo;
  222. }
  223. const ARMBaseInstrInfo *getInstrInfo() const override {
  224. return InstrInfo.get();
  225. }
  226. const ARMTargetLowering *getTargetLowering() const override {
  227. return &TLInfo;
  228. }
  229. const ARMFrameLowering *getFrameLowering() const override {
  230. return FrameLowering.get();
  231. }
  232. const ARMBaseRegisterInfo *getRegisterInfo() const override {
  233. return &InstrInfo->getRegisterInfo();
  234. }
  235. const CallLowering *getCallLowering() const override;
  236. InstructionSelector *getInstructionSelector() const override;
  237. const LegalizerInfo *getLegalizerInfo() const override;
  238. const RegisterBankInfo *getRegBankInfo() const override;
  239. private:
  240. ARMSelectionDAGInfo TSInfo;
  241. // Either Thumb1FrameLowering or ARMFrameLowering.
  242. std::unique_ptr<ARMFrameLowering> FrameLowering;
  243. // Either Thumb1InstrInfo or Thumb2InstrInfo.
  244. std::unique_ptr<ARMBaseInstrInfo> InstrInfo;
  245. ARMTargetLowering TLInfo;
  246. /// GlobalISel related APIs.
  247. std::unique_ptr<CallLowering> CallLoweringInfo;
  248. std::unique_ptr<InstructionSelector> InstSelector;
  249. std::unique_ptr<LegalizerInfo> Legalizer;
  250. std::unique_ptr<RegisterBankInfo> RegBankInfo;
  251. void initializeEnvironment();
  252. void initSubtargetFeatures(StringRef CPU, StringRef FS);
  253. ARMFrameLowering *initializeFrameLowering(StringRef CPU, StringRef FS);
  254. std::bitset<8> CoprocCDE = {};
  255. public:
  256. // Getters for SubtargetFeatures defined in tablegen
  257. #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
  258. bool GETTER() const { return ATTRIBUTE; }
  259. #include "ARMGenSubtargetInfo.inc"
  260. void computeIssueWidth();
  261. /// @{
  262. /// These functions are obsolete, please consider adding subtarget features
  263. /// or properties instead of calling them.
  264. bool isCortexA5() const { return ARMProcFamily == CortexA5; }
  265. bool isCortexA7() const { return ARMProcFamily == CortexA7; }
  266. bool isCortexA8() const { return ARMProcFamily == CortexA8; }
  267. bool isCortexA9() const { return ARMProcFamily == CortexA9; }
  268. bool isCortexA15() const { return ARMProcFamily == CortexA15; }
  269. bool isSwift() const { return ARMProcFamily == Swift; }
  270. bool isCortexM3() const { return ARMProcFamily == CortexM3; }
  271. bool isCortexM7() const { return ARMProcFamily == CortexM7; }
  272. bool isLikeA9() const { return isCortexA9() || isCortexA15() || isKrait(); }
  273. bool isCortexR5() const { return ARMProcFamily == CortexR5; }
  274. bool isKrait() const { return ARMProcFamily == Krait; }
  275. /// @}
  276. bool hasARMOps() const { return !NoARM; }
  277. bool useNEONForSinglePrecisionFP() const {
  278. return hasNEON() && hasNEONForFP();
  279. }
  280. bool hasVFP2Base() const { return hasVFPv2SP(); }
  281. bool hasVFP3Base() const { return hasVFPv3D16SP(); }
  282. bool hasVFP4Base() const { return hasVFPv4D16SP(); }
  283. bool hasFPARMv8Base() const { return hasFPARMv8D16SP(); }
  284. bool hasAnyDataBarrier() const {
  285. return HasDataBarrier || (hasV6Ops() && !isThumb());
  286. }
  287. bool useMulOps() const { return UseMulOps; }
  288. bool useFPVMLx() const { return !SlowFPVMLx; }
  289. bool useFPVFMx() const {
  290. return !isTargetDarwin() && hasVFP4Base() && !SlowFPVFMx;
  291. }
  292. bool useFPVFMx16() const { return useFPVFMx() && hasFullFP16(); }
  293. bool useFPVFMx64() const { return useFPVFMx() && hasFP64(); }
  294. bool useSjLjEH() const { return UseSjLjEH; }
  295. bool hasBaseDSP() const {
  296. if (isThumb())
  297. return hasDSP();
  298. else
  299. return hasV5TEOps();
  300. }
  301. /// Return true if the CPU supports any kind of instruction fusion.
  302. bool hasFusion() const { return hasFuseAES() || hasFuseLiterals(); }
  303. const Triple &getTargetTriple() const { return TargetTriple; }
  304. bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
  305. bool isTargetIOS() const { return TargetTriple.isiOS(); }
  306. bool isTargetWatchOS() const { return TargetTriple.isWatchOS(); }
  307. bool isTargetWatchABI() const { return TargetTriple.isWatchABI(); }
  308. bool isTargetDriverKit() const { return TargetTriple.isDriverKit(); }
  309. bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
  310. bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
  311. bool isTargetNetBSD() const { return TargetTriple.isOSNetBSD(); }
  312. bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
  313. bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
  314. bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
  315. bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
  316. // ARM EABI is the bare-metal EABI described in ARM ABI documents and
  317. // can be accessed via -target arm-none-eabi. This is NOT GNUEABI.
  318. // FIXME: Add a flag for bare-metal for that target and set Triple::EABI
  319. // even for GNUEABI, so we can make a distinction here and still conform to
  320. // the EABI on GNU (and Android) mode. This requires change in Clang, too.
  321. // FIXME: The Darwin exception is temporary, while we move users to
  322. // "*-*-*-macho" triples as quickly as possible.
  323. bool isTargetAEABI() const {
  324. return (TargetTriple.getEnvironment() == Triple::EABI ||
  325. TargetTriple.getEnvironment() == Triple::EABIHF) &&
  326. !isTargetDarwin() && !isTargetWindows();
  327. }
  328. bool isTargetGNUAEABI() const {
  329. return (TargetTriple.getEnvironment() == Triple::GNUEABI ||
  330. TargetTriple.getEnvironment() == Triple::GNUEABIHF) &&
  331. !isTargetDarwin() && !isTargetWindows();
  332. }
  333. bool isTargetMuslAEABI() const {
  334. return (TargetTriple.getEnvironment() == Triple::MuslEABI ||
  335. TargetTriple.getEnvironment() == Triple::MuslEABIHF) &&
  336. !isTargetDarwin() && !isTargetWindows();
  337. }
  338. // ARM Targets that support EHABI exception handling standard
  339. // Darwin uses SjLj. Other targets might need more checks.
  340. bool isTargetEHABICompatible() const {
  341. return TargetTriple.isTargetEHABICompatible();
  342. }
  343. bool isTargetHardFloat() const;
  344. bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
  345. bool isXRaySupported() const override;
  346. bool isAPCS_ABI() const;
  347. bool isAAPCS_ABI() const;
  348. bool isAAPCS16_ABI() const;
  349. bool isROPI() const;
  350. bool isRWPI() const;
  351. bool useMachineScheduler() const { return UseMISched; }
  352. bool useMachinePipeliner() const { return UseMIPipeliner; }
  353. bool hasMinSize() const { return OptMinSize; }
  354. bool isThumb1Only() const { return isThumb() && !hasThumb2(); }
  355. bool isThumb2() const { return isThumb() && hasThumb2(); }
  356. bool isMClass() const { return ARMProcClass == MClass; }
  357. bool isRClass() const { return ARMProcClass == RClass; }
  358. bool isAClass() const { return ARMProcClass == AClass; }
  359. bool isR9Reserved() const {
  360. return isTargetMachO() ? (ReserveR9 || !HasV6Ops) : ReserveR9;
  361. }
  362. MCPhysReg getFramePointerReg() const {
  363. if (isTargetDarwin() ||
  364. (!isTargetWindows() && isThumb() && !createAAPCSFrameChain()))
  365. return ARM::R7;
  366. return ARM::R11;
  367. }
  368. /// Returns true if the frame setup is split into two separate pushes (first
  369. /// r0-r7,lr then r8-r11), principally so that the frame pointer is adjacent
  370. /// to lr. This is always required on Thumb1-only targets, as the push and
  371. /// pop instructions can't access the high registers.
  372. bool splitFramePushPop(const MachineFunction &MF) const {
  373. if (MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress())
  374. return true;
  375. return (getFramePointerReg() == ARM::R7 &&
  376. MF.getTarget().Options.DisableFramePointerElim(MF)) ||
  377. isThumb1Only();
  378. }
  379. bool splitFramePointerPush(const MachineFunction &MF) const;
  380. bool useStride4VFPs() const;
  381. bool useMovt() const;
  382. bool supportsTailCall() const { return SupportsTailCall; }
  383. bool allowsUnalignedMem() const { return !StrictAlign; }
  384. bool restrictIT() const { return RestrictIT; }
  385. const std::string & getCPUString() const { return CPUString; }
  386. bool isLittle() const { return IsLittle; }
  387. unsigned getMispredictionPenalty() const;
  388. /// Returns true if machine scheduler should be enabled.
  389. bool enableMachineScheduler() const override;
  390. /// Returns true if machine pipeliner should be enabled.
  391. bool enableMachinePipeliner() const override;
  392. bool useDFAforSMS() const override;
  393. /// True for some subtargets at > -O0.
  394. bool enablePostRAScheduler() const override;
  395. /// True for some subtargets at > -O0.
  396. bool enablePostRAMachineScheduler() const override;
  397. /// Check whether this subtarget wants to use subregister liveness.
  398. bool enableSubRegLiveness() const override;
  399. /// Enable use of alias analysis during code generation (during MI
  400. /// scheduling, DAGCombine, etc.).
  401. bool useAA() const override { return true; }
  402. /// getInstrItins - Return the instruction itineraries based on subtarget
  403. /// selection.
  404. const InstrItineraryData *getInstrItineraryData() const override {
  405. return &InstrItins;
  406. }
  407. /// getStackAlignment - Returns the minimum alignment known to hold of the
  408. /// stack frame on entry to the function and which must be maintained by every
  409. /// function for this subtarget.
  410. Align getStackAlignment() const { return stackAlignment; }
  411. unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
  412. unsigned getPartialUpdateClearance() const { return PartialUpdateClearance; }
  413. ARMLdStMultipleTiming getLdStMultipleTiming() const {
  414. return LdStMultipleTiming;
  415. }
  416. int getPreISelOperandLatencyAdjustment() const {
  417. return PreISelOperandLatencyAdjustment;
  418. }
  419. /// True if the GV will be accessed via an indirect symbol.
  420. bool isGVIndirectSymbol(const GlobalValue *GV) const;
  421. /// Returns the constant pool modifier needed to access the GV.
  422. bool isGVInGOT(const GlobalValue *GV) const;
  423. /// True if fast-isel is used.
  424. bool useFastISel() const;
  425. /// Returns the correct return opcode for the current feature set.
  426. /// Use BX if available to allow mixing thumb/arm code, but fall back
  427. /// to plain mov pc,lr on ARMv4.
  428. unsigned getReturnOpcode() const {
  429. if (isThumb())
  430. return ARM::tBX_RET;
  431. if (hasV4TOps())
  432. return ARM::BX_RET;
  433. return ARM::MOVPCLR;
  434. }
  435. /// Allow movt+movw for PIC global address calculation.
  436. /// ELF does not have GOT relocations for movt+movw.
  437. /// ROPI does not use GOT.
  438. bool allowPositionIndependentMovt() const {
  439. return isROPI() || !isTargetELF();
  440. }
  441. unsigned getPrefLoopLogAlignment() const { return PrefLoopLogAlignment; }
  442. unsigned
  443. getMVEVectorCostFactor(TargetTransformInfo::TargetCostKind CostKind) const {
  444. if (CostKind == TargetTransformInfo::TCK_CodeSize)
  445. return 1;
  446. return MVEVectorCostFactor;
  447. }
  448. bool ignoreCSRForAllocationOrder(const MachineFunction &MF,
  449. unsigned PhysReg) const override;
  450. unsigned getGPRAllocationOrder(const MachineFunction &MF) const;
  451. };
  452. } // end namespace llvm
  453. #endif // LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H