1 //===- ARCExpandPseudosPass - ARC expand pseudo loads -----------*- 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 pass expands stores with large offsets into an appropriate sequence. 10 //===----------------------------------------------------------------------===// 11 12 #include "ARC.h" 13 #include "ARCInstrInfo.h" 14 #include "ARCRegisterInfo.h" 15 #include "ARCSubtarget.h" 16 #include "llvm/ADT/Statistic.h" 17 #include "llvm/CodeGen/MachineFunctionPass.h" 18 #include "llvm/CodeGen/MachineInstrBuilder.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 21 using namespace llvm; 22 23 #define DEBUG_TYPE "arc-expand-pseudos" 24 25 namespace { 26 27 class ARCExpandPseudos : public MachineFunctionPass { 28 public: 29 static char ID; 30 ARCExpandPseudos() : MachineFunctionPass(ID) {} 31 32 bool runOnMachineFunction(MachineFunction &Fn) override; 33 34 StringRef getPassName() const override { return "ARC Expand Pseudos"; } 35 36 private: 37 void ExpandStore(MachineFunction &, MachineBasicBlock::iterator); 38 39 const ARCInstrInfo *TII; 40 }; 41 42 char ARCExpandPseudos::ID = 0; 43 44 } // end anonymous namespace 45 46 static unsigned getMappedOp(unsigned PseudoOp) { 47 switch (PseudoOp) { 48 case ARC::ST_FAR: 49 return ARC::ST_rs9; 50 case ARC::STH_FAR: 51 return ARC::STH_rs9; 52 case ARC::STB_FAR: 53 return ARC::STB_rs9; 54 default: 55 llvm_unreachable("Unhandled pseudo op."); 56 } 57 } 58 59 void ARCExpandPseudos::ExpandStore(MachineFunction &MF, 60 MachineBasicBlock::iterator SII) { 61 MachineInstr &SI = *SII; 62 unsigned AddrReg = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass); 63 unsigned AddOpc = 64 isUInt<6>(SI.getOperand(2).getImm()) ? ARC::ADD_rru6 : ARC::ADD_rrlimm; 65 BuildMI(*SI.getParent(), SI, SI.getDebugLoc(), TII->get(AddOpc), AddrReg) 66 .addReg(SI.getOperand(1).getReg()) 67 .addImm(SI.getOperand(2).getImm()); 68 BuildMI(*SI.getParent(), SI, SI.getDebugLoc(), 69 TII->get(getMappedOp(SI.getOpcode()))) 70 .addReg(SI.getOperand(0).getReg()) 71 .addReg(AddrReg) 72 .addImm(0); 73 SI.eraseFromParent(); 74 } 75 76 bool ARCExpandPseudos::runOnMachineFunction(MachineFunction &MF) { 77 const ARCSubtarget *STI = &MF.getSubtarget<ARCSubtarget>(); 78 TII = STI->getInstrInfo(); 79 bool ExpandedStore = false; 80 for (auto &MBB : MF) { 81 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 82 while (MBBI != E) { 83 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 84 switch (MBBI->getOpcode()) { 85 case ARC::ST_FAR: 86 case ARC::STH_FAR: 87 case ARC::STB_FAR: 88 ExpandStore(MF, MBBI); 89 ExpandedStore = true; 90 break; 91 default: 92 break; 93 } 94 MBBI = NMBBI; 95 } 96 } 97 return ExpandedStore; 98 } 99 100 FunctionPass *llvm::createARCExpandPseudosPass() { 101 return new ARCExpandPseudos(); 102 } 103