xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVPostRAExpandPseudoInsts.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15f757f3fSDimitry Andric //===-- RISCVPostRAExpandPseudoInsts.cpp - Expand pseudo instrs ----===//
25f757f3fSDimitry Andric //
35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric //
75f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric //
95f757f3fSDimitry Andric // This file contains a pass that expands the pseudo instruction pseudolisimm32
105f757f3fSDimitry Andric // into target instructions. This pass should be run during the post-regalloc
115f757f3fSDimitry Andric // passes, before post RA scheduling.
125f757f3fSDimitry Andric //
135f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
145f757f3fSDimitry Andric 
155f757f3fSDimitry Andric #include "MCTargetDesc/RISCVMatInt.h"
165f757f3fSDimitry Andric #include "RISCV.h"
175f757f3fSDimitry Andric #include "RISCVInstrInfo.h"
185f757f3fSDimitry Andric #include "RISCVTargetMachine.h"
195f757f3fSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
205f757f3fSDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
215f757f3fSDimitry Andric 
225f757f3fSDimitry Andric using namespace llvm;
235f757f3fSDimitry Andric 
245f757f3fSDimitry Andric #define RISCV_POST_RA_EXPAND_PSEUDO_NAME                                       \
255f757f3fSDimitry Andric   "RISC-V post-regalloc pseudo instruction expansion pass"
265f757f3fSDimitry Andric 
275f757f3fSDimitry Andric namespace {
285f757f3fSDimitry Andric 
295f757f3fSDimitry Andric class RISCVPostRAExpandPseudo : public MachineFunctionPass {
305f757f3fSDimitry Andric public:
315f757f3fSDimitry Andric   const RISCVInstrInfo *TII;
325f757f3fSDimitry Andric   static char ID;
335f757f3fSDimitry Andric 
34*0fca6ea1SDimitry Andric   RISCVPostRAExpandPseudo() : MachineFunctionPass(ID) {}
355f757f3fSDimitry Andric 
365f757f3fSDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
375f757f3fSDimitry Andric 
385f757f3fSDimitry Andric   StringRef getPassName() const override {
395f757f3fSDimitry Andric     return RISCV_POST_RA_EXPAND_PSEUDO_NAME;
405f757f3fSDimitry Andric   }
415f757f3fSDimitry Andric 
425f757f3fSDimitry Andric private:
435f757f3fSDimitry Andric   bool expandMBB(MachineBasicBlock &MBB);
445f757f3fSDimitry Andric   bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
455f757f3fSDimitry Andric                 MachineBasicBlock::iterator &NextMBBI);
465f757f3fSDimitry Andric   bool expandMovImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
47*0fca6ea1SDimitry Andric   bool expandMovAddr(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
485f757f3fSDimitry Andric };
495f757f3fSDimitry Andric 
505f757f3fSDimitry Andric char RISCVPostRAExpandPseudo::ID = 0;
515f757f3fSDimitry Andric 
525f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
535f757f3fSDimitry Andric   TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo());
545f757f3fSDimitry Andric   bool Modified = false;
555f757f3fSDimitry Andric   for (auto &MBB : MF)
565f757f3fSDimitry Andric     Modified |= expandMBB(MBB);
575f757f3fSDimitry Andric   return Modified;
585f757f3fSDimitry Andric }
595f757f3fSDimitry Andric 
605f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
615f757f3fSDimitry Andric   bool Modified = false;
625f757f3fSDimitry Andric 
635f757f3fSDimitry Andric   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
645f757f3fSDimitry Andric   while (MBBI != E) {
655f757f3fSDimitry Andric     MachineBasicBlock::iterator NMBBI = std::next(MBBI);
665f757f3fSDimitry Andric     Modified |= expandMI(MBB, MBBI, NMBBI);
675f757f3fSDimitry Andric     MBBI = NMBBI;
685f757f3fSDimitry Andric   }
695f757f3fSDimitry Andric 
705f757f3fSDimitry Andric   return Modified;
715f757f3fSDimitry Andric }
725f757f3fSDimitry Andric 
735f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::expandMI(MachineBasicBlock &MBB,
745f757f3fSDimitry Andric                                        MachineBasicBlock::iterator MBBI,
755f757f3fSDimitry Andric                                        MachineBasicBlock::iterator &NextMBBI) {
765f757f3fSDimitry Andric   switch (MBBI->getOpcode()) {
775f757f3fSDimitry Andric   case RISCV::PseudoMovImm:
785f757f3fSDimitry Andric     return expandMovImm(MBB, MBBI);
79*0fca6ea1SDimitry Andric   case RISCV::PseudoMovAddr:
80*0fca6ea1SDimitry Andric     return expandMovAddr(MBB, MBBI);
815f757f3fSDimitry Andric   default:
825f757f3fSDimitry Andric     return false;
835f757f3fSDimitry Andric   }
845f757f3fSDimitry Andric }
855f757f3fSDimitry Andric 
865f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::expandMovImm(MachineBasicBlock &MBB,
875f757f3fSDimitry Andric                                            MachineBasicBlock::iterator MBBI) {
885f757f3fSDimitry Andric   DebugLoc DL = MBBI->getDebugLoc();
895f757f3fSDimitry Andric 
905f757f3fSDimitry Andric   int64_t Val = MBBI->getOperand(1).getImm();
915f757f3fSDimitry Andric 
925f757f3fSDimitry Andric   Register DstReg = MBBI->getOperand(0).getReg();
935f757f3fSDimitry Andric   bool DstIsDead = MBBI->getOperand(0).isDead();
945f757f3fSDimitry Andric   bool Renamable = MBBI->getOperand(0).isRenamable();
955f757f3fSDimitry Andric 
965f757f3fSDimitry Andric   TII->movImm(MBB, MBBI, DL, DstReg, Val, MachineInstr::NoFlags, Renamable,
975f757f3fSDimitry Andric               DstIsDead);
985f757f3fSDimitry Andric 
995f757f3fSDimitry Andric   MBBI->eraseFromParent();
1005f757f3fSDimitry Andric   return true;
1015f757f3fSDimitry Andric }
1025f757f3fSDimitry Andric 
103*0fca6ea1SDimitry Andric bool RISCVPostRAExpandPseudo::expandMovAddr(MachineBasicBlock &MBB,
104*0fca6ea1SDimitry Andric                                             MachineBasicBlock::iterator MBBI) {
105*0fca6ea1SDimitry Andric   DebugLoc DL = MBBI->getDebugLoc();
106*0fca6ea1SDimitry Andric 
107*0fca6ea1SDimitry Andric   Register DstReg = MBBI->getOperand(0).getReg();
108*0fca6ea1SDimitry Andric   bool DstIsDead = MBBI->getOperand(0).isDead();
109*0fca6ea1SDimitry Andric   bool Renamable = MBBI->getOperand(0).isRenamable();
110*0fca6ea1SDimitry Andric 
111*0fca6ea1SDimitry Andric   BuildMI(MBB, MBBI, DL, TII->get(RISCV::LUI))
112*0fca6ea1SDimitry Andric       .addReg(DstReg, RegState::Define | getRenamableRegState(Renamable))
113*0fca6ea1SDimitry Andric       .add(MBBI->getOperand(1));
114*0fca6ea1SDimitry Andric   BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI))
115*0fca6ea1SDimitry Andric       .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead) |
116*0fca6ea1SDimitry Andric                           getRenamableRegState(Renamable))
117*0fca6ea1SDimitry Andric       .addReg(DstReg, RegState::Kill | getRenamableRegState(Renamable))
118*0fca6ea1SDimitry Andric       .add(MBBI->getOperand(2));
119*0fca6ea1SDimitry Andric   MBBI->eraseFromParent();
120*0fca6ea1SDimitry Andric   return true;
121*0fca6ea1SDimitry Andric }
122*0fca6ea1SDimitry Andric 
1235f757f3fSDimitry Andric } // end of anonymous namespace
1245f757f3fSDimitry Andric 
1255f757f3fSDimitry Andric INITIALIZE_PASS(RISCVPostRAExpandPseudo, "riscv-expand-pseudolisimm32",
1265f757f3fSDimitry Andric                 RISCV_POST_RA_EXPAND_PSEUDO_NAME, false, false)
1275f757f3fSDimitry Andric namespace llvm {
1285f757f3fSDimitry Andric 
1295f757f3fSDimitry Andric FunctionPass *createRISCVPostRAExpandPseudoPass() {
1305f757f3fSDimitry Andric   return new RISCVPostRAExpandPseudo();
1315f757f3fSDimitry Andric }
1325f757f3fSDimitry Andric 
1335f757f3fSDimitry Andric } // end of namespace llvm
134