summaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-05-10 02:47:57 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-05-10 02:47:57 +0000
commit3eff89bf8967d35176fc1d3e80c1a5faf74fb9d8 (patch)
tree9aeb6c9f39b34d56707d90ad78cc97de77fa7eec /utils/TableGen
parent045953c37a1251bf646c06fe791365191ab15dec (diff)
downloadllvm-3eff89bf8967d35176fc1d3e80c1a5faf74fb9d8.tar.gz
llvm-3eff89bf8967d35176fc1d3e80c1a5faf74fb9d8.tar.bz2
llvm-3eff89bf8967d35176fc1d3e80c1a5faf74fb9d8.tar.xz
Watch out for the following case:
1. Use expects a chain output. 2. Node is expanded into multiple target ops. 3. One of the inner node produces a chain, the outer most one doesn't. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28209 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp48
1 files changed, 37 insertions, 11 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 803d6c4778..c2b14ed701 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -2462,6 +2462,8 @@ public:
PatternHasProperty(Pattern, SDNodeInfo::SDNPOutFlag, ISE));
bool NodeHasChain = InstPatNode &&
PatternHasProperty(InstPatNode, SDNodeInfo::SDNPHasChain, ISE);
+ bool InputHasChain = isRoot &&
+ NodeHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE);
if (NodeHasInFlag || NodeHasOutFlag || NodeHasOptInFlag || HasImpInputs)
emitDecl("InFlag");
@@ -2538,7 +2540,8 @@ public:
unsigned NumResults = Inst.getNumResults();
unsigned ResNo = TmpNo++;
- if (!isRoot || NodeHasChain || NodeHasOutFlag || NodeHasOptInFlag) {
+ if (!isRoot || InputHasChain || NodeHasChain || NodeHasOutFlag ||
+ NodeHasOptInFlag) {
if (NodeHasOptInFlag) {
unsigned FlagNo = (unsigned) NodeHasChain + Pattern->getNumChildren();
emitDecl("ResNode", true);
@@ -2548,7 +2551,7 @@ public:
// Output order: results, chain, flags
// Result types.
- if (NumResults > 0) {
+ if (PatResults > 0) {
if (N->getTypeNum(0) != MVT::isVoid)
Code += ", MVT::" + getEnumName(N->getTypeNum(0));
}
@@ -2569,7 +2572,7 @@ public:
// Output order: results, chain, flags
// Result types.
- if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid)
+ if (PatResults > 0 && N->getTypeNum(0) != MVT::isVoid)
Code += ", MVT::" + getEnumName(N->getTypeNum(0));
if (NodeHasChain)
Code += ", MVT::Other";
@@ -2581,14 +2584,20 @@ public:
Code += ", Tmp" + utostr(Ops[i]);
if (NodeHasChain) Code += ", " + ChainName + ");";
emitCode(Code);
+
+ if (NodeHasChain)
+ // Remember which op produces the chain.
+ emitCode(ChainName + " = SDOperand(ResNode" +
+ ", " + utostr(PatResults) + ");");
} else {
std::string Code;
+ std::string NodeName;
if (!isRoot) {
- std::string NodeName = "Tmp" + utostr(ResNo);
+ NodeName = "Tmp" + utostr(ResNo);
emitDecl(NodeName);
Code = NodeName + " = SDOperand(";
} else {
- std::string NodeName = "ResNode";
+ NodeName = "ResNode";
emitDecl(NodeName, true);
Code = NodeName + " = ";
}
@@ -2613,6 +2622,15 @@ public:
emitCode(Code + "), 0);");
else
emitCode(Code + ");");
+
+ if (NodeHasChain)
+ // Remember which op produces the chain.
+ if (!isRoot)
+ emitCode(ChainName + " = SDOperand(" + NodeName +
+ ".Val, " + utostr(PatResults) + ");");
+ else
+ emitCode(ChainName + " = SDOperand(" + NodeName +
+ ", " + utostr(PatResults) + ");");
}
if (!isRoot)
@@ -2637,16 +2655,14 @@ public:
NumResults = 1;
}
- bool InputHasChain =
- NodeHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE);
if (InputHasChain) {
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " +
- utostr(PatResults) + ", ResNode, " +
- utostr(NumResults) + ");");
+ utostr(PatResults) + ", " + ChainName + ".Val, " +
+ ChainName + ".ResNo" + ");");
if (DoReplace)
emitCode("if (N.ResNo == 0) AddHandleReplacement(N.Val, " +
- utostr(PatResults) + ", " + "ResNode, " +
- utostr(NumResults) + ");");
+ utostr(PatResults) + ", " + ChainName + ".Val, " +
+ ChainName + ".ResNo" + ");");
}
if (FoldedChains.size() > 0) {
@@ -2682,6 +2698,16 @@ public:
emitCode("else");
emitCode(" Result = SDOperand(ResNode, N.ResNo+1);");
}
+ } else if (InputHasChain && !NodeHasChain) {
+ // One of the inner node produces a chain.
+ emitCode("if (N.ResNo < " + utostr(PatResults) + ")");
+ emitCode(" Result = SDOperand(ResNode, N.ResNo);");
+ if (NodeHasOutFlag) {
+ emitCode("else if (N.ResNo > " + utostr(PatResults) + ")");
+ emitCode(" Result = SDOperand(ResNode, N.ResNo-1);");
+ }
+ emitCode("else");
+ emitCode(" Result = SDOperand(" + ChainName + ".Val, " + ChainName + ".ResNo);");
} else {
emitCode("Result = SDOperand(ResNode, N.ResNo);");
}