aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-01-26 19:13:45 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-01-26 19:13:45 +0000
commit1feeeecf4cb28e34c7577719087aa41ec6610b28 (patch)
treeeefd0c8ffc78b8aec6c79adfc55efe9d17976c88
parente4da1ddadae9aebac6265060626bb7cced4fc863 (diff)
Another folding problem: if a node r/w chain or flag, don't fold it if it
has already been selected. The number of use check is not strong enough since a node can be replaced with newly created target node. e.g. If the original node has two uses, when it is selected for one of the uses it is replaced with another. Each node now has a single use but isel still should not fold it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25651 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp25
1 files changed, 20 insertions, 5 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 7b00b4e4dc..2ce87cf422 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -1909,7 +1909,8 @@ public:
unsigned OpNo = 0;
bool NodeHasChain = NodeHasProperty(N, SDNodeInfo::SDNPHasChain, ISE);
bool HasChain = PatternHasProperty(N, SDNodeInfo::SDNPHasChain, ISE);
- bool EmittedCheck = false;
+ bool EmittedUseCheck = false;
+ bool EmittedSlctedCheck = false;
if (HasChain) {
if (NodeHasChain)
OpNo = 1;
@@ -1917,7 +1918,14 @@ public:
const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator());
OS << " if (!" << RootName << ".hasOneUse()) goto P"
<< PatternNo << "Fail; // Multiple uses of actual result?\n";
- EmittedCheck = true;
+ EmittedUseCheck = true;
+ // hasOneUse() check is not strong enough. If the original node has
+ // already been selected, it may have been replaced with another.
+ for (unsigned j = 0; j < CInfo.getNumResults(); j++)
+ OS << " if (CodeGenMap.count(" << RootName
+ << ".getValue(" << j << "))) goto P"
+ << PatternNo << "Fail; // Already selected?\n";
+ EmittedSlctedCheck = true;
if (NodeHasChain)
OS << " if (CodeGenMap.count(" << RootName
<< ".getValue(" << CInfo.getNumResults() << "))) goto P"
@@ -1933,15 +1941,22 @@ public:
// FIXME: we really need to separate the concepts of flag and "glue". Those
// real flag results, e.g. X86CMP output, can have multiple uses.
// FIXME: If the incoming flag is optional. Then it is ok to fold it.
- if (!EmittedCheck &&
+ if (!isRoot &&
(PatternHasProperty(N, SDNodeInfo::SDNPInFlag, ISE) ||
PatternHasProperty(N, SDNodeInfo::SDNPOptInFlag, ISE) ||
PatternHasProperty(N, SDNodeInfo::SDNPOutFlag, ISE))) {
- if (!isRoot) {
- const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator());
+ const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator());
+ if (!EmittedUseCheck) {
OS << " if (!" << RootName << ".hasOneUse()) goto P"
<< PatternNo << "Fail; // Multiple uses of actual result?\n";
}
+ if (!EmittedSlctedCheck)
+ // hasOneUse() check is not strong enough. If the original node has
+ // already been selected, it may have been replaced with another.
+ for (unsigned j = 0; j < CInfo.getNumResults(); j++)
+ OS << " if (CodeGenMap.count(" << RootName
+ << ".getValue(" << j << "))) goto P"
+ << PatternNo << "Fail; // Already selected?\n";
}
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {