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();
|
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
|
||||||
unsigned RetOpcode = MBBI->getOpcode();
|
unsigned RetOpcode = MBBI->getOpcode();
|
||||||
|
|
||||||
return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;
|
return RetOpcode == Hexagon::TCRETURNi || RetOpcode == Hexagon::TCRETURNr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
|
void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||||
|
|
|
@ -212,8 +212,10 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
--I;
|
--I;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&
|
||||||
|
I->getOperand(0).isMBB();
|
||||||
// Delete the JMP if it's equivalent to a fall-through.
|
// 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())) {
|
MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
|
||||||
DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
|
DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
|
||||||
I->eraseFromParent();
|
I->eraseFromParent();
|
||||||
|
@ -243,6 +245,14 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
} while(I);
|
} while(I);
|
||||||
|
|
||||||
int LastOpcode = LastInst->getOpcode();
|
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 LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
|
||||||
bool LastOpcodeHasNot = PredOpcodeHasNot(LastOpcode);
|
bool LastOpcodeHasNot = PredOpcodeHasNot(LastOpcode);
|
||||||
|
@ -270,8 +280,6 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SecLastOpcode = SecondLastInst->getOpcode();
|
|
||||||
|
|
||||||
bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
|
bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
|
||||||
bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode);
|
bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode);
|
||||||
if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
|
if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
|
||||||
|
@ -549,6 +557,21 @@ void HexagonInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
|
||||||
SmallVectorImpl<MachineInstr*> &NewMIs) const {
|
SmallVectorImpl<MachineInstr*> &NewMIs) const {
|
||||||
llvm_unreachable("Unimplemented");
|
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 *HexagonInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
|
||||||
MachineInstr *MI,
|
MachineInstr *MI,
|
||||||
|
|
|
@ -102,6 +102,14 @@ public:
|
||||||
const TargetRegisterClass *RC,
|
const TargetRegisterClass *RC,
|
||||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
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,
|
MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
|
||||||
ArrayRef<unsigned> Ops,
|
ArrayRef<unsigned> Ops,
|
||||||
int FrameIndex) const override;
|
int FrameIndex) const override;
|
||||||
|
|
|
@ -4877,21 +4877,17 @@ let isPseudo = 1, isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
|
||||||
def TCRETURNr : T_JMPr;
|
def TCRETURNr : T_JMPr;
|
||||||
|
|
||||||
// Direct tail-calls.
|
// Direct tail-calls.
|
||||||
let isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
|
let isPseudo = 1, isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
|
||||||
isTerminator = 1, isCodeGenOnly = 1 in {
|
isTerminator = 1, isCodeGenOnly = 1 in
|
||||||
def TCRETURNtg : JInst<(outs), (ins calltarget:$dst), "jump $dst",
|
def TCRETURNi : JInst<(outs), (ins calltarget:$dst), "", []>;
|
||||||
[], "", J_tc_2early_SLOT23>;
|
|
||||||
def TCRETURNtext : JInst<(outs), (ins calltarget:$dst), "jump $dst",
|
|
||||||
[], "", J_tc_2early_SLOT23>;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Tail calls.
|
//Tail calls.
|
||||||
def: Pat<(HexagonTCRet tglobaladdr:$dst),
|
def: Pat<(HexagonTCRet tglobaladdr:$dst),
|
||||||
(TCRETURNtg tglobaladdr:$dst)>;
|
(TCRETURNi tglobaladdr:$dst)>;
|
||||||
def: Pat<(HexagonTCRet texternalsym:$dst),
|
def: Pat<(HexagonTCRet texternalsym:$dst),
|
||||||
(TCRETURNtext texternalsym:$dst)>;
|
(TCRETURNi texternalsym:$dst)>;
|
||||||
def: Pat<(HexagonTCRet (i32 IntRegs:$dst)),
|
def: Pat<(HexagonTCRet (i32 IntRegs:$dst)),
|
||||||
(TCRETURNr (i32 IntRegs:$dst))>;
|
(TCRETURNr IntRegs:$dst)>;
|
||||||
|
|
||||||
// Map from r0 = and(r1, 65535) to r0 = zxth(r1)
|
// Map from r0 = and(r1, 65535) to r0 = zxth(r1)
|
||||||
def: Pat<(and (i32 IntRegs:$src1), 65535),
|
def: Pat<(and (i32 IntRegs:$src1), 65535),
|
||||||
|
|
Loading…
Reference in New Issue