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