Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
35290 views
1
//===- CodeGenDAGPatterns.h - Read DAG patterns from .td file ---*- C++ -*-===//
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 file declares the CodeGenDAGPatterns class, which is used to read and
10
// represent the patterns present in a .td file for instructions.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_UTILS_TABLEGEN_CODEGENDAGPATTERNS_H
15
#define LLVM_UTILS_TABLEGEN_CODEGENDAGPATTERNS_H
16
17
#include "Basic/CodeGenIntrinsics.h"
18
#include "Basic/SDNodeProperties.h"
19
#include "CodeGenTarget.h"
20
#include "llvm/ADT/IntrusiveRefCntPtr.h"
21
#include "llvm/ADT/MapVector.h"
22
#include "llvm/ADT/PointerUnion.h"
23
#include "llvm/ADT/SmallVector.h"
24
#include "llvm/ADT/StringMap.h"
25
#include "llvm/ADT/StringSet.h"
26
#include "llvm/ADT/Twine.h"
27
#include "llvm/Support/ErrorHandling.h"
28
#include "llvm/Support/MathExtras.h"
29
#include "llvm/TableGen/Record.h"
30
#include <algorithm>
31
#include <array>
32
#include <functional>
33
#include <map>
34
#include <numeric>
35
#include <vector>
36
37
namespace llvm {
38
39
class Init;
40
class ListInit;
41
class DagInit;
42
class SDNodeInfo;
43
class TreePattern;
44
class TreePatternNode;
45
class CodeGenDAGPatterns;
46
47
/// Shared pointer for TreePatternNode.
48
using TreePatternNodePtr = IntrusiveRefCntPtr<TreePatternNode>;
49
50
/// This represents a set of MVTs. Since the underlying type for the MVT
51
/// is uint8_t, there are at most 256 values. To reduce the number of memory
52
/// allocations and deallocations, represent the set as a sequence of bits.
53
/// To reduce the allocations even further, make MachineValueTypeSet own
54
/// the storage and use std::array as the bit container.
55
struct MachineValueTypeSet {
56
static_assert(std::is_same<std::underlying_type_t<MVT::SimpleValueType>,
57
uint8_t>::value,
58
"Change uint8_t here to the SimpleValueType's type");
59
static unsigned constexpr Capacity = std::numeric_limits<uint8_t>::max() + 1;
60
using WordType = uint64_t;
61
static unsigned constexpr WordWidth = CHAR_BIT * sizeof(WordType);
62
static unsigned constexpr NumWords = Capacity / WordWidth;
63
static_assert(NumWords * WordWidth == Capacity,
64
"Capacity should be a multiple of WordWidth");
65
66
LLVM_ATTRIBUTE_ALWAYS_INLINE
67
MachineValueTypeSet() { clear(); }
68
69
LLVM_ATTRIBUTE_ALWAYS_INLINE
70
unsigned size() const {
71
unsigned Count = 0;
72
for (WordType W : Words)
73
Count += llvm::popcount(W);
74
return Count;
75
}
76
LLVM_ATTRIBUTE_ALWAYS_INLINE
77
void clear() { std::memset(Words.data(), 0, NumWords * sizeof(WordType)); }
78
LLVM_ATTRIBUTE_ALWAYS_INLINE
79
bool empty() const {
80
for (WordType W : Words)
81
if (W != 0)
82
return false;
83
return true;
84
}
85
LLVM_ATTRIBUTE_ALWAYS_INLINE
86
unsigned count(MVT T) const {
87
return (Words[T.SimpleTy / WordWidth] >> (T.SimpleTy % WordWidth)) & 1;
88
}
89
std::pair<MachineValueTypeSet &, bool> insert(MVT T) {
90
bool V = count(T.SimpleTy);
91
Words[T.SimpleTy / WordWidth] |= WordType(1) << (T.SimpleTy % WordWidth);
92
return {*this, V};
93
}
94
MachineValueTypeSet &insert(const MachineValueTypeSet &S) {
95
for (unsigned i = 0; i != NumWords; ++i)
96
Words[i] |= S.Words[i];
97
return *this;
98
}
99
LLVM_ATTRIBUTE_ALWAYS_INLINE
100
void erase(MVT T) {
101
Words[T.SimpleTy / WordWidth] &= ~(WordType(1) << (T.SimpleTy % WordWidth));
102
}
103
104
void writeToStream(raw_ostream &OS) const;
105
106
struct const_iterator {
107
// Some implementations of the C++ library require these traits to be
108
// defined.
109
using iterator_category = std::forward_iterator_tag;
110
using value_type = MVT;
111
using difference_type = ptrdiff_t;
112
using pointer = const MVT *;
113
using reference = const MVT &;
114
115
LLVM_ATTRIBUTE_ALWAYS_INLINE
116
MVT operator*() const {
117
assert(Pos != Capacity);
118
return MVT::SimpleValueType(Pos);
119
}
120
LLVM_ATTRIBUTE_ALWAYS_INLINE
121
const_iterator(const MachineValueTypeSet *S, bool End) : Set(S) {
122
Pos = End ? Capacity : find_from_pos(0);
123
}
124
LLVM_ATTRIBUTE_ALWAYS_INLINE
125
const_iterator &operator++() {
126
assert(Pos != Capacity);
127
Pos = find_from_pos(Pos + 1);
128
return *this;
129
}
130
131
LLVM_ATTRIBUTE_ALWAYS_INLINE
132
bool operator==(const const_iterator &It) const {
133
return Set == It.Set && Pos == It.Pos;
134
}
135
LLVM_ATTRIBUTE_ALWAYS_INLINE
136
bool operator!=(const const_iterator &It) const { return !operator==(It); }
137
138
private:
139
unsigned find_from_pos(unsigned P) const {
140
unsigned SkipWords = P / WordWidth;
141
unsigned SkipBits = P % WordWidth;
142
unsigned Count = SkipWords * WordWidth;
143
144
// If P is in the middle of a word, process it manually here, because
145
// the trailing bits need to be masked off to use findFirstSet.
146
if (SkipBits != 0) {
147
WordType W = Set->Words[SkipWords];
148
W &= maskLeadingOnes<WordType>(WordWidth - SkipBits);
149
if (W != 0)
150
return Count + llvm::countr_zero(W);
151
Count += WordWidth;
152
SkipWords++;
153
}
154
155
for (unsigned i = SkipWords; i != NumWords; ++i) {
156
WordType W = Set->Words[i];
157
if (W != 0)
158
return Count + llvm::countr_zero(W);
159
Count += WordWidth;
160
}
161
return Capacity;
162
}
163
164
const MachineValueTypeSet *Set;
165
unsigned Pos;
166
};
167
168
LLVM_ATTRIBUTE_ALWAYS_INLINE
169
const_iterator begin() const { return const_iterator(this, false); }
170
LLVM_ATTRIBUTE_ALWAYS_INLINE
171
const_iterator end() const { return const_iterator(this, true); }
172
173
LLVM_ATTRIBUTE_ALWAYS_INLINE
174
bool operator==(const MachineValueTypeSet &S) const {
175
return Words == S.Words;
176
}
177
LLVM_ATTRIBUTE_ALWAYS_INLINE
178
bool operator!=(const MachineValueTypeSet &S) const { return !operator==(S); }
179
180
private:
181
friend struct const_iterator;
182
std::array<WordType, NumWords> Words;
183
};
184
185
raw_ostream &operator<<(raw_ostream &OS, const MachineValueTypeSet &T);
186
187
struct TypeSetByHwMode : public InfoByHwMode<MachineValueTypeSet> {
188
using SetType = MachineValueTypeSet;
189
unsigned AddrSpace = std::numeric_limits<unsigned>::max();
190
191
TypeSetByHwMode() = default;
192
TypeSetByHwMode(const TypeSetByHwMode &VTS) = default;
193
TypeSetByHwMode &operator=(const TypeSetByHwMode &) = default;
194
TypeSetByHwMode(MVT::SimpleValueType VT)
195
: TypeSetByHwMode(ValueTypeByHwMode(VT)) {}
196
TypeSetByHwMode(ValueTypeByHwMode VT)
197
: TypeSetByHwMode(ArrayRef<ValueTypeByHwMode>(&VT, 1)) {}
198
TypeSetByHwMode(ArrayRef<ValueTypeByHwMode> VTList);
199
200
SetType &getOrCreate(unsigned Mode) { return Map[Mode]; }
201
202
bool isValueTypeByHwMode(bool AllowEmpty) const;
203
ValueTypeByHwMode getValueTypeByHwMode() const;
204
205
LLVM_ATTRIBUTE_ALWAYS_INLINE
206
bool isMachineValueType() const {
207
return isSimple() && getSimple().size() == 1;
208
}
209
210
LLVM_ATTRIBUTE_ALWAYS_INLINE
211
MVT getMachineValueType() const {
212
assert(isMachineValueType());
213
return *getSimple().begin();
214
}
215
216
bool isPossible() const;
217
218
bool isPointer() const { return getValueTypeByHwMode().isPointer(); }
219
220
unsigned getPtrAddrSpace() const {
221
assert(isPointer());
222
return getValueTypeByHwMode().PtrAddrSpace;
223
}
224
225
bool insert(const ValueTypeByHwMode &VVT);
226
bool constrain(const TypeSetByHwMode &VTS);
227
template <typename Predicate> bool constrain(Predicate P);
228
template <typename Predicate>
229
bool assign_if(const TypeSetByHwMode &VTS, Predicate P);
230
231
void writeToStream(raw_ostream &OS) const;
232
233
bool operator==(const TypeSetByHwMode &VTS) const;
234
bool operator!=(const TypeSetByHwMode &VTS) const { return !(*this == VTS); }
235
236
void dump() const;
237
bool validate() const;
238
239
private:
240
unsigned PtrAddrSpace = std::numeric_limits<unsigned>::max();
241
/// Intersect two sets. Return true if anything has changed.
242
bool intersect(SetType &Out, const SetType &In);
243
};
244
245
raw_ostream &operator<<(raw_ostream &OS, const TypeSetByHwMode &T);
246
247
struct TypeInfer {
248
TypeInfer(TreePattern &T) : TP(T) {}
249
250
bool isConcrete(const TypeSetByHwMode &VTS, bool AllowEmpty) const {
251
return VTS.isValueTypeByHwMode(AllowEmpty);
252
}
253
ValueTypeByHwMode getConcrete(const TypeSetByHwMode &VTS,
254
bool AllowEmpty) const {
255
assert(VTS.isValueTypeByHwMode(AllowEmpty));
256
return VTS.getValueTypeByHwMode();
257
}
258
259
/// The protocol in the following functions (Merge*, force*, Enforce*,
260
/// expand*) is to return "true" if a change has been made, "false"
261
/// otherwise.
262
263
bool MergeInTypeInfo(TypeSetByHwMode &Out, const TypeSetByHwMode &In) const;
264
bool MergeInTypeInfo(TypeSetByHwMode &Out, MVT::SimpleValueType InVT) const {
265
return MergeInTypeInfo(Out, TypeSetByHwMode(InVT));
266
}
267
bool MergeInTypeInfo(TypeSetByHwMode &Out, ValueTypeByHwMode InVT) const {
268
return MergeInTypeInfo(Out, TypeSetByHwMode(InVT));
269
}
270
271
/// Reduce the set \p Out to have at most one element for each mode.
272
bool forceArbitrary(TypeSetByHwMode &Out);
273
274
/// The following four functions ensure that upon return the set \p Out
275
/// will only contain types of the specified kind: integer, floating-point,
276
/// scalar, or vector.
277
/// If \p Out is empty, all legal types of the specified kind will be added
278
/// to it. Otherwise, all types that are not of the specified kind will be
279
/// removed from \p Out.
280
bool EnforceInteger(TypeSetByHwMode &Out);
281
bool EnforceFloatingPoint(TypeSetByHwMode &Out);
282
bool EnforceScalar(TypeSetByHwMode &Out);
283
bool EnforceVector(TypeSetByHwMode &Out);
284
285
/// If \p Out is empty, fill it with all legal types. Otherwise, leave it
286
/// unchanged.
287
bool EnforceAny(TypeSetByHwMode &Out);
288
/// Make sure that for each type in \p Small, there exists a larger type
289
/// in \p Big. \p SmallIsVT indicates that this is being called for
290
/// SDTCisVTSmallerThanOp. In that case the TypeSetByHwMode is re-created for
291
/// each call and needs special consideration in how we detect changes.
292
bool EnforceSmallerThan(TypeSetByHwMode &Small, TypeSetByHwMode &Big,
293
bool SmallIsVT = false);
294
/// 1. Ensure that for each type T in \p Vec, T is a vector type, and that
295
/// for each type U in \p Elem, U is a scalar type.
296
/// 2. Ensure that for each (scalar) type U in \p Elem, there exists a
297
/// (vector) type T in \p Vec, such that U is the element type of T.
298
bool EnforceVectorEltTypeIs(TypeSetByHwMode &Vec, TypeSetByHwMode &Elem);
299
bool EnforceVectorEltTypeIs(TypeSetByHwMode &Vec,
300
const ValueTypeByHwMode &VVT);
301
/// Ensure that for each type T in \p Sub, T is a vector type, and there
302
/// exists a type U in \p Vec such that U is a vector type with the same
303
/// element type as T and at least as many elements as T.
304
bool EnforceVectorSubVectorTypeIs(TypeSetByHwMode &Vec, TypeSetByHwMode &Sub);
305
/// 1. Ensure that \p V has a scalar type iff \p W has a scalar type.
306
/// 2. Ensure that for each vector type T in \p V, there exists a vector
307
/// type U in \p W, such that T and U have the same number of elements.
308
/// 3. Ensure that for each vector type U in \p W, there exists a vector
309
/// type T in \p V, such that T and U have the same number of elements
310
/// (reverse of 2).
311
bool EnforceSameNumElts(TypeSetByHwMode &V, TypeSetByHwMode &W);
312
/// 1. Ensure that for each type T in \p A, there exists a type U in \p B,
313
/// such that T and U have equal size in bits.
314
/// 2. Ensure that for each type U in \p B, there exists a type T in \p A
315
/// such that T and U have equal size in bits (reverse of 1).
316
bool EnforceSameSize(TypeSetByHwMode &A, TypeSetByHwMode &B);
317
318
/// For each overloaded type (i.e. of form *Any), replace it with the
319
/// corresponding subset of legal, specific types.
320
void expandOverloads(TypeSetByHwMode &VTS) const;
321
void expandOverloads(TypeSetByHwMode::SetType &Out,
322
const TypeSetByHwMode::SetType &Legal) const;
323
324
struct ValidateOnExit {
325
ValidateOnExit(const TypeSetByHwMode &T, const TypeInfer &TI)
326
: Infer(TI), VTS(T) {}
327
~ValidateOnExit();
328
const TypeInfer &Infer;
329
const TypeSetByHwMode &VTS;
330
};
331
332
struct SuppressValidation {
333
SuppressValidation(TypeInfer &TI) : Infer(TI), SavedValidate(TI.Validate) {
334
Infer.Validate = false;
335
}
336
~SuppressValidation() { Infer.Validate = SavedValidate; }
337
TypeInfer &Infer;
338
bool SavedValidate;
339
};
340
341
TreePattern &TP;
342
bool Validate = true; // Indicate whether to validate types.
343
344
private:
345
const TypeSetByHwMode &getLegalTypes() const;
346
347
/// Cached legal types (in default mode).
348
mutable bool LegalTypesCached = false;
349
mutable TypeSetByHwMode LegalCache;
350
};
351
352
/// Set type used to track multiply used variables in patterns
353
typedef StringSet<> MultipleUseVarSet;
354
355
/// SDTypeConstraint - This is a discriminated union of constraints,
356
/// corresponding to the SDTypeConstraint tablegen class in Target.td.
357
struct SDTypeConstraint {
358
SDTypeConstraint(Record *R, const CodeGenHwModes &CGH);
359
360
unsigned OperandNo; // The operand # this constraint applies to.
361
enum {
362
SDTCisVT,
363
SDTCisPtrTy,
364
SDTCisInt,
365
SDTCisFP,
366
SDTCisVec,
367
SDTCisSameAs,
368
SDTCisVTSmallerThanOp,
369
SDTCisOpSmallerThanOp,
370
SDTCisEltOfVec,
371
SDTCisSubVecOfVec,
372
SDTCVecEltisVT,
373
SDTCisSameNumEltsAs,
374
SDTCisSameSizeAs
375
} ConstraintType;
376
377
union { // The discriminated union.
378
struct {
379
unsigned OtherOperandNum;
380
} SDTCisSameAs_Info;
381
struct {
382
unsigned OtherOperandNum;
383
} SDTCisVTSmallerThanOp_Info;
384
struct {
385
unsigned BigOperandNum;
386
} SDTCisOpSmallerThanOp_Info;
387
struct {
388
unsigned OtherOperandNum;
389
} SDTCisEltOfVec_Info;
390
struct {
391
unsigned OtherOperandNum;
392
} SDTCisSubVecOfVec_Info;
393
struct {
394
unsigned OtherOperandNum;
395
} SDTCisSameNumEltsAs_Info;
396
struct {
397
unsigned OtherOperandNum;
398
} SDTCisSameSizeAs_Info;
399
} x;
400
401
// The VT for SDTCisVT and SDTCVecEltisVT.
402
// Must not be in the union because it has a non-trivial destructor.
403
ValueTypeByHwMode VVT;
404
405
/// ApplyTypeConstraint - Given a node in a pattern, apply this type
406
/// constraint to the nodes operands. This returns true if it makes a
407
/// change, false otherwise. If a type contradiction is found, an error
408
/// is flagged.
409
bool ApplyTypeConstraint(TreePatternNode &N, const SDNodeInfo &NodeInfo,
410
TreePattern &TP) const;
411
};
412
413
/// ScopedName - A name of a node associated with a "scope" that indicates
414
/// the context (e.g. instance of Pattern or PatFrag) in which the name was
415
/// used. This enables substitution of pattern fragments while keeping track
416
/// of what name(s) were originally given to various nodes in the tree.
417
class ScopedName {
418
unsigned Scope;
419
std::string Identifier;
420
421
public:
422
ScopedName(unsigned Scope, StringRef Identifier)
423
: Scope(Scope), Identifier(std::string(Identifier)) {
424
assert(Scope != 0 &&
425
"Scope == 0 is used to indicate predicates without arguments");
426
}
427
428
unsigned getScope() const { return Scope; }
429
const std::string &getIdentifier() const { return Identifier; }
430
431
bool operator==(const ScopedName &o) const;
432
bool operator!=(const ScopedName &o) const;
433
};
434
435
/// SDNodeInfo - One of these records is created for each SDNode instance in
436
/// the target .td file. This represents the various dag nodes we will be
437
/// processing.
438
class SDNodeInfo {
439
Record *Def;
440
StringRef EnumName;
441
StringRef SDClassName;
442
unsigned Properties;
443
unsigned NumResults;
444
int NumOperands;
445
std::vector<SDTypeConstraint> TypeConstraints;
446
447
public:
448
// Parse the specified record.
449
SDNodeInfo(Record *R, const CodeGenHwModes &CGH);
450
451
unsigned getNumResults() const { return NumResults; }
452
453
/// getNumOperands - This is the number of operands required or -1 if
454
/// variadic.
455
int getNumOperands() const { return NumOperands; }
456
Record *getRecord() const { return Def; }
457
StringRef getEnumName() const { return EnumName; }
458
StringRef getSDClassName() const { return SDClassName; }
459
460
const std::vector<SDTypeConstraint> &getTypeConstraints() const {
461
return TypeConstraints;
462
}
463
464
/// getKnownType - If the type constraints on this node imply a fixed type
465
/// (e.g. all stores return void, etc), then return it as an
466
/// MVT::SimpleValueType. Otherwise, return MVT::Other.
467
MVT::SimpleValueType getKnownType(unsigned ResNo) const;
468
469
/// hasProperty - Return true if this node has the specified property.
470
///
471
bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
472
473
/// ApplyTypeConstraints - Given a node in a pattern, apply the type
474
/// constraints for this node to the operands of the node. This returns
475
/// true if it makes a change, false otherwise. If a type contradiction is
476
/// found, an error is flagged.
477
bool ApplyTypeConstraints(TreePatternNode &N, TreePattern &TP) const;
478
};
479
480
/// TreePredicateFn - This is an abstraction that represents the predicates on
481
/// a PatFrag node. This is a simple one-word wrapper around a pointer to
482
/// provide nice accessors.
483
class TreePredicateFn {
484
/// PatFragRec - This is the TreePattern for the PatFrag that we
485
/// originally came from.
486
TreePattern *PatFragRec;
487
488
public:
489
/// TreePredicateFn constructor. Here 'N' is a subclass of PatFrag.
490
TreePredicateFn(TreePattern *N);
491
492
TreePattern *getOrigPatFragRecord() const { return PatFragRec; }
493
494
/// isAlwaysTrue - Return true if this is a noop predicate.
495
bool isAlwaysTrue() const;
496
497
bool isImmediatePattern() const { return hasImmCode(); }
498
499
/// getImmediatePredicateCode - Return the code that evaluates this pattern if
500
/// this is an immediate predicate. It is an error to call this on a
501
/// non-immediate pattern.
502
std::string getImmediatePredicateCode() const {
503
std::string Result = getImmCode();
504
assert(!Result.empty() && "Isn't an immediate pattern!");
505
return Result;
506
}
507
508
bool operator==(const TreePredicateFn &RHS) const {
509
return PatFragRec == RHS.PatFragRec;
510
}
511
512
bool operator!=(const TreePredicateFn &RHS) const { return !(*this == RHS); }
513
514
/// Return the name to use in the generated code to reference this, this is
515
/// "Predicate_foo" if from a pattern fragment "foo".
516
std::string getFnName() const;
517
518
/// getCodeToRunOnSDNode - Return the code for the function body that
519
/// evaluates this predicate. The argument is expected to be in "Node",
520
/// not N. This handles casting and conversion to a concrete node type as
521
/// appropriate.
522
std::string getCodeToRunOnSDNode() const;
523
524
/// Get the data type of the argument to getImmediatePredicateCode().
525
StringRef getImmType() const;
526
527
/// Get a string that describes the type returned by getImmType() but is
528
/// usable as part of an identifier.
529
StringRef getImmTypeIdentifier() const;
530
531
// Predicate code uses the PatFrag's captured operands.
532
bool usesOperands() const;
533
534
// Check if the HasNoUse predicate is set.
535
bool hasNoUse() const;
536
// Check if the HasOneUse predicate is set.
537
bool hasOneUse() const;
538
539
// Is the desired predefined predicate for a load?
540
bool isLoad() const;
541
// Is the desired predefined predicate for a store?
542
bool isStore() const;
543
// Is the desired predefined predicate for an atomic?
544
bool isAtomic() const;
545
546
/// Is this predicate the predefined unindexed load predicate?
547
/// Is this predicate the predefined unindexed store predicate?
548
bool isUnindexed() const;
549
/// Is this predicate the predefined non-extending load predicate?
550
bool isNonExtLoad() const;
551
/// Is this predicate the predefined any-extend load predicate?
552
bool isAnyExtLoad() const;
553
/// Is this predicate the predefined sign-extend load predicate?
554
bool isSignExtLoad() const;
555
/// Is this predicate the predefined zero-extend load predicate?
556
bool isZeroExtLoad() const;
557
/// Is this predicate the predefined non-truncating store predicate?
558
bool isNonTruncStore() const;
559
/// Is this predicate the predefined truncating store predicate?
560
bool isTruncStore() const;
561
562
/// Is this predicate the predefined monotonic atomic predicate?
563
bool isAtomicOrderingMonotonic() const;
564
/// Is this predicate the predefined acquire atomic predicate?
565
bool isAtomicOrderingAcquire() const;
566
/// Is this predicate the predefined release atomic predicate?
567
bool isAtomicOrderingRelease() const;
568
/// Is this predicate the predefined acquire-release atomic predicate?
569
bool isAtomicOrderingAcquireRelease() const;
570
/// Is this predicate the predefined sequentially consistent atomic predicate?
571
bool isAtomicOrderingSequentiallyConsistent() const;
572
573
/// Is this predicate the predefined acquire-or-stronger atomic predicate?
574
bool isAtomicOrderingAcquireOrStronger() const;
575
/// Is this predicate the predefined weaker-than-acquire atomic predicate?
576
bool isAtomicOrderingWeakerThanAcquire() const;
577
578
/// Is this predicate the predefined release-or-stronger atomic predicate?
579
bool isAtomicOrderingReleaseOrStronger() const;
580
/// Is this predicate the predefined weaker-than-release atomic predicate?
581
bool isAtomicOrderingWeakerThanRelease() const;
582
583
/// If non-null, indicates that this predicate is a predefined memory VT
584
/// predicate for a load/store and returns the ValueType record for the memory
585
/// VT.
586
Record *getMemoryVT() const;
587
/// If non-null, indicates that this predicate is a predefined memory VT
588
/// predicate (checking only the scalar type) for load/store and returns the
589
/// ValueType record for the memory VT.
590
Record *getScalarMemoryVT() const;
591
592
ListInit *getAddressSpaces() const;
593
int64_t getMinAlignment() const;
594
595
// If true, indicates that GlobalISel-based C++ code was supplied.
596
bool hasGISelPredicateCode() const;
597
std::string getGISelPredicateCode() const;
598
599
private:
600
bool hasPredCode() const;
601
bool hasImmCode() const;
602
std::string getPredCode() const;
603
std::string getImmCode() const;
604
bool immCodeUsesAPInt() const;
605
bool immCodeUsesAPFloat() const;
606
607
bool isPredefinedPredicateEqualTo(StringRef Field, bool Value) const;
608
};
609
610
struct TreePredicateCall {
611
TreePredicateFn Fn;
612
613
// Scope -- unique identifier for retrieving named arguments. 0 is used when
614
// the predicate does not use named arguments.
615
unsigned Scope;
616
617
TreePredicateCall(const TreePredicateFn &Fn, unsigned Scope)
618
: Fn(Fn), Scope(Scope) {}
619
620
bool operator==(const TreePredicateCall &o) const {
621
return Fn == o.Fn && Scope == o.Scope;
622
}
623
bool operator!=(const TreePredicateCall &o) const { return !(*this == o); }
624
};
625
626
class TreePatternNode : public RefCountedBase<TreePatternNode> {
627
/// The type of each node result. Before and during type inference, each
628
/// result may be a set of possible types. After (successful) type inference,
629
/// each is a single concrete type.
630
std::vector<TypeSetByHwMode> Types;
631
632
/// The index of each result in results of the pattern.
633
std::vector<unsigned> ResultPerm;
634
635
/// OperatorOrVal - The Record for the operator if this is an interior node
636
/// (not a leaf) or the init value (e.g. the "GPRC" record, or "7") for a
637
/// leaf.
638
PointerUnion<Record *, Init *> OperatorOrVal;
639
640
/// Name - The name given to this node with the :$foo notation.
641
///
642
std::string Name;
643
644
std::vector<ScopedName> NamesAsPredicateArg;
645
646
/// PredicateCalls - The predicate functions to execute on this node to check
647
/// for a match. If this list is empty, no predicate is involved.
648
std::vector<TreePredicateCall> PredicateCalls;
649
650
/// TransformFn - The transformation function to execute on this node before
651
/// it can be substituted into the resulting instruction on a pattern match.
652
Record *TransformFn;
653
654
std::vector<TreePatternNodePtr> Children;
655
656
/// If this was instantiated from a PatFrag node, and the PatFrag was derived
657
/// from "GISelFlags": the original Record derived from GISelFlags.
658
const Record *GISelFlags = nullptr;
659
660
public:
661
TreePatternNode(Record *Op, std::vector<TreePatternNodePtr> Ch,
662
unsigned NumResults)
663
: OperatorOrVal(Op), TransformFn(nullptr), Children(std::move(Ch)) {
664
Types.resize(NumResults);
665
ResultPerm.resize(NumResults);
666
std::iota(ResultPerm.begin(), ResultPerm.end(), 0);
667
}
668
TreePatternNode(Init *val, unsigned NumResults) // leaf ctor
669
: OperatorOrVal(val), TransformFn(nullptr) {
670
Types.resize(NumResults);
671
ResultPerm.resize(NumResults);
672
std::iota(ResultPerm.begin(), ResultPerm.end(), 0);
673
}
674
675
bool hasName() const { return !Name.empty(); }
676
const std::string &getName() const { return Name; }
677
void setName(StringRef N) { Name.assign(N.begin(), N.end()); }
678
679
const std::vector<ScopedName> &getNamesAsPredicateArg() const {
680
return NamesAsPredicateArg;
681
}
682
void setNamesAsPredicateArg(const std::vector<ScopedName> &Names) {
683
NamesAsPredicateArg = Names;
684
}
685
void addNameAsPredicateArg(const ScopedName &N) {
686
NamesAsPredicateArg.push_back(N);
687
}
688
689
bool isLeaf() const { return isa<Init *>(OperatorOrVal); }
690
691
// Type accessors.
692
unsigned getNumTypes() const { return Types.size(); }
693
ValueTypeByHwMode getType(unsigned ResNo) const {
694
return Types[ResNo].getValueTypeByHwMode();
695
}
696
const std::vector<TypeSetByHwMode> &getExtTypes() const { return Types; }
697
const TypeSetByHwMode &getExtType(unsigned ResNo) const {
698
return Types[ResNo];
699
}
700
TypeSetByHwMode &getExtType(unsigned ResNo) { return Types[ResNo]; }
701
void setType(unsigned ResNo, const TypeSetByHwMode &T) { Types[ResNo] = T; }
702
MVT::SimpleValueType getSimpleType(unsigned ResNo) const {
703
return Types[ResNo].getMachineValueType().SimpleTy;
704
}
705
706
bool hasConcreteType(unsigned ResNo) const {
707
return Types[ResNo].isValueTypeByHwMode(false);
708
}
709
bool isTypeCompletelyUnknown(unsigned ResNo, TreePattern &TP) const {
710
return Types[ResNo].empty();
711
}
712
713
unsigned getNumResults() const { return ResultPerm.size(); }
714
unsigned getResultIndex(unsigned ResNo) const { return ResultPerm[ResNo]; }
715
void setResultIndex(unsigned ResNo, unsigned RI) { ResultPerm[ResNo] = RI; }
716
717
Init *getLeafValue() const {
718
assert(isLeaf());
719
return cast<Init *>(OperatorOrVal);
720
}
721
Record *getOperator() const {
722
assert(!isLeaf());
723
return cast<Record *>(OperatorOrVal);
724
}
725
726
unsigned getNumChildren() const { return Children.size(); }
727
const TreePatternNode &getChild(unsigned N) const {
728
return *Children[N].get();
729
}
730
TreePatternNode &getChild(unsigned N) { return *Children[N].get(); }
731
const TreePatternNodePtr &getChildShared(unsigned N) const {
732
return Children[N];
733
}
734
TreePatternNodePtr &getChildSharedPtr(unsigned N) { return Children[N]; }
735
void setChild(unsigned i, TreePatternNodePtr N) { Children[i] = N; }
736
737
/// hasChild - Return true if N is any of our children.
738
bool hasChild(const TreePatternNode *N) const {
739
for (unsigned i = 0, e = Children.size(); i != e; ++i)
740
if (Children[i].get() == N)
741
return true;
742
return false;
743
}
744
745
bool hasProperTypeByHwMode() const;
746
bool hasPossibleType() const;
747
bool setDefaultMode(unsigned Mode);
748
749
bool hasAnyPredicate() const { return !PredicateCalls.empty(); }
750
751
const std::vector<TreePredicateCall> &getPredicateCalls() const {
752
return PredicateCalls;
753
}
754
void clearPredicateCalls() { PredicateCalls.clear(); }
755
void setPredicateCalls(const std::vector<TreePredicateCall> &Calls) {
756
assert(PredicateCalls.empty() && "Overwriting non-empty predicate list!");
757
PredicateCalls = Calls;
758
}
759
void addPredicateCall(const TreePredicateCall &Call) {
760
assert(!Call.Fn.isAlwaysTrue() && "Empty predicate string!");
761
assert(!is_contained(PredicateCalls, Call) &&
762
"predicate applied recursively");
763
PredicateCalls.push_back(Call);
764
}
765
void addPredicateCall(const TreePredicateFn &Fn, unsigned Scope) {
766
assert((Scope != 0) == Fn.usesOperands());
767
addPredicateCall(TreePredicateCall(Fn, Scope));
768
}
769
770
Record *getTransformFn() const { return TransformFn; }
771
void setTransformFn(Record *Fn) { TransformFn = Fn; }
772
773
/// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
774
/// CodeGenIntrinsic information for it, otherwise return a null pointer.
775
const CodeGenIntrinsic *getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const;
776
777
/// getComplexPatternInfo - If this node corresponds to a ComplexPattern,
778
/// return the ComplexPattern information, otherwise return null.
779
const ComplexPattern *
780
getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const;
781
782
/// Returns the number of MachineInstr operands that would be produced by this
783
/// node if it mapped directly to an output Instruction's
784
/// operand. ComplexPattern specifies this explicitly; MIOperandInfo gives it
785
/// for Operands; otherwise 1.
786
unsigned getNumMIResults(const CodeGenDAGPatterns &CGP) const;
787
788
/// NodeHasProperty - Return true if this node has the specified property.
789
bool NodeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
790
791
/// TreeHasProperty - Return true if any node in this tree has the specified
792
/// property.
793
bool TreeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
794
795
/// isCommutativeIntrinsic - Return true if the node is an intrinsic which is
796
/// marked isCommutative.
797
bool isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const;
798
799
void setGISelFlagsRecord(const Record *R) { GISelFlags = R; }
800
const Record *getGISelFlagsRecord() const { return GISelFlags; }
801
802
void print(raw_ostream &OS) const;
803
void dump() const;
804
805
public: // Higher level manipulation routines.
806
/// clone - Return a new copy of this tree.
807
///
808
TreePatternNodePtr clone() const;
809
810
/// RemoveAllTypes - Recursively strip all the types of this tree.
811
void RemoveAllTypes();
812
813
/// isIsomorphicTo - Return true if this node is recursively isomorphic to
814
/// the specified node. For this comparison, all of the state of the node
815
/// is considered, except for the assigned name. Nodes with differing names
816
/// that are otherwise identical are considered isomorphic.
817
bool isIsomorphicTo(const TreePatternNode &N,
818
const MultipleUseVarSet &DepVars) const;
819
820
/// SubstituteFormalArguments - Replace the formal arguments in this tree
821
/// with actual values specified by ArgMap.
822
void
823
SubstituteFormalArguments(std::map<std::string, TreePatternNodePtr> &ArgMap);
824
825
/// InlinePatternFragments - If \p T pattern refers to any pattern
826
/// fragments, return the set of inlined versions (this can be more than
827
/// one if a PatFrags record has multiple alternatives).
828
void InlinePatternFragments(TreePattern &TP,
829
std::vector<TreePatternNodePtr> &OutAlternatives);
830
831
/// ApplyTypeConstraints - Apply all of the type constraints relevant to
832
/// this node and its children in the tree. This returns true if it makes a
833
/// change, false otherwise. If a type contradiction is found, flag an error.
834
bool ApplyTypeConstraints(TreePattern &TP, bool NotRegisters);
835
836
/// UpdateNodeType - Set the node type of N to VT if VT contains
837
/// information. If N already contains a conflicting type, then flag an
838
/// error. This returns true if any information was updated.
839
///
840
bool UpdateNodeType(unsigned ResNo, const TypeSetByHwMode &InTy,
841
TreePattern &TP);
842
bool UpdateNodeType(unsigned ResNo, MVT::SimpleValueType InTy,
843
TreePattern &TP);
844
bool UpdateNodeType(unsigned ResNo, ValueTypeByHwMode InTy, TreePattern &TP);
845
846
// Update node type with types inferred from an instruction operand or result
847
// def from the ins/outs lists.
848
// Return true if the type changed.
849
bool UpdateNodeTypeFromInst(unsigned ResNo, Record *Operand, TreePattern &TP);
850
851
/// ContainsUnresolvedType - Return true if this tree contains any
852
/// unresolved types.
853
bool ContainsUnresolvedType(TreePattern &TP) const;
854
855
/// canPatternMatch - If it is impossible for this pattern to match on this
856
/// target, fill in Reason and return false. Otherwise, return true.
857
bool canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP);
858
};
859
860
inline raw_ostream &operator<<(raw_ostream &OS, const TreePatternNode &TPN) {
861
TPN.print(OS);
862
return OS;
863
}
864
865
/// TreePattern - Represent a pattern, used for instructions, pattern
866
/// fragments, etc.
867
///
868
class TreePattern {
869
/// Trees - The list of pattern trees which corresponds to this pattern.
870
/// Note that PatFrag's only have a single tree.
871
///
872
std::vector<TreePatternNodePtr> Trees;
873
874
/// NamedNodes - This is all of the nodes that have names in the trees in this
875
/// pattern.
876
StringMap<SmallVector<TreePatternNode *, 1>> NamedNodes;
877
878
/// TheRecord - The actual TableGen record corresponding to this pattern.
879
///
880
Record *TheRecord;
881
882
/// Args - This is a list of all of the arguments to this pattern (for
883
/// PatFrag patterns), which are the 'node' markers in this pattern.
884
std::vector<std::string> Args;
885
886
/// CDP - the top-level object coordinating this madness.
887
///
888
CodeGenDAGPatterns &CDP;
889
890
/// isInputPattern - True if this is an input pattern, something to match.
891
/// False if this is an output pattern, something to emit.
892
bool isInputPattern;
893
894
/// hasError - True if the currently processed nodes have unresolvable types
895
/// or other non-fatal errors
896
bool HasError;
897
898
/// It's important that the usage of operands in ComplexPatterns is
899
/// consistent: each named operand can be defined by at most one
900
/// ComplexPattern. This records the ComplexPattern instance and the operand
901
/// number for each operand encountered in a ComplexPattern to aid in that
902
/// check.
903
StringMap<std::pair<Record *, unsigned>> ComplexPatternOperands;
904
905
TypeInfer Infer;
906
907
public:
908
/// TreePattern constructor - Parse the specified DagInits into the
909
/// current record.
910
TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
911
CodeGenDAGPatterns &ise);
912
TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
913
CodeGenDAGPatterns &ise);
914
TreePattern(Record *TheRec, TreePatternNodePtr Pat, bool isInput,
915
CodeGenDAGPatterns &ise);
916
917
/// getTrees - Return the tree patterns which corresponds to this pattern.
918
///
919
const std::vector<TreePatternNodePtr> &getTrees() const { return Trees; }
920
unsigned getNumTrees() const { return Trees.size(); }
921
const TreePatternNodePtr &getTree(unsigned i) const { return Trees[i]; }
922
void setTree(unsigned i, TreePatternNodePtr Tree) { Trees[i] = Tree; }
923
const TreePatternNodePtr &getOnlyTree() const {
924
assert(Trees.size() == 1 && "Doesn't have exactly one pattern!");
925
return Trees[0];
926
}
927
928
const StringMap<SmallVector<TreePatternNode *, 1>> &getNamedNodesMap() {
929
if (NamedNodes.empty())
930
ComputeNamedNodes();
931
return NamedNodes;
932
}
933
934
/// getRecord - Return the actual TableGen record corresponding to this
935
/// pattern.
936
///
937
Record *getRecord() const { return TheRecord; }
938
939
unsigned getNumArgs() const { return Args.size(); }
940
const std::string &getArgName(unsigned i) const {
941
assert(i < Args.size() && "Argument reference out of range!");
942
return Args[i];
943
}
944
std::vector<std::string> &getArgList() { return Args; }
945
946
CodeGenDAGPatterns &getDAGPatterns() const { return CDP; }
947
948
/// InlinePatternFragments - If this pattern refers to any pattern
949
/// fragments, inline them into place, giving us a pattern without any
950
/// PatFrags references. This may increase the number of trees in the
951
/// pattern if a PatFrags has multiple alternatives.
952
void InlinePatternFragments() {
953
std::vector<TreePatternNodePtr> Copy;
954
Trees.swap(Copy);
955
for (const TreePatternNodePtr &C : Copy)
956
C->InlinePatternFragments(*this, Trees);
957
}
958
959
/// InferAllTypes - Infer/propagate as many types throughout the expression
960
/// patterns as possible. Return true if all types are inferred, false
961
/// otherwise. Bail out if a type contradiction is found.
962
bool InferAllTypes(
963
const StringMap<SmallVector<TreePatternNode *, 1>> *NamedTypes = nullptr);
964
965
/// error - If this is the first error in the current resolution step,
966
/// print it and set the error flag. Otherwise, continue silently.
967
void error(const Twine &Msg);
968
bool hasError() const { return HasError; }
969
void resetError() { HasError = false; }
970
971
TypeInfer &getInfer() { return Infer; }
972
973
void print(raw_ostream &OS) const;
974
void dump() const;
975
976
private:
977
TreePatternNodePtr ParseTreePattern(Init *DI, StringRef OpName);
978
void ComputeNamedNodes();
979
void ComputeNamedNodes(TreePatternNode &N);
980
};
981
982
inline bool TreePatternNode::UpdateNodeType(unsigned ResNo,
983
const TypeSetByHwMode &InTy,
984
TreePattern &TP) {
985
TypeSetByHwMode VTS(InTy);
986
TP.getInfer().expandOverloads(VTS);
987
return TP.getInfer().MergeInTypeInfo(Types[ResNo], VTS);
988
}
989
990
inline bool TreePatternNode::UpdateNodeType(unsigned ResNo,
991
MVT::SimpleValueType InTy,
992
TreePattern &TP) {
993
TypeSetByHwMode VTS(InTy);
994
TP.getInfer().expandOverloads(VTS);
995
return TP.getInfer().MergeInTypeInfo(Types[ResNo], VTS);
996
}
997
998
inline bool TreePatternNode::UpdateNodeType(unsigned ResNo,
999
ValueTypeByHwMode InTy,
1000
TreePattern &TP) {
1001
TypeSetByHwMode VTS(InTy);
1002
TP.getInfer().expandOverloads(VTS);
1003
return TP.getInfer().MergeInTypeInfo(Types[ResNo], VTS);
1004
}
1005
1006
/// DAGDefaultOperand - One of these is created for each OperandWithDefaultOps
1007
/// that has a set ExecuteAlways / DefaultOps field.
1008
struct DAGDefaultOperand {
1009
std::vector<TreePatternNodePtr> DefaultOps;
1010
};
1011
1012
class DAGInstruction {
1013
std::vector<Record *> Results;
1014
std::vector<Record *> Operands;
1015
std::vector<Record *> ImpResults;
1016
TreePatternNodePtr SrcPattern;
1017
TreePatternNodePtr ResultPattern;
1018
1019
public:
1020
DAGInstruction(std::vector<Record *> &&results,
1021
std::vector<Record *> &&operands,
1022
std::vector<Record *> &&impresults,
1023
TreePatternNodePtr srcpattern = nullptr,
1024
TreePatternNodePtr resultpattern = nullptr)
1025
: Results(std::move(results)), Operands(std::move(operands)),
1026
ImpResults(std::move(impresults)), SrcPattern(srcpattern),
1027
ResultPattern(resultpattern) {}
1028
1029
unsigned getNumResults() const { return Results.size(); }
1030
unsigned getNumOperands() const { return Operands.size(); }
1031
unsigned getNumImpResults() const { return ImpResults.size(); }
1032
const std::vector<Record *> &getImpResults() const { return ImpResults; }
1033
1034
Record *getResult(unsigned RN) const {
1035
assert(RN < Results.size());
1036
return Results[RN];
1037
}
1038
1039
Record *getOperand(unsigned ON) const {
1040
assert(ON < Operands.size());
1041
return Operands[ON];
1042
}
1043
1044
Record *getImpResult(unsigned RN) const {
1045
assert(RN < ImpResults.size());
1046
return ImpResults[RN];
1047
}
1048
1049
TreePatternNodePtr getSrcPattern() const { return SrcPattern; }
1050
TreePatternNodePtr getResultPattern() const { return ResultPattern; }
1051
};
1052
1053
/// PatternToMatch - Used by CodeGenDAGPatterns to keep tab of patterns
1054
/// processed to produce isel.
1055
class PatternToMatch {
1056
Record *SrcRecord; // Originating Record for the pattern.
1057
ListInit *Predicates; // Top level predicate conditions to match.
1058
TreePatternNodePtr SrcPattern; // Source pattern to match.
1059
TreePatternNodePtr DstPattern; // Resulting pattern.
1060
std::vector<Record *> Dstregs; // Physical register defs being matched.
1061
std::string HwModeFeatures;
1062
int AddedComplexity; // Add to matching pattern complexity.
1063
bool GISelShouldIgnore; // Should GlobalISel ignore importing this pattern.
1064
unsigned ID; // Unique ID for the record.
1065
1066
public:
1067
PatternToMatch(Record *srcrecord, ListInit *preds, TreePatternNodePtr src,
1068
TreePatternNodePtr dst, std::vector<Record *> dstregs,
1069
int complexity, unsigned uid, bool ignore,
1070
const Twine &hwmodefeatures = "")
1071
: SrcRecord(srcrecord), Predicates(preds), SrcPattern(src),
1072
DstPattern(dst), Dstregs(std::move(dstregs)),
1073
HwModeFeatures(hwmodefeatures.str()), AddedComplexity(complexity),
1074
GISelShouldIgnore(ignore), ID(uid) {}
1075
1076
Record *getSrcRecord() const { return SrcRecord; }
1077
ListInit *getPredicates() const { return Predicates; }
1078
TreePatternNode &getSrcPattern() const { return *SrcPattern; }
1079
TreePatternNodePtr getSrcPatternShared() const { return SrcPattern; }
1080
TreePatternNode &getDstPattern() const { return *DstPattern; }
1081
TreePatternNodePtr getDstPatternShared() const { return DstPattern; }
1082
const std::vector<Record *> &getDstRegs() const { return Dstregs; }
1083
StringRef getHwModeFeatures() const { return HwModeFeatures; }
1084
int getAddedComplexity() const { return AddedComplexity; }
1085
bool getGISelShouldIgnore() const { return GISelShouldIgnore; }
1086
unsigned getID() const { return ID; }
1087
1088
std::string getPredicateCheck() const;
1089
void getPredicateRecords(SmallVectorImpl<Record *> &PredicateRecs) const;
1090
1091
/// Compute the complexity metric for the input pattern. This roughly
1092
/// corresponds to the number of nodes that are covered.
1093
int getPatternComplexity(const CodeGenDAGPatterns &CGP) const;
1094
};
1095
1096
class CodeGenDAGPatterns {
1097
RecordKeeper &Records;
1098
CodeGenTarget Target;
1099
CodeGenIntrinsicTable Intrinsics;
1100
1101
std::map<Record *, SDNodeInfo, LessRecordByID> SDNodes;
1102
std::map<Record *, std::pair<Record *, std::string>, LessRecordByID>
1103
SDNodeXForms;
1104
std::map<Record *, ComplexPattern, LessRecordByID> ComplexPatterns;
1105
std::map<Record *, std::unique_ptr<TreePattern>, LessRecordByID>
1106
PatternFragments;
1107
std::map<Record *, DAGDefaultOperand, LessRecordByID> DefaultOperands;
1108
std::map<Record *, DAGInstruction, LessRecordByID> Instructions;
1109
1110
// Specific SDNode definitions:
1111
Record *intrinsic_void_sdnode;
1112
Record *intrinsic_w_chain_sdnode, *intrinsic_wo_chain_sdnode;
1113
1114
/// PatternsToMatch - All of the things we are matching on the DAG. The first
1115
/// value is the pattern to match, the second pattern is the result to
1116
/// emit.
1117
std::vector<PatternToMatch> PatternsToMatch;
1118
1119
TypeSetByHwMode LegalVTS;
1120
1121
using PatternRewriterFn = std::function<void(TreePattern *)>;
1122
PatternRewriterFn PatternRewriter;
1123
1124
unsigned NumScopes = 0;
1125
1126
public:
1127
CodeGenDAGPatterns(RecordKeeper &R,
1128
PatternRewriterFn PatternRewriter = nullptr);
1129
1130
CodeGenTarget &getTargetInfo() { return Target; }
1131
const CodeGenTarget &getTargetInfo() const { return Target; }
1132
const TypeSetByHwMode &getLegalTypes() const { return LegalVTS; }
1133
1134
Record *getSDNodeNamed(StringRef Name) const;
1135
1136
const SDNodeInfo &getSDNodeInfo(Record *R) const {
1137
auto F = SDNodes.find(R);
1138
assert(F != SDNodes.end() && "Unknown node!");
1139
return F->second;
1140
}
1141
1142
// Node transformation lookups.
1143
typedef std::pair<Record *, std::string> NodeXForm;
1144
const NodeXForm &getSDNodeTransform(Record *R) const {
1145
auto F = SDNodeXForms.find(R);
1146
assert(F != SDNodeXForms.end() && "Invalid transform!");
1147
return F->second;
1148
}
1149
1150
const ComplexPattern &getComplexPattern(Record *R) const {
1151
auto F = ComplexPatterns.find(R);
1152
assert(F != ComplexPatterns.end() && "Unknown addressing mode!");
1153
return F->second;
1154
}
1155
1156
const CodeGenIntrinsic &getIntrinsic(Record *R) const {
1157
for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
1158
if (Intrinsics[i].TheDef == R)
1159
return Intrinsics[i];
1160
llvm_unreachable("Unknown intrinsic!");
1161
}
1162
1163
const CodeGenIntrinsic &getIntrinsicInfo(unsigned IID) const {
1164
if (IID - 1 < Intrinsics.size())
1165
return Intrinsics[IID - 1];
1166
llvm_unreachable("Bad intrinsic ID!");
1167
}
1168
1169
unsigned getIntrinsicID(Record *R) const {
1170
for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
1171
if (Intrinsics[i].TheDef == R)
1172
return i;
1173
llvm_unreachable("Unknown intrinsic!");
1174
}
1175
1176
const DAGDefaultOperand &getDefaultOperand(Record *R) const {
1177
auto F = DefaultOperands.find(R);
1178
assert(F != DefaultOperands.end() && "Isn't an analyzed default operand!");
1179
return F->second;
1180
}
1181
1182
// Pattern Fragment information.
1183
TreePattern *getPatternFragment(Record *R) const {
1184
auto F = PatternFragments.find(R);
1185
assert(F != PatternFragments.end() && "Invalid pattern fragment request!");
1186
return F->second.get();
1187
}
1188
TreePattern *getPatternFragmentIfRead(Record *R) const {
1189
auto F = PatternFragments.find(R);
1190
if (F == PatternFragments.end())
1191
return nullptr;
1192
return F->second.get();
1193
}
1194
1195
typedef std::map<Record *, std::unique_ptr<TreePattern>,
1196
LessRecordByID>::const_iterator pf_iterator;
1197
pf_iterator pf_begin() const { return PatternFragments.begin(); }
1198
pf_iterator pf_end() const { return PatternFragments.end(); }
1199
iterator_range<pf_iterator> ptfs() const { return PatternFragments; }
1200
1201
// Patterns to match information.
1202
typedef std::vector<PatternToMatch>::const_iterator ptm_iterator;
1203
ptm_iterator ptm_begin() const { return PatternsToMatch.begin(); }
1204
ptm_iterator ptm_end() const { return PatternsToMatch.end(); }
1205
iterator_range<ptm_iterator> ptms() const { return PatternsToMatch; }
1206
1207
/// Parse the Pattern for an instruction, and insert the result in DAGInsts.
1208
typedef std::map<Record *, DAGInstruction, LessRecordByID> DAGInstMap;
1209
void parseInstructionPattern(CodeGenInstruction &CGI, ListInit *Pattern,
1210
DAGInstMap &DAGInsts);
1211
1212
const DAGInstruction &getInstruction(Record *R) const {
1213
auto F = Instructions.find(R);
1214
assert(F != Instructions.end() && "Unknown instruction!");
1215
return F->second;
1216
}
1217
1218
Record *get_intrinsic_void_sdnode() const { return intrinsic_void_sdnode; }
1219
Record *get_intrinsic_w_chain_sdnode() const {
1220
return intrinsic_w_chain_sdnode;
1221
}
1222
Record *get_intrinsic_wo_chain_sdnode() const {
1223
return intrinsic_wo_chain_sdnode;
1224
}
1225
1226
unsigned allocateScope() { return ++NumScopes; }
1227
1228
bool operandHasDefault(Record *Op) const {
1229
return Op->isSubClassOf("OperandWithDefaultOps") &&
1230
!getDefaultOperand(Op).DefaultOps.empty();
1231
}
1232
1233
private:
1234
void ParseNodeInfo();
1235
void ParseNodeTransforms();
1236
void ParseComplexPatterns();
1237
void ParsePatternFragments(bool OutFrags = false);
1238
void ParseDefaultOperands();
1239
void ParseInstructions();
1240
void ParsePatterns();
1241
void ExpandHwModeBasedTypes();
1242
void InferInstructionFlags();
1243
void GenerateVariants();
1244
void VerifyInstructionFlags();
1245
1246
void ParseOnePattern(Record *TheDef, TreePattern &Pattern,
1247
TreePattern &Result,
1248
const std::vector<Record *> &InstImpResults,
1249
bool ShouldIgnore = false);
1250
void AddPatternToMatch(TreePattern *Pattern, PatternToMatch &&PTM);
1251
void FindPatternInputsAndOutputs(
1252
TreePattern &I, TreePatternNodePtr Pat,
1253
std::map<std::string, TreePatternNodePtr> &InstInputs,
1254
MapVector<std::string, TreePatternNodePtr,
1255
std::map<std::string, unsigned>> &InstResults,
1256
std::vector<Record *> &InstImpResults);
1257
};
1258
1259
inline bool SDNodeInfo::ApplyTypeConstraints(TreePatternNode &N,
1260
TreePattern &TP) const {
1261
bool MadeChange = false;
1262
for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i)
1263
MadeChange |= TypeConstraints[i].ApplyTypeConstraint(N, *this, TP);
1264
return MadeChange;
1265
}
1266
1267
} // end namespace llvm
1268
1269
#endif
1270
1271