mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-29 10:32:47 +00:00
Move some Legalize functionality over to the DAGCombiner where it belongs.
Kill some dead code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23706 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ced9d5dcd3
commit
ded4963ab9
@ -451,6 +451,9 @@ SDOperand DAGCombiner::visit(SDNode *N) {
|
||||
}
|
||||
|
||||
SDOperand DAGCombiner::visitTokenFactor(SDNode *N) {
|
||||
std::vector<SDOperand> Ops;
|
||||
bool Changed = false;
|
||||
|
||||
// If the token factor has two operands and one is the entry token, replace
|
||||
// the token factor with the other operand.
|
||||
if (N->getNumOperands() == 2) {
|
||||
@ -459,6 +462,19 @@ SDOperand DAGCombiner::visitTokenFactor(SDNode *N) {
|
||||
if (N->getOperand(1).getOpcode() == ISD::EntryToken)
|
||||
return N->getOperand(0);
|
||||
}
|
||||
// fold (tokenfactor (tokenfactor)) -> tokenfactor
|
||||
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
|
||||
SDOperand Op = N->getOperand(i);
|
||||
if (Op.getOpcode() == ISD::TokenFactor && Op.hasOneUse()) {
|
||||
Changed = true;
|
||||
for (unsigned j = 0, e = Op.getNumOperands(); j != e; ++j)
|
||||
Ops.push_back(Op.getOperand(j));
|
||||
} else {
|
||||
Ops.push_back(Op);
|
||||
}
|
||||
}
|
||||
if (Changed)
|
||||
return DAG.getNode(ISD::TokenFactor, MVT::Other, Ops);
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
@ -782,6 +798,40 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
|
||||
WorkList.push_back(ANDNode.Val);
|
||||
return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1));
|
||||
}
|
||||
// fold (zext_inreg (extload x)) -> (zextload x)
|
||||
if (N1C && N0.getOpcode() == ISD::EXTLOAD) {
|
||||
MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
|
||||
// If the type of the zext_inreg and the extload match, and we're running
|
||||
// before Legalize, or the resulting zextload is legal on the target, then
|
||||
// go ahead and do the fold.
|
||||
if ((N1C->getValue() == (1ULL << MVT::getSizeInBits(EVT))-1) &&
|
||||
(!AfterLegalize ||
|
||||
TargetLowering::Legal == TLI.getOperationAction(ISD::ZEXTLOAD, EVT))) {
|
||||
SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0),
|
||||
N0.getOperand(1), N0.getOperand(2),
|
||||
EVT);
|
||||
CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0));
|
||||
WorkList.push_back(N);
|
||||
return SDOperand();
|
||||
}
|
||||
}
|
||||
// fold (zext_inreg (sextload x)) -> (zextload x) iff load has one use
|
||||
if (N1C && N0.getOpcode() == ISD::SEXTLOAD && N0.Val->hasNUsesOfValue(1, 0)) {
|
||||
MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
|
||||
// If the type of the zext_inreg and the extload match, and we're running
|
||||
// before Legalize, or the resulting zextload is legal on the target, then
|
||||
// go ahead and do the fold.
|
||||
if ((N1C->getValue() == (1ULL << MVT::getSizeInBits(EVT))-1) &&
|
||||
(!AfterLegalize ||
|
||||
TargetLowering::Legal == TLI.getOperationAction(ISD::ZEXTLOAD, EVT))) {
|
||||
SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0),
|
||||
N0.getOperand(1), N0.getOperand(2),
|
||||
EVT);
|
||||
CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0));
|
||||
WorkList.push_back(N);
|
||||
return SDOperand();
|
||||
}
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
@ -1272,6 +1322,30 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
|
||||
return DAG.getNode(ISD::SRA, N0.getValueType(), N0.getOperand(0),
|
||||
N0.getOperand(1));
|
||||
}
|
||||
// fold (sext_inreg (extload x)) -> (sextload x)
|
||||
if (N0.getOpcode() == ISD::EXTLOAD &&
|
||||
EVT == cast<VTSDNode>(N0.getOperand(3))->getVT() &&
|
||||
(!AfterLegalize ||
|
||||
(TargetLowering::Legal == TLI.getOperationAction(ISD::SEXTLOAD, EVT)))) {
|
||||
SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0),
|
||||
N0.getOperand(1), N0.getOperand(2),
|
||||
EVT);
|
||||
CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0));
|
||||
WorkList.push_back(N);
|
||||
return SDOperand();
|
||||
}
|
||||
// fold (sext_inreg (zextload x)) -> (sextload x) iff load has one use
|
||||
if (N0.getOpcode() == ISD::ZEXTLOAD && N0.Val->hasNUsesOfValue(1, 0) &&
|
||||
EVT == cast<VTSDNode>(N0.getOperand(3))->getVT() &&
|
||||
(!AfterLegalize ||
|
||||
(TargetLowering::Legal == TLI.getOperationAction(ISD::SEXTLOAD, EVT)))) {
|
||||
SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0),
|
||||
N0.getOperand(1), N0.getOperand(2),
|
||||
EVT);
|
||||
CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0));
|
||||
WorkList.push_back(N);
|
||||
return SDOperand();
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
|
@ -635,18 +635,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
case ISD::TokenFactor: {
|
||||
std::vector<SDOperand> Ops;
|
||||
bool Changed = false;
|
||||
// Legalize the operands
|
||||
for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
|
||||
SDOperand Op = Node->getOperand(i);
|
||||
// Fold single-use TokenFactor nodes into this token factor as we go.
|
||||
// FIXME: This is something that the DAGCombiner should do!!
|
||||
if (Op.getOpcode() == ISD::TokenFactor && Op.hasOneUse()) {
|
||||
Changed = true;
|
||||
for (unsigned j = 0, e = Op.getNumOperands(); j != e; ++j)
|
||||
Ops.push_back(LegalizeOp(Op.getOperand(j)));
|
||||
} else {
|
||||
Ops.push_back(LegalizeOp(Op)); // Legalize the operands
|
||||
Changed |= Ops[i] != Op;
|
||||
}
|
||||
Ops.push_back(LegalizeOp(Op));
|
||||
Changed |= Ops[i] != Op;
|
||||
}
|
||||
if (Changed)
|
||||
Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Ops);
|
||||
@ -2352,14 +2345,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
|
||||
case ISD::LOAD:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
|
||||
// FIXME: When the DAG combiner exists, change this to use EXTLOAD!
|
||||
if (MVT::isInteger(NVT))
|
||||
Result = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2,
|
||||
Node->getOperand(2), VT);
|
||||
else
|
||||
Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp1, Tmp2,
|
||||
Node->getOperand(2), VT);
|
||||
|
||||
Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp1, Tmp2,
|
||||
Node->getOperand(2), VT);
|
||||
// Remember that we legalized the chain.
|
||||
AddLegalizedOperand(Op.getValue(1), Result.getValue(1));
|
||||
break;
|
||||
|
@ -779,134 +779,6 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::SimplifySelectCC(SDOperand N1, SDOperand N2,
|
||||
SDOperand N3, SDOperand N4,
|
||||
ISD::CondCode CC) {
|
||||
MVT::ValueType VT = N3.getValueType();
|
||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
|
||||
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val);
|
||||
ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N3.Val);
|
||||
ConstantSDNode *N4C = dyn_cast<ConstantSDNode>(N4.Val);
|
||||
|
||||
// Check to see if we can simplify the select into an fabs node
|
||||
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N2)) {
|
||||
// Allow either -0.0 or 0.0
|
||||
if (CFP->getValue() == 0.0) {
|
||||
// select (setg[te] X, +/-0.0), X, fneg(X) -> fabs
|
||||
if ((CC == ISD::SETGE || CC == ISD::SETGT) &&
|
||||
N1 == N3 && N4.getOpcode() == ISD::FNEG &&
|
||||
N1 == N4.getOperand(0))
|
||||
return getNode(ISD::FABS, VT, N1);
|
||||
|
||||
// select (setl[te] X, +/-0.0), fneg(X), X -> fabs
|
||||
if ((CC == ISD::SETLT || CC == ISD::SETLE) &&
|
||||
N1 == N4 && N3.getOpcode() == ISD::FNEG &&
|
||||
N3.getOperand(0) == N4)
|
||||
return getNode(ISD::FABS, VT, N4);
|
||||
}
|
||||
}
|
||||
|
||||
// check to see if we're select_cc'ing a select_cc.
|
||||
// this allows us to turn:
|
||||
// select_cc set[eq,ne] (select_cc cc, lhs, rhs, 1, 0), 0, true, false ->
|
||||
// select_cc cc, lhs, rhs, true, false
|
||||
if ((N1C && N1C->isNullValue() && N2.getOpcode() == ISD::SELECT_CC) ||
|
||||
(N2C && N2C->isNullValue() && N1.getOpcode() == ISD::SELECT_CC) &&
|
||||
(CC == ISD::SETEQ || CC == ISD::SETNE)) {
|
||||
SDOperand SCC = N1C ? N2 : N1;
|
||||
ConstantSDNode *SCCT = dyn_cast<ConstantSDNode>(SCC.getOperand(2));
|
||||
ConstantSDNode *SCCF = dyn_cast<ConstantSDNode>(SCC.getOperand(3));
|
||||
if (SCCT && SCCF && SCCF->isNullValue() && SCCT->getValue() == 1ULL) {
|
||||
if (CC == ISD::SETEQ) std::swap(N3, N4);
|
||||
return getNode(ISD::SELECT_CC, N3.getValueType(), SCC.getOperand(0),
|
||||
SCC.getOperand(1), N3, N4, SCC.getOperand(4));
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if we can perform the "gzip trick", transforming
|
||||
// select_cc setlt X, 0, A, 0 -> and (sra X, size(X)-1), A
|
||||
if (N2C && N2C->isNullValue() && N4C && N4C->isNullValue() &&
|
||||
MVT::isInteger(N1.getValueType()) &&
|
||||
MVT::isInteger(N3.getValueType()) && CC == ISD::SETLT) {
|
||||
MVT::ValueType XType = N1.getValueType();
|
||||
MVT::ValueType AType = N3.getValueType();
|
||||
if (XType >= AType) {
|
||||
// and (sra X, size(X)-1, A) -> "and (srl X, C2), A" iff A is a
|
||||
// single-bit constant. FIXME: remove once the dag combiner
|
||||
// exists.
|
||||
if (N3C && ((N3C->getValue() & (N3C->getValue()-1)) == 0)) {
|
||||
unsigned ShCtV = Log2_64(N3C->getValue());
|
||||
ShCtV = MVT::getSizeInBits(XType)-ShCtV-1;
|
||||
SDOperand ShCt = getConstant(ShCtV, TLI.getShiftAmountTy());
|
||||
SDOperand Shift = getNode(ISD::SRL, XType, N1, ShCt);
|
||||
if (XType > AType)
|
||||
Shift = getNode(ISD::TRUNCATE, AType, Shift);
|
||||
return getNode(ISD::AND, AType, Shift, N3);
|
||||
}
|
||||
SDOperand Shift = getNode(ISD::SRA, XType, N1,
|
||||
getConstant(MVT::getSizeInBits(XType)-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
if (XType > AType)
|
||||
Shift = getNode(ISD::TRUNCATE, AType, Shift);
|
||||
return getNode(ISD::AND, AType, Shift, N3);
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if this is the equivalent of setcc
|
||||
if (N4C && N4C->isNullValue() && N3C && (N3C->getValue() == 1ULL)) {
|
||||
MVT::ValueType XType = N1.getValueType();
|
||||
if (TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultTy())) {
|
||||
SDOperand Res = getSetCC(TLI.getSetCCResultTy(), N1, N2, CC);
|
||||
if (Res.getValueType() != VT)
|
||||
Res = getNode(ISD::ZERO_EXTEND, VT, Res);
|
||||
return Res;
|
||||
}
|
||||
|
||||
// seteq X, 0 -> srl (ctlz X, log2(size(X)))
|
||||
if (N2C && N2C->isNullValue() && CC == ISD::SETEQ &&
|
||||
TLI.isOperationLegal(ISD::CTLZ, XType)) {
|
||||
SDOperand Ctlz = getNode(ISD::CTLZ, XType, N1);
|
||||
return getNode(ISD::SRL, XType, Ctlz,
|
||||
getConstant(Log2_32(MVT::getSizeInBits(XType)),
|
||||
TLI.getShiftAmountTy()));
|
||||
}
|
||||
// setgt X, 0 -> srl (and (-X, ~X), size(X)-1)
|
||||
if (N2C && N2C->isNullValue() && CC == ISD::SETGT) {
|
||||
SDOperand NegN1 = getNode(ISD::SUB, XType, getConstant(0, XType), N1);
|
||||
SDOperand NotN1 = getNode(ISD::XOR, XType, N1, getConstant(~0ULL, XType));
|
||||
return getNode(ISD::SRL, XType, getNode(ISD::AND, XType, NegN1, NotN1),
|
||||
getConstant(MVT::getSizeInBits(XType)-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
}
|
||||
// setgt X, -1 -> xor (srl (X, size(X)-1), 1)
|
||||
if (N2C && N2C->isAllOnesValue() && CC == ISD::SETGT) {
|
||||
SDOperand Sign = getNode(ISD::SRL, XType, N1,
|
||||
getConstant(MVT::getSizeInBits(XType)-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
return getNode(ISD::XOR, XType, Sign, getConstant(1, XType));
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if this is an integer abs. select_cc setl[te] X, 0, -X, X ->
|
||||
// Y = sra (X, size(X)-1); xor (add (X, Y), Y)
|
||||
if (N2C && N2C->isNullValue() && (CC == ISD::SETLT || CC == ISD::SETLE) &&
|
||||
N1 == N4 && N3.getOpcode() == ISD::SUB && N1 == N3.getOperand(1)) {
|
||||
if (ConstantSDNode *SubC = dyn_cast<ConstantSDNode>(N3.getOperand(0))) {
|
||||
MVT::ValueType XType = N1.getValueType();
|
||||
if (SubC->isNullValue() && MVT::isInteger(XType)) {
|
||||
SDOperand Shift = getNode(ISD::SRA, XType, N1,
|
||||
getConstant(MVT::getSizeInBits(XType)-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
return getNode(ISD::XOR, XType, getNode(ISD::ADD, XType, N1, Shift),
|
||||
Shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Could not fold it.
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
/// getNode - Gets or creates the specified node.
|
||||
///
|
||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) {
|
||||
@ -1370,9 +1242,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
"True and False arms of SelectCC must have same type!");
|
||||
assert(Ops[2].getValueType() == VT &&
|
||||
"select_cc node must be of same type as true and false value!");
|
||||
SDOperand Simp = SimplifySelectCC(Ops[0], Ops[1], Ops[2], Ops[3],
|
||||
cast<CondCodeSDNode>(Ops[4])->get());
|
||||
if (Simp.Val) return Simp;
|
||||
break;
|
||||
}
|
||||
case ISD::BR_CC: {
|
||||
|
Loading…
Reference in New Issue
Block a user