Allow target to place 2-address pass inserted copies in better spots. Thumb2 will use this to try to avoid breaking up IT blocks.

llvm-svn: 105745
This commit is contained in:
Evan Cheng 2010-06-09 19:26:01 +00:00
parent aea0620b89
commit a0746bd50a
5 changed files with 66 additions and 13 deletions

View File

@ -203,6 +203,14 @@ public:
const MachineInstr *Orig,
const TargetRegisterInfo &TRI) const = 0;
/// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the
/// two-addrss instruction inserted by two-address pass.
virtual void scheduleTwoAddrSource(MachineInstr *SrcMI,
MachineInstr *UseMI,
const TargetRegisterInfo &TRI) const {
// Do nothing.
}
/// duplicate - Create a duplicate of the Orig instruction in MF. This is like
/// MachineFunction::CloneMachineInstr(), but the target may update operands
/// that are required to be unique.

View File

@ -1104,7 +1104,12 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
}
}
}
// Schedule the source copy / remat inserted to form two-address
// instruction. FIXME: Does it matter the distance map may not be
// accurate after it's scheduled?
TII->scheduleTwoAddrSource(prior(mi), mi, *TRI);
MadeChange = true;
DEBUG(dbgs() << "\t\trewrite to:\t" << *mi);

View File

@ -61,15 +61,7 @@ static ARMCC::CondCodes getPredicate(const MachineInstr *MI, unsigned &PredReg){
unsigned Opc = MI->getOpcode();
if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
return ARMCC::AL;
int PIdx = MI->findFirstPredOperandIdx();
if (PIdx == -1) {
PredReg = 0;
return ARMCC::AL;
}
PredReg = MI->getOperand(PIdx+1).getReg();
return (ARMCC::CondCodes)MI->getOperand(PIdx).getImm();
return llvm::getInstrPredicate(MI, PredReg);
}
bool
@ -242,15 +234,15 @@ bool Thumb2ITBlockPass::InsertITBlock(MachineInstr *First, MachineInstr *Last) {
// Insert a new block for consecutive predicated instructions.
MachineFunction *MF = MBB->getParent();
MachineBasicBlock *NewMBB = MF->CreateMachineBasicBlock(MBB->getBasicBlock());
MachineFunction::iterator Pos = MBB;
MF->insert(++Pos, NewMBB);
MachineFunction::iterator InsertPos = MBB;
MF->insert(++InsertPos, NewMBB);
// Move all the successors of this block to the specified block.
NewMBB->transferSuccessors(MBB);
// Add an edge from CurMBB to NewMBB for the fall-through.
MBB->addSuccessor(NewMBB);
NewMBB->splice(NewMBB->end(), MBB, ++MBBI, MBB->end());
NewMBB->splice(NewMBB->end(), MBB, ++MBBI, MBB->end());
return true;
}

View File

@ -503,3 +503,46 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
Offset = (isSub) ? -Offset : Offset;
return Offset == 0;
}
/// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the
/// two-addrss instruction inserted by two-address pass.
void
Thumb2InstrInfo::scheduleTwoAddrSource(MachineInstr *SrcMI,
MachineInstr *UseMI,
const TargetRegisterInfo &TRI) const {
if (SrcMI->getOpcode() != ARM::tMOVgpr2gpr ||
SrcMI->getOperand(1).isKill())
return;
unsigned PredReg = 0;
ARMCC::CondCodes CC = llvm::getInstrPredicate(UseMI, PredReg);
if (CC == ARMCC::AL || PredReg != ARM::CPSR)
return;
// Schedule the copy so it doesn't come between previous instructions
// and UseMI which can form an IT block.
unsigned SrcReg = SrcMI->getOperand(1).getReg();
ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
MachineBasicBlock *MBB = UseMI->getParent();
MachineBasicBlock::iterator MBBI = SrcMI;
unsigned NumInsts = 0;
while (--MBBI != MBB->begin()) {
if (MBBI->isDebugValue())
continue;
MachineInstr *NMI = &*MBBI;
ARMCC::CondCodes NCC = llvm::getInstrPredicate(NMI, PredReg);
if (!(NCC == CC || NCC == OCC) ||
NMI->modifiesRegister(SrcReg, &TRI) ||
NMI->definesRegister(ARM::CPSR))
break;
if (++NumInsts == 4)
// Too many in a row!
return;
}
if (NumInsts) {
MBB->remove(SrcMI);
MBB->insert(++MBBI, SrcMI);
}
}

View File

@ -50,6 +50,11 @@ public:
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const;
/// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the
/// two-addrss instruction inserted by two-address pass.
void scheduleTwoAddrSource(MachineInstr *SrcMI, MachineInstr *UseMI,
const TargetRegisterInfo &TRI) const;
/// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
/// such, whenever a client has an instance of instruction info, it should
/// always be able to get register info as well (through this method).