From 58dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 16 Jun 2008 07:33:11 +0000 Subject: [PATCH] Add option to commuteInstruction() which forces it to create a new (commuted) instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52308 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetInstrInfo.h | 8 ++++++-- lib/CodeGen/TargetInstrInfoImpl.cpp | 19 ++++++++++++++++-- lib/Target/PowerPC/PPCInstrInfo.cpp | 28 ++++++++++++++++++++++----- lib/Target/PowerPC/PPCInstrInfo.h | 2 +- lib/Target/X86/X86InstrInfo.cpp | 5 +++-- lib/Target/X86/X86InstrInfo.h | 2 +- 6 files changed, 51 insertions(+), 13 deletions(-) diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index f9fd6ab30d8..a2dc86f4a3a 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -155,7 +155,10 @@ public: /// return a new machine instruction. If an instruction cannot commute, it /// can also return null. /// - virtual MachineInstr *commuteInstruction(MachineInstr *MI) const = 0; + /// If NewMI is true, then a new machine instruction must be created. + /// + 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 @@ -411,7 +414,8 @@ protected: TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes) : TargetInstrInfo(desc, NumOpcodes) {} public: - virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; + virtual MachineInstr *commuteInstruction(MachineInstr *MI, + bool NewMI = false) const; virtual bool CommuteChangesDestination(MachineInstr *MI, unsigned &OpIdx) const; virtual bool PredicateInstruction(MachineInstr *MI, diff --git a/lib/CodeGen/TargetInstrInfoImpl.cpp b/lib/CodeGen/TargetInstrInfoImpl.cpp index 1bb08ab93bb..ff9c129994e 100644 --- a/lib/CodeGen/TargetInstrInfoImpl.cpp +++ b/lib/CodeGen/TargetInstrInfoImpl.cpp @@ -14,24 +14,39 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" using namespace llvm; // commuteInstruction - The default implementation of this method just exchanges // operand 1 and 2. -MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI) const { +MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI, + bool NewMI) const { assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() && "This only knows how to commute register operands so far"); unsigned Reg1 = MI->getOperand(1).getReg(); unsigned Reg2 = MI->getOperand(2).getReg(); bool Reg1IsKill = MI->getOperand(1).isKill(); bool Reg2IsKill = MI->getOperand(2).isKill(); + bool ChangeReg0 = false; if (MI->getOperand(0).getReg() == Reg1) { // Must be two address instruction! assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) && "Expecting a two-address instruction!"); Reg2IsKill = false; - MI->getOperand(0).setReg(Reg2); + ChangeReg0 = true; } + + if (NewMI) { + // Create a new instruction. + unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg(); + bool Reg0IsDead = MI->getOperand(0).isDead(); + return BuildMI(MI->getDesc()).addReg(Reg0, true, false, false, Reg0IsDead) + .addReg(Reg2, false, false, Reg2IsKill) + .addReg(Reg1, false, false, Reg1IsKill); + } + + if (ChangeReg0) + MI->getOperand(0).setReg(Reg2); MI->getOperand(2).setReg(Reg1); MI->getOperand(1).setReg(Reg2); MI->getOperand(2).setIsKill(Reg1IsKill); diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 27ff7671562..d7adea3c778 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -136,10 +136,11 @@ unsigned PPCInstrInfo::isStoreToStackSlot(MachineInstr *MI, // commuteInstruction - We can commute rlwimi instructions, but only if the // rotate amt is zero. We also have to munge the immediates a bit. -MachineInstr *PPCInstrInfo::commuteInstruction(MachineInstr *MI) const { +MachineInstr * +PPCInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const { // Normal instructions can be commuted the obvious way. if (MI->getOpcode() != PPC::RLWIMI) - return TargetInstrInfoImpl::commuteInstruction(MI); + return TargetInstrInfoImpl::commuteInstruction(MI, NewMI); // Cannot commute if it has a non-zero rotate count. if (MI->getOperand(3).getImm() != 0) @@ -158,23 +159,40 @@ MachineInstr *PPCInstrInfo::commuteInstruction(MachineInstr *MI) const { unsigned Reg2 = MI->getOperand(2).getReg(); bool Reg1IsKill = MI->getOperand(1).isKill(); bool Reg2IsKill = MI->getOperand(2).isKill(); + bool ChangeReg0 = false; // If machine instrs are no longer in two-address forms, update // destination register as well. if (Reg0 == Reg1) { // Must be two address instruction! assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) && "Expecting a two-address instruction!"); - MI->getOperand(0).setReg(Reg2); Reg2IsKill = false; + ChangeReg0 = true; } + + // Masks. + unsigned MB = MI->getOperand(4).getImm(); + unsigned ME = MI->getOperand(5).getImm(); + + if (NewMI) { + // Create a new instruction. + unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg(); + bool Reg0IsDead = MI->getOperand(0).isDead(); + return BuildMI(MI->getDesc()).addReg(Reg0, true, false, false, Reg0IsDead) + .addReg(Reg2, false, false, Reg2IsKill) + .addReg(Reg1, false, false, Reg1IsKill) + .addImm((ME+1) & 31) + .addImm((MB-1) & 31); + } + + if (ChangeReg0) + MI->getOperand(0).setReg(Reg2); MI->getOperand(2).setReg(Reg1); MI->getOperand(1).setReg(Reg2); MI->getOperand(2).setIsKill(Reg1IsKill); MI->getOperand(1).setIsKill(Reg2IsKill); // Swap the mask around. - unsigned MB = MI->getOperand(4).getImm(); - unsigned ME = MI->getOperand(5).getImm(); MI->getOperand(4).setImm((ME+1) & 31); MI->getOperand(5).setImm((MB-1) & 31); return MI; diff --git a/lib/Target/PowerPC/PPCInstrInfo.h b/lib/Target/PowerPC/PPCInstrInfo.h index ffeab791c83..df36e9af69c 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.h +++ b/lib/Target/PowerPC/PPCInstrInfo.h @@ -96,7 +96,7 @@ public: // commuteInstruction - We can commute rlwimi instructions, but only if the // rotate amt is zero. We also have to munge the immediates a bit. - virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; + virtual MachineInstr *commuteInstruction(MachineInstr *MI, bool NewMI) const; virtual void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const; diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 43844264248..bbe5bd363ee 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -1146,7 +1146,8 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, /// commuteInstruction - We have a few instructions that must be hacked on to /// commute them. /// -MachineInstr *X86InstrInfo::commuteInstruction(MachineInstr *MI) const { +MachineInstr * +X86InstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const { switch (MI->getOpcode()) { case X86::SHRD16rri8: // A = SHRD16rri8 B, C, I -> A = SHLD16rri8 C, B, (16-I) case X86::SHLD16rri8: // A = SHLD16rri8 B, C, I -> A = SHRD16rri8 C, B, (16-I) @@ -1276,7 +1277,7 @@ MachineInstr *X86InstrInfo::commuteInstruction(MachineInstr *MI) const { // Fallthrough intended. } default: - return TargetInstrInfoImpl::commuteInstruction(MI); + return TargetInstrInfoImpl::commuteInstruction(MI, NewMI); } } diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index b49fb31c16a..8bbe64d1a5d 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -283,7 +283,7 @@ public: /// commuteInstruction - We have a few instructions that must be hacked on to /// commute them. /// - virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; + virtual MachineInstr *commuteInstruction(MachineInstr *MI, bool NewMI) const; // Branch analysis. virtual bool isUnpredicatedTerminator(const MachineInstr* MI) const;