ARMExpandPseudoInsts.cpp revision 431300797b84600fc9b4eb8ca283277d3e0674eb
1b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng//===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -----*- C++ -*-=// 2b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// 3b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// The LLVM Compiler Infrastructure 4b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// 5b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// This file is distributed under the University of Illinois Open Source 6b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// License. See LICENSE.TXT for details. 7b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// 8b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng//===----------------------------------------------------------------------===// 9b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// 10b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// This file contains a pass that expand pseudo instructions into target 11b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// instructions to allow proper scheduling, if-conversion, and other late 12b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// optimizations. This pass should be run after register allocation but before 13b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// post- regalloc scheduling pass. 14b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// 15b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng//===----------------------------------------------------------------------===// 16b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 17b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#define DEBUG_TYPE "arm-pseudo" 18b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#include "ARM.h" 19b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#include "ARMBaseInstrInfo.h" 20b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#include "llvm/CodeGen/MachineFunctionPass.h" 21b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#include "llvm/CodeGen/MachineInstrBuilder.h" 22b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 23b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Chengusing namespace llvm; 24b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 25b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Chengnamespace { 26b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng class ARMExpandPseudo : public MachineFunctionPass { 27b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng public: 28b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng static char ID; 29b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng ARMExpandPseudo() : MachineFunctionPass(&ID) {} 30b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 31b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng const TargetInstrInfo *TII; 32b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 33b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng virtual bool runOnMachineFunction(MachineFunction &Fn); 34b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 35b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng virtual const char *getPassName() const { 36b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng return "ARM pseudo instruction expansion pass"; 37b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 38b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 39b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng private: 40431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng void TransferImpOps(MachineInstr &OldMI, 41431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI); 42b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng bool ExpandMBB(MachineBasicBlock &MBB); 43b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng }; 44b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng char ARMExpandPseudo::ID = 0; 45b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng} 46b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 47431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng/// TransferImpOps - Transfer implicit operands on the pseudo instruction to 48431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng/// the instructions created from the expansion. 49431300797b84600fc9b4eb8ca283277d3e0674ebEvan Chengvoid ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI, 50431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder &UseMI, 51431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder &DefMI) { 52431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng const TargetInstrDesc &Desc = OldMI.getDesc(); 53431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands(); 54431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng i != e; ++i) { 55431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng const MachineOperand &MO = OldMI.getOperand(i); 56431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng assert(MO.isReg() && MO.getReg()); 57431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng if (MO.isUse()) 58431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng UseMI.addReg(MO.getReg(), getKillRegState(MO.isKill())); 59431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng else 60431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng DefMI.addReg(MO.getReg(), 61431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng getDefRegState(true) | getDeadRegState(MO.isDead())); 62431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng } 63431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng} 64431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng 65b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Chengbool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { 66b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng bool Modified = false; 67b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 68b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 69b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng while (MBBI != E) { 70b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng MachineInstr &MI = *MBBI; 717896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner MachineBasicBlock::iterator NMBBI = llvm::next(MBBI); 72b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 73b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng unsigned Opcode = MI.getOpcode(); 74b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng switch (Opcode) { 75b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng default: break; 76b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng case ARM::tLDRpci_pic: 77b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng case ARM::t2LDRpci_pic: { 78b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic) 79b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng ? ARM::tLDRpci : ARM::t2LDRpci; 80b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng unsigned DstReg = MI.getOperand(0).getReg(); 81431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng bool DstIsDead = MI.getOperand(0).isDead(); 82431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder MIB1 = 83431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), 84431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng TII->get(NewLdOpc), DstReg) 85431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addOperand(MI.getOperand(1))); 86431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng (*MIB1).setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 87431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(), 88431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng TII->get(ARM::tPICADD)) 89431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead)) 90431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addReg(DstReg) 91431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addOperand(MI.getOperand(2)); 92431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng TransferImpOps(MI, MIB1, MIB2); 93b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng MI.eraseFromParent(); 94b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng Modified = true; 95b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng break; 96b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 97431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng 98b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng case ARM::t2MOVi32imm: { 99431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng unsigned PredReg = 0; 100431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg); 101b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng unsigned DstReg = MI.getOperand(0).getReg(); 102431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng bool DstIsDead = MI.getOperand(0).isDead(); 103431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng const MachineOperand &MO = MI.getOperand(1); 104431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder LO16, HI16; 105431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng 106431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVi16), 107431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng DstReg); 108431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVTi16)) 109431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead)) 110431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addReg(DstReg); 111431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng 112431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng if (MO.isImm()) { 113431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng unsigned Imm = MO.getImm(); 114431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng unsigned Lo16 = Imm & 0xffff; 115431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng unsigned Hi16 = (Imm >> 16) & 0xffff; 116431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng LO16 = LO16.addImm(Lo16); 117431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng HI16 = HI16.addImm(Hi16); 118431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng } else { 119431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng const GlobalValue *GV = MO.getGlobal(); 120431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng unsigned TF = MO.getTargetFlags(); 121431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16); 122431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16); 123b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 124431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng (*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 125431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng (*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 126431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng LO16.addImm(Pred).addReg(PredReg); 127431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng HI16.addImm(Pred).addReg(PredReg); 128431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng TransferImpOps(MI, LO16, HI16); 129b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng MI.eraseFromParent(); 130b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng Modified = true; 131b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 132b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 133b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng MBBI = NMBBI; 134b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 135b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 136b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng return Modified; 137b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng} 138b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 139b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Chengbool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 140b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng TII = MF.getTarget().getInstrInfo(); 141b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 142b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng bool Modified = false; 143b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E; 144b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng ++MFI) 145b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng Modified |= ExpandMBB(*MFI); 146b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng return Modified; 147b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng} 148b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 149b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng/// createARMExpandPseudoPass - returns an instance of the pseudo instruction 150b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng/// expansion pass. 151b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan ChengFunctionPass *llvm::createARMExpandPseudoPass() { 152b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng return new ARMExpandPseudo(); 153b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng} 154