diff options
Diffstat (limited to 'lib/CodeGen/LowerSubregs.cpp')
-rw-r--r-- | lib/CodeGen/LowerSubregs.cpp | 223 |
1 files changed, 0 insertions, 223 deletions
diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp deleted file mode 100644 index 7871ba9..0000000 --- a/lib/CodeGen/LowerSubregs.cpp +++ /dev/null @@ -1,223 +0,0 @@ -//===-- LowerSubregs.cpp - Subregister Lowering instruction pass ----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a MachineFunction pass which runs after register -// allocation that turns subreg insert/extract instructions into register -// copies, as needed. This ensures correct codegen even if the coalescer -// isn't able to remove all subreg instructions. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "lowersubregs" -#include "llvm/CodeGen/Passes.h" -#include "llvm/Function.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -namespace { - struct LowerSubregsInstructionPass : public MachineFunctionPass { - private: - const TargetRegisterInfo *TRI; - const TargetInstrInfo *TII; - - public: - static char ID; // Pass identification, replacement for typeid - LowerSubregsInstructionPass() : MachineFunctionPass(ID) {} - - const char *getPassName() const { - return "Subregister lowering instruction pass"; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); - AU.addPreservedID(MachineLoopInfoID); - AU.addPreservedID(MachineDominatorsID); - MachineFunctionPass::getAnalysisUsage(AU); - } - - /// runOnMachineFunction - pass entry point - bool runOnMachineFunction(MachineFunction&); - - private: - bool LowerSubregToReg(MachineInstr *MI); - bool LowerCopy(MachineInstr *MI); - - void TransferDeadFlag(MachineInstr *MI, unsigned DstReg, - const TargetRegisterInfo *TRI); - void TransferImplicitDefs(MachineInstr *MI); - }; - - char LowerSubregsInstructionPass::ID = 0; -} - -FunctionPass *llvm::createLowerSubregsPass() { - return new LowerSubregsInstructionPass(); -} - -/// TransferDeadFlag - MI is a pseudo-instruction with DstReg dead, -/// and the lowered replacement instructions immediately precede it. -/// Mark the replacement instructions with the dead flag. -void -LowerSubregsInstructionPass::TransferDeadFlag(MachineInstr *MI, - unsigned DstReg, - const TargetRegisterInfo *TRI) { - for (MachineBasicBlock::iterator MII = - prior(MachineBasicBlock::iterator(MI)); ; --MII) { - if (MII->addRegisterDead(DstReg, TRI)) - break; - assert(MII != MI->getParent()->begin() && - "copyPhysReg output doesn't reference destination register!"); - } -} - -/// TransferImplicitDefs - MI is a pseudo-instruction, and the lowered -/// replacement instructions immediately precede it. Copy any implicit-def -/// operands from MI to the replacement instruction. -void -LowerSubregsInstructionPass::TransferImplicitDefs(MachineInstr *MI) { - MachineBasicBlock::iterator CopyMI = MI; - --CopyMI; - - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isImplicit() || MO.isUse()) - continue; - CopyMI->addOperand(MachineOperand::CreateReg(MO.getReg(), true, true)); - } -} - -bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) { - MachineBasicBlock *MBB = MI->getParent(); - assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && - MI->getOperand(1).isImm() && - (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && - MI->getOperand(3).isImm() && "Invalid subreg_to_reg"); - - unsigned DstReg = MI->getOperand(0).getReg(); - unsigned InsReg = MI->getOperand(2).getReg(); - assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?"); - unsigned SubIdx = MI->getOperand(3).getImm(); - - assert(SubIdx != 0 && "Invalid index for insert_subreg"); - unsigned DstSubReg = TRI->getSubReg(DstReg, SubIdx); - - assert(TargetRegisterInfo::isPhysicalRegister(DstReg) && - "Insert destination must be in a physical register"); - assert(TargetRegisterInfo::isPhysicalRegister(InsReg) && - "Inserted value must be in a physical register"); - - DEBUG(dbgs() << "subreg: CONVERTING: " << *MI); - - if (DstSubReg == InsReg) { - // No need to insert an identify copy instruction. - // Watch out for case like this: - // %RAX<def> = SUBREG_TO_REG 0, %EAX<kill>, 3 - // We must leave %RAX live. - if (DstReg != InsReg) { - MI->setDesc(TII->get(TargetOpcode::KILL)); - MI->RemoveOperand(3); // SubIdx - MI->RemoveOperand(1); // Imm - DEBUG(dbgs() << "subreg: replace by: " << *MI); - return true; - } - DEBUG(dbgs() << "subreg: eliminated!"); - } else { - TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg, - MI->getOperand(2).isKill()); - // Transfer the kill/dead flags, if needed. - if (MI->getOperand(0).isDead()) - TransferDeadFlag(MI, DstSubReg, TRI); - DEBUG({ - MachineBasicBlock::iterator dMI = MI; - dbgs() << "subreg: " << *(--dMI); - }); - } - - DEBUG(dbgs() << '\n'); - MBB->erase(MI); - return true; -} - -bool LowerSubregsInstructionPass::LowerCopy(MachineInstr *MI) { - MachineOperand &DstMO = MI->getOperand(0); - MachineOperand &SrcMO = MI->getOperand(1); - - if (SrcMO.getReg() == DstMO.getReg()) { - DEBUG(dbgs() << "identity copy: " << *MI); - // No need to insert an identity copy instruction, but replace with a KILL - // if liveness is changed. - if (DstMO.isDead() || SrcMO.isUndef() || MI->getNumOperands() > 2) { - // We must make sure the super-register gets killed. Replace the - // instruction with KILL. - MI->setDesc(TII->get(TargetOpcode::KILL)); - DEBUG(dbgs() << "replaced by: " << *MI); - return true; - } - // Vanilla identity copy. - MI->eraseFromParent(); - return true; - } - - DEBUG(dbgs() << "real copy: " << *MI); - TII->copyPhysReg(*MI->getParent(), MI, MI->getDebugLoc(), - DstMO.getReg(), SrcMO.getReg(), SrcMO.isKill()); - - if (DstMO.isDead()) - TransferDeadFlag(MI, DstMO.getReg(), TRI); - if (MI->getNumOperands() > 2) - TransferImplicitDefs(MI); - DEBUG({ - MachineBasicBlock::iterator dMI = MI; - dbgs() << "replaced by: " << *(--dMI); - }); - MI->eraseFromParent(); - return true; -} - -/// runOnMachineFunction - Reduce subregister inserts and extracts to register -/// copies. -/// -bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) { - DEBUG(dbgs() << "Machine Function\n" - << "********** LOWERING SUBREG INSTRS **********\n" - << "********** Function: " - << MF.getFunction()->getName() << '\n'); - TRI = MF.getTarget().getRegisterInfo(); - TII = MF.getTarget().getInstrInfo(); - - bool MadeChange = false; - - for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end(); - mbbi != mbbe; ++mbbi) { - for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end(); - mi != me;) { - MachineBasicBlock::iterator nmi = llvm::next(mi); - MachineInstr *MI = mi; - assert(!MI->isInsertSubreg() && "INSERT_SUBREG should no longer appear"); - assert(MI->getOpcode() != TargetOpcode::EXTRACT_SUBREG && - "EXTRACT_SUBREG should no longer appear"); - if (MI->isSubregToReg()) { - MadeChange |= LowerSubregToReg(MI); - } else if (MI->isCopy()) { - MadeChange |= LowerCopy(MI); - } - mi = nmi; - } - } - - return MadeChange; -} |