[llvm-commits] [llvm] r47601 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.cpp LegalizeTypes.h LegalizeTypesExpand.cpp LegalizeTypesPromote.cpp LegalizeTypesScalarize.cpp LegalizeTypesSplit.cpp
Duncan Sands
baldrick at free.fr
Tue Feb 26 03:21:44 PST 2008
Author: baldrick
Date: Tue Feb 26 05:21:42 2008
New Revision: 47601
URL: http://llvm.org/viewvc/llvm-project?rev=47601&view=rev
Log:
Fix a nasty bug in LegalizeTypes (spotted in
CodeGen/PowerPC/illegal-element-type.ll): suppose
a node X is processed, and processing maps it to
a node Y. Then X continues to exist in the DAG,
but with no users. While processing some other
node, a new node may be created that happens to
be equal to X, and thus X will be reused rather
than a truly new node. This can cause X to
"magically reappear", and since it is in the
Processed state in will not be reprocessed, so
at the end of type legalization the illegal node
X can still be present. The solution is to replace
X with Y whenever X gets resurrected like this.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=47601&r1=47600&r2=47601&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Tue Feb 26 05:21:42 2008
@@ -207,9 +207,10 @@
#endif
}
-/// MarkNewNodes - The specified node is the root of a subtree of potentially
-/// new nodes. Add the correct NodeId to mark it.
-void DAGTypeLegalizer::MarkNewNodes(SDNode *N) {
+/// AnalyzeNewNode - The specified node is the root of a subtree of potentially
+/// new nodes. Correct any processed operands (this may change the node) and
+/// calculate the NodeId.
+void DAGTypeLegalizer::AnalyzeNewNode(SDNode *&N) {
// If this was an existing node that is already done, we're done.
if (N->getNodeId() != NewNode)
return;
@@ -221,15 +222,39 @@
//
// As we walk the operands, keep track of the number of nodes that are
// processed. If non-zero, this will become the new nodeid of this node.
+ // Already processed operands may need to be remapped to the node that
+ // replaced them, which can result in our node changing. Since remapping
+ // is rare, the code tries to minimize overhead in the non-remapping case.
+
+ SmallVector<SDOperand, 8> NewOps;
unsigned NumProcessed = 0;
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- int OpId = N->getOperand(i).Val->getNodeId();
- if (OpId == NewNode)
- MarkNewNodes(N->getOperand(i).Val);
- else if (OpId == Processed)
+ SDOperand OrigOp = N->getOperand(i);
+ SDOperand Op = OrigOp;
+
+ if (Op.Val->getNodeId() == Processed)
+ RemapNode(Op);
+
+ if (Op.Val->getNodeId() == NewNode)
+ AnalyzeNewNode(Op.Val);
+ else if (Op.Val->getNodeId() == Processed)
++NumProcessed;
+
+ if (!NewOps.empty()) {
+ // Some previous operand changed. Add this one to the list.
+ NewOps.push_back(Op);
+ } else if (Op != OrigOp) {
+ // This is the first operand to change - add all operands so far.
+ for (unsigned j = 0; j < i; ++j)
+ NewOps.push_back(N->getOperand(j));
+ NewOps.push_back(Op);
+ }
}
-
+
+ // Some operands changed - update the node.
+ if (!NewOps.empty())
+ N = DAG.UpdateNodeOperands(SDOperand(N, 0), &NewOps[0], NewOps.size()).Val;
+
N->setNodeId(N->getNumOperands()-NumProcessed);
if (N->getNodeId() == ReadyToProcess)
Worklist.push_back(N);
@@ -258,7 +283,7 @@
assert(N->getNodeId() != DAGTypeLegalizer::Processed &&
N->getNodeId() != DAGTypeLegalizer::ReadyToProcess &&
"RAUW updated processed node!");
- DTL.ReanalyzeNodeFlags(N);
+ DTL.ReanalyzeNode(N);
}
};
}
@@ -269,11 +294,10 @@
/// of From to use To instead.
void DAGTypeLegalizer::ReplaceValueWith(SDOperand From, SDOperand To) {
if (From == To) return;
-
+
// If expansion produced new nodes, make sure they are properly marked.
- if (To.Val->getNodeId() == NewNode)
- MarkNewNodes(To.Val);
-
+ AnalyzeNewNode(To.Val);
+
// Anything that used the old node should now use the new one. Note that this
// can potentially cause recursive merging.
NodeUpdateListener NUL(*this);
@@ -288,13 +312,13 @@
/// node's results. The from and to node must define identical result types.
void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) {
if (From == To) return;
+
+ // If expansion produced new nodes, make sure they are properly marked.
+ AnalyzeNewNode(To);
+
assert(From->getNumValues() == To->getNumValues() &&
"Node results don't match");
-
- // If expansion produced new nodes, make sure they are properly marked.
- if (To->getNodeId() == NewNode)
- MarkNewNodes(To);
-
+
// Anything that used the old node should now use the new one. Note that this
// can potentially cause recursive merging.
NodeUpdateListener NUL(*this);
@@ -323,8 +347,7 @@
}
void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) {
- if (Result.Val->getNodeId() == NewNode)
- MarkNewNodes(Result.Val);
+ AnalyzeNewNode(Result.Val);
SDOperand &OpEntry = PromotedNodes[Op];
assert(OpEntry.Val == 0 && "Node is already promoted!");
@@ -332,9 +355,8 @@
}
void DAGTypeLegalizer::SetScalarizedOp(SDOperand Op, SDOperand Result) {
- if (Result.Val->getNodeId() == NewNode)
- MarkNewNodes(Result.Val);
-
+ AnalyzeNewNode(Result.Val);
+
SDOperand &OpEntry = ScalarizedNodes[Op];
assert(OpEntry.Val == 0 && "Node is already scalarized!");
OpEntry = Result;
@@ -352,17 +374,15 @@
}
void DAGTypeLegalizer::SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi) {
+ // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant.
+ AnalyzeNewNode(Lo.Val);
+ AnalyzeNewNode(Hi.Val);
+
// Remember that this is the result of the node.
std::pair<SDOperand, SDOperand> &Entry = ExpandedNodes[Op];
assert(Entry.first.Val == 0 && "Node already expanded");
Entry.first = Lo;
Entry.second = Hi;
-
- // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant.
- if (Lo.Val->getNodeId() == NewNode)
- MarkNewNodes(Lo.Val);
- if (Hi.Val->getNodeId() == NewNode)
- MarkNewNodes(Hi.Val);
}
void DAGTypeLegalizer::GetSplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) {
@@ -375,17 +395,15 @@
}
void DAGTypeLegalizer::SetSplitOp(SDOperand Op, SDOperand Lo, SDOperand Hi) {
+ // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant.
+ AnalyzeNewNode(Lo.Val);
+ AnalyzeNewNode(Hi.Val);
+
// Remember that this is the result of the node.
std::pair<SDOperand, SDOperand> &Entry = SplitNodes[Op];
assert(Entry.first.Val == 0 && "Node already split");
Entry.first = Lo;
Entry.second = Hi;
-
- // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant.
- if (Lo.Val->getNodeId() == NewNode)
- MarkNewNodes(Lo.Val);
- if (Hi.Val->getNodeId() == NewNode)
- MarkNewNodes(Hi.Val);
}
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=47601&r1=47600&r2=47601&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Tue Feb 26 05:21:42 2008
@@ -117,16 +117,16 @@
void run();
- /// ReanalyzeNodeFlags - Recompute the NodeID flags for the specified node,
- /// adding it to the worklist if ready.
- void ReanalyzeNodeFlags(SDNode *N) {
+ /// ReanalyzeNode - Recompute the NodeID and correct processed operands
+ /// for the specified node, adding it to the worklist if ready.
+ void ReanalyzeNode(SDNode *N) {
N->setNodeId(NewNode);
- MarkNewNodes(N);
+ AnalyzeNewNode(N);
}
-
+
private:
- void MarkNewNodes(SDNode *N);
-
+ void AnalyzeNewNode(SDNode *&N);
+
void ReplaceValueWith(SDOperand From, SDOperand To);
void ReplaceNodeWith(SDNode *From, SDNode *To);
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp?rev=47601&r1=47600&r2=47601&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp Tue Feb 26 05:21:42 2008
@@ -879,8 +879,7 @@
// Mark N as new and remark N and its operands. This allows us to correctly
// revisit N if it needs another step of promotion and allows us to visit
// any new operands to N.
- N->setNodeId(NewNode);
- MarkNewNodes(N);
+ ReanalyzeNode(N);
return true;
}
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp?rev=47601&r1=47600&r2=47601&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp Tue Feb 26 05:21:42 2008
@@ -368,11 +368,10 @@
// Mark N as new and remark N and its operands. This allows us to correctly
// revisit N if it needs another step of promotion and allows us to visit
// any new operands to N.
- N->setNodeId(NewNode);
- MarkNewNodes(N);
+ ReanalyzeNode(N);
return true;
}
-
+
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
"Invalid operand expansion");
@@ -448,10 +447,8 @@
// that the value is properly zero extended.
unsigned BitWidth = Cond.getValueSizeInBits();
if (!DAG.MaskedValueIsZero(Cond,
- APInt::getHighBitsSet(BitWidth, BitWidth-1))) {
+ APInt::getHighBitsSet(BitWidth, BitWidth-1)))
Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
- MarkNewNodes(Cond.Val);
- }
// The chain (Op#0) and basic block destination (Op#2) are always legal types.
return DAG.UpdateNodeOperands(SDOperand(N, 0), Cond, N->getOperand(1),
@@ -466,11 +463,9 @@
// that the value is properly zero extended.
unsigned BitWidth = Cond.getValueSizeInBits();
if (!DAG.MaskedValueIsZero(Cond,
- APInt::getHighBitsSet(BitWidth, BitWidth-1))) {
+ APInt::getHighBitsSet(BitWidth, BitWidth-1)))
Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
- MarkNewNodes(Cond.Val);
- }
-
+
// The chain (Op#0) and basic block destination (Op#2) are always legal types.
return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), Cond,
N->getOperand(2));
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp?rev=47601&r1=47600&r2=47601&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp Tue Feb 26 05:21:42 2008
@@ -182,11 +182,10 @@
// Mark N as new and remark N and its operands. This allows us to correctly
// revisit N if it needs another step of promotion and allows us to visit
// any new operands to N.
- N->setNodeId(NewNode);
- MarkNewNodes(N);
+ ReanalyzeNode(N);
return true;
}
-
+
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
"Invalid operand expansion");
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp?rev=47601&r1=47600&r2=47601&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Tue Feb 26 05:21:42 2008
@@ -353,11 +353,10 @@
// Mark N as new and remark N and its operands. This allows us to correctly
// revisit N if it needs another step of promotion and allows us to visit
// any new operands to N.
- N->setNodeId(NewNode);
- MarkNewNodes(N);
+ ReanalyzeNode(N);
return true;
}
-
+
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
"Invalid operand expansion");
More information about the llvm-commits
mailing list