From 8d0e28ce957aa2040a7906b4f45f19d134ed52a7 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 3 May 2016 05:54:13 +0000 Subject: [PATCH] [CodeGen] Add some space optimized forms of EmitNode and MorphNodeTo that implicitly indicate the number of result VTs. This shaves about 16K off the X86 matching table taking it down to about 470K. Overall this reduces the llc binary size with all in-tree targets by about 40K. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268365 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAGISel.h | 4 ++++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 23 ++++++++++++++----- utils/TableGen/DAGISelMatcherEmitter.cpp | 17 ++++++++++---- 3 files changed, 33 insertions(+), 11 deletions(-) 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);