[SystemZ] Recognize INLINEASM_BR in backend

Handle the remaining cases also by handling asm goto in
SystemZInstrInfo::getBranchInfo().

Review: Ulrich Weigand
https://reviews.llvm.org/D67151

llvm-svn: 371048
This commit is contained in:
Jonas Paulsson 2019-09-05 10:20:05 +00:00
parent 67991a59cb
commit 821858780e
5 changed files with 34 additions and 20 deletions

View File

@ -462,13 +462,13 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
break;
// A terminator that isn't a branch can't easily be handled by this
// analysis. Asm goto is not understood / optimized.
if (!I->isBranch() || I->getOpcode() == SystemZ::INLINEASM_BR)
// analysis.
if (!I->isBranch())
return true;
// Can't handle indirect branches.
SystemZII::Branch Branch(getBranchInfo(*I));
if (!Branch.Target->isMBB())
if (!Branch.hasMBBTarget())
return true;
// Punt on compound branches.
@ -478,7 +478,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
if (Branch.CCMask == SystemZ::CCMASK_ANY) {
// Handle unconditional branches.
if (!AllowModify) {
TBB = Branch.Target->getMBB();
TBB = Branch.getMBBTarget();
continue;
}
@ -490,7 +490,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
FBB = nullptr;
// Delete the JMP if it's equivalent to a fall-through.
if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) {
if (MBB.isLayoutSuccessor(Branch.getMBBTarget())) {
TBB = nullptr;
I->eraseFromParent();
I = MBB.end();
@ -498,7 +498,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
}
// TBB is used to indicate the unconditinal destination.
TBB = Branch.Target->getMBB();
TBB = Branch.getMBBTarget();
continue;
}
@ -506,7 +506,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
if (Cond.empty()) {
// FIXME: add X86-style branch swap
FBB = TBB;
TBB = Branch.Target->getMBB();
TBB = Branch.getMBBTarget();
Cond.push_back(MachineOperand::CreateImm(Branch.CCValid));
Cond.push_back(MachineOperand::CreateImm(Branch.CCMask));
continue;
@ -517,7 +517,7 @@ bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
// Only handle the case where all conditional branches branch to the same
// destination.
if (TBB != Branch.Target->getMBB())
if (TBB != Branch.getMBBTarget())
return true;
// If the conditions are the same, we can leave them alone.
@ -547,7 +547,7 @@ unsigned SystemZInstrInfo::removeBranch(MachineBasicBlock &MBB,
continue;
if (!I->isBranch())
break;
if (!getBranchInfo(*I).Target->isMBB())
if (!getBranchInfo(*I).hasMBBTarget())
break;
// Remove the branch.
I->eraseFromParent();
@ -1546,6 +1546,10 @@ SystemZInstrInfo::getBranchInfo(const MachineInstr &MI) const {
return SystemZII::Branch(SystemZII::BranchCLG, SystemZ::CCMASK_ICMP,
MI.getOperand(2).getImm(), &MI.getOperand(3));
case SystemZ::INLINEASM_BR:
// Don't try to analyze asm goto, so pass nullptr as branch target argument.
return SystemZII::Branch(SystemZII::AsmGoto, 0, 0, nullptr);
default:
llvm_unreachable("Unrecognized branch opcode");
}

View File

@ -100,11 +100,18 @@ enum BranchType {
// An instruction that decrements a 64-bit register and branches if
// the result is nonzero.
BranchCTG
BranchCTG,
// An instruction representing an asm goto statement.
AsmGoto
};
// Information about a branch instruction.
struct Branch {
class Branch {
// The target of the branch. In case of INLINEASM_BR, this is nullptr.
const MachineOperand *Target;
public:
// The type of the branch.
BranchType Type;
@ -114,12 +121,15 @@ struct Branch {
// CCMASK_<N> is set if the branch should be taken when CC == N.
unsigned CCMask;
// The target of the branch.
const MachineOperand *Target;
Branch(BranchType type, unsigned ccValid, unsigned ccMask,
const MachineOperand *target)
: Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {}
: Target(target), Type(type), CCValid(ccValid), CCMask(ccMask) {}
bool isIndirect() { return Target != nullptr && Target->isReg(); }
bool hasMBBTarget() { return Target != nullptr && Target->isMBB(); }
MachineBasicBlock *getMBBTarget() {
return hasMBBTarget() ? Target->getMBB() : nullptr;
}
};
// Kinds of fused compares in compare-and-* instructions. Together with type

View File

@ -258,7 +258,7 @@ TerminatorInfo SystemZLongBranch::describeTerminator(MachineInstr &MI) {
}
Terminator.Branch = &MI;
Terminator.TargetBlock =
TII->getBranchInfo(MI).Target->getMBB()->getNumber();
TII->getBranchInfo(MI).getMBBTarget()->getNumber();
}
return Terminator;
}

View File

@ -108,8 +108,8 @@ void SystemZPostRASchedStrategy::enterMBB(MachineBasicBlock *NextMBB) {
I != SinglePredMBB->end(); I++) {
LLVM_DEBUG(dbgs() << "** Emitting incoming branch: "; I->dump(););
bool TakenBranch = (I->isBranch() &&
(TII->getBranchInfo(*I).Target->isReg() || // Relative branch
TII->getBranchInfo(*I).Target->getMBB() == MBB));
(TII->getBranchInfo(*I).isIndirect() ||
TII->getBranchInfo(*I).getMBBTarget() == MBB));
HazardRec->emitInstruction(&*I, TakenBranch);
if (TakenBranch)
break;

View File

@ -1,10 +1,10 @@
; Test that asm goto can be compiled.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14
define i32 @c() {
entry:
callbr void asm sideeffect "", "X"(i8* blockaddress(@c, %d))
callbr void asm sideeffect "j d", "X"(i8* blockaddress(@c, %d))
to label %asm.fallthrough [label %d]
asm.fallthrough: ; preds = %entry