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 21using namespace llvm; 22 23#define DEBUG_TYPE "arc-expand-pseudos" 24 25namespace { 26 27class ARCExpandPseudos : public MachineFunctionPass { 28public: 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 36private: 37 void ExpandStore(MachineFunction &, MachineBasicBlock::iterator); 38 39 const ARCInstrInfo *TII; 40}; 41 42char ARCExpandPseudos::ID = 0; 43 44} // end anonymous namespace 45 46static 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 59void 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 76bool 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 100FunctionPass *llvm::createARCExpandPseudosPass() { 101 return new ARCExpandPseudos(); 102} 103