[SystemZ] Tweak SystemZInstrInfo::isBranch() interface

This is needed for the upcoming compare-and-branch patch.  No functional
change intended.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182762 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Sandiford 2013-05-28 10:13:54 +00:00
parent c1a0806ff5
commit 06c3c9a9e1
3 changed files with 34 additions and 33 deletions

View File

@ -124,19 +124,18 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// A terminator that isn't a branch can't easily be handled by this
// analysis.
unsigned ThisCond;
const MachineOperand *ThisTarget;
if (!isBranch(I, ThisCond, ThisTarget))
if (!I->isBranch())
return true;
// Can't handle indirect branches.
if (!ThisTarget->isMBB())
SystemZII::Branch Branch(getBranchInfo(I));
if (!Branch.Target->isMBB())
return true;
if (ThisCond == SystemZ::CCMASK_ANY) {
if (Branch.CCMask == SystemZ::CCMASK_ANY) {
// Handle unconditional branches.
if (!AllowModify) {
TBB = ThisTarget->getMBB();
TBB = Branch.Target->getMBB();
continue;
}
@ -148,7 +147,7 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
FBB = 0;
// Delete the JMP if it's equivalent to a fall-through.
if (MBB.isLayoutSuccessor(ThisTarget->getMBB())) {
if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) {
TBB = 0;
I->eraseFromParent();
I = MBB.end();
@ -156,7 +155,7 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
}
// TBB is used to indicate the unconditinal destination.
TBB = ThisTarget->getMBB();
TBB = Branch.Target->getMBB();
continue;
}
@ -164,8 +163,8 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
if (Cond.empty()) {
// FIXME: add X86-style branch swap
FBB = TBB;
TBB = ThisTarget->getMBB();
Cond.push_back(MachineOperand::CreateImm(ThisCond));
TBB = Branch.Target->getMBB();
Cond.push_back(MachineOperand::CreateImm(Branch.CCMask));
continue;
}
@ -175,12 +174,12 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// Only handle the case where all conditional branches branch to the same
// destination.
if (TBB != ThisTarget->getMBB())
if (TBB != Branch.Target->getMBB())
return true;
// If the conditions are the same, we can leave them alone.
unsigned OldCond = Cond[0].getImm();
if (OldCond == ThisCond)
if (OldCond == Branch.CCMask)
continue;
// FIXME: Try combining conditions like X86 does. Should be easy on Z!
@ -198,11 +197,9 @@ unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
--I;
if (I->isDebugValue())
continue;
unsigned Cond;
const MachineOperand *Target;
if (!isBranch(I, Cond, Target))
if (!I->isBranch())
break;
if (!Target->isMBB())
if (!getBranchInfo(I).Target->isMBB())
break;
// Remove the branch.
I->eraseFromParent();
@ -358,25 +355,20 @@ uint64_t SystemZInstrInfo::getInstSizeInBytes(const MachineInstr *MI) const {
return MI->getDesc().getSize();
}
bool SystemZInstrInfo::isBranch(const MachineInstr *MI, unsigned &Cond,
const MachineOperand *&Target) const {
SystemZII::Branch
SystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const {
switch (MI->getOpcode()) {
case SystemZ::BR:
case SystemZ::J:
case SystemZ::JG:
Cond = SystemZ::CCMASK_ANY;
Target = &MI->getOperand(0);
return true;
return SystemZII::Branch(SystemZ::CCMASK_ANY, &MI->getOperand(0));
case SystemZ::BRC:
case SystemZ::BRCL:
Cond = MI->getOperand(0).getImm();
Target = &MI->getOperand(1);
return true;
return SystemZII::Branch(MI->getOperand(0).getImm(), &MI->getOperand(1));
default:
assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
return false;
llvm_unreachable("Unrecognized branch opcode");
}
}

View File

@ -42,6 +42,17 @@ namespace SystemZII {
// @GOT (aka @GOTENT)
MO_GOT = (1 << 0)
};
// Information about a branch instruction.
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(unsigned ccMask, const MachineOperand *target)
: CCMask(ccMask), Target(target) {}
};
}
class SystemZInstrInfo : public SystemZGenInstrInfo {
@ -101,8 +112,7 @@ public:
// values on which the instruction will branch, and set Target
// to the operand that contains the branch target. This target
// can be a register or a basic block.
bool isBranch(const MachineInstr *MI, unsigned &Cond,
const MachineOperand *&Target) const;
SystemZII::Branch getBranchInfo(const MachineInstr *MI) const;
// Get the load and store opcodes for a given register class.
void getLoadStoreOpcodes(const TargetRegisterClass *RC,

View File

@ -211,22 +211,21 @@ TerminatorInfo SystemZLongBranch::describeTerminator(MachineInstr *MI) {
TerminatorInfo Terminator;
Terminator.Size = TII->getInstSizeInBytes(MI);
if (MI->isConditionalBranch() || MI->isUnconditionalBranch()) {
Terminator.Branch = MI;
switch (MI->getOpcode()) {
case SystemZ::J:
// Relaxes to JG, which is 2 bytes longer.
Terminator.TargetBlock = MI->getOperand(0).getMBB()->getNumber();
Terminator.ExtraRelaxSize = 2;
break;
case SystemZ::BRC:
// Relaxes to BRCL, which is 2 bytes longer. Operand 0 is the
// condition code mask.
Terminator.TargetBlock = MI->getOperand(1).getMBB()->getNumber();
// Relaxes to BRCL, which is 2 bytes longer.
Terminator.ExtraRelaxSize = 2;
break;
default:
llvm_unreachable("Unrecognized branch instruction");
}
Terminator.Branch = MI;
Terminator.TargetBlock =
TII->getBranchInfo(MI).Target->getMBB()->getNumber();
}
return Terminator;
}