xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1*5f757f3fSDimitry Andric //===-- RISCVPostRAExpandPseudoInsts.cpp - Expand pseudo instrs ----===//
2*5f757f3fSDimitry Andric //
3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5f757f3fSDimitry Andric //
7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
8*5f757f3fSDimitry Andric //
9*5f757f3fSDimitry Andric // This file contains a pass that expands the pseudo instruction pseudolisimm32
10*5f757f3fSDimitry Andric // into target instructions. This pass should be run during the post-regalloc
11*5f757f3fSDimitry Andric // passes, before post RA scheduling.
12*5f757f3fSDimitry Andric //
13*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
14*5f757f3fSDimitry Andric 
15*5f757f3fSDimitry Andric #include "MCTargetDesc/RISCVMatInt.h"
16*5f757f3fSDimitry Andric #include "RISCV.h"
17*5f757f3fSDimitry Andric #include "RISCVInstrInfo.h"
18*5f757f3fSDimitry Andric #include "RISCVTargetMachine.h"
19*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
20*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
21*5f757f3fSDimitry Andric 
22*5f757f3fSDimitry Andric using namespace llvm;
23*5f757f3fSDimitry Andric 
24*5f757f3fSDimitry Andric #define RISCV_POST_RA_EXPAND_PSEUDO_NAME                                       \
25*5f757f3fSDimitry Andric   "RISC-V post-regalloc pseudo instruction expansion pass"
26*5f757f3fSDimitry Andric 
27*5f757f3fSDimitry Andric namespace {
28*5f757f3fSDimitry Andric 
29*5f757f3fSDimitry Andric class RISCVPostRAExpandPseudo : public MachineFunctionPass {
30*5f757f3fSDimitry Andric public:
31*5f757f3fSDimitry Andric   const RISCVInstrInfo *TII;
32*5f757f3fSDimitry Andric   static char ID;
33*5f757f3fSDimitry Andric 
34*5f757f3fSDimitry Andric   RISCVPostRAExpandPseudo() : MachineFunctionPass(ID) {
35*5f757f3fSDimitry Andric     initializeRISCVPostRAExpandPseudoPass(*PassRegistry::getPassRegistry());
36*5f757f3fSDimitry Andric   }
37*5f757f3fSDimitry Andric 
38*5f757f3fSDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
39*5f757f3fSDimitry Andric 
40*5f757f3fSDimitry Andric   StringRef getPassName() const override {
41*5f757f3fSDimitry Andric     return RISCV_POST_RA_EXPAND_PSEUDO_NAME;
42*5f757f3fSDimitry Andric   }
43*5f757f3fSDimitry Andric 
44*5f757f3fSDimitry Andric private:
45*5f757f3fSDimitry Andric   bool expandMBB(MachineBasicBlock &MBB);
46*5f757f3fSDimitry Andric   bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
47*5f757f3fSDimitry Andric                 MachineBasicBlock::iterator &NextMBBI);
48*5f757f3fSDimitry Andric   bool expandMovImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
49*5f757f3fSDimitry Andric };
50*5f757f3fSDimitry Andric 
51*5f757f3fSDimitry Andric char RISCVPostRAExpandPseudo::ID = 0;
52*5f757f3fSDimitry Andric 
53*5f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
54*5f757f3fSDimitry Andric   TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo());
55*5f757f3fSDimitry Andric   bool Modified = false;
56*5f757f3fSDimitry Andric   for (auto &MBB : MF)
57*5f757f3fSDimitry Andric     Modified |= expandMBB(MBB);
58*5f757f3fSDimitry Andric   return Modified;
59*5f757f3fSDimitry Andric }
60*5f757f3fSDimitry Andric 
61*5f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
62*5f757f3fSDimitry Andric   bool Modified = false;
63*5f757f3fSDimitry Andric 
64*5f757f3fSDimitry Andric   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
65*5f757f3fSDimitry Andric   while (MBBI != E) {
66*5f757f3fSDimitry Andric     MachineBasicBlock::iterator NMBBI = std::next(MBBI);
67*5f757f3fSDimitry Andric     Modified |= expandMI(MBB, MBBI, NMBBI);
68*5f757f3fSDimitry Andric     MBBI = NMBBI;
69*5f757f3fSDimitry Andric   }
70*5f757f3fSDimitry Andric 
71*5f757f3fSDimitry Andric   return Modified;
72*5f757f3fSDimitry Andric }
73*5f757f3fSDimitry Andric 
74*5f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::expandMI(MachineBasicBlock &MBB,
75*5f757f3fSDimitry Andric                                        MachineBasicBlock::iterator MBBI,
76*5f757f3fSDimitry Andric                                        MachineBasicBlock::iterator &NextMBBI) {
77*5f757f3fSDimitry Andric   switch (MBBI->getOpcode()) {
78*5f757f3fSDimitry Andric   case RISCV::PseudoMovImm:
79*5f757f3fSDimitry Andric     return expandMovImm(MBB, MBBI);
80*5f757f3fSDimitry Andric   default:
81*5f757f3fSDimitry Andric     return false;
82*5f757f3fSDimitry Andric   }
83*5f757f3fSDimitry Andric }
84*5f757f3fSDimitry Andric 
85*5f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::expandMovImm(MachineBasicBlock &MBB,
86*5f757f3fSDimitry Andric                                            MachineBasicBlock::iterator MBBI) {
87*5f757f3fSDimitry Andric   DebugLoc DL = MBBI->getDebugLoc();
88*5f757f3fSDimitry Andric 
89*5f757f3fSDimitry Andric   int64_t Val = MBBI->getOperand(1).getImm();
90*5f757f3fSDimitry Andric 
91*5f757f3fSDimitry Andric   RISCVMatInt::InstSeq Seq =
92*5f757f3fSDimitry Andric       RISCVMatInt::generateInstSeq(Val, MBB.getParent()->getSubtarget());
93*5f757f3fSDimitry Andric   assert(!Seq.empty());
94*5f757f3fSDimitry Andric 
95*5f757f3fSDimitry Andric   Register DstReg = MBBI->getOperand(0).getReg();
96*5f757f3fSDimitry Andric   bool DstIsDead = MBBI->getOperand(0).isDead();
97*5f757f3fSDimitry Andric   bool Renamable = MBBI->getOperand(0).isRenamable();
98*5f757f3fSDimitry Andric 
99*5f757f3fSDimitry Andric   TII->movImm(MBB, MBBI, DL, DstReg, Val, MachineInstr::NoFlags, Renamable,
100*5f757f3fSDimitry Andric               DstIsDead);
101*5f757f3fSDimitry Andric 
102*5f757f3fSDimitry Andric   MBBI->eraseFromParent();
103*5f757f3fSDimitry Andric   return true;
104*5f757f3fSDimitry Andric }
105*5f757f3fSDimitry Andric 
106*5f757f3fSDimitry Andric } // end of anonymous namespace
107*5f757f3fSDimitry Andric 
108*5f757f3fSDimitry Andric INITIALIZE_PASS(RISCVPostRAExpandPseudo, "riscv-expand-pseudolisimm32",
109*5f757f3fSDimitry Andric                 RISCV_POST_RA_EXPAND_PSEUDO_NAME, false, false)
110*5f757f3fSDimitry Andric namespace llvm {
111*5f757f3fSDimitry Andric 
112*5f757f3fSDimitry Andric FunctionPass *createRISCVPostRAExpandPseudoPass() {
113*5f757f3fSDimitry Andric   return new RISCVPostRAExpandPseudo();
114*5f757f3fSDimitry Andric }
115*5f757f3fSDimitry Andric 
116*5f757f3fSDimitry Andric } // end of namespace llvm
117