From 32982836b6407326d45c08a91e8ef0a06b5c9d5e Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 10 May 2006 02:47:57 +0000 Subject: [PATCH] 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. llvm-svn: 28209 --- llvm/utils/TableGen/DAGISelEmitter.cpp | 48 ++++++++++++++++++++------ 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/llvm/utils/TableGen/DAGISelEmitter.cpp b/llvm/utils/TableGen/DAGISelEmitter.cpp index 803d6c47789d..c2b14ed70131 100644 --- a/llvm/utils/TableGen/DAGISelEmitter.cpp +++ b/llvm/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);"); }