mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +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 PeepholePPC64();
|
||||||
void PeepholdCROps();
|
void PeepholdCROps();
|
||||||
|
|
||||||
|
bool AllUsersSelectZero(SDNode *N);
|
||||||
|
void SwapAllSelectUsers(SDNode *N);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1504,6 +1507,74 @@ void PPCDAGToDAGISel::PostprocessISelDAG() {
|
|||||||
PeepholdCROps();
|
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() {
|
void PPCDAGToDAGISel::PeepholdCROps() {
|
||||||
bool IsModified;
|
bool IsModified;
|
||||||
do {
|
do {
|
||||||
@ -1563,6 +1634,7 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SelectSwap = false;
|
||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
default: break;
|
default: break;
|
||||||
case PPC::CRAND:
|
case PPC::CRAND:
|
||||||
@ -1591,6 +1663,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
|||||||
MVT::i1, MachineNode->getOperand(0),
|
MVT::i1, MachineNode->getOperand(0),
|
||||||
MachineNode->getOperand(1).
|
MachineNode->getOperand(1).
|
||||||
getOperand(0));
|
getOperand(0));
|
||||||
|
else if (AllUsersSelectZero(MachineNode))
|
||||||
|
ResNode = CurDAG->getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
|
||||||
|
MVT::i1, MachineNode->getOperand(0),
|
||||||
|
MachineNode->getOperand(1)),
|
||||||
|
SelectSwap = true;
|
||||||
break;
|
break;
|
||||||
case PPC::CRNAND:
|
case PPC::CRNAND:
|
||||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||||
@ -1624,6 +1701,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
|||||||
MVT::i1, MachineNode->getOperand(1).
|
MVT::i1, MachineNode->getOperand(1).
|
||||||
getOperand(0),
|
getOperand(0),
|
||||||
MachineNode->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;
|
break;
|
||||||
case PPC::CROR:
|
case PPC::CROR:
|
||||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||||
@ -1651,6 +1733,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
|||||||
MVT::i1, MachineNode->getOperand(0),
|
MVT::i1, MachineNode->getOperand(0),
|
||||||
MachineNode->getOperand(1).
|
MachineNode->getOperand(1).
|
||||||
getOperand(0));
|
getOperand(0));
|
||||||
|
else if (AllUsersSelectZero(MachineNode))
|
||||||
|
ResNode = CurDAG->getMachineNode(PPC::CRNOR, SDLoc(MachineNode),
|
||||||
|
MVT::i1, MachineNode->getOperand(0),
|
||||||
|
MachineNode->getOperand(1)),
|
||||||
|
SelectSwap = true;
|
||||||
break;
|
break;
|
||||||
case PPC::CRXOR:
|
case PPC::CRXOR:
|
||||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||||
@ -1685,6 +1772,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
|||||||
MVT::i1, MachineNode->getOperand(0),
|
MVT::i1, MachineNode->getOperand(0),
|
||||||
MachineNode->getOperand(1).
|
MachineNode->getOperand(1).
|
||||||
getOperand(0));
|
getOperand(0));
|
||||||
|
else if (AllUsersSelectZero(MachineNode))
|
||||||
|
ResNode = CurDAG->getMachineNode(PPC::CREQV, SDLoc(MachineNode),
|
||||||
|
MVT::i1, MachineNode->getOperand(0),
|
||||||
|
MachineNode->getOperand(1)),
|
||||||
|
SelectSwap = true;
|
||||||
break;
|
break;
|
||||||
case PPC::CRNOR:
|
case PPC::CRNOR:
|
||||||
if (Op1Set || Op2Set)
|
if (Op1Set || Op2Set)
|
||||||
@ -1713,6 +1805,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
|||||||
MVT::i1, MachineNode->getOperand(1).
|
MVT::i1, MachineNode->getOperand(1).
|
||||||
getOperand(0),
|
getOperand(0),
|
||||||
MachineNode->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;
|
break;
|
||||||
case PPC::CREQV:
|
case PPC::CREQV:
|
||||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||||
@ -1747,6 +1844,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
|||||||
MVT::i1, MachineNode->getOperand(0),
|
MVT::i1, MachineNode->getOperand(0),
|
||||||
MachineNode->getOperand(1).
|
MachineNode->getOperand(1).
|
||||||
getOperand(0));
|
getOperand(0));
|
||||||
|
else if (AllUsersSelectZero(MachineNode))
|
||||||
|
ResNode = CurDAG->getMachineNode(PPC::CRXOR, SDLoc(MachineNode),
|
||||||
|
MVT::i1, MachineNode->getOperand(0),
|
||||||
|
MachineNode->getOperand(1)),
|
||||||
|
SelectSwap = true;
|
||||||
break;
|
break;
|
||||||
case PPC::CRANDC:
|
case PPC::CRANDC:
|
||||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||||
@ -1777,6 +1879,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
|||||||
MVT::i1, MachineNode->getOperand(0),
|
MVT::i1, MachineNode->getOperand(0),
|
||||||
MachineNode->getOperand(1).
|
MachineNode->getOperand(1).
|
||||||
getOperand(0));
|
getOperand(0));
|
||||||
|
else if (AllUsersSelectZero(MachineNode))
|
||||||
|
ResNode = CurDAG->getMachineNode(PPC::CRORC, SDLoc(MachineNode),
|
||||||
|
MVT::i1, MachineNode->getOperand(1),
|
||||||
|
MachineNode->getOperand(0)),
|
||||||
|
SelectSwap = true;
|
||||||
break;
|
break;
|
||||||
case PPC::CRORC:
|
case PPC::CRORC:
|
||||||
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
if (MachineNode->getOperand(0) == MachineNode->getOperand(1))
|
||||||
@ -1807,6 +1914,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
|||||||
MVT::i1, MachineNode->getOperand(0),
|
MVT::i1, MachineNode->getOperand(0),
|
||||||
MachineNode->getOperand(1).
|
MachineNode->getOperand(1).
|
||||||
getOperand(0));
|
getOperand(0));
|
||||||
|
else if (AllUsersSelectZero(MachineNode))
|
||||||
|
ResNode = CurDAG->getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
|
||||||
|
MVT::i1, MachineNode->getOperand(1),
|
||||||
|
MachineNode->getOperand(0)),
|
||||||
|
SelectSwap = true;
|
||||||
break;
|
break;
|
||||||
case PPC::SELECT_I4:
|
case PPC::SELECT_I4:
|
||||||
case PPC::SELECT_I8:
|
case PPC::SELECT_I8:
|
||||||
@ -1841,6 +1953,11 @@ void PPCDAGToDAGISel::PeepholdCROps() {
|
|||||||
break;
|
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) {
|
if (ResNode != MachineNode) {
|
||||||
DEBUG(dbgs() << "CR Peephole replacing:\nOld: ");
|
DEBUG(dbgs() << "CR Peephole replacing:\nOld: ");
|
||||||
DEBUG(MachineNode->dump(CurDAG));
|
DEBUG(MachineNode->dump(CurDAG));
|
||||||
|
@ -2,10 +2,6 @@
|
|||||||
target datalayout = "E-m:e-i64:64-n32:64"
|
target datalayout = "E-m:e-i64:64-n32:64"
|
||||||
target triple = "powerpc64-unknown-linux-gnu"
|
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
|
; Function Attrs: nounwind readnone
|
||||||
define zeroext i1 @test1(float %v1, float %v2) #0 {
|
define zeroext i1 @test1(float %v1, float %v2) #0 {
|
||||||
entry:
|
entry:
|
||||||
@ -18,12 +14,11 @@ entry:
|
|||||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
|
; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
|
||||||
; CHECK-DAG: li [[REG1:[0-9]+]], 1
|
; CHECK-DAG: li [[REG1:[0-9]+]], 1
|
||||||
; CHECK-DAG: lfs [[REG2:[0-9]+]],
|
; CHECK-DAG: lfs [[REG2:[0-9]+]],
|
||||||
; CHECK-DAG: li [[REG3:[0-9]+]], 0
|
|
||||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
|
; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
|
||||||
; CHECK: crnor
|
; CHECK: crnor
|
||||||
; CHECK: crnor
|
; CHECK: crnor
|
||||||
; CHECK: crand [[REG4:[0-9]+]],
|
; CHECK: crnand [[REG4:[0-9]+]],
|
||||||
; CHECK: isel 3, [[REG1]], [[REG3]], [[REG4]]
|
; CHECK: isel 3, 0, [[REG1]], [[REG4]]
|
||||||
; CHECK: blr
|
; CHECK: blr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,12 +34,11 @@ entry:
|
|||||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
|
; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
|
||||||
; CHECK-DAG: li [[REG1:[0-9]+]], 1
|
; CHECK-DAG: li [[REG1:[0-9]+]], 1
|
||||||
; CHECK-DAG: lfs [[REG2:[0-9]+]],
|
; CHECK-DAG: lfs [[REG2:[0-9]+]],
|
||||||
; CHECK-DAG: li [[REG3:[0-9]+]], 0
|
|
||||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
|
; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
|
||||||
; CHECK: crnor
|
; CHECK: crnor
|
||||||
; CHECK: crnor
|
; CHECK: crnor
|
||||||
; CHECK: crxor [[REG4:[0-9]+]],
|
; CHECK: creqv [[REG4:[0-9]+]],
|
||||||
; CHECK: isel 3, [[REG1]], [[REG3]], [[REG4]]
|
; CHECK: isel 3, 0, [[REG1]], [[REG4]]
|
||||||
; CHECK: blr
|
; CHECK: blr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,13 +56,12 @@ entry:
|
|||||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
|
; CHECK-DAG: fcmpu {{[0-9]+}}, 1, 2
|
||||||
; CHECK-DAG: li [[REG1:[0-9]+]], 1
|
; CHECK-DAG: li [[REG1:[0-9]+]], 1
|
||||||
; CHECK-DAG: lfs [[REG2:[0-9]+]],
|
; CHECK-DAG: lfs [[REG2:[0-9]+]],
|
||||||
; CHECK-DAG: li [[REG3:[0-9]+]], 0
|
|
||||||
; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
|
; CHECK-DAG: fcmpu {{[0-9]+}}, 2, [[REG2]]
|
||||||
; CHECK: crnor
|
; CHECK: crnor
|
||||||
; CHECK: crnor
|
; CHECK: crnor
|
||||||
; CHECK: crandc
|
; CHECK: crandc
|
||||||
; CHECK: crxor [[REG4:[0-9]+]],
|
; CHECK: creqv [[REG4:[0-9]+]],
|
||||||
; CHECK: isel 3, [[REG1]], [[REG3]], [[REG4]]
|
; CHECK: isel 3, 0, [[REG1]], [[REG4]]
|
||||||
; CHECK: blr
|
; CHECK: blr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,11 +89,10 @@ entry:
|
|||||||
; CHECK-LABEL: @test5
|
; CHECK-LABEL: @test5
|
||||||
; CHECK-DAG: and [[REG1:[0-9]+]], 3, 4
|
; CHECK-DAG: and [[REG1:[0-9]+]], 3, 4
|
||||||
; CHECK-DAG: cmpwi {{[0-9]+}}, 5, -2
|
; CHECK-DAG: cmpwi {{[0-9]+}}, 5, -2
|
||||||
; CHECK: li [[REG3:[0-9]+]], 1
|
; CHECK-DAG: li [[REG3:[0-9]+]], 1
|
||||||
; CHECK: andi. {{[0-9]+}}, [[REG1]], 1
|
; CHECK-DAG: andi. {{[0-9]+}}, [[REG1]], 1
|
||||||
; CHECK: li [[REG4:[0-9]+]], 0
|
; CHECK-DAG: crandc [[REG5:[0-9]+]],
|
||||||
; CHECK: crorc [[REG5:[0-9]+]],
|
; CHECK: isel 3, 0, [[REG3]], [[REG5]]
|
||||||
; CHECK: isel 3, [[REG3]], [[REG4]], [[REG5]]
|
|
||||||
; CHECK: blr
|
; CHECK: blr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,12 +108,11 @@ entry:
|
|||||||
; CHECK-DAG: andi. {{[0-9]+}}, 3, 1
|
; CHECK-DAG: andi. {{[0-9]+}}, 3, 1
|
||||||
; CHECK-DAG: cmpwi {{[0-9]+}}, 5, -2
|
; CHECK-DAG: cmpwi {{[0-9]+}}, 5, -2
|
||||||
; CHECK-DAG: cror [[REG1:[0-9]+]], 1, 1
|
; CHECK-DAG: cror [[REG1:[0-9]+]], 1, 1
|
||||||
; CHECK: andi. {{[0-9]+}}, 4, 1
|
; CHECK-DAG: andi. {{[0-9]+}}, 4, 1
|
||||||
; CHECK: li [[REG2:[0-9]+]], 1
|
; CHECK-DAG: li [[REG2:[0-9]+]], 1
|
||||||
; CHECK: li [[REG3:[0-9]+]], 0
|
; CHECK-DAG: crorc [[REG4:[0-9]+]], 1,
|
||||||
; CHECK: crorc [[REG4:[0-9]+]], 1,
|
; CHECK-DAG: crnand [[REG5:[0-9]+]], [[REG4]], [[REG1]]
|
||||||
; CHECK: crand [[REG5:[0-9]+]], [[REG4]], [[REG1]]
|
; CHECK: isel 3, 0, [[REG2]], [[REG5]]
|
||||||
; CHECK: isel 3, [[REG2]], [[REG3]], [[REG5]]
|
|
||||||
; CHECK: blr
|
; CHECK: blr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,10 +154,9 @@ entry:
|
|||||||
; CHECK-LABEL: @test10
|
; CHECK-LABEL: @test10
|
||||||
; CHECK-DAG: cmpwi {{[0-9]+}}, 3, 0
|
; CHECK-DAG: cmpwi {{[0-9]+}}, 3, 0
|
||||||
; CHECK-DAG: cmpwi {{[0-9]+}}, 4, 0
|
; CHECK-DAG: cmpwi {{[0-9]+}}, 4, 0
|
||||||
; CHECK-DAG: li [[REG1:[0-9]+]], 0
|
|
||||||
; CHECK-DAG: li [[REG2:[0-9]+]], 1
|
; CHECK-DAG: li [[REG2:[0-9]+]], 1
|
||||||
; CHECK: crandc [[REG3:[0-9]+]],
|
; CHECK-DAG: crorc [[REG3:[0-9]+]],
|
||||||
; CHECK: isel 3, [[REG2]], [[REG1]], [[REG3]]
|
; CHECK: isel 3, 0, [[REG2]], [[REG3]]
|
||||||
; CHECK: blr
|
; CHECK: blr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user