mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 05:00:26 +00:00
[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:
parent
c1a0806ff5
commit
06c3c9a9e1
@ -124,19 +124,18 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
// A terminator that isn't a branch can't easily be handled by this
|
// A terminator that isn't a branch can't easily be handled by this
|
||||||
// analysis.
|
// analysis.
|
||||||
unsigned ThisCond;
|
if (!I->isBranch())
|
||||||
const MachineOperand *ThisTarget;
|
|
||||||
if (!isBranch(I, ThisCond, ThisTarget))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Can't handle indirect branches.
|
// Can't handle indirect branches.
|
||||||
if (!ThisTarget->isMBB())
|
SystemZII::Branch Branch(getBranchInfo(I));
|
||||||
|
if (!Branch.Target->isMBB())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (ThisCond == SystemZ::CCMASK_ANY) {
|
if (Branch.CCMask == SystemZ::CCMASK_ANY) {
|
||||||
// Handle unconditional branches.
|
// Handle unconditional branches.
|
||||||
if (!AllowModify) {
|
if (!AllowModify) {
|
||||||
TBB = ThisTarget->getMBB();
|
TBB = Branch.Target->getMBB();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +147,7 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
|||||||
FBB = 0;
|
FBB = 0;
|
||||||
|
|
||||||
// Delete the JMP if it's equivalent to a fall-through.
|
// Delete the JMP if it's equivalent to a fall-through.
|
||||||
if (MBB.isLayoutSuccessor(ThisTarget->getMBB())) {
|
if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) {
|
||||||
TBB = 0;
|
TBB = 0;
|
||||||
I->eraseFromParent();
|
I->eraseFromParent();
|
||||||
I = MBB.end();
|
I = MBB.end();
|
||||||
@ -156,7 +155,7 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TBB is used to indicate the unconditinal destination.
|
// TBB is used to indicate the unconditinal destination.
|
||||||
TBB = ThisTarget->getMBB();
|
TBB = Branch.Target->getMBB();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,8 +163,8 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
|||||||
if (Cond.empty()) {
|
if (Cond.empty()) {
|
||||||
// FIXME: add X86-style branch swap
|
// FIXME: add X86-style branch swap
|
||||||
FBB = TBB;
|
FBB = TBB;
|
||||||
TBB = ThisTarget->getMBB();
|
TBB = Branch.Target->getMBB();
|
||||||
Cond.push_back(MachineOperand::CreateImm(ThisCond));
|
Cond.push_back(MachineOperand::CreateImm(Branch.CCMask));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,12 +174,12 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
// Only handle the case where all conditional branches branch to the same
|
// Only handle the case where all conditional branches branch to the same
|
||||||
// destination.
|
// destination.
|
||||||
if (TBB != ThisTarget->getMBB())
|
if (TBB != Branch.Target->getMBB())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If the conditions are the same, we can leave them alone.
|
// If the conditions are the same, we can leave them alone.
|
||||||
unsigned OldCond = Cond[0].getImm();
|
unsigned OldCond = Cond[0].getImm();
|
||||||
if (OldCond == ThisCond)
|
if (OldCond == Branch.CCMask)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// FIXME: Try combining conditions like X86 does. Should be easy on Z!
|
// FIXME: Try combining conditions like X86 does. Should be easy on Z!
|
||||||
@ -198,11 +197,9 @@ unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
|
|||||||
--I;
|
--I;
|
||||||
if (I->isDebugValue())
|
if (I->isDebugValue())
|
||||||
continue;
|
continue;
|
||||||
unsigned Cond;
|
if (!I->isBranch())
|
||||||
const MachineOperand *Target;
|
|
||||||
if (!isBranch(I, Cond, Target))
|
|
||||||
break;
|
break;
|
||||||
if (!Target->isMBB())
|
if (!getBranchInfo(I).Target->isMBB())
|
||||||
break;
|
break;
|
||||||
// Remove the branch.
|
// Remove the branch.
|
||||||
I->eraseFromParent();
|
I->eraseFromParent();
|
||||||
@ -358,25 +355,20 @@ uint64_t SystemZInstrInfo::getInstSizeInBytes(const MachineInstr *MI) const {
|
|||||||
return MI->getDesc().getSize();
|
return MI->getDesc().getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SystemZInstrInfo::isBranch(const MachineInstr *MI, unsigned &Cond,
|
SystemZII::Branch
|
||||||
const MachineOperand *&Target) const {
|
SystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const {
|
||||||
switch (MI->getOpcode()) {
|
switch (MI->getOpcode()) {
|
||||||
case SystemZ::BR:
|
case SystemZ::BR:
|
||||||
case SystemZ::J:
|
case SystemZ::J:
|
||||||
case SystemZ::JG:
|
case SystemZ::JG:
|
||||||
Cond = SystemZ::CCMASK_ANY;
|
return SystemZII::Branch(SystemZ::CCMASK_ANY, &MI->getOperand(0));
|
||||||
Target = &MI->getOperand(0);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case SystemZ::BRC:
|
case SystemZ::BRC:
|
||||||
case SystemZ::BRCL:
|
case SystemZ::BRCL:
|
||||||
Cond = MI->getOperand(0).getImm();
|
return SystemZII::Branch(MI->getOperand(0).getImm(), &MI->getOperand(1));
|
||||||
Target = &MI->getOperand(1);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
|
llvm_unreachable("Unrecognized branch opcode");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,17 @@ namespace SystemZII {
|
|||||||
// @GOT (aka @GOTENT)
|
// @GOT (aka @GOTENT)
|
||||||
MO_GOT = (1 << 0)
|
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 {
|
class SystemZInstrInfo : public SystemZGenInstrInfo {
|
||||||
@ -101,8 +112,7 @@ public:
|
|||||||
// values on which the instruction will branch, and set Target
|
// values on which the instruction will branch, and set Target
|
||||||
// to the operand that contains the branch target. This target
|
// to the operand that contains the branch target. This target
|
||||||
// can be a register or a basic block.
|
// can be a register or a basic block.
|
||||||
bool isBranch(const MachineInstr *MI, unsigned &Cond,
|
SystemZII::Branch getBranchInfo(const MachineInstr *MI) const;
|
||||||
const MachineOperand *&Target) const;
|
|
||||||
|
|
||||||
// Get the load and store opcodes for a given register class.
|
// Get the load and store opcodes for a given register class.
|
||||||
void getLoadStoreOpcodes(const TargetRegisterClass *RC,
|
void getLoadStoreOpcodes(const TargetRegisterClass *RC,
|
||||||
|
@ -211,22 +211,21 @@ TerminatorInfo SystemZLongBranch::describeTerminator(MachineInstr *MI) {
|
|||||||
TerminatorInfo Terminator;
|
TerminatorInfo Terminator;
|
||||||
Terminator.Size = TII->getInstSizeInBytes(MI);
|
Terminator.Size = TII->getInstSizeInBytes(MI);
|
||||||
if (MI->isConditionalBranch() || MI->isUnconditionalBranch()) {
|
if (MI->isConditionalBranch() || MI->isUnconditionalBranch()) {
|
||||||
Terminator.Branch = MI;
|
|
||||||
switch (MI->getOpcode()) {
|
switch (MI->getOpcode()) {
|
||||||
case SystemZ::J:
|
case SystemZ::J:
|
||||||
// Relaxes to JG, which is 2 bytes longer.
|
// Relaxes to JG, which is 2 bytes longer.
|
||||||
Terminator.TargetBlock = MI->getOperand(0).getMBB()->getNumber();
|
|
||||||
Terminator.ExtraRelaxSize = 2;
|
Terminator.ExtraRelaxSize = 2;
|
||||||
break;
|
break;
|
||||||
case SystemZ::BRC:
|
case SystemZ::BRC:
|
||||||
// Relaxes to BRCL, which is 2 bytes longer. Operand 0 is the
|
// Relaxes to BRCL, which is 2 bytes longer.
|
||||||
// condition code mask.
|
|
||||||
Terminator.TargetBlock = MI->getOperand(1).getMBB()->getNumber();
|
|
||||||
Terminator.ExtraRelaxSize = 2;
|
Terminator.ExtraRelaxSize = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("Unrecognized branch instruction");
|
llvm_unreachable("Unrecognized branch instruction");
|
||||||
}
|
}
|
||||||
|
Terminator.Branch = MI;
|
||||||
|
Terminator.TargetBlock =
|
||||||
|
TII->getBranchInfo(MI).Target->getMBB()->getNumber();
|
||||||
}
|
}
|
||||||
return Terminator;
|
return Terminator;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user