RISCVExpandPseudoInsts.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. //===-- RISCVExpandPseudoInsts.cpp - Expand pseudo instructions -----------===//
  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 contains a pass that expands pseudo instructions into target
  10. // instructions. This pass should be run after register allocation but before
  11. // the post-regalloc scheduling pass.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "RISCV.h"
  15. #include "RISCVInstrInfo.h"
  16. #include "RISCVTargetMachine.h"
  17. #include "llvm/CodeGen/LivePhysRegs.h"
  18. #include "llvm/CodeGen/MachineFunctionPass.h"
  19. #include "llvm/CodeGen/MachineInstrBuilder.h"
  20. #include "llvm/MC/MCContext.h"
  21. using namespace llvm;
  22. #define RISCV_EXPAND_PSEUDO_NAME "RISCV pseudo instruction expansion pass"
  23. #define RISCV_PRERA_EXPAND_PSEUDO_NAME "RISCV Pre-RA pseudo instruction expansion pass"
  24. namespace {
  25. class RISCVExpandPseudo : public MachineFunctionPass {
  26. public:
  27. const RISCVInstrInfo *TII;
  28. static char ID;
  29. RISCVExpandPseudo() : MachineFunctionPass(ID) {
  30. initializeRISCVExpandPseudoPass(*PassRegistry::getPassRegistry());
  31. }
  32. bool runOnMachineFunction(MachineFunction &MF) override;
  33. StringRef getPassName() const override { return RISCV_EXPAND_PSEUDO_NAME; }
  34. private:
  35. bool expandMBB(MachineBasicBlock &MBB);
  36. bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  37. MachineBasicBlock::iterator &NextMBBI);
  38. bool expandCCOp(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  39. MachineBasicBlock::iterator &NextMBBI);
  40. bool expandVSetVL(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
  41. bool expandVMSET_VMCLR(MachineBasicBlock &MBB,
  42. MachineBasicBlock::iterator MBBI, unsigned Opcode);
  43. };
  44. char RISCVExpandPseudo::ID = 0;
  45. bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
  46. TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo());
  47. bool Modified = false;
  48. for (auto &MBB : MF)
  49. Modified |= expandMBB(MBB);
  50. return Modified;
  51. }
  52. bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
  53. bool Modified = false;
  54. MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
  55. while (MBBI != E) {
  56. MachineBasicBlock::iterator NMBBI = std::next(MBBI);
  57. Modified |= expandMI(MBB, MBBI, NMBBI);
  58. MBBI = NMBBI;
  59. }
  60. return Modified;
  61. }
  62. bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
  63. MachineBasicBlock::iterator MBBI,
  64. MachineBasicBlock::iterator &NextMBBI) {
  65. // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the
  66. // expanded instructions for each pseudo is correct in the Size field of the
  67. // tablegen definition for the pseudo.
  68. switch (MBBI->getOpcode()) {
  69. case RISCV::PseudoCCMOVGPR:
  70. case RISCV::PseudoCCADD:
  71. case RISCV::PseudoCCSUB:
  72. case RISCV::PseudoCCAND:
  73. case RISCV::PseudoCCOR:
  74. case RISCV::PseudoCCXOR:
  75. case RISCV::PseudoCCADDW:
  76. case RISCV::PseudoCCSUBW:
  77. return expandCCOp(MBB, MBBI, NextMBBI);
  78. case RISCV::PseudoVSETVLI:
  79. case RISCV::PseudoVSETVLIX0:
  80. case RISCV::PseudoVSETIVLI:
  81. return expandVSetVL(MBB, MBBI);
  82. case RISCV::PseudoVMCLR_M_B1:
  83. case RISCV::PseudoVMCLR_M_B2:
  84. case RISCV::PseudoVMCLR_M_B4:
  85. case RISCV::PseudoVMCLR_M_B8:
  86. case RISCV::PseudoVMCLR_M_B16:
  87. case RISCV::PseudoVMCLR_M_B32:
  88. case RISCV::PseudoVMCLR_M_B64:
  89. // vmclr.m vd => vmxor.mm vd, vd, vd
  90. return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXOR_MM);
  91. case RISCV::PseudoVMSET_M_B1:
  92. case RISCV::PseudoVMSET_M_B2:
  93. case RISCV::PseudoVMSET_M_B4:
  94. case RISCV::PseudoVMSET_M_B8:
  95. case RISCV::PseudoVMSET_M_B16:
  96. case RISCV::PseudoVMSET_M_B32:
  97. case RISCV::PseudoVMSET_M_B64:
  98. // vmset.m vd => vmxnor.mm vd, vd, vd
  99. return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXNOR_MM);
  100. }
  101. return false;
  102. }
  103. bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
  104. MachineBasicBlock::iterator MBBI,
  105. MachineBasicBlock::iterator &NextMBBI) {
  106. MachineFunction *MF = MBB.getParent();
  107. MachineInstr &MI = *MBBI;
  108. DebugLoc DL = MI.getDebugLoc();
  109. MachineBasicBlock *TrueBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
  110. MachineBasicBlock *MergeBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
  111. MF->insert(++MBB.getIterator(), TrueBB);
  112. MF->insert(++TrueBB->getIterator(), MergeBB);
  113. // We want to copy the "true" value when the condition is true which means
  114. // we need to invert the branch condition to jump over TrueBB when the
  115. // condition is false.
  116. auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
  117. CC = RISCVCC::getOppositeBranchCondition(CC);
  118. // Insert branch instruction.
  119. BuildMI(MBB, MBBI, DL, TII->getBrCond(CC))
  120. .addReg(MI.getOperand(1).getReg())
  121. .addReg(MI.getOperand(2).getReg())
  122. .addMBB(MergeBB);
  123. Register DestReg = MI.getOperand(0).getReg();
  124. assert(MI.getOperand(4).getReg() == DestReg);
  125. if (MI.getOpcode() == RISCV::PseudoCCMOVGPR) {
  126. // Add MV.
  127. BuildMI(TrueBB, DL, TII->get(RISCV::ADDI), DestReg)
  128. .add(MI.getOperand(5))
  129. .addImm(0);
  130. } else {
  131. unsigned NewOpc;
  132. switch (MI.getOpcode()) {
  133. default:
  134. llvm_unreachable("Unexpected opcode!");
  135. case RISCV::PseudoCCADD: NewOpc = RISCV::ADD; break;
  136. case RISCV::PseudoCCSUB: NewOpc = RISCV::SUB; break;
  137. case RISCV::PseudoCCAND: NewOpc = RISCV::AND; break;
  138. case RISCV::PseudoCCOR: NewOpc = RISCV::OR; break;
  139. case RISCV::PseudoCCXOR: NewOpc = RISCV::XOR; break;
  140. case RISCV::PseudoCCADDW: NewOpc = RISCV::ADDW; break;
  141. case RISCV::PseudoCCSUBW: NewOpc = RISCV::SUBW; break;
  142. }
  143. BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)
  144. .add(MI.getOperand(5))
  145. .add(MI.getOperand(6));
  146. }
  147. TrueBB->addSuccessor(MergeBB);
  148. MergeBB->splice(MergeBB->end(), &MBB, MI, MBB.end());
  149. MergeBB->transferSuccessors(&MBB);
  150. MBB.addSuccessor(TrueBB);
  151. MBB.addSuccessor(MergeBB);
  152. NextMBBI = MBB.end();
  153. MI.eraseFromParent();
  154. // Make sure live-ins are correctly attached to this new basic block.
  155. LivePhysRegs LiveRegs;
  156. computeAndAddLiveIns(LiveRegs, *TrueBB);
  157. computeAndAddLiveIns(LiveRegs, *MergeBB);
  158. return true;
  159. }
  160. bool RISCVExpandPseudo::expandVSetVL(MachineBasicBlock &MBB,
  161. MachineBasicBlock::iterator MBBI) {
  162. assert(MBBI->getNumExplicitOperands() == 3 && MBBI->getNumOperands() >= 5 &&
  163. "Unexpected instruction format");
  164. DebugLoc DL = MBBI->getDebugLoc();
  165. assert((MBBI->getOpcode() == RISCV::PseudoVSETVLI ||
  166. MBBI->getOpcode() == RISCV::PseudoVSETVLIX0 ||
  167. MBBI->getOpcode() == RISCV::PseudoVSETIVLI) &&
  168. "Unexpected pseudo instruction");
  169. unsigned Opcode;
  170. if (MBBI->getOpcode() == RISCV::PseudoVSETIVLI)
  171. Opcode = RISCV::VSETIVLI;
  172. else
  173. Opcode = RISCV::VSETVLI;
  174. const MCInstrDesc &Desc = TII->get(Opcode);
  175. assert(Desc.getNumOperands() == 3 && "Unexpected instruction format");
  176. Register DstReg = MBBI->getOperand(0).getReg();
  177. bool DstIsDead = MBBI->getOperand(0).isDead();
  178. BuildMI(MBB, MBBI, DL, Desc)
  179. .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
  180. .add(MBBI->getOperand(1)) // VL
  181. .add(MBBI->getOperand(2)); // VType
  182. MBBI->eraseFromParent(); // The pseudo instruction is gone now.
  183. return true;
  184. }
  185. bool RISCVExpandPseudo::expandVMSET_VMCLR(MachineBasicBlock &MBB,
  186. MachineBasicBlock::iterator MBBI,
  187. unsigned Opcode) {
  188. DebugLoc DL = MBBI->getDebugLoc();
  189. Register DstReg = MBBI->getOperand(0).getReg();
  190. const MCInstrDesc &Desc = TII->get(Opcode);
  191. BuildMI(MBB, MBBI, DL, Desc, DstReg)
  192. .addReg(DstReg, RegState::Undef)
  193. .addReg(DstReg, RegState::Undef);
  194. MBBI->eraseFromParent(); // The pseudo instruction is gone now.
  195. return true;
  196. }
  197. class RISCVPreRAExpandPseudo : public MachineFunctionPass {
  198. public:
  199. const RISCVInstrInfo *TII;
  200. static char ID;
  201. RISCVPreRAExpandPseudo() : MachineFunctionPass(ID) {
  202. initializeRISCVPreRAExpandPseudoPass(*PassRegistry::getPassRegistry());
  203. }
  204. bool runOnMachineFunction(MachineFunction &MF) override;
  205. void getAnalysisUsage(AnalysisUsage &AU) const override {
  206. AU.setPreservesCFG();
  207. MachineFunctionPass::getAnalysisUsage(AU);
  208. }
  209. StringRef getPassName() const override {
  210. return RISCV_PRERA_EXPAND_PSEUDO_NAME;
  211. }
  212. private:
  213. bool expandMBB(MachineBasicBlock &MBB);
  214. bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  215. MachineBasicBlock::iterator &NextMBBI);
  216. bool expandAuipcInstPair(MachineBasicBlock &MBB,
  217. MachineBasicBlock::iterator MBBI,
  218. MachineBasicBlock::iterator &NextMBBI,
  219. unsigned FlagsHi, unsigned SecondOpcode);
  220. bool expandLoadLocalAddress(MachineBasicBlock &MBB,
  221. MachineBasicBlock::iterator MBBI,
  222. MachineBasicBlock::iterator &NextMBBI);
  223. bool expandLoadAddress(MachineBasicBlock &MBB,
  224. MachineBasicBlock::iterator MBBI,
  225. MachineBasicBlock::iterator &NextMBBI);
  226. bool expandLoadTLSIEAddress(MachineBasicBlock &MBB,
  227. MachineBasicBlock::iterator MBBI,
  228. MachineBasicBlock::iterator &NextMBBI);
  229. bool expandLoadTLSGDAddress(MachineBasicBlock &MBB,
  230. MachineBasicBlock::iterator MBBI,
  231. MachineBasicBlock::iterator &NextMBBI);
  232. };
  233. char RISCVPreRAExpandPseudo::ID = 0;
  234. bool RISCVPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
  235. TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo());
  236. bool Modified = false;
  237. for (auto &MBB : MF)
  238. Modified |= expandMBB(MBB);
  239. return Modified;
  240. }
  241. bool RISCVPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
  242. bool Modified = false;
  243. MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
  244. while (MBBI != E) {
  245. MachineBasicBlock::iterator NMBBI = std::next(MBBI);
  246. Modified |= expandMI(MBB, MBBI, NMBBI);
  247. MBBI = NMBBI;
  248. }
  249. return Modified;
  250. }
  251. bool RISCVPreRAExpandPseudo::expandMI(MachineBasicBlock &MBB,
  252. MachineBasicBlock::iterator MBBI,
  253. MachineBasicBlock::iterator &NextMBBI) {
  254. switch (MBBI->getOpcode()) {
  255. case RISCV::PseudoLLA:
  256. return expandLoadLocalAddress(MBB, MBBI, NextMBBI);
  257. case RISCV::PseudoLA:
  258. return expandLoadAddress(MBB, MBBI, NextMBBI);
  259. case RISCV::PseudoLA_TLS_IE:
  260. return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI);
  261. case RISCV::PseudoLA_TLS_GD:
  262. return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI);
  263. }
  264. return false;
  265. }
  266. bool RISCVPreRAExpandPseudo::expandAuipcInstPair(
  267. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  268. MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi,
  269. unsigned SecondOpcode) {
  270. MachineFunction *MF = MBB.getParent();
  271. MachineInstr &MI = *MBBI;
  272. DebugLoc DL = MI.getDebugLoc();
  273. Register DestReg = MI.getOperand(0).getReg();
  274. Register ScratchReg =
  275. MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
  276. MachineOperand &Symbol = MI.getOperand(1);
  277. Symbol.setTargetFlags(FlagsHi);
  278. MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("pcrel_hi");
  279. MachineInstr *MIAUIPC =
  280. BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol);
  281. MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol);
  282. MachineInstr *SecondMI =
  283. BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg)
  284. .addReg(ScratchReg)
  285. .addSym(AUIPCSymbol, RISCVII::MO_PCREL_LO);
  286. if (MI.hasOneMemOperand())
  287. SecondMI->addMemOperand(*MF, *MI.memoperands_begin());
  288. MI.eraseFromParent();
  289. return true;
  290. }
  291. bool RISCVPreRAExpandPseudo::expandLoadLocalAddress(
  292. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  293. MachineBasicBlock::iterator &NextMBBI) {
  294. return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI,
  295. RISCV::ADDI);
  296. }
  297. bool RISCVPreRAExpandPseudo::expandLoadAddress(
  298. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  299. MachineBasicBlock::iterator &NextMBBI) {
  300. MachineFunction *MF = MBB.getParent();
  301. const auto &STI = MF->getSubtarget<RISCVSubtarget>();
  302. // When HWASAN is used and tagging of global variables is enabled
  303. // they should be accessed via the GOT, since the tagged address of a global
  304. // is incompatible with existing code models. This also applies to non-pic
  305. // mode.
  306. assert(MF->getTarget().isPositionIndependent() || STI.allowTaggedGlobals());
  307. unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW;
  308. return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_GOT_HI,
  309. SecondOpcode);
  310. }
  311. bool RISCVPreRAExpandPseudo::expandLoadTLSIEAddress(
  312. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  313. MachineBasicBlock::iterator &NextMBBI) {
  314. MachineFunction *MF = MBB.getParent();
  315. const auto &STI = MF->getSubtarget<RISCVSubtarget>();
  316. unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW;
  317. return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GOT_HI,
  318. SecondOpcode);
  319. }
  320. bool RISCVPreRAExpandPseudo::expandLoadTLSGDAddress(
  321. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  322. MachineBasicBlock::iterator &NextMBBI) {
  323. return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GD_HI,
  324. RISCV::ADDI);
  325. }
  326. } // end of anonymous namespace
  327. INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo",
  328. RISCV_EXPAND_PSEUDO_NAME, false, false)
  329. INITIALIZE_PASS(RISCVPreRAExpandPseudo, "riscv-prera-expand-pseudo",
  330. RISCV_PRERA_EXPAND_PSEUDO_NAME, false, false)
  331. namespace llvm {
  332. FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); }
  333. FunctionPass *createRISCVPreRAExpandPseudoPass() { return new RISCVPreRAExpandPseudo(); }
  334. } // end of namespace llvm