forked from OSchip/llvm-project
[Hexagon] Use single tailcall pseudoinst and fix checking for label jumping versus tail calling.
llvm-svn: 231713
This commit is contained in:
parent
de34ec0193
commit
7b1799c7f8
|
@ -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,
|
||||
|
|
|
@ -212,8 +212,10 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
|||
--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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue