diff options
author | Chris Lattner <sabre@nondot.org> | 2010-02-24 05:33:42 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-02-24 05:33:42 +0000 |
commit | 02f73585f7d018ea3ddcda88c8273ee4e5ea4de3 (patch) | |
tree | 5d2407fb803c6ee01369d5a82ad80516c792ff9b /include | |
parent | 91ff7f75f55a626eb41761f3ded9f3d13002980c (diff) | |
download | external_llvm-02f73585f7d018ea3ddcda88c8273ee4e5ea4de3.zip external_llvm-02f73585f7d018ea3ddcda88c8273ee4e5ea4de3.tar.gz external_llvm-02f73585f7d018ea3ddcda88c8273ee4e5ea4de3.tar.bz2 |
The new isel was not properly handling patterns that covered
internal nodes with flag results. Record these with a new
OPC_MarkFlagResults opcode and use this to update the interior
nodes' flag results properly. This fixes CodeGen/X86/i256-add.ll
with the new isel.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97021 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/CodeGen/DAGISelHeader.h | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h index b4cc0d7..7a6c196 100644 --- a/include/llvm/CodeGen/DAGISelHeader.h +++ b/include/llvm/CodeGen/DAGISelHeader.h @@ -247,6 +247,7 @@ enum BuiltinOpcodes { OPC_EmitCopyToReg, OPC_EmitNodeXForm, OPC_EmitNode, + OPC_MarkFlagResults, OPC_CompleteMatch }; @@ -290,7 +291,7 @@ struct MatchScope { SDValue InputChain, InputFlag; /// HasChainNodesMatched - True if the ChainNodesMatched list is non-empty. - bool HasChainNodesMatched; + bool HasChainNodesMatched, HasFlagResultNodesMatched; }; SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, @@ -354,6 +355,7 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, // which ones they are. The result is captured into this list so that we can // update the chain results when the pattern is complete. SmallVector<SDNode*, 3> ChainNodesMatched; + SmallVector<SDNode*, 3> FlagResultNodesMatched; DEBUG(errs() << "ISEL: Starting pattern match on root node: "; NodeToMatch->dump(CurDAG); @@ -374,6 +376,7 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, NewEntry.InputChain = InputChain; NewEntry.InputFlag = InputFlag; NewEntry.HasChainNodesMatched = !ChainNodesMatched.empty(); + NewEntry.HasFlagResultNodesMatched = !FlagResultNodesMatched.empty(); MatchScopes.push_back(NewEntry); continue; } @@ -387,6 +390,7 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, NewEntry.InputChain = InputChain; NewEntry.InputFlag = InputFlag; NewEntry.HasChainNodesMatched = !ChainNodesMatched.empty(); + NewEntry.HasFlagResultNodesMatched = !FlagResultNodesMatched.empty(); MatchScopes.push_back(NewEntry); continue; } @@ -796,6 +800,21 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, DEBUG(errs() << " Created node: "; Res->dump(CurDAG); errs() << "\n"); continue; } + + case OPC_MarkFlagResults: { + unsigned NumNodes = MatcherTable[MatcherIndex++]; + + // Read and remember all the flag-result nodes. + for (unsigned i = 0; i != NumNodes; ++i) { + unsigned RecNo = MatcherTable[MatcherIndex++]; + if (RecNo & 128) + RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex); + + assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); + FlagResultNodesMatched.push_back(RecordedNodes[RecNo].getNode()); + } + continue; + } case OPC_CompleteMatch: { // The match has been completed, and any new nodes (if any) have been @@ -844,12 +863,24 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, ReplaceUses(ChainVal, InputChain); } } - // If the root node produces a flag, make sure to replace its flag - // result with the resultant flag. - if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) == - MVT::Flag) - ReplaceUses(SDValue(NodeToMatch, NodeToMatch->getNumValues()-1), - InputFlag); + + // If the result produces a flag, update any flag results in the matched + // pattern with the flag result. + if (InputFlag.getNode() != 0) { + // Handle the root node: + if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) == + MVT::Flag) + ReplaceUses(SDValue(NodeToMatch, NodeToMatch->getNumValues()-1), + InputFlag); + + // Handle any interior nodes explicitly marked. + for (unsigned i = 0, e = FlagResultNodesMatched.size(); i != e; ++i) { + SDNode *FRN = FlagResultNodesMatched[i]; + assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Flag && + "Doesn't have a flag result"); + ReplaceUses(SDValue(FRN, FRN->getNumValues()-1), InputFlag); + } + } assert(NodeToMatch->use_empty() && "Didn't replace all uses of the node?"); @@ -885,7 +916,9 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, InputFlag = LastScope.InputFlag; if (!LastScope.HasChainNodesMatched) ChainNodesMatched.clear(); - + if (!LastScope.HasFlagResultNodesMatched) + FlagResultNodesMatched.clear(); + MatchScopes.pop_back(); } } |