1 | //===- DAGISelEmitter.cpp - Generate an instruction selector --------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This tablegen backend emits a DAG instruction selector. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "Common/CodeGenDAGPatterns.h" |
14 | #include "Common/CodeGenInstruction.h" |
15 | #include "Common/CodeGenTarget.h" |
16 | #include "Common/DAGISelMatcher.h" |
17 | #include "llvm/Support/Debug.h" |
18 | #include "llvm/TableGen/Record.h" |
19 | #include "llvm/TableGen/TableGenBackend.h" |
20 | using namespace llvm; |
21 | |
22 | #define DEBUG_TYPE "dag-isel-emitter" |
23 | |
24 | namespace { |
25 | /// DAGISelEmitter - The top-level class which coordinates construction |
26 | /// and emission of the instruction selector. |
27 | class DAGISelEmitter { |
28 | RecordKeeper &Records; // Just so we can get at the timing functions. |
29 | CodeGenDAGPatterns CGP; |
30 | |
31 | public: |
32 | explicit DAGISelEmitter(RecordKeeper &R) : Records(R), CGP(R) {} |
33 | void run(raw_ostream &OS); |
34 | }; |
35 | } // End anonymous namespace |
36 | |
37 | //===----------------------------------------------------------------------===// |
38 | // DAGISelEmitter Helper methods |
39 | // |
40 | |
41 | /// Compute the number of instructions for this pattern. |
42 | /// This is a temporary hack. We should really include the instruction |
43 | /// latencies in this calculation. |
44 | static unsigned getResultPatternCost(TreePatternNode &P, |
45 | const CodeGenDAGPatterns &CGP) { |
46 | if (P.isLeaf()) |
47 | return 0; |
48 | |
49 | unsigned Cost = 0; |
50 | Record *Op = P.getOperator(); |
51 | if (Op->isSubClassOf(Name: "Instruction" )) { |
52 | Cost++; |
53 | CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(InstRec: Op); |
54 | if (II.usesCustomInserter) |
55 | Cost += 10; |
56 | } |
57 | for (unsigned i = 0, e = P.getNumChildren(); i != e; ++i) |
58 | Cost += getResultPatternCost(P&: P.getChild(N: i), CGP); |
59 | return Cost; |
60 | } |
61 | |
62 | /// getResultPatternCodeSize - Compute the code size of instructions for this |
63 | /// pattern. |
64 | static unsigned getResultPatternSize(TreePatternNode &P, |
65 | const CodeGenDAGPatterns &CGP) { |
66 | if (P.isLeaf()) |
67 | return 0; |
68 | |
69 | unsigned Cost = 0; |
70 | Record *Op = P.getOperator(); |
71 | if (Op->isSubClassOf(Name: "Instruction" )) { |
72 | Cost += Op->getValueAsInt(FieldName: "CodeSize" ); |
73 | } |
74 | for (unsigned i = 0, e = P.getNumChildren(); i != e; ++i) |
75 | Cost += getResultPatternSize(P&: P.getChild(N: i), CGP); |
76 | return Cost; |
77 | } |
78 | |
79 | namespace { |
80 | // PatternSortingPredicate - return true if we prefer to match LHS before RHS. |
81 | // In particular, we want to match maximal patterns first and lowest cost within |
82 | // a particular complexity first. |
83 | struct PatternSortingPredicate { |
84 | PatternSortingPredicate(CodeGenDAGPatterns &cgp) : CGP(cgp) {} |
85 | CodeGenDAGPatterns &CGP; |
86 | |
87 | bool operator()(const PatternToMatch *LHS, const PatternToMatch *RHS) { |
88 | const TreePatternNode < = LHS->getSrcPattern(); |
89 | const TreePatternNode &RT = RHS->getSrcPattern(); |
90 | |
91 | MVT LHSVT = LT.getNumTypes() != 0 ? LT.getSimpleType(ResNo: 0) : MVT::Other; |
92 | MVT RHSVT = RT.getNumTypes() != 0 ? RT.getSimpleType(ResNo: 0) : MVT::Other; |
93 | if (LHSVT.isVector() != RHSVT.isVector()) |
94 | return RHSVT.isVector(); |
95 | |
96 | if (LHSVT.isFloatingPoint() != RHSVT.isFloatingPoint()) |
97 | return RHSVT.isFloatingPoint(); |
98 | |
99 | // Otherwise, if the patterns might both match, sort based on complexity, |
100 | // which means that we prefer to match patterns that cover more nodes in the |
101 | // input over nodes that cover fewer. |
102 | int LHSSize = LHS->getPatternComplexity(CGP); |
103 | int RHSSize = RHS->getPatternComplexity(CGP); |
104 | if (LHSSize > RHSSize) |
105 | return true; // LHS -> bigger -> less cost |
106 | if (LHSSize < RHSSize) |
107 | return false; |
108 | |
109 | // If the patterns have equal complexity, compare generated instruction cost |
110 | unsigned LHSCost = getResultPatternCost(P&: LHS->getDstPattern(), CGP); |
111 | unsigned RHSCost = getResultPatternCost(P&: RHS->getDstPattern(), CGP); |
112 | if (LHSCost < RHSCost) |
113 | return true; |
114 | if (LHSCost > RHSCost) |
115 | return false; |
116 | |
117 | unsigned LHSPatSize = getResultPatternSize(P&: LHS->getDstPattern(), CGP); |
118 | unsigned RHSPatSize = getResultPatternSize(P&: RHS->getDstPattern(), CGP); |
119 | if (LHSPatSize < RHSPatSize) |
120 | return true; |
121 | if (LHSPatSize > RHSPatSize) |
122 | return false; |
123 | |
124 | // Sort based on the UID of the pattern, to reflect source order. |
125 | // Note that this is not guaranteed to be unique, since a single source |
126 | // pattern may have been resolved into multiple match patterns due to |
127 | // alternative fragments. To ensure deterministic output, always use |
128 | // std::stable_sort with this predicate. |
129 | return LHS->getID() < RHS->getID(); |
130 | } |
131 | }; |
132 | } // End anonymous namespace |
133 | |
134 | void DAGISelEmitter::run(raw_ostream &OS) { |
135 | Records.startTimer(Name: "Parse patterns" ); |
136 | emitSourceFileHeader(Desc: "DAG Instruction Selector for the " + |
137 | CGP.getTargetInfo().getName().str() + " target" , |
138 | OS); |
139 | |
140 | OS << "// *** NOTE: This file is #included into the middle of the target\n" |
141 | << "// *** instruction selector class. These functions are really " |
142 | << "methods.\n\n" ; |
143 | |
144 | OS << "// If GET_DAGISEL_DECL is #defined with any value, only function\n" |
145 | "// declarations will be included when this file is included.\n" |
146 | "// If GET_DAGISEL_BODY is #defined, its value should be the name of\n" |
147 | "// the instruction selector class. Function bodies will be emitted\n" |
148 | "// and each function's name will be qualified with the name of the\n" |
149 | "// class.\n" |
150 | "//\n" |
151 | "// When neither of the GET_DAGISEL* macros is defined, the functions\n" |
152 | "// are emitted inline.\n\n" ; |
153 | |
154 | LLVM_DEBUG(errs() << "\n\nALL PATTERNS TO MATCH:\n\n" ; |
155 | for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), |
156 | E = CGP.ptm_end(); |
157 | I != E; ++I) { |
158 | errs() << "PATTERN: " ; |
159 | I->getSrcPattern().dump(); |
160 | errs() << "\nRESULT: " ; |
161 | I->getDstPattern().dump(); |
162 | errs() << "\n" ; |
163 | }); |
164 | |
165 | // Add all the patterns to a temporary list so we can sort them. |
166 | Records.startTimer(Name: "Sort patterns" ); |
167 | std::vector<const PatternToMatch *> Patterns; |
168 | for (const PatternToMatch &PTM : CGP.ptms()) |
169 | Patterns.push_back(x: &PTM); |
170 | |
171 | // We want to process the matches in order of minimal cost. Sort the patterns |
172 | // so the least cost one is at the start. |
173 | llvm::stable_sort(Range&: Patterns, C: PatternSortingPredicate(CGP)); |
174 | |
175 | // Convert each variant of each pattern into a Matcher. |
176 | Records.startTimer(Name: "Convert to matchers" ); |
177 | SmallVector<Matcher *, 0> PatternMatchers; |
178 | for (const PatternToMatch *PTM : Patterns) { |
179 | for (unsigned Variant = 0;; ++Variant) { |
180 | if (Matcher *M = ConvertPatternToMatcher(Pattern: *PTM, Variant, CGP)) |
181 | PatternMatchers.push_back(Elt: M); |
182 | else |
183 | break; |
184 | } |
185 | } |
186 | |
187 | std::unique_ptr<Matcher> TheMatcher = |
188 | std::make_unique<ScopeMatcher>(args: std::move(PatternMatchers)); |
189 | |
190 | Records.startTimer(Name: "Optimize matchers" ); |
191 | OptimizeMatcher(Matcher&: TheMatcher, CGP); |
192 | |
193 | // Matcher->dump(); |
194 | |
195 | Records.startTimer(Name: "Emit matcher table" ); |
196 | EmitMatcherTable(Matcher: TheMatcher.get(), CGP, OS); |
197 | } |
198 | |
199 | static TableGen::Emitter::OptClass<DAGISelEmitter> |
200 | X("gen-dag-isel" , "Generate a DAG instruction selector" ); |
201 | |