mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Swap PPC isel operands to allow for 0-folding
The PPC isel instruction can fold 0 into the first operand (thus eliminating the need to materialize a zero-containing register when the 'true' result of the isel is 0). When the isel is fed by a bit register operation that we can invert, do so as part of the bit-register-operation peephole routine. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202469 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
49c76560f3
commit
3d2ce7a5a7
@ -189,6 +189,9 @@ private:
|
||||
|
||||
void PeepholePPC64();
|
||||
void PeepholdCROps();
|
||||
|
||||
bool AllUsersSelectZero(SDNode *N);
|
||||
void SwapAllSelectUsers(SDNode *N);
|
||||
};
|
||||
}
|
||||
|
||||
@ -1504,6 +1507,74 @@ void PPCDAGToDAGISel::PostprocessISelDAG() {
|
||||
PeepholdCROps();
|
||||
}
|
||||
|
||||
// Check if all users of this node will become isel where the second operand
|
||||
// is the constant zero. If this is so, and if we can negate the condition,
|
||||
// then we can flip the true and false operands. This will allow the zero to
|
||||
// be folded with the isel so that we don't need to materialize a register
|
||||
// containing zero.
|
||||
bool PPCDAGToDAGISel::AllUsersSelectZero(SDNode *N) {
|
||||
// If we're not using isel, then this does not matter.
|
||||
if (!PPCSubTarget.hasISEL())
|
||||
return false;
|
||||
|
||||
for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end();
|
||||
UI != UE; ++UI) {
|
||||
SDNode *User = *UI;
|
||||
if (!User->isMachineOpcode())
|
||||
return false;
|
||||
if (User->getMachineOpcode() != PPC::SELECT_I4 &&
|
||||
User->getMachineOpcode() != PPC::SELECT_I8)
|
||||
return false;
|
||||
|
||||
SDNode *Op2 = User->getOperand(2).getNode();
|
||||
if (!Op2->isMachineOpcode())
|
||||
return false;
|
||||
|
||||
if (Op2->getMachineOpcode() != PPC::LI &&
|
||||
Op2->getMachineOpcode() != PPC::LI8)
|
||||
return false;
|
||||
|
||||
ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op2->getOperand(0));
|
||||
if (!C)
|
||||
return false;
|
||||
|
||||
if (!C->isNullValue())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PPCDAGToDAGISel::SwapAllSelectUsers(SDNode *N) {
|
||||
SmallVector<SDNode *, 4> ToReplace;
|
||||
for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end();
|
||||
UI != UE; ++UI) {
|
||||
SDNode *User = *UI;
|
||||
assert((User->getMachineOpcode() == PPC::SELECT_I4 ||
|
||||
User->getMachineOpcode() == PPC::SELECT_I8) &&
|
||||
"Must have all select users");
|
||||
ToReplace.push_back(User);
|
||||
}
|
||||
|
||||
for (SmallVector<SDNode *, 4>::iterator UI = ToReplace.begin(),
|
||||
UE = ToReplace.end(); UI != UE; ++UI) {
|
||||
SDNode *User = *UI;
|
||||
SDNode *ResNode =
|
||||
CurDAG->getMachineNode(User->getMachineOpcode(), SDLoc(User),
|
||||
User->getValueType(0), User->getOperand(0),
|
||||
User->getOperand(2),
|
||||
User->getOperand(1));
|
||||
|
||||
DEBUG(dbgs() << "CR Peephole replacing:\nOld: ");
|
||||
DEBUG(User->dump(CurDAG));
|
||||
DEBUG(dbgs() << "\nNew: ");
|
||||
DEBUG(ResNode->dump(CurDAG));
|
||||
DEBUG(dbgs() << "\n");
|
||||
|
||||
ReplaceUses(User, ResNode);
|
||||
}
|
||||
}
|
||||
|
||||
void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
bool IsModified;
|
||||
do {
|
||||
@ -1563,6 +1634,7 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
break;
|
||||
}
|
||||
|
||||
bool SelectSwap = false;
|
||||
switch (Opcode) {
|
||||
default: break;
|
||||
case PPC::CRAND:
|
||||
@ -1591,6 +1663,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1).
|
||||
getOperand(0));
|
||||
else if (AllUsersSelectZero(MachineNode))
|
||||
ResNode = CurDAG->getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1)),
|
||||
SelectSwap = true;
|
||||
break;
|
||||
case PPC::CRNAND:
|
||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||
@ -1624,6 +1701,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
MVT::i1, MachineNode->getOperand(1).
|
||||
getOperand(0),
|
||||
MachineNode->getOperand(0));
|
||||
else if (AllUsersSelectZero(MachineNode))
|
||||
ResNode = CurDAG->getMachineNode(PPC::CRAND, SDLoc(MachineNode),
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1)),
|
||||
SelectSwap = true;
|
||||
break;
|
||||
case PPC::CROR:
|
||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||
@ -1651,6 +1733,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1).
|
||||
getOperand(0));
|
||||
else if (AllUsersSelectZero(MachineNode))
|
||||
ResNode = CurDAG->getMachineNode(PPC::CRNOR, SDLoc(MachineNode),
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1)),
|
||||
SelectSwap = true;
|
||||
break;
|
||||
case PPC::CRXOR:
|
||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||
@ -1685,6 +1772,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1).
|
||||
getOperand(0));
|
||||
else if (AllUsersSelectZero(MachineNode))
|
||||
ResNode = CurDAG->getMachineNode(PPC::CREQV, SDLoc(MachineNode),
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1)),
|
||||
SelectSwap = true;
|
||||
break;
|
||||
case PPC::CRNOR:
|
||||
if (Op1Set || Op2Set)
|
||||
@ -1713,6 +1805,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
MVT::i1, MachineNode->getOperand(1).
|
||||
getOperand(0),
|
||||
MachineNode->getOperand(0));
|
||||
else if (AllUsersSelectZero(MachineNode))
|
||||
ResNode = CurDAG->getMachineNode(PPC::CROR, SDLoc(MachineNode),
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1)),
|
||||
SelectSwap = true;
|
||||
break;
|
||||
case PPC::CREQV:
|
||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||
@ -1747,6 +1844,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1).
|
||||
getOperand(0));
|
||||
else if (AllUsersSelectZero(MachineNode))
|
||||
ResNode = CurDAG->getMachineNode(PPC::CRXOR, SDLoc(MachineNode),
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1)),
|
||||
SelectSwap = true;
|
||||
break;
|
||||
case PPC::CRANDC:
|
||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||
@ -1777,6 +1879,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1).
|
||||
getOperand(0));
|
||||
else if (AllUsersSelectZero(MachineNode))
|
||||
ResNode = CurDAG->getMachineNode(PPC::CRORC, SDLoc(MachineNode),
|
||||
MVT::i1, MachineNode->getOperand(1),
|
||||
MachineNode->getOperand(0)),
|
||||
SelectSwap = true;
|
||||
break;
|
||||
case PPC::CRORC:
|
||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||
@ -1807,6 +1914,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
MVT::i1, MachineNode->getOperand(0),
|
||||
MachineNode->getOperand(1).
|
||||
getOperand(0));
|
||||
else if (AllUsersSelectZero(MachineNode))
|
||||
ResNode = CurDAG->getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
|
||||
MVT::i1, MachineNode->getOperand(1),
|
||||
MachineNode->getOperand(0)),
|
||||
SelectSwap = true;
|
||||
break;
|
||||
case PPC::SELECT_I4:
|
||||
case PPC::SELECT_I8:
|
||||
@ -1841,6 +1953,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
||||
break;
|
||||
}
|
||||
|
||||
// If we're inverting this node because it is used only by selects that
|
||||
// we'd like to swap, then swap the selects before the node replacement.
|
||||
if (SelectSwap)
|
||||
SwapAllSelectUsers(MachineNode);
|
||||
|
||||
if (ResNode != MachineNode) {
|
||||
DEBUG(dbgs() << "CR Peephole replacing:\nOld: ");
|
||||
DEBUG(MachineNode->dump(CurDAG));
|
||||
|
@ -2,10 +2,6 @@
|
||||
target datalayout = "E-m:e-i64:64-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
|
||||
; FIXME: For a number of these we load (1, 0) for the isel into two registers,
|
||||
; whereas if we reverse the condition, we could use only one register (using ZERO
|
||||
; for 0 in the isel).
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
define zeroext i1 @test1(float %v1, float %v2) #0 {
|
||||
entry:
|
||||
@ -18,12 +14,11 @@ entry:
|
||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
|
||||
; CHECK-DAG: li [[REG1:[0-9]+]], 1
|
||||
; CHECK-DAG: lfs [[REG2:[0-9]+]],
|
||||
; CHECK-DAG: li [[REG3:[0-9]+]], 0
|
||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
|
||||
; CHECK: crnor
|
||||
; CHECK: crnor
|
||||
; CHECK: crand [[REG4:[0-9]+]],
|
||||
; CHECK: isel 3, [[REG1]], [[REG3]], [[REG4]]
|
||||
; CHECK: crnand [[REG4:[0-9]+]],
|
||||
; CHECK: isel 3, 0, [[REG1]], [[REG4]]
|
||||
; CHECK: blr
|
||||
}
|
||||
|
||||
@ -39,12 +34,11 @@ entry:
|
||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
|
||||
; CHECK-DAG: li [[REG1:[0-9]+]], 1
|
||||
; CHECK-DAG: lfs [[REG2:[0-9]+]],
|
||||
; CHECK-DAG: li [[REG3:[0-9]+]], 0
|
||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
|
||||
; CHECK: crnor
|
||||
; CHECK: crnor
|
||||
; CHECK: crxor [[REG4:[0-9]+]],
|
||||
; CHECK: isel 3, [[REG1]], [[REG3]], [[REG4]]
|
||||
; CHECK: creqv [[REG4:[0-9]+]],
|
||||
; CHECK: isel 3, 0, [[REG1]], [[REG4]]
|
||||
; CHECK: blr
|
||||
}
|
||||
|
||||
@ -62,13 +56,12 @@ entry:
|
||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
|
||||
; CHECK-DAG: li [[REG1:[0-9]+]], 1
|
||||
; CHECK-DAG: lfs [[REG2:[0-9]+]],
|
||||
; CHECK-DAG: li [[REG3:[0-9]+]], 0
|
||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
|
||||
; CHECK: crnor
|
||||
; CHECK: crnor
|
||||
; CHECK: crandc
|
||||
; CHECK: crxor [[REG4:[0-9]+]],
|
||||
; CHECK: isel 3, [[REG1]], [[REG3]], [[REG4]]
|
||||
; CHECK: creqv [[REG4:[0-9]+]],
|
||||
; CHECK: isel 3, 0, [[REG1]], [[REG4]]
|
||||
; CHECK: blr
|
||||
}
|
||||
|
||||
@ -96,11 +89,10 @@ entry:
|
||||
; CHECK-LABEL: @test5
|
||||
; CHECK-DAG: and [[REG1:[0-9]+]], 3, 4
|
||||
; CHECK-DAG: cmpwi {{[0-9]+}}, 5, -2
|
||||
; CHECK: li [[REG3:[0-9]+]], 1
|
||||
; CHECK: andi. {{[0-9]+}}, [[REG1]], 1
|
||||
; CHECK: li [[REG4:[0-9]+]], 0
|
||||
; CHECK: crorc [[REG5:[0-9]+]],
|
||||
; CHECK: isel 3, [[REG3]], [[REG4]], [[REG5]]
|
||||
; CHECK-DAG: li [[REG3:[0-9]+]], 1
|
||||
; CHECK-DAG: andi. {{[0-9]+}}, [[REG1]], 1
|
||||
; CHECK-DAG: crandc [[REG5:[0-9]+]],
|
||||
; CHECK: isel 3, 0, [[REG3]], [[REG5]]
|
||||
; CHECK: blr
|
||||
}
|
||||
|
||||
@ -116,12 +108,11 @@ entry:
|
||||
; CHECK-DAG: andi. {{[0-9]+}}, 3, 1
|
||||
; CHECK-DAG: cmpwi {{[0-9]+}}, 5, -2
|
||||
; CHECK-DAG: cror [[REG1:[0-9]+]], 1, 1
|
||||
; CHECK: andi. {{[0-9]+}}, 4, 1
|
||||
; CHECK: li [[REG2:[0-9]+]], 1
|
||||
; CHECK: li [[REG3:[0-9]+]], 0
|
||||
; CHECK: crorc [[REG4:[0-9]+]], 1,
|
||||
; CHECK: crand [[REG5:[0-9]+]], [[REG4]], [[REG1]]
|
||||
; CHECK: isel 3, [[REG2]], [[REG3]], [[REG5]]
|
||||
; CHECK-DAG: andi. {{[0-9]+}}, 4, 1
|
||||
; CHECK-DAG: li [[REG2:[0-9]+]], 1
|
||||
; CHECK-DAG: crorc [[REG4:[0-9]+]], 1,
|
||||
; CHECK-DAG: crnand [[REG5:[0-9]+]], [[REG4]], [[REG1]]
|
||||
; CHECK: isel 3, 0, [[REG2]], [[REG5]]
|
||||
; CHECK: blr
|
||||
}
|
||||
|
||||
@ -163,10 +154,9 @@ entry:
|
||||
; CHECK-LABEL: @test10
|
||||
; CHECK-DAG: cmpwi {{[0-9]+}}, 3, 0
|
||||
; CHECK-DAG: cmpwi {{[0-9]+}}, 4, 0
|
||||
; CHECK-DAG: li [[REG1:[0-9]+]], 0
|
||||
; CHECK-DAG: li [[REG2:[0-9]+]], 1
|
||||
; CHECK: crandc [[REG3:[0-9]+]],
|
||||
; CHECK: isel 3, [[REG2]], [[REG1]], [[REG3]]
|
||||
; CHECK-DAG: crorc [[REG3:[0-9]+]],
|
||||
; CHECK: isel 3, 0, [[REG2]], [[REG3]]
|
||||
; CHECK: blr
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user