blob: a1b0b2a3b0f40abc7df8e7e4b89f7640ccb11a07 [file] [log] [blame]
Chris Lattnerab3242f2008-01-06 01:10:31 +00001//===- CodeGenDAGPatterns.h - Read DAG patterns from .td file ---*- C++ -*-===//
Chris Lattner8cab0212008-01-05 22:25:12 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Chris Lattnerab3242f2008-01-06 01:10:31 +000010// This file declares the CodeGenDAGPatterns class, which is used to read and
Chris Lattner8cab0212008-01-05 22:25:12 +000011// represent the patterns present in a .td file for instructions.
12//
13//===----------------------------------------------------------------------===//
14
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000015#ifndef LLVM_UTILS_TABLEGEN_CODEGENDAGPATTERNS_H
16#define LLVM_UTILS_TABLEGEN_CODEGENDAGPATTERNS_H
Chris Lattner8cab0212008-01-05 22:25:12 +000017
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +000018#include "CodeGenHwModes.h"
Chris Lattner8cab0212008-01-05 22:25:12 +000019#include "CodeGenIntrinsics.h"
Chandler Carruth91d19d82012-12-04 10:37:14 +000020#include "CodeGenTarget.h"
Chris Lattnercabe0372010-03-15 06:00:16 +000021#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringMap.h"
Craig Topperc4965bc2012-02-05 07:21:30 +000023#include "llvm/Support/ErrorHandling.h"
Krzysztof Parzyszekaffd2012017-09-19 18:42:34 +000024#include "llvm/Support/MathExtras.h"
Chris Lattner1802b172010-03-19 01:07:44 +000025#include <algorithm>
Krzysztof Parzyszekaffd2012017-09-19 18:42:34 +000026#include <array>
Chris Lattner1802b172010-03-19 01:07:44 +000027#include <map>
Chandler Carruth91d19d82012-12-04 10:37:14 +000028#include <set>
29#include <vector>
Chris Lattner8cab0212008-01-05 22:25:12 +000030
31namespace llvm {
Chris Lattner8cab0212008-01-05 22:25:12 +000032
Krzysztof Parzyszekaffd2012017-09-19 18:42:34 +000033class Record;
34class Init;
35class ListInit;
36class DagInit;
37class SDNodeInfo;
38class TreePattern;
39class TreePatternNode;
40class CodeGenDAGPatterns;
41class ComplexPattern;
42
43/// This represents a set of MVTs. Since the underlying type for the MVT
44/// is uint8_t, there are at most 256 values. To reduce the number of memory
45/// allocations and deallocations, represent the set as a sequence of bits.
46/// To reduce the allocations even further, make MachineValueTypeSet own
47/// the storage and use std::array as the bit container.
48struct MachineValueTypeSet {
49 static_assert(std::is_same<std::underlying_type<MVT::SimpleValueType>::type,
50 uint8_t>::value,
51 "Change uint8_t here to the SimpleValueType's type");
52 static unsigned constexpr Capacity = std::numeric_limits<uint8_t>::max()+1;
53 using WordType = uint64_t;
54 static unsigned constexpr WordWidth = 8*sizeof(WordType);
55 static unsigned constexpr NumWords = Capacity/WordWidth;
56 static_assert(NumWords*WordWidth == Capacity,
57 "Capacity should be a multiple of WordWidth");
58
59 LLVM_ATTRIBUTE_ALWAYS_INLINE
60 MachineValueTypeSet() {
61 clear();
62 }
63
64 LLVM_ATTRIBUTE_ALWAYS_INLINE
65 unsigned size() const {
66 unsigned Count = 0;
67 for (WordType W : Words)
68 Count += countPopulation(W);
69 return Count;
70 }
71 LLVM_ATTRIBUTE_ALWAYS_INLINE
72 void clear() {
73 std::memset(Words.data(), 0, NumWords*sizeof(WordType));
74 }
75 LLVM_ATTRIBUTE_ALWAYS_INLINE
76 bool empty() const {
77 for (WordType W : Words)
78 if (W != 0)
79 return false;
80 return true;
81 }
82 LLVM_ATTRIBUTE_ALWAYS_INLINE
83 unsigned count(MVT T) const {
84 return (Words[T.SimpleTy / WordWidth] >> (T.SimpleTy % WordWidth)) & 1;
85 }
86 std::pair<MachineValueTypeSet&,bool> insert(MVT T) {
87 bool V = count(T.SimpleTy);
88 Words[T.SimpleTy / WordWidth] |= WordType(1) << (T.SimpleTy % WordWidth);
89 return {*this, V};
90 }
91 MachineValueTypeSet &insert(const MachineValueTypeSet &S) {
92 for (unsigned i = 0; i != NumWords; ++i)
93 Words[i] |= S.Words[i];
94 return *this;
95 }
96 LLVM_ATTRIBUTE_ALWAYS_INLINE
97 void erase(MVT T) {
98 Words[T.SimpleTy / WordWidth] &= ~(WordType(1) << (T.SimpleTy % WordWidth));
99 }
100
101 struct const_iterator {
102 // Some implementations of the C++ library require these traits to be
103 // defined.
104 using iterator_category = std::forward_iterator_tag;
105 using value_type = MVT;
106 using difference_type = ptrdiff_t;
107 using pointer = const MVT*;
108 using reference = const MVT&;
109
110 LLVM_ATTRIBUTE_ALWAYS_INLINE
111 MVT operator*() const {
112 assert(Pos != Capacity);
113 return MVT::SimpleValueType(Pos);
114 }
115 LLVM_ATTRIBUTE_ALWAYS_INLINE
116 const_iterator(const MachineValueTypeSet *S, bool End) : Set(S) {
117 Pos = End ? Capacity : find_from_pos(0);
118 }
119 LLVM_ATTRIBUTE_ALWAYS_INLINE
120 const_iterator &operator++() {
121 assert(Pos != Capacity);
122 Pos = find_from_pos(Pos+1);
123 return *this;
124 }
125
126 LLVM_ATTRIBUTE_ALWAYS_INLINE
127 bool operator==(const const_iterator &It) const {
128 return Set == It.Set && Pos == It.Pos;
129 }
130 LLVM_ATTRIBUTE_ALWAYS_INLINE
131 bool operator!=(const const_iterator &It) const {
132 return !operator==(It);
133 }
134
135 private:
136 unsigned find_from_pos(unsigned P) const {
137 unsigned SkipWords = P / WordWidth;
138 unsigned SkipBits = P % WordWidth;
139 unsigned Count = SkipWords * WordWidth;
140
141 // If P is in the middle of a word, process it manually here, because
142 // the trailing bits need to be masked off to use findFirstSet.
143 if (SkipBits != 0) {
144 WordType W = Set->Words[SkipWords];
145 W &= maskLeadingOnes<WordType>(WordWidth-SkipBits);
146 if (W != 0)
147 return Count + findFirstSet(W);
148 Count += WordWidth;
149 SkipWords++;
150 }
151
152 for (unsigned i = SkipWords; i != NumWords; ++i) {
153 WordType W = Set->Words[i];
154 if (W != 0)
155 return Count + findFirstSet(W);
156 Count += WordWidth;
157 }
158 return Capacity;
159 }
160
161 const MachineValueTypeSet *Set;
162 unsigned Pos;
163 };
164
165 LLVM_ATTRIBUTE_ALWAYS_INLINE
166 const_iterator begin() const { return const_iterator(this, false); }
167 LLVM_ATTRIBUTE_ALWAYS_INLINE
168 const_iterator end() const { return const_iterator(this, true); }
169
170 LLVM_ATTRIBUTE_ALWAYS_INLINE
171 bool operator==(const MachineValueTypeSet &S) const {
172 return Words == S.Words;
173 }
174 LLVM_ATTRIBUTE_ALWAYS_INLINE
175 bool operator!=(const MachineValueTypeSet &S) const {
176 return !operator==(S);
177 }
178
179private:
180 friend struct const_iterator;
181 std::array<WordType,NumWords> Words;
182};
183
184struct TypeSetByHwMode : public InfoByHwMode<MachineValueTypeSet> {
185 using SetType = MachineValueTypeSet;
Jim Grosbach50986b52010-12-24 05:06:32 +0000186
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000187 TypeSetByHwMode() = default;
188 TypeSetByHwMode(const TypeSetByHwMode &VTS) = default;
189 TypeSetByHwMode(MVT::SimpleValueType VT)
190 : TypeSetByHwMode(ValueTypeByHwMode(VT)) {}
191 TypeSetByHwMode(ValueTypeByHwMode VT)
192 : TypeSetByHwMode(ArrayRef<ValueTypeByHwMode>(&VT, 1)) {}
193 TypeSetByHwMode(ArrayRef<ValueTypeByHwMode> VTList);
Jim Grosbach50986b52010-12-24 05:06:32 +0000194
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000195 SetType &getOrCreate(unsigned Mode) {
196 if (hasMode(Mode))
197 return get(Mode);
198 return Map.insert({Mode,SetType()}).first->second;
199 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000200
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000201 bool isValueTypeByHwMode(bool AllowEmpty) const;
202 ValueTypeByHwMode getValueTypeByHwMode() const;
Krzysztof Parzyszekaffd2012017-09-19 18:42:34 +0000203
204 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000205 bool isMachineValueType() const {
206 return isDefaultOnly() && Map.begin()->second.size() == 1;
207 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000208
Krzysztof Parzyszekaffd2012017-09-19 18:42:34 +0000209 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000210 MVT getMachineValueType() const {
211 assert(isMachineValueType());
212 return *Map.begin()->second.begin();
213 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000214
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000215 bool isPossible() const;
Krzysztof Parzyszekaffd2012017-09-19 18:42:34 +0000216
217 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000218 bool isDefaultOnly() const {
Krzysztof Parzyszekaffd2012017-09-19 18:42:34 +0000219 return Map.size() == 1 && Map.begin()->first == DefaultMode;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000220 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000221
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000222 bool insert(const ValueTypeByHwMode &VVT);
223 bool constrain(const TypeSetByHwMode &VTS);
224 template <typename Predicate> bool constrain(Predicate P);
225 template <typename Predicate> bool assign_if(const TypeSetByHwMode &VTS,
226 Predicate P);
Jim Grosbach50986b52010-12-24 05:06:32 +0000227
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000228 std::string getAsString() const;
229 static std::string getAsString(const SetType &S);
Jim Grosbach50986b52010-12-24 05:06:32 +0000230
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000231 bool operator==(const TypeSetByHwMode &VTS) const;
232 bool operator!=(const TypeSetByHwMode &VTS) const { return !(*this == VTS); }
Jim Grosbach50986b52010-12-24 05:06:32 +0000233
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000234 void dump() const;
235 void validate() const;
Craig Topper74169dc2014-01-28 04:49:01 +0000236
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000237private:
238 /// Intersect two sets. Return true if anything has changed.
239 bool intersect(SetType &Out, const SetType &In);
240};
Jim Grosbach50986b52010-12-24 05:06:32 +0000241
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000242struct TypeInfer {
243 TypeInfer(TreePattern &T) : TP(T), ForceMode(0) {}
Jim Grosbach50986b52010-12-24 05:06:32 +0000244
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000245 bool isConcrete(const TypeSetByHwMode &VTS, bool AllowEmpty) const {
246 return VTS.isValueTypeByHwMode(AllowEmpty);
247 }
248 ValueTypeByHwMode getConcrete(const TypeSetByHwMode &VTS,
249 bool AllowEmpty) const {
250 assert(VTS.isValueTypeByHwMode(AllowEmpty));
251 return VTS.getValueTypeByHwMode();
252 }
Duncan Sands13237ac2008-06-06 12:08:01 +0000253
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000254 /// The protocol in the following functions (Merge*, force*, Enforce*,
255 /// expand*) is to return "true" if a change has been made, "false"
256 /// otherwise.
Chris Lattner8cab0212008-01-05 22:25:12 +0000257
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000258 bool MergeInTypeInfo(TypeSetByHwMode &Out, const TypeSetByHwMode &In);
259 bool MergeInTypeInfo(TypeSetByHwMode &Out, MVT::SimpleValueType InVT) {
260 return MergeInTypeInfo(Out, TypeSetByHwMode(InVT));
261 }
262 bool MergeInTypeInfo(TypeSetByHwMode &Out, ValueTypeByHwMode InVT) {
263 return MergeInTypeInfo(Out, TypeSetByHwMode(InVT));
264 }
Bob Wilsonf7e587f2009-08-12 22:30:59 +0000265
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000266 /// Reduce the set \p Out to have at most one element for each mode.
267 bool forceArbitrary(TypeSetByHwMode &Out);
Chris Lattnercabe0372010-03-15 06:00:16 +0000268
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000269 /// The following four functions ensure that upon return the set \p Out
270 /// will only contain types of the specified kind: integer, floating-point,
271 /// scalar, or vector.
272 /// If \p Out is empty, all legal types of the specified kind will be added
273 /// to it. Otherwise, all types that are not of the specified kind will be
274 /// removed from \p Out.
275 bool EnforceInteger(TypeSetByHwMode &Out);
276 bool EnforceFloatingPoint(TypeSetByHwMode &Out);
277 bool EnforceScalar(TypeSetByHwMode &Out);
278 bool EnforceVector(TypeSetByHwMode &Out);
Chris Lattnercabe0372010-03-15 06:00:16 +0000279
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000280 /// If \p Out is empty, fill it with all legal types. Otherwise, leave it
281 /// unchanged.
282 bool EnforceAny(TypeSetByHwMode &Out);
283 /// Make sure that for each type in \p Small, there exists a larger type
284 /// in \p Big.
285 bool EnforceSmallerThan(TypeSetByHwMode &Small, TypeSetByHwMode &Big);
286 /// 1. Ensure that for each type T in \p Vec, T is a vector type, and that
287 /// for each type U in \p Elem, U is a scalar type.
288 /// 2. Ensure that for each (scalar) type U in \p Elem, there exists a
289 /// (vector) type T in \p Vec, such that U is the element type of T.
290 bool EnforceVectorEltTypeIs(TypeSetByHwMode &Vec, TypeSetByHwMode &Elem);
291 bool EnforceVectorEltTypeIs(TypeSetByHwMode &Vec,
292 const ValueTypeByHwMode &VVT);
293 /// Ensure that for each type T in \p Sub, T is a vector type, and there
294 /// exists a type U in \p Vec such that U is a vector type with the same
295 /// element type as T and at least as many elements as T.
296 bool EnforceVectorSubVectorTypeIs(TypeSetByHwMode &Vec,
297 TypeSetByHwMode &Sub);
298 /// 1. Ensure that \p V has a scalar type iff \p W has a scalar type.
299 /// 2. Ensure that for each vector type T in \p V, there exists a vector
300 /// type U in \p W, such that T and U have the same number of elements.
301 /// 3. Ensure that for each vector type U in \p W, there exists a vector
302 /// type T in \p V, such that T and U have the same number of elements
303 /// (reverse of 2).
304 bool EnforceSameNumElts(TypeSetByHwMode &V, TypeSetByHwMode &W);
305 /// 1. Ensure that for each type T in \p A, there exists a type U in \p B,
306 /// such that T and U have equal size in bits.
307 /// 2. Ensure that for each type U in \p B, there exists a type T in \p A
308 /// such that T and U have equal size in bits (reverse of 1).
309 bool EnforceSameSize(TypeSetByHwMode &A, TypeSetByHwMode &B);
Chris Lattnercabe0372010-03-15 06:00:16 +0000310
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000311 /// For each overloaded type (i.e. of form *Any), replace it with the
312 /// corresponding subset of legal, specific types.
313 void expandOverloads(TypeSetByHwMode &VTS);
314 void expandOverloads(TypeSetByHwMode::SetType &Out,
315 const TypeSetByHwMode::SetType &Legal);
Jim Grosbach50986b52010-12-24 05:06:32 +0000316
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000317 struct ValidateOnExit {
318 ValidateOnExit(TypeSetByHwMode &T) : VTS(T) {}
319 ~ValidateOnExit() { VTS.validate(); }
320 TypeSetByHwMode &VTS;
Chris Lattnercabe0372010-03-15 06:00:16 +0000321 };
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000322
323 TreePattern &TP;
324 unsigned ForceMode; // Mode to use when set.
325 bool CodeGen = false; // Set during generation of matcher code.
326
327private:
328 TypeSetByHwMode getLegalTypes();
Krzysztof Parzyszekaffd2012017-09-19 18:42:34 +0000329
330 /// Cached legal types.
331 bool LegalTypesCached = false;
332 TypeSetByHwMode::SetType LegalCache = {};
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000333};
Chris Lattner8cab0212008-01-05 22:25:12 +0000334
Scott Michel94420742008-03-05 17:49:05 +0000335/// Set type used to track multiply used variables in patterns
336typedef std::set<std::string> MultipleUseVarSet;
337
Chris Lattner8cab0212008-01-05 22:25:12 +0000338/// SDTypeConstraint - This is a discriminated union of constraints,
339/// corresponding to the SDTypeConstraint tablegen class in Target.td.
340struct SDTypeConstraint {
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000341 SDTypeConstraint(Record *R, const CodeGenHwModes &CGH);
Jim Grosbach50986b52010-12-24 05:06:32 +0000342
Chris Lattner8cab0212008-01-05 22:25:12 +0000343 unsigned OperandNo; // The operand # this constraint applies to.
Jim Grosbach50986b52010-12-24 05:06:32 +0000344 enum {
345 SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisVec, SDTCisSameAs,
David Greene127fd1d2011-01-24 20:53:18 +0000346 SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisEltOfVec,
Craig Topper9a44b3f2015-11-26 07:02:18 +0000347 SDTCisSubVecOfVec, SDTCVecEltisVT, SDTCisSameNumEltsAs, SDTCisSameSizeAs
Chris Lattner8cab0212008-01-05 22:25:12 +0000348 } ConstraintType;
Jim Grosbach50986b52010-12-24 05:06:32 +0000349
Chris Lattner8cab0212008-01-05 22:25:12 +0000350 union { // The discriminated union.
351 struct {
Chris Lattner8cab0212008-01-05 22:25:12 +0000352 unsigned OtherOperandNum;
353 } SDTCisSameAs_Info;
354 struct {
355 unsigned OtherOperandNum;
356 } SDTCisVTSmallerThanOp_Info;
357 struct {
358 unsigned BigOperandNum;
359 } SDTCisOpSmallerThanOp_Info;
360 struct {
361 unsigned OtherOperandNum;
Nate Begeman17bedbc2008-02-09 01:37:05 +0000362 } SDTCisEltOfVec_Info;
David Greene127fd1d2011-01-24 20:53:18 +0000363 struct {
364 unsigned OtherOperandNum;
365 } SDTCisSubVecOfVec_Info;
Craig Topper0be34582015-03-05 07:11:34 +0000366 struct {
Craig Topper0be34582015-03-05 07:11:34 +0000367 unsigned OtherOperandNum;
368 } SDTCisSameNumEltsAs_Info;
Craig Topper9a44b3f2015-11-26 07:02:18 +0000369 struct {
370 unsigned OtherOperandNum;
371 } SDTCisSameSizeAs_Info;
Chris Lattner8cab0212008-01-05 22:25:12 +0000372 } x;
373
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000374 // The VT for SDTCisVT and SDTCVecEltisVT.
375 // Must not be in the union because it has a non-trivial destructor.
376 ValueTypeByHwMode VVT;
377
Chris Lattner8cab0212008-01-05 22:25:12 +0000378 /// ApplyTypeConstraint - Given a node in a pattern, apply this type
379 /// constraint to the nodes operands. This returns true if it makes a
Joerg Sonnenberger635debe2012-10-25 20:33:17 +0000380 /// change, false otherwise. If a type contradiction is found, an error
381 /// is flagged.
Chris Lattner8cab0212008-01-05 22:25:12 +0000382 bool ApplyTypeConstraint(TreePatternNode *N, const SDNodeInfo &NodeInfo,
383 TreePattern &TP) const;
Chris Lattner8cab0212008-01-05 22:25:12 +0000384};
385
386/// SDNodeInfo - One of these records is created for each SDNode instance in
387/// the target .td file. This represents the various dag nodes we will be
388/// processing.
389class SDNodeInfo {
390 Record *Def;
Craig Topperbcd3c372017-05-31 21:12:46 +0000391 StringRef EnumName;
392 StringRef SDClassName;
Chris Lattner8cab0212008-01-05 22:25:12 +0000393 unsigned Properties;
394 unsigned NumResults;
395 int NumOperands;
396 std::vector<SDTypeConstraint> TypeConstraints;
397public:
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000398 // Parse the specified record.
399 SDNodeInfo(Record *R, const CodeGenHwModes &CGH);
Jim Grosbach50986b52010-12-24 05:06:32 +0000400
Chris Lattner8cab0212008-01-05 22:25:12 +0000401 unsigned getNumResults() const { return NumResults; }
Jim Grosbach50986b52010-12-24 05:06:32 +0000402
Chris Lattner135091b2010-03-28 08:48:47 +0000403 /// getNumOperands - This is the number of operands required or -1 if
404 /// variadic.
Chris Lattner8cab0212008-01-05 22:25:12 +0000405 int getNumOperands() const { return NumOperands; }
406 Record *getRecord() const { return Def; }
Craig Topperbcd3c372017-05-31 21:12:46 +0000407 StringRef getEnumName() const { return EnumName; }
408 StringRef getSDClassName() const { return SDClassName; }
Jim Grosbach50986b52010-12-24 05:06:32 +0000409
Chris Lattner8cab0212008-01-05 22:25:12 +0000410 const std::vector<SDTypeConstraint> &getTypeConstraints() const {
411 return TypeConstraints;
412 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000413
Chris Lattner99e53b32010-02-28 00:22:30 +0000414 /// getKnownType - If the type constraints on this node imply a fixed type
415 /// (e.g. all stores return void, etc), then return it as an
Chris Lattnerda5b4ad2010-03-19 01:14:27 +0000416 /// MVT::SimpleValueType. Otherwise, return MVT::Other.
Chris Lattner6c2d1782010-03-24 00:41:19 +0000417 MVT::SimpleValueType getKnownType(unsigned ResNo) const;
Jim Grosbach50986b52010-12-24 05:06:32 +0000418
Chris Lattner8cab0212008-01-05 22:25:12 +0000419 /// hasProperty - Return true if this node has the specified property.
420 ///
421 bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
422
423 /// ApplyTypeConstraints - Given a node in a pattern, apply the type
424 /// constraints for this node to the operands of the node. This returns
425 /// true if it makes a change, false otherwise. If a type contradiction is
Joerg Sonnenberger635debe2012-10-25 20:33:17 +0000426 /// found, an error is flagged.
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000427 bool ApplyTypeConstraints(TreePatternNode *N, TreePattern &TP) const;
Chris Lattner8cab0212008-01-05 22:25:12 +0000428};
Chris Lattner514e2922011-04-17 21:38:24 +0000429
430/// TreePredicateFn - This is an abstraction that represents the predicates on
431/// a PatFrag node. This is a simple one-word wrapper around a pointer to
432/// provide nice accessors.
433class TreePredicateFn {
434 /// PatFragRec - This is the TreePattern for the PatFrag that we
435 /// originally came from.
436 TreePattern *PatFragRec;
437public:
438 /// TreePredicateFn constructor. Here 'N' is a subclass of PatFrag.
Chris Lattner2ff8c1a2011-04-17 22:05:17 +0000439 TreePredicateFn(TreePattern *N);
Chris Lattner514e2922011-04-17 21:38:24 +0000440
441
442 TreePattern *getOrigPatFragRecord() const { return PatFragRec; }
443
444 /// isAlwaysTrue - Return true if this is a noop predicate.
445 bool isAlwaysTrue() const;
446
Chris Lattner07add492011-04-18 06:22:33 +0000447 bool isImmediatePattern() const { return !getImmCode().empty(); }
448
449 /// getImmediatePredicateCode - Return the code that evaluates this pattern if
450 /// this is an immediate predicate. It is an error to call this on a
451 /// non-immediate pattern.
452 std::string getImmediatePredicateCode() const {
453 std::string Result = getImmCode();
454 assert(!Result.empty() && "Isn't an immediate pattern!");
455 return Result;
456 }
457
Chris Lattner514e2922011-04-17 21:38:24 +0000458
459 bool operator==(const TreePredicateFn &RHS) const {
460 return PatFragRec == RHS.PatFragRec;
461 }
462
463 bool operator!=(const TreePredicateFn &RHS) const { return !(*this == RHS); }
464
465 /// Return the name to use in the generated code to reference this, this is
466 /// "Predicate_foo" if from a pattern fragment "foo".
467 std::string getFnName() const;
468
469 /// getCodeToRunOnSDNode - Return the code for the function body that
470 /// evaluates this predicate. The argument is expected to be in "Node",
471 /// not N. This handles casting and conversion to a concrete node type as
472 /// appropriate.
473 std::string getCodeToRunOnSDNode() const;
474
475private:
476 std::string getPredCode() const;
Chris Lattner2ff8c1a2011-04-17 22:05:17 +0000477 std::string getImmCode() const;
Chris Lattner514e2922011-04-17 21:38:24 +0000478};
David Blaikiecf195302014-11-17 22:55:41 +0000479
Chris Lattner8cab0212008-01-05 22:25:12 +0000480
481/// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped
482/// patterns), and as such should be ref counted. We currently just leak all
483/// TreePatternNode objects!
484class TreePatternNode {
Chris Lattnerf1447252010-03-19 21:37:09 +0000485 /// The type of each node result. Before and during type inference, each
486 /// result may be a set of possible types. After (successful) type inference,
487 /// each is a single concrete type.
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000488 std::vector<TypeSetByHwMode> Types;
Jim Grosbach50986b52010-12-24 05:06:32 +0000489
Chris Lattner8cab0212008-01-05 22:25:12 +0000490 /// Operator - The Record for the operator if this is an interior node (not
491 /// a leaf).
492 Record *Operator;
Jim Grosbach50986b52010-12-24 05:06:32 +0000493
Chris Lattner8cab0212008-01-05 22:25:12 +0000494 /// Val - The init value (e.g. the "GPRC" record, or "7") for a leaf.
495 ///
David Greeneaf8ee2c2011-07-29 22:43:06 +0000496 Init *Val;
Jim Grosbach50986b52010-12-24 05:06:32 +0000497
Chris Lattner8cab0212008-01-05 22:25:12 +0000498 /// Name - The name given to this node with the :$foo notation.
499 ///
500 std::string Name;
Jim Grosbach50986b52010-12-24 05:06:32 +0000501
Dan Gohman6e979022008-10-15 06:17:21 +0000502 /// PredicateFns - The predicate functions to execute on this node to check
503 /// for a match. If this list is empty, no predicate is involved.
Chris Lattner514e2922011-04-17 21:38:24 +0000504 std::vector<TreePredicateFn> PredicateFns;
Jim Grosbach50986b52010-12-24 05:06:32 +0000505
Chris Lattner8cab0212008-01-05 22:25:12 +0000506 /// TransformFn - The transformation function to execute on this node before
507 /// it can be substituted into the resulting instruction on a pattern match.
508 Record *TransformFn;
Jim Grosbach50986b52010-12-24 05:06:32 +0000509
Chris Lattner8cab0212008-01-05 22:25:12 +0000510 std::vector<TreePatternNode*> Children;
511public:
Chris Lattnerf1447252010-03-19 21:37:09 +0000512 TreePatternNode(Record *Op, const std::vector<TreePatternNode*> &Ch,
Jim Grosbach50986b52010-12-24 05:06:32 +0000513 unsigned NumResults)
Craig Topperada08572014-04-16 04:21:27 +0000514 : Operator(Op), Val(nullptr), TransformFn(nullptr), Children(Ch) {
Chris Lattnerf1447252010-03-19 21:37:09 +0000515 Types.resize(NumResults);
516 }
David Greeneaf8ee2c2011-07-29 22:43:06 +0000517 TreePatternNode(Init *val, unsigned NumResults) // leaf ctor
Craig Topperada08572014-04-16 04:21:27 +0000518 : Operator(nullptr), Val(val), TransformFn(nullptr) {
Chris Lattnerf1447252010-03-19 21:37:09 +0000519 Types.resize(NumResults);
Chris Lattner8cab0212008-01-05 22:25:12 +0000520 }
521 ~TreePatternNode();
Jim Grosbach50986b52010-12-24 05:06:32 +0000522
Jakob Stoklund Olesenb5b91102013-03-23 18:08:44 +0000523 bool hasName() const { return !Name.empty(); }
Chris Lattner8cab0212008-01-05 22:25:12 +0000524 const std::string &getName() const { return Name; }
Chris Lattneradf7ecf2010-03-28 06:50:34 +0000525 void setName(StringRef N) { Name.assign(N.begin(), N.end()); }
Jim Grosbach50986b52010-12-24 05:06:32 +0000526
Craig Topperada08572014-04-16 04:21:27 +0000527 bool isLeaf() const { return Val != nullptr; }
Jim Grosbach50986b52010-12-24 05:06:32 +0000528
Chris Lattnercabe0372010-03-15 06:00:16 +0000529 // Type accessors.
Chris Lattnerf1447252010-03-19 21:37:09 +0000530 unsigned getNumTypes() const { return Types.size(); }
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000531 ValueTypeByHwMode getType(unsigned ResNo) const {
532 return Types[ResNo].getValueTypeByHwMode();
Chris Lattnerf1447252010-03-19 21:37:09 +0000533 }
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000534 const std::vector<TypeSetByHwMode> &getExtTypes() const { return Types; }
535 const TypeSetByHwMode &getExtType(unsigned ResNo) const {
536 return Types[ResNo];
537 }
538 TypeSetByHwMode &getExtType(unsigned ResNo) { return Types[ResNo]; }
539 void setType(unsigned ResNo, const TypeSetByHwMode &T) { Types[ResNo] = T; }
540 MVT::SimpleValueType getSimpleType(unsigned ResNo) const {
541 return Types[ResNo].getMachineValueType().SimpleTy;
542 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000543
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000544 bool hasConcreteType(unsigned ResNo) const {
545 return Types[ResNo].isValueTypeByHwMode(false);
Chris Lattnerf1447252010-03-19 21:37:09 +0000546 }
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000547 bool isTypeCompletelyUnknown(unsigned ResNo, TreePattern &TP) const {
548 return Types[ResNo].empty();
Chris Lattnerf1447252010-03-19 21:37:09 +0000549 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000550
David Greeneaf8ee2c2011-07-29 22:43:06 +0000551 Init *getLeafValue() const { assert(isLeaf()); return Val; }
Chris Lattner8cab0212008-01-05 22:25:12 +0000552 Record *getOperator() const { assert(!isLeaf()); return Operator; }
Jim Grosbach50986b52010-12-24 05:06:32 +0000553
Chris Lattner8cab0212008-01-05 22:25:12 +0000554 unsigned getNumChildren() const { return Children.size(); }
555 TreePatternNode *getChild(unsigned N) const { return Children[N]; }
556 void setChild(unsigned i, TreePatternNode *N) {
557 Children[i] = N;
558 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000559
Chris Lattneraa7d3e02010-02-16 06:10:58 +0000560 /// hasChild - Return true if N is any of our children.
561 bool hasChild(const TreePatternNode *N) const {
562 for (unsigned i = 0, e = Children.size(); i != e; ++i)
563 if (Children[i] == N) return true;
564 return false;
565 }
Chris Lattner89c65662008-01-06 05:36:50 +0000566
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000567 bool hasProperTypeByHwMode() const;
568 bool hasPossibleType() const;
569 bool setDefaultMode(unsigned Mode);
570
Chris Lattner514e2922011-04-17 21:38:24 +0000571 bool hasAnyPredicate() const { return !PredicateFns.empty(); }
572
573 const std::vector<TreePredicateFn> &getPredicateFns() const {
574 return PredicateFns;
575 }
Dan Gohman6e979022008-10-15 06:17:21 +0000576 void clearPredicateFns() { PredicateFns.clear(); }
Chris Lattner514e2922011-04-17 21:38:24 +0000577 void setPredicateFns(const std::vector<TreePredicateFn> &Fns) {
Dan Gohman6e979022008-10-15 06:17:21 +0000578 assert(PredicateFns.empty() && "Overwriting non-empty predicate list!");
579 PredicateFns = Fns;
580 }
Chris Lattner514e2922011-04-17 21:38:24 +0000581 void addPredicateFn(const TreePredicateFn &Fn) {
582 assert(!Fn.isAlwaysTrue() && "Empty predicate string!");
David Majnemer0d955d02016-08-11 22:21:41 +0000583 if (!is_contained(PredicateFns, Fn))
Dan Gohman6e979022008-10-15 06:17:21 +0000584 PredicateFns.push_back(Fn);
585 }
Chris Lattner8cab0212008-01-05 22:25:12 +0000586
587 Record *getTransformFn() const { return TransformFn; }
588 void setTransformFn(Record *Fn) { TransformFn = Fn; }
Jim Grosbach50986b52010-12-24 05:06:32 +0000589
Chris Lattner89c65662008-01-06 05:36:50 +0000590 /// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
591 /// CodeGenIntrinsic information for it, otherwise return a null pointer.
592 const CodeGenIntrinsic *getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const;
Evan Cheng49bad4c2008-06-16 20:29:38 +0000593
Chris Lattner53c39ba2010-02-14 22:22:58 +0000594 /// getComplexPatternInfo - If this node corresponds to a ComplexPattern,
595 /// return the ComplexPattern information, otherwise return null.
596 const ComplexPattern *
597 getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const;
598
Tim Northoverc807a172014-05-20 11:52:46 +0000599 /// Returns the number of MachineInstr operands that would be produced by this
600 /// node if it mapped directly to an output Instruction's
601 /// operand. ComplexPattern specifies this explicitly; MIOperandInfo gives it
602 /// for Operands; otherwise 1.
603 unsigned getNumMIResults(const CodeGenDAGPatterns &CGP) const;
604
Chris Lattner53c39ba2010-02-14 22:22:58 +0000605 /// NodeHasProperty - Return true if this node has the specified property.
Chris Lattner450d5042010-02-14 22:33:49 +0000606 bool NodeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
Jim Grosbach50986b52010-12-24 05:06:32 +0000607
Chris Lattner53c39ba2010-02-14 22:22:58 +0000608 /// TreeHasProperty - Return true if any node in this tree has the specified
609 /// property.
Chris Lattner450d5042010-02-14 22:33:49 +0000610 bool TreeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
Jim Grosbach50986b52010-12-24 05:06:32 +0000611
Evan Cheng49bad4c2008-06-16 20:29:38 +0000612 /// isCommutativeIntrinsic - Return true if the node is an intrinsic which is
613 /// marked isCommutative.
614 bool isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const;
Jim Grosbach50986b52010-12-24 05:06:32 +0000615
Daniel Dunbar38a22bf2009-07-03 00:10:29 +0000616 void print(raw_ostream &OS) const;
Chris Lattner8cab0212008-01-05 22:25:12 +0000617 void dump() const;
Jim Grosbach50986b52010-12-24 05:06:32 +0000618
Chris Lattner8cab0212008-01-05 22:25:12 +0000619public: // Higher level manipulation routines.
620
621 /// clone - Return a new copy of this tree.
622 ///
623 TreePatternNode *clone() const;
Chris Lattner53c39ba2010-02-14 22:22:58 +0000624
625 /// RemoveAllTypes - Recursively strip all the types of this tree.
626 void RemoveAllTypes();
Jim Grosbach50986b52010-12-24 05:06:32 +0000627
Chris Lattner8cab0212008-01-05 22:25:12 +0000628 /// isIsomorphicTo - Return true if this node is recursively isomorphic to
629 /// the specified node. For this comparison, all of the state of the node
630 /// is considered, except for the assigned name. Nodes with differing names
631 /// that are otherwise identical are considered isomorphic.
Scott Michel94420742008-03-05 17:49:05 +0000632 bool isIsomorphicTo(const TreePatternNode *N,
633 const MultipleUseVarSet &DepVars) const;
Jim Grosbach50986b52010-12-24 05:06:32 +0000634
Chris Lattner8cab0212008-01-05 22:25:12 +0000635 /// SubstituteFormalArguments - Replace the formal arguments in this tree
636 /// with actual values specified by ArgMap.
637 void SubstituteFormalArguments(std::map<std::string,
638 TreePatternNode*> &ArgMap);
639
640 /// InlinePatternFragments - If this pattern refers to any pattern
641 /// fragments, inline them into place, giving us a pattern without any
642 /// PatFrag references.
643 TreePatternNode *InlinePatternFragments(TreePattern &TP);
Jim Grosbach50986b52010-12-24 05:06:32 +0000644
Bob Wilson1b97f3f2009-01-05 17:23:09 +0000645 /// ApplyTypeConstraints - Apply all of the type constraints relevant to
Chris Lattner8cab0212008-01-05 22:25:12 +0000646 /// this node and its children in the tree. This returns true if it makes a
Joerg Sonnenberger635debe2012-10-25 20:33:17 +0000647 /// change, false otherwise. If a type contradiction is found, flag an error.
Chris Lattner8cab0212008-01-05 22:25:12 +0000648 bool ApplyTypeConstraints(TreePattern &TP, bool NotRegisters);
Jim Grosbach50986b52010-12-24 05:06:32 +0000649
Chris Lattner8cab0212008-01-05 22:25:12 +0000650 /// UpdateNodeType - Set the node type of N to VT if VT contains
Joerg Sonnenberger635debe2012-10-25 20:33:17 +0000651 /// information. If N already contains a conflicting type, then flag an
652 /// error. This returns true if any information was updated.
Chris Lattner8cab0212008-01-05 22:25:12 +0000653 ///
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000654 bool UpdateNodeType(unsigned ResNo, const TypeSetByHwMode &InTy,
655 TreePattern &TP);
Chris Lattnerf1447252010-03-19 21:37:09 +0000656 bool UpdateNodeType(unsigned ResNo, MVT::SimpleValueType InTy,
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000657 TreePattern &TP);
658 bool UpdateNodeType(unsigned ResNo, ValueTypeByHwMode InTy,
659 TreePattern &TP);
Jim Grosbach50986b52010-12-24 05:06:32 +0000660
Jakob Stoklund Olesen57a86502013-03-18 04:08:07 +0000661 // Update node type with types inferred from an instruction operand or result
662 // def from the ins/outs lists.
663 // Return true if the type changed.
664 bool UpdateNodeTypeFromInst(unsigned ResNo, Record *Operand, TreePattern &TP);
665
Chris Lattner8cab0212008-01-05 22:25:12 +0000666 /// ContainsUnresolvedType - Return true if this tree contains any
667 /// unresolved types.
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000668 bool ContainsUnresolvedType(TreePattern &TP) const;
Jim Grosbach50986b52010-12-24 05:06:32 +0000669
Chris Lattner8cab0212008-01-05 22:25:12 +0000670 /// canPatternMatch - If it is impossible for this pattern to match on this
671 /// target, fill in Reason and return false. Otherwise, return true.
Dan Gohmanfc4ad7de2008-04-03 00:02:49 +0000672 bool canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP);
Chris Lattner8cab0212008-01-05 22:25:12 +0000673};
674
Chris Lattnerdd2ec582010-02-14 21:10:33 +0000675inline raw_ostream &operator<<(raw_ostream &OS, const TreePatternNode &TPN) {
676 TPN.print(OS);
677 return OS;
678}
Jim Grosbach50986b52010-12-24 05:06:32 +0000679
Chris Lattner8cab0212008-01-05 22:25:12 +0000680
681/// TreePattern - Represent a pattern, used for instructions, pattern
682/// fragments, etc.
683///
684class TreePattern {
685 /// Trees - The list of pattern trees which corresponds to this pattern.
686 /// Note that PatFrag's only have a single tree.
687 ///
David Blaikiecf195302014-11-17 22:55:41 +0000688 std::vector<TreePatternNode*> Trees;
Jim Grosbach50986b52010-12-24 05:06:32 +0000689
Chris Lattnercabe0372010-03-15 06:00:16 +0000690 /// NamedNodes - This is all of the nodes that have names in the trees in this
691 /// pattern.
692 StringMap<SmallVector<TreePatternNode*,1> > NamedNodes;
Jim Grosbach50986b52010-12-24 05:06:32 +0000693
Chris Lattner8cab0212008-01-05 22:25:12 +0000694 /// TheRecord - The actual TableGen record corresponding to this pattern.
695 ///
696 Record *TheRecord;
Jim Grosbach50986b52010-12-24 05:06:32 +0000697
Chris Lattner8cab0212008-01-05 22:25:12 +0000698 /// Args - This is a list of all of the arguments to this pattern (for
699 /// PatFrag patterns), which are the 'node' markers in this pattern.
700 std::vector<std::string> Args;
Jim Grosbach50986b52010-12-24 05:06:32 +0000701
Chris Lattner8cab0212008-01-05 22:25:12 +0000702 /// CDP - the top-level object coordinating this madness.
703 ///
Chris Lattnerab3242f2008-01-06 01:10:31 +0000704 CodeGenDAGPatterns &CDP;
Chris Lattner8cab0212008-01-05 22:25:12 +0000705
706 /// isInputPattern - True if this is an input pattern, something to match.
707 /// False if this is an output pattern, something to emit.
708 bool isInputPattern;
Joerg Sonnenberger635debe2012-10-25 20:33:17 +0000709
710 /// hasError - True if the currently processed nodes have unresolvable types
711 /// or other non-fatal errors
712 bool HasError;
Tim Northoverc807a172014-05-20 11:52:46 +0000713
714 /// It's important that the usage of operands in ComplexPatterns is
715 /// consistent: each named operand can be defined by at most one
716 /// ComplexPattern. This records the ComplexPattern instance and the operand
717 /// number for each operand encountered in a ComplexPattern to aid in that
718 /// check.
719 StringMap<std::pair<Record *, unsigned>> ComplexPatternOperands;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000720
721 TypeInfer Infer;
722
Chris Lattner8cab0212008-01-05 22:25:12 +0000723public:
Jim Grosbach50986b52010-12-24 05:06:32 +0000724
Chris Lattner8cab0212008-01-05 22:25:12 +0000725 /// TreePattern constructor - Parse the specified DagInits into the
726 /// current record.
David Greeneaf8ee2c2011-07-29 22:43:06 +0000727 TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
Chris Lattnerab3242f2008-01-06 01:10:31 +0000728 CodeGenDAGPatterns &ise);
David Greeneaf8ee2c2011-07-29 22:43:06 +0000729 TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
Chris Lattnerab3242f2008-01-06 01:10:31 +0000730 CodeGenDAGPatterns &ise);
David Blaikiecf195302014-11-17 22:55:41 +0000731 TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
732 CodeGenDAGPatterns &ise);
Jim Grosbach50986b52010-12-24 05:06:32 +0000733
Chris Lattner8cab0212008-01-05 22:25:12 +0000734 /// getTrees - Return the tree patterns which corresponds to this pattern.
735 ///
David Blaikiecf195302014-11-17 22:55:41 +0000736 const std::vector<TreePatternNode*> &getTrees() const { return Trees; }
Chris Lattner8cab0212008-01-05 22:25:12 +0000737 unsigned getNumTrees() const { return Trees.size(); }
David Blaikiecf195302014-11-17 22:55:41 +0000738 TreePatternNode *getTree(unsigned i) const { return Trees[i]; }
739 TreePatternNode *getOnlyTree() const {
Chris Lattner8cab0212008-01-05 22:25:12 +0000740 assert(Trees.size() == 1 && "Doesn't have exactly one pattern!");
741 return Trees[0];
742 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000743
Chris Lattnercabe0372010-03-15 06:00:16 +0000744 const StringMap<SmallVector<TreePatternNode*,1> > &getNamedNodesMap() {
745 if (NamedNodes.empty())
746 ComputeNamedNodes();
747 return NamedNodes;
748 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000749
Chris Lattner8cab0212008-01-05 22:25:12 +0000750 /// getRecord - Return the actual TableGen record corresponding to this
751 /// pattern.
752 ///
753 Record *getRecord() const { return TheRecord; }
Jim Grosbach50986b52010-12-24 05:06:32 +0000754
Chris Lattner8cab0212008-01-05 22:25:12 +0000755 unsigned getNumArgs() const { return Args.size(); }
756 const std::string &getArgName(unsigned i) const {
757 assert(i < Args.size() && "Argument reference out of range!");
758 return Args[i];
759 }
760 std::vector<std::string> &getArgList() { return Args; }
Jim Grosbach50986b52010-12-24 05:06:32 +0000761
Chris Lattnerab3242f2008-01-06 01:10:31 +0000762 CodeGenDAGPatterns &getDAGPatterns() const { return CDP; }
Chris Lattner8cab0212008-01-05 22:25:12 +0000763
764 /// InlinePatternFragments - If this pattern refers to any pattern
765 /// fragments, inline them into place, giving us a pattern without any
766 /// PatFrag references.
767 void InlinePatternFragments() {
768 for (unsigned i = 0, e = Trees.size(); i != e; ++i)
David Blaikiecf195302014-11-17 22:55:41 +0000769 Trees[i] = Trees[i]->InlinePatternFragments(*this);
Chris Lattner8cab0212008-01-05 22:25:12 +0000770 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000771
Chris Lattner8cab0212008-01-05 22:25:12 +0000772 /// InferAllTypes - Infer/propagate as many types throughout the expression
Jim Grosbach975c1cb2009-03-26 16:17:51 +0000773 /// patterns as possible. Return true if all types are inferred, false
Joerg Sonnenberger635debe2012-10-25 20:33:17 +0000774 /// otherwise. Bail out if a type contradiction is found.
Chris Lattnercabe0372010-03-15 06:00:16 +0000775 bool InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> >
Craig Topperada08572014-04-16 04:21:27 +0000776 *NamedTypes=nullptr);
Jim Grosbach50986b52010-12-24 05:06:32 +0000777
Joerg Sonnenberger635debe2012-10-25 20:33:17 +0000778 /// error - If this is the first error in the current resolution step,
779 /// print it and set the error flag. Otherwise, continue silently.
Matt Arsenaultea8df3a2014-11-11 23:48:11 +0000780 void error(const Twine &Msg);
Joerg Sonnenberger635debe2012-10-25 20:33:17 +0000781 bool hasError() const {
782 return HasError;
783 }
784 void resetError() {
785 HasError = false;
786 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000787
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000788 TypeInfer &getInfer() { return Infer; }
789
Daniel Dunbar38a22bf2009-07-03 00:10:29 +0000790 void print(raw_ostream &OS) const;
Chris Lattner8cab0212008-01-05 22:25:12 +0000791 void dump() const;
Jim Grosbach50986b52010-12-24 05:06:32 +0000792
Chris Lattner8cab0212008-01-05 22:25:12 +0000793private:
David Blaikiecf195302014-11-17 22:55:41 +0000794 TreePatternNode *ParseTreePattern(Init *DI, StringRef OpName);
Chris Lattnercabe0372010-03-15 06:00:16 +0000795 void ComputeNamedNodes();
796 void ComputeNamedNodes(TreePatternNode *N);
Chris Lattner8cab0212008-01-05 22:25:12 +0000797};
798
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000799
800inline bool TreePatternNode::UpdateNodeType(unsigned ResNo,
801 const TypeSetByHwMode &InTy,
802 TreePattern &TP) {
803 TypeSetByHwMode VTS(InTy);
804 TP.getInfer().expandOverloads(VTS);
805 return TP.getInfer().MergeInTypeInfo(Types[ResNo], VTS);
806}
807
808inline bool TreePatternNode::UpdateNodeType(unsigned ResNo,
809 MVT::SimpleValueType InTy,
810 TreePattern &TP) {
811 TypeSetByHwMode VTS(InTy);
812 TP.getInfer().expandOverloads(VTS);
813 return TP.getInfer().MergeInTypeInfo(Types[ResNo], VTS);
814}
815
816inline bool TreePatternNode::UpdateNodeType(unsigned ResNo,
817 ValueTypeByHwMode InTy,
818 TreePattern &TP) {
819 TypeSetByHwMode VTS(InTy);
820 TP.getInfer().expandOverloads(VTS);
821 return TP.getInfer().MergeInTypeInfo(Types[ResNo], VTS);
822}
823
824
Tom Stellardb7246a72012-09-06 14:15:52 +0000825/// DAGDefaultOperand - One of these is created for each OperandWithDefaultOps
826/// that has a set ExecuteAlways / DefaultOps field.
Chris Lattner8cab0212008-01-05 22:25:12 +0000827struct DAGDefaultOperand {
828 std::vector<TreePatternNode*> DefaultOps;
829};
830
831class DAGInstruction {
832 TreePattern *Pattern;
833 std::vector<Record*> Results;
834 std::vector<Record*> Operands;
835 std::vector<Record*> ImpResults;
David Blaikiecf195302014-11-17 22:55:41 +0000836 TreePatternNode *ResultPattern;
Chris Lattner8cab0212008-01-05 22:25:12 +0000837public:
838 DAGInstruction(TreePattern *TP,
839 const std::vector<Record*> &results,
840 const std::vector<Record*> &operands,
Chris Lattner9dc68d32010-04-20 06:28:43 +0000841 const std::vector<Record*> &impresults)
Jim Grosbach50986b52010-12-24 05:06:32 +0000842 : Pattern(TP), Results(results), Operands(operands),
David Blaikiecf195302014-11-17 22:55:41 +0000843 ImpResults(impresults), ResultPattern(nullptr) {}
Chris Lattner8cab0212008-01-05 22:25:12 +0000844
Joerg Sonnenberger635debe2012-10-25 20:33:17 +0000845 TreePattern *getPattern() const { return Pattern; }
Chris Lattner8cab0212008-01-05 22:25:12 +0000846 unsigned getNumResults() const { return Results.size(); }
847 unsigned getNumOperands() const { return Operands.size(); }
848 unsigned getNumImpResults() const { return ImpResults.size(); }
Chris Lattner8cab0212008-01-05 22:25:12 +0000849 const std::vector<Record*>& getImpResults() const { return ImpResults; }
Jim Grosbach50986b52010-12-24 05:06:32 +0000850
David Blaikiecf195302014-11-17 22:55:41 +0000851 void setResultPattern(TreePatternNode *R) { ResultPattern = R; }
Jim Grosbach50986b52010-12-24 05:06:32 +0000852
Chris Lattner8cab0212008-01-05 22:25:12 +0000853 Record *getResult(unsigned RN) const {
854 assert(RN < Results.size());
855 return Results[RN];
856 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000857
Chris Lattner8cab0212008-01-05 22:25:12 +0000858 Record *getOperand(unsigned ON) const {
859 assert(ON < Operands.size());
860 return Operands[ON];
861 }
862
863 Record *getImpResult(unsigned RN) const {
864 assert(RN < ImpResults.size());
865 return ImpResults[RN];
866 }
Jim Grosbach50986b52010-12-24 05:06:32 +0000867
David Blaikiecf195302014-11-17 22:55:41 +0000868 TreePatternNode *getResultPattern() const { return ResultPattern; }
Chris Lattner8cab0212008-01-05 22:25:12 +0000869};
Jim Grosbach50986b52010-12-24 05:06:32 +0000870
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000871/// This class represents a condition that has to be satisfied for a pattern
872/// to be tried. It is a generalization of a class "Pattern" from Target.td:
873/// in addition to the Target.td's predicates, this class can also represent
874/// conditions associated with HW modes. Both types will eventually become
875/// strings containing C++ code to be executed, the difference is in how
876/// these strings are generated.
877class Predicate {
878public:
879 Predicate(Record *R, bool C = true) : Def(R), IfCond(C), IsHwMode(false) {
880 assert(R->isSubClassOf("Predicate") &&
881 "Predicate objects should only be created for records derived"
882 "from Predicate class");
883 }
884 Predicate(StringRef FS, bool C = true) : Def(nullptr), Features(FS.str()),
885 IfCond(C), IsHwMode(true) {}
886
887 /// Return a string which contains the C++ condition code that will serve
888 /// as a predicate during instruction selection.
889 std::string getCondString() const {
890 // The string will excute in a subclass of SelectionDAGISel.
891 // Cast to std::string explicitly to avoid ambiguity with StringRef.
892 std::string C = IsHwMode
893 ? std::string("MF->getSubtarget().checkFeatures(\"" + Features + "\")")
894 : std::string(Def->getValueAsString("CondString"));
895 return IfCond ? C : "!("+C+')';
896 }
897 bool operator==(const Predicate &P) const {
898 return IfCond == P.IfCond && IsHwMode == P.IsHwMode && Def == P.Def;
899 }
900 bool operator<(const Predicate &P) const {
901 if (IsHwMode != P.IsHwMode)
902 return IsHwMode < P.IsHwMode;
903 assert(!Def == !P.Def && "Inconsistency between Def and IsHwMode");
904 if (IfCond != P.IfCond)
905 return IfCond < P.IfCond;
906 if (Def)
907 return LessRecord()(Def, P.Def);
908 return Features < P.Features;
909 }
910 Record *Def; ///< Predicate definition from .td file, null for
911 ///< HW modes.
912 std::string Features; ///< Feature string for HW mode.
913 bool IfCond; ///< The boolean value that the condition has to
914 ///< evaluate to for this predicate to be true.
915 bool IsHwMode; ///< Does this predicate correspond to a HW mode?
916};
917
Chris Lattnerab3242f2008-01-06 01:10:31 +0000918/// PatternToMatch - Used by CodeGenDAGPatterns to keep tab of patterns
Chris Lattner8cab0212008-01-05 22:25:12 +0000919/// processed to produce isel.
Chris Lattner7ed81692010-02-18 06:47:49 +0000920class PatternToMatch {
921public:
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000922 PatternToMatch(Record *srcrecord, const std::vector<Predicate> &preds,
923 TreePatternNode *src, TreePatternNode *dst,
924 const std::vector<Record*> &dstregs,
925 int complexity, unsigned uid, unsigned setmode = 0)
926 : SrcRecord(srcrecord), SrcPattern(src), DstPattern(dst),
927 Predicates(preds), Dstregs(std::move(dstregs)),
928 AddedComplexity(complexity), ID(uid), ForceMode(setmode) {}
929
930 PatternToMatch(Record *srcrecord, std::vector<Predicate> &&preds,
931 TreePatternNode *src, TreePatternNode *dst,
932 std::vector<Record*> &&dstregs,
933 int complexity, unsigned uid, unsigned setmode = 0)
934 : SrcRecord(srcrecord), SrcPattern(src), DstPattern(dst),
935 Predicates(preds), Dstregs(std::move(dstregs)),
936 AddedComplexity(complexity), ID(uid), ForceMode(setmode) {}
Chris Lattner8cab0212008-01-05 22:25:12 +0000937
Jim Grosbachfb116ae2010-12-07 23:05:49 +0000938 Record *SrcRecord; // Originating Record for the pattern.
Chris Lattner8cab0212008-01-05 22:25:12 +0000939 TreePatternNode *SrcPattern; // Source pattern to match.
940 TreePatternNode *DstPattern; // Resulting pattern.
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000941 std::vector<Predicate> Predicates; // Top level predicate conditions
942 // to match.
Chris Lattner8cab0212008-01-05 22:25:12 +0000943 std::vector<Record*> Dstregs; // Physical register defs being matched.
Tom Stellard6655dd62014-08-01 00:32:36 +0000944 int AddedComplexity; // Add to matching pattern complexity.
Chris Lattnerd39f75b2010-03-01 22:09:11 +0000945 unsigned ID; // Unique ID for the record.
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000946 unsigned ForceMode; // Force this mode in type inference when set.
Chris Lattner8cab0212008-01-05 22:25:12 +0000947
Jim Grosbachfb116ae2010-12-07 23:05:49 +0000948 Record *getSrcRecord() const { return SrcRecord; }
Chris Lattner8cab0212008-01-05 22:25:12 +0000949 TreePatternNode *getSrcPattern() const { return SrcPattern; }
950 TreePatternNode *getDstPattern() const { return DstPattern; }
951 const std::vector<Record*> &getDstRegs() const { return Dstregs; }
Tom Stellard6655dd62014-08-01 00:32:36 +0000952 int getAddedComplexity() const { return AddedComplexity; }
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000953 const std::vector<Predicate> &getPredicates() const { return Predicates; }
Dan Gohman49e19e92008-08-22 00:20:26 +0000954
955 std::string getPredicateCheck() const;
Jim Grosbach50986b52010-12-24 05:06:32 +0000956
Chris Lattner05925fe2010-03-29 01:40:38 +0000957 /// Compute the complexity metric for the input pattern. This roughly
958 /// corresponds to the number of nodes that are covered.
Tom Stellard6655dd62014-08-01 00:32:36 +0000959 int getPatternComplexity(const CodeGenDAGPatterns &CGP) const;
Chris Lattner8cab0212008-01-05 22:25:12 +0000960};
961
Chris Lattnerab3242f2008-01-06 01:10:31 +0000962class CodeGenDAGPatterns {
Chris Lattner8cab0212008-01-05 22:25:12 +0000963 RecordKeeper &Records;
964 CodeGenTarget Target;
Justin Bogner92a8c612016-07-15 16:31:37 +0000965 CodeGenIntrinsicTable Intrinsics;
966 CodeGenIntrinsicTable TgtIntrinsics;
Jim Grosbach50986b52010-12-24 05:06:32 +0000967
Sean Silvaa4e2c5f2012-09-19 01:47:00 +0000968 std::map<Record*, SDNodeInfo, LessRecordByID> SDNodes;
Krzysztof Parzyszek426bf362017-09-12 15:31:26 +0000969 std::map<Record*, std::pair<Record*, std::string>, LessRecordByID>
970 SDNodeXForms;
Sean Silvaa4e2c5f2012-09-19 01:47:00 +0000971 std::map<Record*, ComplexPattern, LessRecordByID> ComplexPatterns;
David Blaikie3c6ca232014-11-13 21:40:02 +0000972 std::map<Record *, std::unique_ptr<TreePattern>, LessRecordByID>
973 PatternFragments;
Sean Silvaa4e2c5f2012-09-19 01:47:00 +0000974 std::map<Record*, DAGDefaultOperand, LessRecordByID> DefaultOperands;
975 std::map<Record*, DAGInstruction, LessRecordByID> Instructions;
Jim Grosbach50986b52010-12-24 05:06:32 +0000976
Chris Lattner8cab0212008-01-05 22:25:12 +0000977 // Specific SDNode definitions:
978 Record *intrinsic_void_sdnode;
979 Record *intrinsic_w_chain_sdnode, *intrinsic_wo_chain_sdnode;
Jim Grosbach50986b52010-12-24 05:06:32 +0000980
Chris Lattner8cab0212008-01-05 22:25:12 +0000981 /// PatternsToMatch - All of the things we are matching on the DAG. The first
982 /// value is the pattern to match, the second pattern is the result to
983 /// emit.
984 std::vector<PatternToMatch> PatternsToMatch;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000985
986 TypeSetByHwMode LegalVTS;
987
Chris Lattner8cab0212008-01-05 22:25:12 +0000988public:
Jim Grosbach50986b52010-12-24 05:06:32 +0000989 CodeGenDAGPatterns(RecordKeeper &R);
Jim Grosbach50986b52010-12-24 05:06:32 +0000990
Dan Gohmanfc4ad7de2008-04-03 00:02:49 +0000991 CodeGenTarget &getTargetInfo() { return Target; }
Chris Lattner8cab0212008-01-05 22:25:12 +0000992 const CodeGenTarget &getTargetInfo() const { return Target; }
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +0000993 const TypeSetByHwMode &getLegalTypes() const { return LegalVTS; }
Jim Grosbach50986b52010-12-24 05:06:32 +0000994
Chris Lattner8cab0212008-01-05 22:25:12 +0000995 Record *getSDNodeNamed(const std::string &Name) const;
Jim Grosbach50986b52010-12-24 05:06:32 +0000996
Chris Lattner8cab0212008-01-05 22:25:12 +0000997 const SDNodeInfo &getSDNodeInfo(Record *R) const {
998 assert(SDNodes.count(R) && "Unknown node!");
999 return SDNodes.find(R)->second;
1000 }
Jim Grosbach50986b52010-12-24 05:06:32 +00001001
Chris Lattnercc43e792008-01-05 22:54:53 +00001002 // Node transformation lookups.
1003 typedef std::pair<Record*, std::string> NodeXForm;
1004 const NodeXForm &getSDNodeTransform(Record *R) const {
Chris Lattner8cab0212008-01-05 22:25:12 +00001005 assert(SDNodeXForms.count(R) && "Invalid transform!");
1006 return SDNodeXForms.find(R)->second;
1007 }
Jim Grosbach50986b52010-12-24 05:06:32 +00001008
Sean Silvaa4e2c5f2012-09-19 01:47:00 +00001009 typedef std::map<Record*, NodeXForm, LessRecordByID>::const_iterator
Benjamin Kramerc2dbd5d2009-08-23 10:39:21 +00001010 nx_iterator;
Chris Lattnercc43e792008-01-05 22:54:53 +00001011 nx_iterator nx_begin() const { return SDNodeXForms.begin(); }
1012 nx_iterator nx_end() const { return SDNodeXForms.end(); }
1013
Jim Grosbach50986b52010-12-24 05:06:32 +00001014
Chris Lattner8cab0212008-01-05 22:25:12 +00001015 const ComplexPattern &getComplexPattern(Record *R) const {
1016 assert(ComplexPatterns.count(R) && "Unknown addressing mode!");
1017 return ComplexPatterns.find(R)->second;
1018 }
Jim Grosbach50986b52010-12-24 05:06:32 +00001019
Chris Lattner8cab0212008-01-05 22:25:12 +00001020 const CodeGenIntrinsic &getIntrinsic(Record *R) const {
1021 for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
1022 if (Intrinsics[i].TheDef == R) return Intrinsics[i];
Dale Johannesenb842d522009-02-05 01:49:45 +00001023 for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
1024 if (TgtIntrinsics[i].TheDef == R) return TgtIntrinsics[i];
Craig Topperc4965bc2012-02-05 07:21:30 +00001025 llvm_unreachable("Unknown intrinsic!");
Chris Lattner8cab0212008-01-05 22:25:12 +00001026 }
Jim Grosbach50986b52010-12-24 05:06:32 +00001027
Chris Lattner8cab0212008-01-05 22:25:12 +00001028 const CodeGenIntrinsic &getIntrinsicInfo(unsigned IID) const {
Dale Johannesenb842d522009-02-05 01:49:45 +00001029 if (IID-1 < Intrinsics.size())
1030 return Intrinsics[IID-1];
1031 if (IID-Intrinsics.size()-1 < TgtIntrinsics.size())
1032 return TgtIntrinsics[IID-Intrinsics.size()-1];
Craig Topperc4965bc2012-02-05 07:21:30 +00001033 llvm_unreachable("Bad intrinsic ID!");
Chris Lattner8cab0212008-01-05 22:25:12 +00001034 }
Jim Grosbach50986b52010-12-24 05:06:32 +00001035
Chris Lattner8cab0212008-01-05 22:25:12 +00001036 unsigned getIntrinsicID(Record *R) const {
1037 for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
1038 if (Intrinsics[i].TheDef == R) return i;
Dale Johannesenb842d522009-02-05 01:49:45 +00001039 for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
1040 if (TgtIntrinsics[i].TheDef == R) return i + Intrinsics.size();
Craig Topperc4965bc2012-02-05 07:21:30 +00001041 llvm_unreachable("Unknown intrinsic!");
Chris Lattner8cab0212008-01-05 22:25:12 +00001042 }
Jim Grosbach50986b52010-12-24 05:06:32 +00001043
Chris Lattner7ed81692010-02-18 06:47:49 +00001044 const DAGDefaultOperand &getDefaultOperand(Record *R) const {
Chris Lattner8cab0212008-01-05 22:25:12 +00001045 assert(DefaultOperands.count(R) &&"Isn't an analyzed default operand!");
1046 return DefaultOperands.find(R)->second;
1047 }
Jim Grosbach50986b52010-12-24 05:06:32 +00001048
Chris Lattner8cab0212008-01-05 22:25:12 +00001049 // Pattern Fragment information.
1050 TreePattern *getPatternFragment(Record *R) const {
1051 assert(PatternFragments.count(R) && "Invalid pattern fragment request!");
David Blaikie3c6ca232014-11-13 21:40:02 +00001052 return PatternFragments.find(R)->second.get();
Chris Lattner8cab0212008-01-05 22:25:12 +00001053 }
Chris Lattnerf1447252010-03-19 21:37:09 +00001054 TreePattern *getPatternFragmentIfRead(Record *R) const {
David Blaikie3c6ca232014-11-13 21:40:02 +00001055 if (!PatternFragments.count(R))
1056 return nullptr;
1057 return PatternFragments.find(R)->second.get();
Chris Lattnerf1447252010-03-19 21:37:09 +00001058 }
Jim Grosbach50986b52010-12-24 05:06:32 +00001059
David Blaikiefcacc742014-11-13 21:56:57 +00001060 typedef std::map<Record *, std::unique_ptr<TreePattern>,
1061 LessRecordByID>::const_iterator pf_iterator;
Chris Lattner8cab0212008-01-05 22:25:12 +00001062 pf_iterator pf_begin() const { return PatternFragments.begin(); }
1063 pf_iterator pf_end() const { return PatternFragments.end(); }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001064 iterator_range<pf_iterator> ptfs() const { return PatternFragments; }
Chris Lattner8cab0212008-01-05 22:25:12 +00001065
1066 // Patterns to match information.
Chris Lattner9abe77b2008-01-05 22:30:17 +00001067 typedef std::vector<PatternToMatch>::const_iterator ptm_iterator;
1068 ptm_iterator ptm_begin() const { return PatternsToMatch.begin(); }
1069 ptm_iterator ptm_end() const { return PatternsToMatch.end(); }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001070 iterator_range<ptm_iterator> ptms() const { return PatternsToMatch; }
Jim Grosbach50986b52010-12-24 05:06:32 +00001071
Ahmed Bougacha14107512013-10-28 18:07:21 +00001072 /// Parse the Pattern for an instruction, and insert the result in DAGInsts.
1073 typedef std::map<Record*, DAGInstruction, LessRecordByID> DAGInstMap;
1074 const DAGInstruction &parseInstructionPattern(
1075 CodeGenInstruction &CGI, ListInit *Pattern,
1076 DAGInstMap &DAGInsts);
Jim Grosbach50986b52010-12-24 05:06:32 +00001077
Chris Lattner8cab0212008-01-05 22:25:12 +00001078 const DAGInstruction &getInstruction(Record *R) const {
1079 assert(Instructions.count(R) && "Unknown instruction!");
1080 return Instructions.find(R)->second;
1081 }
Jim Grosbach50986b52010-12-24 05:06:32 +00001082
Chris Lattner8cab0212008-01-05 22:25:12 +00001083 Record *get_intrinsic_void_sdnode() const {
1084 return intrinsic_void_sdnode;
1085 }
1086 Record *get_intrinsic_w_chain_sdnode() const {
1087 return intrinsic_w_chain_sdnode;
1088 }
1089 Record *get_intrinsic_wo_chain_sdnode() const {
1090 return intrinsic_wo_chain_sdnode;
1091 }
Jim Grosbach50986b52010-12-24 05:06:32 +00001092
Jakob Stoklund Olesene4197252009-10-15 18:50:03 +00001093 bool hasTargetIntrinsics() { return !TgtIntrinsics.empty(); }
1094
Chris Lattner8cab0212008-01-05 22:25:12 +00001095private:
1096 void ParseNodeInfo();
Chris Lattnercc43e792008-01-05 22:54:53 +00001097 void ParseNodeTransforms();
Chris Lattner8cab0212008-01-05 22:25:12 +00001098 void ParseComplexPatterns();
Hal Finkel2756dc12014-02-28 00:26:56 +00001099 void ParsePatternFragments(bool OutFrags = false);
Chris Lattner8cab0212008-01-05 22:25:12 +00001100 void ParseDefaultOperands();
1101 void ParseInstructions();
1102 void ParsePatterns();
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00001103 void ExpandHwModeBasedTypes();
Dan Gohmanfc4ad7de2008-04-03 00:02:49 +00001104 void InferInstructionFlags();
Chris Lattner8cab0212008-01-05 22:25:12 +00001105 void GenerateVariants();
Jakob Stoklund Olesena9d322a2012-08-28 03:26:49 +00001106 void VerifyInstructionFlags();
Jim Grosbach50986b52010-12-24 05:06:32 +00001107
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00001108 std::vector<Predicate> makePredList(ListInit *L);
1109
Craig Topper18e6b572017-06-25 17:33:49 +00001110 void AddPatternToMatch(TreePattern *Pattern, PatternToMatch &&PTM);
Chris Lattner8cab0212008-01-05 22:25:12 +00001111 void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
1112 std::map<std::string,
1113 TreePatternNode*> &InstInputs,
1114 std::map<std::string,
1115 TreePatternNode*> &InstResults,
Chris Lattner8cab0212008-01-05 22:25:12 +00001116 std::vector<Record*> &InstImpResults);
1117};
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00001118
1119
1120inline bool SDNodeInfo::ApplyTypeConstraints(TreePatternNode *N,
1121 TreePattern &TP) const {
1122 bool MadeChange = false;
1123 for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i)
1124 MadeChange |= TypeConstraints[i].ApplyTypeConstraint(N, *this, TP);
1125 return MadeChange;
1126 }
Chris Lattner8cab0212008-01-05 22:25:12 +00001127} // end namespace llvm
1128
1129#endif