From f8a5bb0f895c3b2be7ec3b407cbdbbc9ded0fbed Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 17 Feb 2010 06:23:39 +0000 Subject: [PATCH] Emulate the current isel's "IsChainCompatible" logic for now. I'd like to eventually rip it out, but for now producing the same selections as the old matcher is more important. llvm-svn: 96458 --- llvm/include/llvm/CodeGen/DAGISelHeader.h | 10 ++++++++- llvm/utils/TableGen/DAGISelMatcher.cpp | 6 +++++ llvm/utils/TableGen/DAGISelMatcher.h | 22 ++++++++++++++++++- llvm/utils/TableGen/DAGISelMatcherEmitter.cpp | 4 ++++ llvm/utils/TableGen/DAGISelMatcherGen.cpp | 21 ++++++++++++++---- 5 files changed, 57 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/CodeGen/DAGISelHeader.h b/llvm/include/llvm/CodeGen/DAGISelHeader.h index 8cd11f6d2679..70c2e02ff4f3 100644 --- a/llvm/include/llvm/CodeGen/DAGISelHeader.h +++ b/llvm/include/llvm/CodeGen/DAGISelHeader.h @@ -217,7 +217,8 @@ enum BuiltinOpcodes { OPC_CheckComplexPat, OPC_CheckAndImm1, OPC_CheckAndImm2, OPC_CheckAndImm4, OPC_CheckAndImm8, OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8, - OPC_CheckFoldableChainNode + OPC_CheckFoldableChainNode, + OPC_CheckChainCompatible }; struct MatchScope { @@ -409,6 +410,13 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, continue; } + case OPC_CheckChainCompatible: { + unsigned PrevNode = MatcherTable[MatcherIndex++]; + assert(PrevNode < RecordedNodes.size() && "Invalid CheckChainCompatible"); + if (!IsChainCompatible(RecordedNodes[PrevNode].getNode(), N.getNode())) + break; + continue; + } } // If the code reached this point, then the match failed pop out to the next diff --git a/llvm/utils/TableGen/DAGISelMatcher.cpp b/llvm/utils/TableGen/DAGISelMatcher.cpp index d7519cec292b..83061093bc15 100644 --- a/llvm/utils/TableGen/DAGISelMatcher.cpp +++ b/llvm/utils/TableGen/DAGISelMatcher.cpp @@ -111,3 +111,9 @@ void CheckFoldableChainNodeMatcherNode::print(raw_ostream &OS, OS.indent(indent) << "CheckFoldableChainNode\n"; printChild(OS, indent); } + +void CheckChainCompatibleMatcherNode::print(raw_ostream &OS, + unsigned indent) const { + OS.indent(indent) << "CheckChainCompatibleMatcherNode " << PreviousOp << "\n"; + printChild(OS, indent); +} diff --git a/llvm/utils/TableGen/DAGISelMatcher.h b/llvm/utils/TableGen/DAGISelMatcher.h index 53cf923e7035..3aa29cdbe253 100644 --- a/llvm/utils/TableGen/DAGISelMatcher.h +++ b/llvm/utils/TableGen/DAGISelMatcher.h @@ -50,7 +50,8 @@ public: CheckComplexPat, CheckAndImm, CheckOrImm, - CheckFoldableChainNode + CheckFoldableChainNode, + CheckChainCompatible }; const KindTy Kind; @@ -380,6 +381,25 @@ public: virtual void print(raw_ostream &OS, unsigned indent = 0) const; }; +/// CheckChainCompatibleMatcherNode - Verify that the current node's chain +/// operand is 'compatible' with the specified recorded node's. +class CheckChainCompatibleMatcherNode : public MatcherNodeWithChild { + unsigned PreviousOp; +public: + CheckChainCompatibleMatcherNode(unsigned previousop) + : MatcherNodeWithChild(CheckChainCompatible), PreviousOp(previousop) {} + + unsigned getPreviousOp() const { return PreviousOp; } + + static inline bool classof(const MatcherNode *N) { + return N->getKind() == CheckChainCompatible; + } + + virtual void print(raw_ostream &OS, unsigned indent = 0) const; +}; + + + } // end namespace llvm #endif diff --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp index 9b37254cbdde..8e29c4717232 100644 --- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -204,6 +204,10 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) { case MatcherNode::CheckFoldableChainNode: OS << "OPC_CheckFoldableChainNode,\n"; return 1; + case MatcherNode::CheckChainCompatible: + OS << "OPC_CheckChainCompatible, " + << cast(N)->getPreviousOp() << ",\n"; + return 2; } assert(0 && "Unreachable"); return 0; diff --git a/llvm/utils/TableGen/DAGISelMatcherGen.cpp b/llvm/utils/TableGen/DAGISelMatcherGen.cpp index e2ffb8e7171d..8efcb4f982f0 100644 --- a/llvm/utils/TableGen/DAGISelMatcherGen.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherGen.cpp @@ -165,6 +165,16 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) { assert(NextRecordedOperandNo > 1 && "Should have recorded input/result chains at least!"); InputChains.push_back(NextRecordedOperandNo-1); + + // IF we need to check chains, do so, see comment for + // "NodeHasProperty(SDNPHasChain" below. + if (InputChains.size() > 1) { + // FIXME: This is broken, we should eliminate this nonsense completely, + // but we want to produce the same selections that the old matcher does + // for now. + unsigned PrevOp = InputChains[InputChains.size()-2]; + AddMatcherNode(new CheckChainCompatibleMatcherNode(PrevOp)); + } } return; } @@ -229,10 +239,13 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N, // sure that folding the chain won't induce cycles in the DAG. This could // happen if there were an intermediate node between the indbr and load, for // example. - - // FIXME: Emit "IsChainCompatible(lastchain.getNode(), CurrentNode)". - // Rename IsChainCompatible -> IsChainUnreachable, add comment about - // complexity. + if (InputChains.size() > 1) { + // FIXME: This is broken, we should eliminate this nonsense completely, + // but we want to produce the same selections that the old matcher does + // for now. + unsigned PrevOp = InputChains[InputChains.size()-2]; + AddMatcherNode(new CheckChainCompatibleMatcherNode(PrevOp)); + } // Don't look at the input chain when matching the tree pattern to the // SDNode.