diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index df5bd7743dc..5fc1a157166 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -146,7 +146,11 @@ public: OPC_EmitCopyToReg, OPC_EmitNodeXForm, OPC_EmitNode, + // Space-optimized forms that implicitly encode number of result VTs. + OPC_EmitNode0, OPC_EmitNode1, OPC_EmitNode2, OPC_MorphNodeTo, + // Space-optimized forms that implicitly encode number of result VTs. + OPC_MorphNodeTo0, OPC_MorphNodeTo1, OPC_MorphNodeTo2, OPC_MarkGlueResults, OPC_CompleteMatch }; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 016dd28a179..d6b737dce9f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3305,13 +3305,22 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, continue; } - case OPC_EmitNode: - case OPC_MorphNodeTo: { + case OPC_EmitNode: case OPC_MorphNodeTo: + case OPC_EmitNode0: case OPC_EmitNode1: case OPC_EmitNode2: + case OPC_MorphNodeTo0: case OPC_MorphNodeTo1: case OPC_MorphNodeTo2: { uint16_t TargetOpc = MatcherTable[MatcherIndex++]; TargetOpc |= (unsigned short)MatcherTable[MatcherIndex++] << 8; unsigned EmitNodeInfo = MatcherTable[MatcherIndex++]; // Get the result VT list. - unsigned NumVTs = MatcherTable[MatcherIndex++]; + unsigned NumVTs; + // If this is one of the compressed forms, get the number of VTs based + // on the Opcode. Otherwise read the next byte from the table. + if (Opcode >= OPC_MorphNodeTo0 && Opcode <= OPC_MorphNodeTo2) + NumVTs = Opcode - OPC_MorphNodeTo0; + else if (Opcode >= OPC_EmitNode0 && Opcode <= OPC_EmitNode2) + NumVTs = Opcode - OPC_EmitNode0; + else + NumVTs = MatcherTable[MatcherIndex++]; SmallVector VTs; for (unsigned i = 0; i != NumVTs; ++i) { MVT::SimpleValueType VT = @@ -3373,7 +3382,9 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, // Create the node. SDNode *Res = nullptr; - if (Opcode != OPC_MorphNodeTo) { + bool IsMorphNodeTo = Opcode == OPC_MorphNodeTo || + (Opcode >= OPC_MorphNodeTo0 && Opcode <= OPC_MorphNodeTo2); + if (!IsMorphNodeTo) { // If this is a normal EmitNode command, just create the new node and // add the results to the RecordedNodes list. Res = CurDAG->getMachineNode(TargetOpc, SDLoc(NodeToMatch), @@ -3453,11 +3464,11 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, } DEBUG(dbgs() << " " - << (Opcode == OPC_MorphNodeTo ? "Morphed" : "Created") + << (IsMorphNodeTo ? "Morphed" : "Created") << " node: "; Res->dump(CurDAG); dbgs() << "\n"); // If this was a MorphNodeTo then we're completely done! - if (Opcode == OPC_MorphNodeTo) { + if (IsMorphNodeTo) { // Update chain and glue uses. UpdateChainsAndGlue(NodeToMatch, InputChain, ChainNodesMatched, InputGlue, GlueResultNodesMatched, true); diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp index 28473996a5c..709e0a4d28a 100644 --- a/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -539,6 +539,10 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, case Matcher::MorphNodeTo: { const EmitNodeMatcherCommon *EN = cast(N); OS << (isa(EN) ? "OPC_EmitNode" : "OPC_MorphNodeTo"); + bool CompressVTs = EN->getNumVTs() < 3; + if (CompressVTs) + OS << EN->getNumVTs(); + OS << ", TARGET_VAL(" << EN->getOpcodeName() << "), 0"; if (EN->hasChain()) OS << "|OPFL_Chain"; @@ -549,10 +553,13 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands(); OS << ",\n"; - OS.PadToColumn(Indent*2+4) << EN->getNumVTs(); - if (!OmitComments) - OS << "/*#VTs*/"; - OS << ", "; + OS.PadToColumn(Indent*2+4); + if (!CompressVTs) { + OS << EN->getNumVTs(); + if (!OmitComments) + OS << "/*#VTs*/"; + OS << ", "; + } for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i) OS << getEnumName(EN->getVT(i)) << ", "; @@ -586,7 +593,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, } else OS << '\n'; - return 6+EN->getNumVTs()+NumOperandBytes; + return 5 + !CompressVTs + EN->getNumVTs() + NumOperandBytes; } case Matcher::MarkGlueResults: { const MarkGlueResultsMatcher *CFR = cast(N);