mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-06 02:17:20 +00:00
Implement Value* tracking for loads and stores in the selection DAG. This enables one to use alias analysis in the backends.
(TRUNK)Stores and (EXT|ZEXT|SEXT)Loads have an extra SDOperand which is a SrcValueSDNode which contains the Value*. Note that if the operation is introduced by the backend, it will still have the operand, but the value* will be null. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21599 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -290,9 +290,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
TLI.getPointerTy());
|
||||
if (Extend) {
|
||||
Result = DAG.getNode(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), CPIdx,
|
||||
MVT::f32);
|
||||
DAG.getSrcValue(NULL), MVT::f32);
|
||||
} else {
|
||||
Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx);
|
||||
Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -428,9 +428,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
case ISD::LOAD:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
|
||||
|
||||
if (Tmp1 != Node->getOperand(0) ||
|
||||
Tmp2 != Node->getOperand(1))
|
||||
Result = DAG.getLoad(Node->getValueType(0), Tmp1, Tmp2);
|
||||
Result = DAG.getLoad(Node->getValueType(0), Tmp1, Tmp2, Node->getOperand(2));
|
||||
else
|
||||
Result = SDOperand(Node, 0);
|
||||
|
||||
@@ -452,7 +453,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
case TargetLowering::Promote:
|
||||
assert(SrcVT == MVT::i1 && "Can only promote EXTLOAD from i1 -> i8!");
|
||||
Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0),
|
||||
Tmp1, Tmp2, MVT::i8);
|
||||
Tmp1, Tmp2, Node->getOperand(2), MVT::i8);
|
||||
// Since loads produce two values, make sure to remember that we legalized
|
||||
// both of them.
|
||||
AddLegalizedOperand(SDOperand(Node, 0), Result);
|
||||
@@ -463,7 +464,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
if (Tmp1 != Node->getOperand(0) ||
|
||||
Tmp2 != Node->getOperand(1))
|
||||
Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0),
|
||||
Tmp1, Tmp2, SrcVT);
|
||||
Tmp1, Tmp2, Node->getOperand(2), SrcVT);
|
||||
else
|
||||
Result = SDOperand(Node, 0);
|
||||
|
||||
@@ -478,7 +479,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
// Turn the unsupported load into an EXTLOAD followed by an explicit
|
||||
// zero/sign extend inreg.
|
||||
Result = DAG.getNode(ISD::EXTLOAD, Node->getValueType(0),
|
||||
Tmp1, Tmp2, SrcVT);
|
||||
Tmp1, Tmp2, Node->getOperand(2), SrcVT);
|
||||
SDOperand ValRes;
|
||||
if (Node->getOpcode() == ISD::SEXTLOAD)
|
||||
ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
|
||||
@@ -591,8 +592,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
float F;
|
||||
} V;
|
||||
V.F = CFP->getValue();
|
||||
Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
|
||||
DAG.getConstant(V.I, MVT::i32), Tmp2);
|
||||
Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
|
||||
DAG.getConstant(V.I, MVT::i32), Tmp2, Node->getOperand(3));
|
||||
} else {
|
||||
assert(CFP->getValueType(0) == MVT::f64 && "Unknown FP type!");
|
||||
union {
|
||||
@@ -600,8 +601,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
double F;
|
||||
} V;
|
||||
V.F = CFP->getValue();
|
||||
Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
|
||||
DAG.getConstant(V.I, MVT::i64), Tmp2);
|
||||
Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
|
||||
DAG.getConstant(V.I, MVT::i64), Tmp2, Node->getOperand(3));
|
||||
}
|
||||
Node = Result.Val;
|
||||
}
|
||||
@@ -611,14 +612,15 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
SDOperand Val = LegalizeOp(Node->getOperand(1));
|
||||
if (Val != Node->getOperand(1) || Tmp1 != Node->getOperand(0) ||
|
||||
Tmp2 != Node->getOperand(2))
|
||||
Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Val, Tmp2);
|
||||
Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Val, Tmp2, Node->getOperand(3));
|
||||
break;
|
||||
}
|
||||
case Promote:
|
||||
// Truncate the value and store the result.
|
||||
Tmp3 = PromoteOp(Node->getOperand(1));
|
||||
Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp3, Tmp2,
|
||||
Node->getOperand(1).getValueType());
|
||||
Node->getOperand(3),
|
||||
Node->getOperand(1).getValueType());
|
||||
break;
|
||||
|
||||
case Expand:
|
||||
@@ -628,14 +630,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
if (!TLI.isLittleEndian())
|
||||
std::swap(Lo, Hi);
|
||||
|
||||
Lo = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Lo, Tmp2);
|
||||
Lo = DAG.getNode(ISD::STORE, MVT::Other,Tmp1, Lo, Tmp2,Node->getOperand(3));
|
||||
|
||||
unsigned IncrementSize = MVT::getSizeInBits(Hi.getValueType())/8;
|
||||
Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
|
||||
getIntPtrConstant(IncrementSize));
|
||||
assert(isTypeLegal(Tmp2.getValueType()) &&
|
||||
"Pointers must be legal!");
|
||||
Hi = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Hi, Tmp2);
|
||||
//Again, claiming both parts of the store came form the same Instr
|
||||
Hi = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Hi, Tmp2, Node->getOperand(3));
|
||||
|
||||
Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
|
||||
break;
|
||||
}
|
||||
@@ -655,6 +659,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
|
||||
Tmp3 != Node->getOperand(2))
|
||||
Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp2, Tmp3,
|
||||
Node->getOperand(3),
|
||||
cast<MVTSDNode>(Node)->getExtraValueType());
|
||||
break;
|
||||
case Promote:
|
||||
@@ -1138,9 +1143,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align);
|
||||
SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
|
||||
Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, DAG.getEntryNode(),
|
||||
Node->getOperand(0), StackSlot, ExtraVT);
|
||||
Node->getOperand(0), StackSlot, DAG.getSrcValue(NULL), ExtraVT);
|
||||
Result = DAG.getNode(ISD::EXTLOAD, Node->getValueType(0),
|
||||
Result, StackSlot, ExtraVT);
|
||||
Result, StackSlot, DAG.getSrcValue(NULL), ExtraVT);
|
||||
} else {
|
||||
assert(0 && "Unknown op");
|
||||
}
|
||||
@@ -1404,9 +1409,9 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
|
||||
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.getNode(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, VT);
|
||||
Result = DAG.getNode(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, Node->getOperand(2), VT);
|
||||
else
|
||||
Result = DAG.getNode(ISD::EXTLOAD, NVT, Tmp1, Tmp2, VT);
|
||||
Result = DAG.getNode(ISD::EXTLOAD, NVT, Tmp1, Tmp2, Node->getOperand(2), VT);
|
||||
|
||||
// Remember that we legalized the chain.
|
||||
AddLegalizedOperand(Op.getValue(1), Result.getValue(1));
|
||||
@@ -1846,11 +1851,11 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) {
|
||||
CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
|
||||
SDOperand FudgeInReg;
|
||||
if (DestTy == MVT::f32)
|
||||
FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx);
|
||||
FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL));
|
||||
else {
|
||||
assert(DestTy == MVT::f64 && "Unexpected conversion");
|
||||
FudgeInReg = DAG.getNode(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(),
|
||||
CPIdx, MVT::f32);
|
||||
CPIdx, DAG.getSrcValue(NULL), MVT::f32);
|
||||
}
|
||||
return DAG.getNode(ISD::ADD, DestTy, SignedConv, FudgeInReg);
|
||||
}
|
||||
@@ -1941,13 +1946,15 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||
case ISD::LOAD: {
|
||||
SDOperand Ch = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
SDOperand Ptr = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
|
||||
Lo = DAG.getLoad(NVT, Ch, Ptr);
|
||||
Lo = DAG.getLoad(NVT, Ch, Ptr, Node->getOperand(2));
|
||||
|
||||
// Increment the pointer to the other half.
|
||||
unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
|
||||
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
|
||||
getIntPtrConstant(IncrementSize));
|
||||
Hi = DAG.getLoad(NVT, Ch, Ptr);
|
||||
//Is this safe? declaring that the two parts of the split load
|
||||
//are from the same instruction?
|
||||
Hi = DAG.getLoad(NVT, Ch, Ptr, Node->getOperand(2));
|
||||
|
||||
// Build a factor node to remember that this load is independent of the
|
||||
// other one.
|
||||
|
@@ -1174,10 +1174,11 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
|
||||
SDOperand Chain, SDOperand Ptr) {
|
||||
SDOperand Chain, SDOperand Ptr,
|
||||
SDOperand SV) {
|
||||
SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, VT))];
|
||||
if (N) return SDOperand(N, 0);
|
||||
N = new SDNode(ISD::LOAD, Chain, Ptr);
|
||||
N = new SDNode(ISD::LOAD, Chain, Ptr, SV);
|
||||
|
||||
// Loads have a token chain.
|
||||
N->setValueTypes(VT, MVT::Other);
|
||||
@@ -1185,9 +1186,9 @@ SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
||||
|
||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
SDOperand N1, SDOperand N2, SDOperand N3) {
|
||||
assert(Opcode != ISD::STORE && "Store shouldn't use this anymore");
|
||||
// Perform various simplifications.
|
||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
|
||||
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val);
|
||||
@@ -1314,6 +1315,27 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
SDOperand N1, SDOperand N2, SDOperand N3,
|
||||
SDOperand N4) {
|
||||
assert(Opcode == ISD::STORE && "Only stores should use this");
|
||||
|
||||
SDNode *N = new SDNode(Opcode, N1, N2, N3, N4);
|
||||
N->setValueTypes(VT);
|
||||
|
||||
// FIXME: memoize NODES
|
||||
AllNodes.push_back(N);
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getSrcValue(const Value* v) {
|
||||
SDNode *N = new SrcValueSDNode(v);
|
||||
N->setValueTypes(MVT::Other);
|
||||
// FIXME: memoize NODES
|
||||
AllNodes.push_back(N);
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
std::vector<SDOperand> &Children) {
|
||||
switch (Children.size()) {
|
||||
@@ -1419,7 +1441,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
SDOperand N2, MVT::ValueType EVT) {
|
||||
SDOperand N2, SDOperand N3, MVT::ValueType EVT) {
|
||||
switch (Opcode) {
|
||||
default: assert(0 && "Bad opcode for this accessor!");
|
||||
case ISD::EXTLOAD:
|
||||
@@ -1428,7 +1450,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
// If they are asking for an extending load from/to the same thing, return a
|
||||
// normal load.
|
||||
if (VT == EVT)
|
||||
return getNode(ISD::LOAD, VT, N1, N2);
|
||||
return getLoad(VT, N1, N2, N3);
|
||||
assert(EVT < VT && "Should only be an extending load, not truncating!");
|
||||
assert((Opcode == ISD::EXTLOAD || MVT::isInteger(VT)) &&
|
||||
"Cannot sign/zero extend a FP load!");
|
||||
@@ -1443,16 +1465,17 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
NN.EVT = EVT;
|
||||
NN.Ops.push_back(N1);
|
||||
NN.Ops.push_back(N2);
|
||||
NN.Ops.push_back(N3);
|
||||
|
||||
SDNode *&N = MVTSDNodes[NN];
|
||||
if (N) return SDOperand(N, 0);
|
||||
N = new MVTSDNode(Opcode, VT, MVT::Other, N1, N2, EVT);
|
||||
N = new MVTSDNode(Opcode, VT, MVT::Other, N1, N2, N3, EVT);
|
||||
AllNodes.push_back(N);
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
SDOperand N2, SDOperand N3, MVT::ValueType EVT) {
|
||||
SDOperand N2, SDOperand N3, SDOperand N4, MVT::ValueType EVT) {
|
||||
switch (Opcode) {
|
||||
default: assert(0 && "Bad opcode for this accessor!");
|
||||
case ISD::TRUNCSTORE:
|
||||
@@ -1467,7 +1490,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
// Also for ConstantFP?
|
||||
#endif
|
||||
if (N1.getValueType() == EVT) // Normal store?
|
||||
return getNode(ISD::STORE, VT, N1, N2, N3);
|
||||
return getNode(ISD::STORE, VT, N1, N2, N3, N4);
|
||||
assert(N2.getValueType() > EVT && "Not a truncation?");
|
||||
assert(MVT::isInteger(N2.getValueType()) == MVT::isInteger(EVT) &&
|
||||
"Can't do FP-INT conversion!");
|
||||
@@ -1481,10 +1504,11 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
NN.Ops.push_back(N1);
|
||||
NN.Ops.push_back(N2);
|
||||
NN.Ops.push_back(N3);
|
||||
NN.Ops.push_back(N4);
|
||||
|
||||
SDNode *&N = MVTSDNodes[NN];
|
||||
if (N) return SDOperand(N, 0);
|
||||
N = new MVTSDNode(Opcode, VT, N1, N2, N3, EVT);
|
||||
N = new MVTSDNode(Opcode, VT, N1, N2, N3, N4, EVT);
|
||||
AllNodes.push_back(N);
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
@@ -623,7 +623,7 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
|
||||
Root = DAG.getRoot();
|
||||
}
|
||||
|
||||
SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), Root, Ptr);
|
||||
SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), Root, Ptr, DAG.getSrcValue(&I));
|
||||
setValue(&I, L);
|
||||
|
||||
if (I.isVolatile())
|
||||
@@ -637,7 +637,8 @@ void SelectionDAGLowering::visitStore(StoreInst &I) {
|
||||
Value *SrcV = I.getOperand(0);
|
||||
SDOperand Src = getValue(SrcV);
|
||||
SDOperand Ptr = getValue(I.getOperand(1));
|
||||
DAG.setRoot(DAG.getNode(ISD::STORE, MVT::Other, getRoot(), Src, Ptr));
|
||||
// DAG.setRoot(DAG.getNode(ISD::STORE, MVT::Other, getRoot(), Src, Ptr));
|
||||
DAG.setRoot(DAG.getNode(ISD::STORE, MVT::Other, getRoot(), Src, Ptr, DAG.getSrcValue(&I)));
|
||||
}
|
||||
|
||||
void SelectionDAGLowering::visitCall(CallInst &I) {
|
||||
|
Reference in New Issue
Block a user