[Hexagon] Use single tailcall pseudoinst and fix checking for label jumping versus tail calling.

llvm-svn: 231713
This commit is contained in:
Colin LeMahieu 2015-03-09 22:05:21 +00:00
parent de34ec0193
commit 7b1799c7f8
4 changed files with 42 additions and 15 deletions

View File

@ -140,7 +140,7 @@ bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
unsigned RetOpcode = MBBI->getOpcode();
return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;
return RetOpcode == Hexagon::TCRETURNi || RetOpcode == Hexagon::TCRETURNr;
}
void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,

View File

@ -211,9 +211,11 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
return false;
--I;
}
bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&
I->getOperand(0).isMBB();
// Delete the JMP if it's equivalent to a fall-through.
if (AllowModify && I->getOpcode() == Hexagon::J2_jump &&
if (AllowModify && JumpToBlock &&
MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
I->eraseFromParent();
@ -243,6 +245,14 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
} while(I);
int LastOpcode = LastInst->getOpcode();
int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;
// If the branch target is not a basic block, it could be a tail call.
// (It is, if the target is a function.)
if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())
return true;
if (SecLastOpcode == Hexagon::J2_jump &&
!SecondLastInst->getOperand(0).isMBB())
return true;
bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
bool LastOpcodeHasNot = PredOpcodeHasNot(LastOpcode);
@ -270,8 +280,6 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
return true;
}
int SecLastOpcode = SecondLastInst->getOpcode();
bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode);
if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
@ -549,6 +557,21 @@ void HexagonInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
SmallVectorImpl<MachineInstr*> &NewMIs) const {
llvm_unreachable("Unimplemented");
}
bool
HexagonInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
unsigned Opc = MI->getOpcode();
switch (Opc) {
case Hexagon::TCRETURNi:
MI->setDesc(get(Hexagon::J2_jump));
return true;
case Hexagon::TCRETURNr:
MI->setDesc(get(Hexagon::J2_jumpr));
return true;
}
return false;
}
MachineInstr *HexagonInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
MachineInstr *MI,

View File

@ -102,6 +102,14 @@ public:
const TargetRegisterClass *RC,
SmallVectorImpl<MachineInstr*> &NewMIs) const;
/// expandPostRAPseudo - This function is called for all pseudo instructions
/// that remain after register allocation. Many pseudo instructions are
/// created to help register allocation. This is the place to convert them
/// into real instructions. The target can edit MI in place, or it can insert
/// new instructions and erase MI. The function should return true if
/// anything was changed.
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
ArrayRef<unsigned> Ops,
int FrameIndex) const override;

View File

@ -4877,21 +4877,17 @@ let isPseudo = 1, isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
def TCRETURNr : T_JMPr;
// Direct tail-calls.
let isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
isTerminator = 1, isCodeGenOnly = 1 in {
def TCRETURNtg : JInst<(outs), (ins calltarget:$dst), "jump $dst",
[], "", J_tc_2early_SLOT23>;
def TCRETURNtext : JInst<(outs), (ins calltarget:$dst), "jump $dst",
[], "", J_tc_2early_SLOT23>;
}
let isPseudo = 1, isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
isTerminator = 1, isCodeGenOnly = 1 in
def TCRETURNi : JInst<(outs), (ins calltarget:$dst), "", []>;
//Tail calls.
def: Pat<(HexagonTCRet tglobaladdr:$dst),
(TCRETURNtg tglobaladdr:$dst)>;
(TCRETURNi tglobaladdr:$dst)>;
def: Pat<(HexagonTCRet texternalsym:$dst),
(TCRETURNtext texternalsym:$dst)>;
(TCRETURNi texternalsym:$dst)>;
def: Pat<(HexagonTCRet (i32 IntRegs:$dst)),
(TCRETURNr (i32 IntRegs:$dst))>;
(TCRETURNr IntRegs:$dst)>;
// Map from r0 = and(r1, 65535) to r0 = zxth(r1)
def: Pat<(and (i32 IntRegs:$src1), 65535),