From 261ce1d5f89155d2e6f914f281db2004c89ee839 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 10 Jul 2009 19:15:51 +0000 Subject: [PATCH] Remove TargetInstrInfo::CommuteChangesDestination and added findCommutedOpIndices which returns the operand indices which are swapped (when applicable). This allows for some code clean up and future enhancements. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75264 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetInstrInfo.h | 16 +++++------ lib/CodeGen/SimpleRegisterCoalescing.cpp | 20 +++++++++++--- lib/CodeGen/TargetInstrInfoImpl.cpp | 34 +++++++++++------------- lib/CodeGen/VirtRegRewriter.cpp | 28 ++++++++++++++++++- 4 files changed, 67 insertions(+), 31 deletions(-) diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index ecdd68258d5..0635c23cbea 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -194,13 +194,11 @@ public: virtual MachineInstr *commuteInstruction(MachineInstr *MI, bool NewMI = false) const = 0; - /// CommuteChangesDestination - Return true if commuting the specified - /// instruction will also changes the destination operand. Also return the - /// current operand index of the would be new destination register by - /// reference. This can happen when the commutable instruction is also a - /// two-address instruction. - virtual bool CommuteChangesDestination(MachineInstr *MI, - unsigned &OpIdx) const = 0; + /// findCommutedOpIndices - If specified MI is commutable, return the two + /// operand indices that would swap value. Return true if the instruction + /// is not in a form which this routine understands. + virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, + unsigned &SrcOpIdx2) const = 0; /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning /// true if it cannot be understood (e.g. it's a switch dispatch or isn't @@ -495,8 +493,8 @@ protected: public: virtual MachineInstr *commuteInstruction(MachineInstr *MI, bool NewMI = false) const; - virtual bool CommuteChangesDestination(MachineInstr *MI, - unsigned &OpIdx) const; + virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, + unsigned &SrcOpIdx2) const; virtual bool PredicateInstruction(MachineInstr *MI, const SmallVectorImpl &Pred) const; virtual void reMaterialize(MachineBasicBlock &MBB, diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 48e6d45713a..d1523f82e9f 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -312,9 +312,23 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, return false; MachineInstr *DefMI = li_->getInstructionFromIndex(AValNo->def); const TargetInstrDesc &TID = DefMI->getDesc(); - unsigned NewDstIdx; - if (!TID.isCommutable() || - !tii_->CommuteChangesDestination(DefMI, NewDstIdx)) + if (!TID.isCommutable()) + return false; + // If DefMI is a two-address instruction then commuting it will change the + // destination register. + int DefIdx = DefMI->findRegisterDefOperandIdx(IntA.reg); + assert(DefIdx != -1); + unsigned UseOpIdx; + if (!DefMI->isRegTiedToUseOperand(DefIdx, &UseOpIdx)) + return false; + unsigned Op1, Op2, NewDstIdx; + if (!tii_->findCommutedOpIndices(DefMI, Op1, Op2)) + return false; + if (Op1 == UseOpIdx) + NewDstIdx = Op2; + else if (Op2 == UseOpIdx) + NewDstIdx = Op1; + else return false; MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx); diff --git a/lib/CodeGen/TargetInstrInfoImpl.cpp b/lib/CodeGen/TargetInstrInfoImpl.cpp index b7595990de7..b9a6040cd1c 100644 --- a/lib/CodeGen/TargetInstrInfoImpl.cpp +++ b/lib/CodeGen/TargetInstrInfoImpl.cpp @@ -70,26 +70,24 @@ MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI, return MI; } -/// CommuteChangesDestination - Return true if commuting the specified -/// instruction will also changes the destination operand. Also return the -/// current operand index of the would be new destination register by -/// reference. This can happen when the commutable instruction is also a -/// two-address instruction. -bool TargetInstrInfoImpl::CommuteChangesDestination(MachineInstr *MI, - unsigned &OpIdx) const{ +/// findCommutedOpIndices - If specified MI is commutable, return the two +/// operand indices that would swap value. Return true if the instruction +/// is not in a form which this routine understands. +bool TargetInstrInfoImpl::findCommutedOpIndices(MachineInstr *MI, + unsigned &SrcOpIdx1, + unsigned &SrcOpIdx2) const { const TargetInstrDesc &TID = MI->getDesc(); - if (!TID.getNumDefs()) + if (!TID.isCommutable()) return false; - assert(MI->getOperand(1).isReg() && MI->getOperand(2).isReg() && - "This only knows how to commute register operands so far"); - if (MI->getOperand(0).getReg() == MI->getOperand(1).getReg()) { - // Must be two address instruction! - assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) && - "Expecting a two-address instruction!"); - OpIdx = 2; - return true; - } - return false; + // This assumes v0 = op v1, v2 and commuting would swap v1 and v2. If this + // is not true, then the target must implement this. + SrcOpIdx1 = TID.getNumDefs(); + SrcOpIdx2 = SrcOpIdx1 + 1; + if (!MI->getOperand(SrcOpIdx1).isReg() || + !MI->getOperand(SrcOpIdx2).isReg()) + // No idea. + return false; + return true; } diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp index be0b016b669..48558fe74fc 100644 --- a/lib/CodeGen/VirtRegRewriter.cpp +++ b/lib/CodeGen/VirtRegRewriter.cpp @@ -1157,6 +1157,32 @@ private: return false; } + /// CommuteChangesDestination - We are looking for r0 = op r1, r2 and + /// where SrcReg is r1 and it is tied to r0. Return true if after + /// commuting this instruction it will be r0 = op r2, r1. + static bool CommuteChangesDestination(MachineInstr *DefMI, + const TargetInstrDesc &TID, + unsigned SrcReg, + const TargetInstrInfo *TII, + unsigned &DstIdx) { + if (TID.getNumDefs() != 1 && TID.getNumOperands() != 3) + return false; + if (!DefMI->getOperand(1).isReg() || + DefMI->getOperand(1).getReg() != SrcReg) + return false; + unsigned DefIdx; + if (!DefMI->isRegTiedToDefOperand(1, &DefIdx) || DefIdx != 0) + return false; + unsigned SrcIdx1, SrcIdx2; + if (!TII->findCommutedOpIndices(DefMI, SrcIdx1, SrcIdx2)) + return false; + if (SrcIdx1 == 1 && SrcIdx2 == 2) { + DstIdx = 2; + return true; + } + return false; + } + /// CommuteToFoldReload - /// Look for /// r1 = load fi#1 @@ -1185,7 +1211,7 @@ private: unsigned NewDstIdx; if (DefMII != MBB.begin() && TID.isCommutable() && - TII->CommuteChangesDestination(DefMI, NewDstIdx)) { + CommuteChangesDestination(DefMI, TID, SrcReg, TII, NewDstIdx)) { MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx); unsigned NewReg = NewDstMO.getReg(); if (!NewDstMO.isKill() || TRI->regsOverlap(NewReg, SrcReg))