forked from OSchip/llvm-project
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:
parent
aea0620b89
commit
a0746bd50a
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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).
|
||||
|
|
Loading…
Reference in New Issue