AArch64Subtarget.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. //===--- AArch64Subtarget.h - Define Subtarget for the AArch64 -*- 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 AArch64 specific subclass of TargetSubtarget.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H
  13. #define LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H
  14. #include "AArch64FrameLowering.h"
  15. #include "AArch64ISelLowering.h"
  16. #include "AArch64InstrInfo.h"
  17. #include "AArch64RegisterInfo.h"
  18. #include "AArch64SelectionDAGInfo.h"
  19. #include "llvm/CodeGen/GlobalISel/CallLowering.h"
  20. #include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h"
  21. #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
  22. #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
  23. #include "llvm/CodeGen/RegisterBankInfo.h"
  24. #include "llvm/CodeGen/TargetSubtargetInfo.h"
  25. #include "llvm/IR/DataLayout.h"
  26. #include <string>
  27. #define GET_SUBTARGETINFO_HEADER
  28. #include "AArch64GenSubtargetInfo.inc"
  29. namespace llvm {
  30. class GlobalValue;
  31. class StringRef;
  32. class Triple;
  33. class AArch64Subtarget final : public AArch64GenSubtargetInfo {
  34. public:
  35. enum ARMProcFamilyEnum : uint8_t {
  36. Others,
  37. A64FX,
  38. Ampere1,
  39. Ampere1A,
  40. AppleA7,
  41. AppleA10,
  42. AppleA11,
  43. AppleA12,
  44. AppleA13,
  45. AppleA14,
  46. AppleA15,
  47. AppleA16,
  48. Carmel,
  49. CortexA35,
  50. CortexA53,
  51. CortexA55,
  52. CortexA510,
  53. CortexA57,
  54. CortexA65,
  55. CortexA72,
  56. CortexA73,
  57. CortexA75,
  58. CortexA76,
  59. CortexA77,
  60. CortexA78,
  61. CortexA78C,
  62. CortexA710,
  63. CortexA715,
  64. CortexR82,
  65. CortexX1,
  66. CortexX1C,
  67. CortexX2,
  68. CortexX3,
  69. ExynosM3,
  70. Falkor,
  71. Kryo,
  72. NeoverseE1,
  73. NeoverseN1,
  74. NeoverseN2,
  75. Neoverse512TVB,
  76. NeoverseV1,
  77. NeoverseV2,
  78. Saphira,
  79. ThunderX2T99,
  80. ThunderX,
  81. ThunderXT81,
  82. ThunderXT83,
  83. ThunderXT88,
  84. ThunderX3T110,
  85. TSV110
  86. };
  87. protected:
  88. /// ARMProcFamily - ARM processor family: Cortex-A53, Cortex-A57, and others.
  89. ARMProcFamilyEnum ARMProcFamily = Others;
  90. // Enable 64-bit vectorization in SLP.
  91. unsigned MinVectorRegisterBitWidth = 64;
  92. // Bool members corresponding to the SubtargetFeatures defined in tablegen
  93. #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
  94. bool ATTRIBUTE = DEFAULT;
  95. #include "AArch64GenSubtargetInfo.inc"
  96. uint8_t MaxInterleaveFactor = 2;
  97. uint8_t VectorInsertExtractBaseCost = 3;
  98. uint16_t CacheLineSize = 0;
  99. uint16_t PrefetchDistance = 0;
  100. uint16_t MinPrefetchStride = 1;
  101. unsigned MaxPrefetchIterationsAhead = UINT_MAX;
  102. unsigned PrefFunctionLogAlignment = 0;
  103. unsigned PrefLoopLogAlignment = 0;
  104. unsigned MaxBytesForLoopAlignment = 0;
  105. unsigned MaxJumpTableSize = 0;
  106. // ReserveXRegister[i] - X#i is not available as a general purpose register.
  107. BitVector ReserveXRegister;
  108. // ReserveXRegisterForRA[i] - X#i is not available for register allocator.
  109. BitVector ReserveXRegisterForRA;
  110. // CustomCallUsedXRegister[i] - X#i call saved.
  111. BitVector CustomCallSavedXRegs;
  112. bool IsLittle;
  113. bool StreamingSVEModeDisabled;
  114. unsigned MinSVEVectorSizeInBits;
  115. unsigned MaxSVEVectorSizeInBits;
  116. unsigned VScaleForTuning = 2;
  117. /// TargetTriple - What processor and OS we're targeting.
  118. Triple TargetTriple;
  119. AArch64FrameLowering FrameLowering;
  120. AArch64InstrInfo InstrInfo;
  121. AArch64SelectionDAGInfo TSInfo;
  122. AArch64TargetLowering TLInfo;
  123. /// GlobalISel related APIs.
  124. std::unique_ptr<CallLowering> CallLoweringInfo;
  125. std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
  126. std::unique_ptr<InstructionSelector> InstSelector;
  127. std::unique_ptr<LegalizerInfo> Legalizer;
  128. std::unique_ptr<RegisterBankInfo> RegBankInfo;
  129. private:
  130. /// initializeSubtargetDependencies - Initializes using CPUString and the
  131. /// passed in feature string so that we can use initializer lists for
  132. /// subtarget initialization.
  133. AArch64Subtarget &initializeSubtargetDependencies(StringRef FS,
  134. StringRef CPUString,
  135. StringRef TuneCPUString);
  136. /// Initialize properties based on the selected processor family.
  137. void initializeProperties();
  138. public:
  139. /// This constructor initializes the data members to match that
  140. /// of the specified triple.
  141. AArch64Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
  142. StringRef FS, const TargetMachine &TM, bool LittleEndian,
  143. unsigned MinSVEVectorSizeInBitsOverride = 0,
  144. unsigned MaxSVEVectorSizeInBitsOverride = 0,
  145. bool StreamingSVEModeDisabled = true);
  146. // Getters for SubtargetFeatures defined in tablegen
  147. #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
  148. bool GETTER() const { return ATTRIBUTE; }
  149. #include "AArch64GenSubtargetInfo.inc"
  150. const AArch64SelectionDAGInfo *getSelectionDAGInfo() const override {
  151. return &TSInfo;
  152. }
  153. const AArch64FrameLowering *getFrameLowering() const override {
  154. return &FrameLowering;
  155. }
  156. const AArch64TargetLowering *getTargetLowering() const override {
  157. return &TLInfo;
  158. }
  159. const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; }
  160. const AArch64RegisterInfo *getRegisterInfo() const override {
  161. return &getInstrInfo()->getRegisterInfo();
  162. }
  163. const CallLowering *getCallLowering() const override;
  164. const InlineAsmLowering *getInlineAsmLowering() const override;
  165. InstructionSelector *getInstructionSelector() const override;
  166. const LegalizerInfo *getLegalizerInfo() const override;
  167. const RegisterBankInfo *getRegBankInfo() const override;
  168. const Triple &getTargetTriple() const { return TargetTriple; }
  169. bool enableMachineScheduler() const override { return true; }
  170. bool enablePostRAScheduler() const override { return usePostRAScheduler(); }
  171. /// Returns ARM processor family.
  172. /// Avoid this function! CPU specifics should be kept local to this class
  173. /// and preferably modeled with SubtargetFeatures or properties in
  174. /// initializeProperties().
  175. ARMProcFamilyEnum getProcFamily() const {
  176. return ARMProcFamily;
  177. }
  178. bool isXRaySupported() const override { return true; }
  179. unsigned getMinVectorRegisterBitWidth() const {
  180. // Don't assume any minimum vector size when PSTATE.SM may not be 0.
  181. if (!isStreamingSVEModeDisabled())
  182. return 0;
  183. return MinVectorRegisterBitWidth;
  184. }
  185. bool isXRegisterReserved(size_t i) const { return ReserveXRegister[i]; }
  186. bool isXRegisterReservedForRA(size_t i) const { return ReserveXRegisterForRA[i]; }
  187. unsigned getNumXRegisterReserved() const {
  188. BitVector AllReservedX(AArch64::GPR64commonRegClass.getNumRegs());
  189. AllReservedX |= ReserveXRegister;
  190. AllReservedX |= ReserveXRegisterForRA;
  191. return AllReservedX.count();
  192. }
  193. bool isXRegCustomCalleeSaved(size_t i) const {
  194. return CustomCallSavedXRegs[i];
  195. }
  196. bool hasCustomCallingConv() const { return CustomCallSavedXRegs.any(); }
  197. /// Return true if the CPU supports any kind of instruction fusion.
  198. bool hasFusion() const {
  199. return hasArithmeticBccFusion() || hasArithmeticCbzFusion() ||
  200. hasFuseAES() || hasFuseArithmeticLogic() || hasFuseCCSelect() ||
  201. hasFuseAdrpAdd() || hasFuseLiterals();
  202. }
  203. unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
  204. unsigned getVectorInsertExtractBaseCost() const;
  205. unsigned getCacheLineSize() const override { return CacheLineSize; }
  206. unsigned getPrefetchDistance() const override { return PrefetchDistance; }
  207. unsigned getMinPrefetchStride(unsigned NumMemAccesses,
  208. unsigned NumStridedMemAccesses,
  209. unsigned NumPrefetches,
  210. bool HasCall) const override {
  211. return MinPrefetchStride;
  212. }
  213. unsigned getMaxPrefetchIterationsAhead() const override {
  214. return MaxPrefetchIterationsAhead;
  215. }
  216. unsigned getPrefFunctionLogAlignment() const {
  217. return PrefFunctionLogAlignment;
  218. }
  219. unsigned getPrefLoopLogAlignment() const { return PrefLoopLogAlignment; }
  220. unsigned getMaxBytesForLoopAlignment() const {
  221. return MaxBytesForLoopAlignment;
  222. }
  223. unsigned getMaximumJumpTableSize() const { return MaxJumpTableSize; }
  224. /// CPU has TBI (top byte of addresses is ignored during HW address
  225. /// translation) and OS enables it.
  226. bool supportsAddressTopByteIgnored() const;
  227. bool isLittleEndian() const { return IsLittle; }
  228. bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
  229. bool isTargetIOS() const { return TargetTriple.isiOS(); }
  230. bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
  231. bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
  232. bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
  233. bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
  234. bool isWindowsArm64EC() const { return TargetTriple.isWindowsArm64EC(); }
  235. bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
  236. bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
  237. bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
  238. bool isTargetILP32() const {
  239. return TargetTriple.isArch32Bit() ||
  240. TargetTriple.getEnvironment() == Triple::GNUILP32;
  241. }
  242. bool useAA() const override;
  243. bool addrSinkUsingGEPs() const override {
  244. // Keeping GEPs inbounds is important for exploiting AArch64
  245. // addressing-modes in ILP32 mode.
  246. return useAA() || isTargetILP32();
  247. }
  248. bool useSmallAddressing() const {
  249. switch (TLInfo.getTargetMachine().getCodeModel()) {
  250. case CodeModel::Kernel:
  251. // Kernel is currently allowed only for Fuchsia targets,
  252. // where it is the same as Small for almost all purposes.
  253. case CodeModel::Small:
  254. return true;
  255. default:
  256. return false;
  257. }
  258. }
  259. /// ParseSubtargetFeatures - Parses features string setting specified
  260. /// subtarget options. Definition of function is auto generated by tblgen.
  261. void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
  262. /// ClassifyGlobalReference - Find the target operand flags that describe
  263. /// how a global value should be referenced for the current subtarget.
  264. unsigned ClassifyGlobalReference(const GlobalValue *GV,
  265. const TargetMachine &TM) const;
  266. unsigned classifyGlobalFunctionReference(const GlobalValue *GV,
  267. const TargetMachine &TM) const;
  268. /// This function is design to compatible with the function def in other
  269. /// targets and escape build error about the virtual function def in base
  270. /// class TargetSubtargetInfo. Updeate me if AArch64 target need to use it.
  271. unsigned char
  272. classifyGlobalFunctionReference(const GlobalValue *GV) const override {
  273. return 0;
  274. }
  275. void overrideSchedPolicy(MachineSchedPolicy &Policy,
  276. unsigned NumRegionInstrs) const override;
  277. bool enableEarlyIfConversion() const override;
  278. std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;
  279. bool isCallingConvWin64(CallingConv::ID CC) const {
  280. switch (CC) {
  281. case CallingConv::C:
  282. case CallingConv::Fast:
  283. case CallingConv::Swift:
  284. return isTargetWindows();
  285. case CallingConv::Win64:
  286. return true;
  287. default:
  288. return false;
  289. }
  290. }
  291. /// Return whether FrameLowering should always set the "extended frame
  292. /// present" bit in FP, or set it based on a symbol in the runtime.
  293. bool swiftAsyncContextIsDynamicallySet() const {
  294. // Older OS versions (particularly system unwinders) are confused by the
  295. // Swift extended frame, so when building code that might be run on them we
  296. // must dynamically query the concurrency library to determine whether
  297. // extended frames should be flagged as present.
  298. const Triple &TT = getTargetTriple();
  299. unsigned Major = TT.getOSVersion().getMajor();
  300. switch(TT.getOS()) {
  301. default:
  302. return false;
  303. case Triple::IOS:
  304. case Triple::TvOS:
  305. return Major < 15;
  306. case Triple::WatchOS:
  307. return Major < 8;
  308. case Triple::MacOSX:
  309. case Triple::Darwin:
  310. return Major < 12;
  311. }
  312. }
  313. void mirFileLoaded(MachineFunction &MF) const override;
  314. bool hasSVEorSME() const { return hasSVE() || hasSME(); }
  315. // Return the known range for the bit length of SVE data registers. A value
  316. // of 0 means nothing is known about that particular limit beyong what's
  317. // implied by the architecture.
  318. unsigned getMaxSVEVectorSizeInBits() const {
  319. assert(hasSVEorSME() &&
  320. "Tried to get SVE vector length without SVE support!");
  321. return MaxSVEVectorSizeInBits;
  322. }
  323. unsigned getMinSVEVectorSizeInBits() const {
  324. assert(hasSVEorSME() &&
  325. "Tried to get SVE vector length without SVE support!");
  326. return MinSVEVectorSizeInBits;
  327. }
  328. bool useSVEForFixedLengthVectors() const {
  329. if (forceStreamingCompatibleSVE())
  330. return true;
  331. // Prefer NEON unless larger SVE registers are available.
  332. return hasSVE() && getMinSVEVectorSizeInBits() >= 256;
  333. }
  334. bool forceStreamingCompatibleSVE() const;
  335. unsigned getVScaleForTuning() const { return VScaleForTuning; }
  336. const char* getChkStkName() const {
  337. if (isWindowsArm64EC())
  338. return "__chkstk_arm64ec";
  339. return "__chkstk";
  340. }
  341. const char* getSecurityCheckCookieName() const {
  342. if (isWindowsArm64EC())
  343. return "__security_check_cookie_arm64ec";
  344. return "__security_check_cookie";
  345. }
  346. bool isStreamingSVEModeDisabled() const { return StreamingSVEModeDisabled; }
  347. };
  348. } // End llvm namespace
  349. #endif