xref: /minix3/external/bsd/llvm/dist/llvm/utils/TableGen/CodeGenDAGPatterns.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===- CodeGenDAGPatterns.h - Read DAG patterns from .td file ---*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file declares the CodeGenDAGPatterns class, which is used to read and
11f4a2713aSLionel Sambuc // represent the patterns present in a .td file for instructions.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc 
15*0a6a1f1dSLionel Sambuc #ifndef LLVM_UTILS_TABLEGEN_CODEGENDAGPATTERNS_H
16*0a6a1f1dSLionel Sambuc #define LLVM_UTILS_TABLEGEN_CODEGENDAGPATTERNS_H
17f4a2713aSLionel Sambuc 
18f4a2713aSLionel Sambuc #include "CodeGenIntrinsics.h"
19f4a2713aSLionel Sambuc #include "CodeGenTarget.h"
20f4a2713aSLionel Sambuc #include "llvm/ADT/SmallVector.h"
21f4a2713aSLionel Sambuc #include "llvm/ADT/StringMap.h"
22f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
23f4a2713aSLionel Sambuc #include <algorithm>
24f4a2713aSLionel Sambuc #include <map>
25f4a2713aSLionel Sambuc #include <set>
26f4a2713aSLionel Sambuc #include <vector>
27f4a2713aSLionel Sambuc 
28f4a2713aSLionel Sambuc namespace llvm {
29f4a2713aSLionel Sambuc   class Record;
30f4a2713aSLionel Sambuc   class Init;
31f4a2713aSLionel Sambuc   class ListInit;
32f4a2713aSLionel Sambuc   class DagInit;
33f4a2713aSLionel Sambuc   class SDNodeInfo;
34f4a2713aSLionel Sambuc   class TreePattern;
35f4a2713aSLionel Sambuc   class TreePatternNode;
36f4a2713aSLionel Sambuc   class CodeGenDAGPatterns;
37f4a2713aSLionel Sambuc   class ComplexPattern;
38f4a2713aSLionel Sambuc 
39f4a2713aSLionel Sambuc /// EEVT::DAGISelGenValueType - These are some extended forms of
40f4a2713aSLionel Sambuc /// MVT::SimpleValueType that we use as lattice values during type inference.
41f4a2713aSLionel Sambuc /// The existing MVT iAny, fAny and vAny types suffice to represent
42f4a2713aSLionel Sambuc /// arbitrary integer, floating-point, and vector types, so only an unknown
43f4a2713aSLionel Sambuc /// value is needed.
44f4a2713aSLionel Sambuc namespace EEVT {
45f4a2713aSLionel Sambuc   /// TypeSet - This is either empty if it's completely unknown, or holds a set
46f4a2713aSLionel Sambuc   /// of types.  It is used during type inference because register classes can
47f4a2713aSLionel Sambuc   /// have multiple possible types and we don't know which one they get until
48f4a2713aSLionel Sambuc   /// type inference is complete.
49f4a2713aSLionel Sambuc   ///
50f4a2713aSLionel Sambuc   /// TypeSet can have three states:
51f4a2713aSLionel Sambuc   ///    Vector is empty: The type is completely unknown, it can be any valid
52f4a2713aSLionel Sambuc   ///       target type.
53f4a2713aSLionel Sambuc   ///    Vector has multiple constrained types: (e.g. v4i32 + v4f32) it is one
54f4a2713aSLionel Sambuc   ///       of those types only.
55f4a2713aSLionel Sambuc   ///    Vector has one concrete type: The type is completely known.
56f4a2713aSLionel Sambuc   ///
57f4a2713aSLionel Sambuc   class TypeSet {
58f4a2713aSLionel Sambuc     SmallVector<MVT::SimpleValueType, 4> TypeVec;
59f4a2713aSLionel Sambuc   public:
TypeSet()60f4a2713aSLionel Sambuc     TypeSet() {}
61f4a2713aSLionel Sambuc     TypeSet(MVT::SimpleValueType VT, TreePattern &TP);
62f4a2713aSLionel Sambuc     TypeSet(ArrayRef<MVT::SimpleValueType> VTList);
63f4a2713aSLionel Sambuc 
isCompletelyUnknown()64f4a2713aSLionel Sambuc     bool isCompletelyUnknown() const { return TypeVec.empty(); }
65f4a2713aSLionel Sambuc 
isConcrete()66f4a2713aSLionel Sambuc     bool isConcrete() const {
67f4a2713aSLionel Sambuc       if (TypeVec.size() != 1) return false;
68f4a2713aSLionel Sambuc       unsigned char T = TypeVec[0]; (void)T;
69f4a2713aSLionel Sambuc       assert(T < MVT::LAST_VALUETYPE || T == MVT::iPTR || T == MVT::iPTRAny);
70f4a2713aSLionel Sambuc       return true;
71f4a2713aSLionel Sambuc     }
72f4a2713aSLionel Sambuc 
getConcrete()73f4a2713aSLionel Sambuc     MVT::SimpleValueType getConcrete() const {
74f4a2713aSLionel Sambuc       assert(isConcrete() && "Type isn't concrete yet");
75f4a2713aSLionel Sambuc       return (MVT::SimpleValueType)TypeVec[0];
76f4a2713aSLionel Sambuc     }
77f4a2713aSLionel Sambuc 
isDynamicallyResolved()78f4a2713aSLionel Sambuc     bool isDynamicallyResolved() const {
79f4a2713aSLionel Sambuc       return getConcrete() == MVT::iPTR || getConcrete() == MVT::iPTRAny;
80f4a2713aSLionel Sambuc     }
81f4a2713aSLionel Sambuc 
getTypeList()82f4a2713aSLionel Sambuc     const SmallVectorImpl<MVT::SimpleValueType> &getTypeList() const {
83f4a2713aSLionel Sambuc       assert(!TypeVec.empty() && "Not a type list!");
84f4a2713aSLionel Sambuc       return TypeVec;
85f4a2713aSLionel Sambuc     }
86f4a2713aSLionel Sambuc 
isVoid()87f4a2713aSLionel Sambuc     bool isVoid() const {
88f4a2713aSLionel Sambuc       return TypeVec.size() == 1 && TypeVec[0] == MVT::isVoid;
89f4a2713aSLionel Sambuc     }
90f4a2713aSLionel Sambuc 
91f4a2713aSLionel Sambuc     /// hasIntegerTypes - Return true if this TypeSet contains any integer value
92f4a2713aSLionel Sambuc     /// types.
93f4a2713aSLionel Sambuc     bool hasIntegerTypes() const;
94f4a2713aSLionel Sambuc 
95f4a2713aSLionel Sambuc     /// hasFloatingPointTypes - Return true if this TypeSet contains an fAny or
96f4a2713aSLionel Sambuc     /// a floating point value type.
97f4a2713aSLionel Sambuc     bool hasFloatingPointTypes() const;
98f4a2713aSLionel Sambuc 
99*0a6a1f1dSLionel Sambuc     /// hasScalarTypes - Return true if this TypeSet contains a scalar value
100*0a6a1f1dSLionel Sambuc     /// type.
101*0a6a1f1dSLionel Sambuc     bool hasScalarTypes() const;
102*0a6a1f1dSLionel Sambuc 
103f4a2713aSLionel Sambuc     /// hasVectorTypes - Return true if this TypeSet contains a vector value
104f4a2713aSLionel Sambuc     /// type.
105f4a2713aSLionel Sambuc     bool hasVectorTypes() const;
106f4a2713aSLionel Sambuc 
107f4a2713aSLionel Sambuc     /// getName() - Return this TypeSet as a string.
108f4a2713aSLionel Sambuc     std::string getName() const;
109f4a2713aSLionel Sambuc 
110f4a2713aSLionel Sambuc     /// MergeInTypeInfo - This merges in type information from the specified
111f4a2713aSLionel Sambuc     /// argument.  If 'this' changes, it returns true.  If the two types are
112f4a2713aSLionel Sambuc     /// contradictory (e.g. merge f32 into i32) then this flags an error.
113f4a2713aSLionel Sambuc     bool MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP);
114f4a2713aSLionel Sambuc 
MergeInTypeInfo(MVT::SimpleValueType InVT,TreePattern & TP)115f4a2713aSLionel Sambuc     bool MergeInTypeInfo(MVT::SimpleValueType InVT, TreePattern &TP) {
116f4a2713aSLionel Sambuc       return MergeInTypeInfo(EEVT::TypeSet(InVT, TP), TP);
117f4a2713aSLionel Sambuc     }
118f4a2713aSLionel Sambuc 
119f4a2713aSLionel Sambuc     /// Force this type list to only contain integer types.
120f4a2713aSLionel Sambuc     bool EnforceInteger(TreePattern &TP);
121f4a2713aSLionel Sambuc 
122f4a2713aSLionel Sambuc     /// Force this type list to only contain floating point types.
123f4a2713aSLionel Sambuc     bool EnforceFloatingPoint(TreePattern &TP);
124f4a2713aSLionel Sambuc 
125f4a2713aSLionel Sambuc     /// EnforceScalar - Remove all vector types from this type list.
126f4a2713aSLionel Sambuc     bool EnforceScalar(TreePattern &TP);
127f4a2713aSLionel Sambuc 
128f4a2713aSLionel Sambuc     /// EnforceVector - Remove all non-vector types from this type list.
129f4a2713aSLionel Sambuc     bool EnforceVector(TreePattern &TP);
130f4a2713aSLionel Sambuc 
131f4a2713aSLionel Sambuc     /// EnforceSmallerThan - 'this' must be a smaller VT than Other.  Update
132f4a2713aSLionel Sambuc     /// this an other based on this information.
133f4a2713aSLionel Sambuc     bool EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP);
134f4a2713aSLionel Sambuc 
135f4a2713aSLionel Sambuc     /// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type
136f4a2713aSLionel Sambuc     /// whose element is VT.
137f4a2713aSLionel Sambuc     bool EnforceVectorEltTypeIs(EEVT::TypeSet &VT, TreePattern &TP);
138f4a2713aSLionel Sambuc 
139f4a2713aSLionel Sambuc     /// EnforceVectorSubVectorTypeIs - 'this' is now constrainted to
140f4a2713aSLionel Sambuc     /// be a vector type VT.
141f4a2713aSLionel Sambuc     bool EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VT, TreePattern &TP);
142f4a2713aSLionel Sambuc 
143f4a2713aSLionel Sambuc     bool operator!=(const TypeSet &RHS) const { return TypeVec != RHS.TypeVec; }
144f4a2713aSLionel Sambuc     bool operator==(const TypeSet &RHS) const { return TypeVec == RHS.TypeVec; }
145f4a2713aSLionel Sambuc 
146f4a2713aSLionel Sambuc   private:
147f4a2713aSLionel Sambuc     /// FillWithPossibleTypes - Set to all legal types and return true, only
148f4a2713aSLionel Sambuc     /// valid on completely unknown type sets.  If Pred is non-null, only MVTs
149f4a2713aSLionel Sambuc     /// that pass the predicate are added.
150f4a2713aSLionel Sambuc     bool FillWithPossibleTypes(TreePattern &TP,
151*0a6a1f1dSLionel Sambuc                                bool (*Pred)(MVT::SimpleValueType) = nullptr,
152*0a6a1f1dSLionel Sambuc                                const char *PredicateName = nullptr);
153f4a2713aSLionel Sambuc   };
154f4a2713aSLionel Sambuc }
155f4a2713aSLionel Sambuc 
156f4a2713aSLionel Sambuc /// Set type used to track multiply used variables in patterns
157f4a2713aSLionel Sambuc typedef std::set<std::string> MultipleUseVarSet;
158f4a2713aSLionel Sambuc 
159f4a2713aSLionel Sambuc /// SDTypeConstraint - This is a discriminated union of constraints,
160f4a2713aSLionel Sambuc /// corresponding to the SDTypeConstraint tablegen class in Target.td.
161f4a2713aSLionel Sambuc struct SDTypeConstraint {
162f4a2713aSLionel Sambuc   SDTypeConstraint(Record *R);
163f4a2713aSLionel Sambuc 
164f4a2713aSLionel Sambuc   unsigned OperandNo;   // The operand # this constraint applies to.
165f4a2713aSLionel Sambuc   enum {
166f4a2713aSLionel Sambuc     SDTCisVT, SDTCisPtrTy, SDTCisInt, SDTCisFP, SDTCisVec, SDTCisSameAs,
167f4a2713aSLionel Sambuc     SDTCisVTSmallerThanOp, SDTCisOpSmallerThanOp, SDTCisEltOfVec,
168f4a2713aSLionel Sambuc     SDTCisSubVecOfVec
169f4a2713aSLionel Sambuc   } ConstraintType;
170f4a2713aSLionel Sambuc 
171f4a2713aSLionel Sambuc   union {   // The discriminated union.
172f4a2713aSLionel Sambuc     struct {
173f4a2713aSLionel Sambuc       MVT::SimpleValueType VT;
174f4a2713aSLionel Sambuc     } SDTCisVT_Info;
175f4a2713aSLionel Sambuc     struct {
176f4a2713aSLionel Sambuc       unsigned OtherOperandNum;
177f4a2713aSLionel Sambuc     } SDTCisSameAs_Info;
178f4a2713aSLionel Sambuc     struct {
179f4a2713aSLionel Sambuc       unsigned OtherOperandNum;
180f4a2713aSLionel Sambuc     } SDTCisVTSmallerThanOp_Info;
181f4a2713aSLionel Sambuc     struct {
182f4a2713aSLionel Sambuc       unsigned BigOperandNum;
183f4a2713aSLionel Sambuc     } SDTCisOpSmallerThanOp_Info;
184f4a2713aSLionel Sambuc     struct {
185f4a2713aSLionel Sambuc       unsigned OtherOperandNum;
186f4a2713aSLionel Sambuc     } SDTCisEltOfVec_Info;
187f4a2713aSLionel Sambuc     struct {
188f4a2713aSLionel Sambuc       unsigned OtherOperandNum;
189f4a2713aSLionel Sambuc     } SDTCisSubVecOfVec_Info;
190f4a2713aSLionel Sambuc   } x;
191f4a2713aSLionel Sambuc 
192f4a2713aSLionel Sambuc   /// ApplyTypeConstraint - Given a node in a pattern, apply this type
193f4a2713aSLionel Sambuc   /// constraint to the nodes operands.  This returns true if it makes a
194f4a2713aSLionel Sambuc   /// change, false otherwise.  If a type contradiction is found, an error
195f4a2713aSLionel Sambuc   /// is flagged.
196f4a2713aSLionel Sambuc   bool ApplyTypeConstraint(TreePatternNode *N, const SDNodeInfo &NodeInfo,
197f4a2713aSLionel Sambuc                            TreePattern &TP) const;
198f4a2713aSLionel Sambuc };
199f4a2713aSLionel Sambuc 
200f4a2713aSLionel Sambuc /// SDNodeInfo - One of these records is created for each SDNode instance in
201f4a2713aSLionel Sambuc /// the target .td file.  This represents the various dag nodes we will be
202f4a2713aSLionel Sambuc /// processing.
203f4a2713aSLionel Sambuc class SDNodeInfo {
204f4a2713aSLionel Sambuc   Record *Def;
205f4a2713aSLionel Sambuc   std::string EnumName;
206f4a2713aSLionel Sambuc   std::string SDClassName;
207f4a2713aSLionel Sambuc   unsigned Properties;
208f4a2713aSLionel Sambuc   unsigned NumResults;
209f4a2713aSLionel Sambuc   int NumOperands;
210f4a2713aSLionel Sambuc   std::vector<SDTypeConstraint> TypeConstraints;
211f4a2713aSLionel Sambuc public:
212f4a2713aSLionel Sambuc   SDNodeInfo(Record *R);  // Parse the specified record.
213f4a2713aSLionel Sambuc 
getNumResults()214f4a2713aSLionel Sambuc   unsigned getNumResults() const { return NumResults; }
215f4a2713aSLionel Sambuc 
216f4a2713aSLionel Sambuc   /// getNumOperands - This is the number of operands required or -1 if
217f4a2713aSLionel Sambuc   /// variadic.
getNumOperands()218f4a2713aSLionel Sambuc   int getNumOperands() const { return NumOperands; }
getRecord()219f4a2713aSLionel Sambuc   Record *getRecord() const { return Def; }
getEnumName()220f4a2713aSLionel Sambuc   const std::string &getEnumName() const { return EnumName; }
getSDClassName()221f4a2713aSLionel Sambuc   const std::string &getSDClassName() const { return SDClassName; }
222f4a2713aSLionel Sambuc 
getTypeConstraints()223f4a2713aSLionel Sambuc   const std::vector<SDTypeConstraint> &getTypeConstraints() const {
224f4a2713aSLionel Sambuc     return TypeConstraints;
225f4a2713aSLionel Sambuc   }
226f4a2713aSLionel Sambuc 
227f4a2713aSLionel Sambuc   /// getKnownType - If the type constraints on this node imply a fixed type
228f4a2713aSLionel Sambuc   /// (e.g. all stores return void, etc), then return it as an
229f4a2713aSLionel Sambuc   /// MVT::SimpleValueType.  Otherwise, return MVT::Other.
230f4a2713aSLionel Sambuc   MVT::SimpleValueType getKnownType(unsigned ResNo) const;
231f4a2713aSLionel Sambuc 
232f4a2713aSLionel Sambuc   /// hasProperty - Return true if this node has the specified property.
233f4a2713aSLionel Sambuc   ///
hasProperty(enum SDNP Prop)234f4a2713aSLionel Sambuc   bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
235f4a2713aSLionel Sambuc 
236f4a2713aSLionel Sambuc   /// ApplyTypeConstraints - Given a node in a pattern, apply the type
237f4a2713aSLionel Sambuc   /// constraints for this node to the operands of the node.  This returns
238f4a2713aSLionel Sambuc   /// true if it makes a change, false otherwise.  If a type contradiction is
239f4a2713aSLionel Sambuc   /// found, an error is flagged.
ApplyTypeConstraints(TreePatternNode * N,TreePattern & TP)240f4a2713aSLionel Sambuc   bool ApplyTypeConstraints(TreePatternNode *N, TreePattern &TP) const {
241f4a2713aSLionel Sambuc     bool MadeChange = false;
242f4a2713aSLionel Sambuc     for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i)
243f4a2713aSLionel Sambuc       MadeChange |= TypeConstraints[i].ApplyTypeConstraint(N, *this, TP);
244f4a2713aSLionel Sambuc     return MadeChange;
245f4a2713aSLionel Sambuc   }
246f4a2713aSLionel Sambuc };
247f4a2713aSLionel Sambuc 
248f4a2713aSLionel Sambuc /// TreePredicateFn - This is an abstraction that represents the predicates on
249f4a2713aSLionel Sambuc /// a PatFrag node.  This is a simple one-word wrapper around a pointer to
250f4a2713aSLionel Sambuc /// provide nice accessors.
251f4a2713aSLionel Sambuc class TreePredicateFn {
252f4a2713aSLionel Sambuc   /// PatFragRec - This is the TreePattern for the PatFrag that we
253f4a2713aSLionel Sambuc   /// originally came from.
254f4a2713aSLionel Sambuc   TreePattern *PatFragRec;
255f4a2713aSLionel Sambuc public:
256f4a2713aSLionel Sambuc   /// TreePredicateFn constructor.  Here 'N' is a subclass of PatFrag.
257f4a2713aSLionel Sambuc   TreePredicateFn(TreePattern *N);
258f4a2713aSLionel Sambuc 
259f4a2713aSLionel Sambuc 
getOrigPatFragRecord()260f4a2713aSLionel Sambuc   TreePattern *getOrigPatFragRecord() const { return PatFragRec; }
261f4a2713aSLionel Sambuc 
262f4a2713aSLionel Sambuc   /// isAlwaysTrue - Return true if this is a noop predicate.
263f4a2713aSLionel Sambuc   bool isAlwaysTrue() const;
264f4a2713aSLionel Sambuc 
isImmediatePattern()265f4a2713aSLionel Sambuc   bool isImmediatePattern() const { return !getImmCode().empty(); }
266f4a2713aSLionel Sambuc 
267f4a2713aSLionel Sambuc   /// getImmediatePredicateCode - Return the code that evaluates this pattern if
268f4a2713aSLionel Sambuc   /// this is an immediate predicate.  It is an error to call this on a
269f4a2713aSLionel Sambuc   /// non-immediate pattern.
getImmediatePredicateCode()270f4a2713aSLionel Sambuc   std::string getImmediatePredicateCode() const {
271f4a2713aSLionel Sambuc     std::string Result = getImmCode();
272f4a2713aSLionel Sambuc     assert(!Result.empty() && "Isn't an immediate pattern!");
273f4a2713aSLionel Sambuc     return Result;
274f4a2713aSLionel Sambuc   }
275f4a2713aSLionel Sambuc 
276f4a2713aSLionel Sambuc 
277f4a2713aSLionel Sambuc   bool operator==(const TreePredicateFn &RHS) const {
278f4a2713aSLionel Sambuc     return PatFragRec == RHS.PatFragRec;
279f4a2713aSLionel Sambuc   }
280f4a2713aSLionel Sambuc 
281f4a2713aSLionel Sambuc   bool operator!=(const TreePredicateFn &RHS) const { return !(*this == RHS); }
282f4a2713aSLionel Sambuc 
283f4a2713aSLionel Sambuc   /// Return the name to use in the generated code to reference this, this is
284f4a2713aSLionel Sambuc   /// "Predicate_foo" if from a pattern fragment "foo".
285f4a2713aSLionel Sambuc   std::string getFnName() const;
286f4a2713aSLionel Sambuc 
287f4a2713aSLionel Sambuc   /// getCodeToRunOnSDNode - Return the code for the function body that
288f4a2713aSLionel Sambuc   /// evaluates this predicate.  The argument is expected to be in "Node",
289f4a2713aSLionel Sambuc   /// not N.  This handles casting and conversion to a concrete node type as
290f4a2713aSLionel Sambuc   /// appropriate.
291f4a2713aSLionel Sambuc   std::string getCodeToRunOnSDNode() const;
292f4a2713aSLionel Sambuc 
293f4a2713aSLionel Sambuc private:
294f4a2713aSLionel Sambuc   std::string getPredCode() const;
295f4a2713aSLionel Sambuc   std::string getImmCode() const;
296f4a2713aSLionel Sambuc };
297f4a2713aSLionel Sambuc 
298f4a2713aSLionel Sambuc 
299f4a2713aSLionel Sambuc /// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped
300f4a2713aSLionel Sambuc /// patterns), and as such should be ref counted.  We currently just leak all
301f4a2713aSLionel Sambuc /// TreePatternNode objects!
302f4a2713aSLionel Sambuc class TreePatternNode {
303f4a2713aSLionel Sambuc   /// The type of each node result.  Before and during type inference, each
304f4a2713aSLionel Sambuc   /// result may be a set of possible types.  After (successful) type inference,
305f4a2713aSLionel Sambuc   /// each is a single concrete type.
306f4a2713aSLionel Sambuc   SmallVector<EEVT::TypeSet, 1> Types;
307f4a2713aSLionel Sambuc 
308f4a2713aSLionel Sambuc   /// Operator - The Record for the operator if this is an interior node (not
309f4a2713aSLionel Sambuc   /// a leaf).
310f4a2713aSLionel Sambuc   Record *Operator;
311f4a2713aSLionel Sambuc 
312f4a2713aSLionel Sambuc   /// Val - The init value (e.g. the "GPRC" record, or "7") for a leaf.
313f4a2713aSLionel Sambuc   ///
314f4a2713aSLionel Sambuc   Init *Val;
315f4a2713aSLionel Sambuc 
316f4a2713aSLionel Sambuc   /// Name - The name given to this node with the :$foo notation.
317f4a2713aSLionel Sambuc   ///
318f4a2713aSLionel Sambuc   std::string Name;
319f4a2713aSLionel Sambuc 
320f4a2713aSLionel Sambuc   /// PredicateFns - The predicate functions to execute on this node to check
321f4a2713aSLionel Sambuc   /// for a match.  If this list is empty, no predicate is involved.
322f4a2713aSLionel Sambuc   std::vector<TreePredicateFn> PredicateFns;
323f4a2713aSLionel Sambuc 
324f4a2713aSLionel Sambuc   /// TransformFn - The transformation function to execute on this node before
325f4a2713aSLionel Sambuc   /// it can be substituted into the resulting instruction on a pattern match.
326f4a2713aSLionel Sambuc   Record *TransformFn;
327f4a2713aSLionel Sambuc 
328f4a2713aSLionel Sambuc   std::vector<TreePatternNode*> Children;
329f4a2713aSLionel Sambuc public:
TreePatternNode(Record * Op,const std::vector<TreePatternNode * > & Ch,unsigned NumResults)330f4a2713aSLionel Sambuc   TreePatternNode(Record *Op, const std::vector<TreePatternNode*> &Ch,
331f4a2713aSLionel Sambuc                   unsigned NumResults)
332*0a6a1f1dSLionel Sambuc     : Operator(Op), Val(nullptr), TransformFn(nullptr), Children(Ch) {
333f4a2713aSLionel Sambuc     Types.resize(NumResults);
334f4a2713aSLionel Sambuc   }
TreePatternNode(Init * val,unsigned NumResults)335f4a2713aSLionel Sambuc   TreePatternNode(Init *val, unsigned NumResults)    // leaf ctor
336*0a6a1f1dSLionel Sambuc     : Operator(nullptr), Val(val), TransformFn(nullptr) {
337f4a2713aSLionel Sambuc     Types.resize(NumResults);
338f4a2713aSLionel Sambuc   }
339f4a2713aSLionel Sambuc   ~TreePatternNode();
340f4a2713aSLionel Sambuc 
hasName()341f4a2713aSLionel Sambuc   bool hasName() const { return !Name.empty(); }
getName()342f4a2713aSLionel Sambuc   const std::string &getName() const { return Name; }
setName(StringRef N)343f4a2713aSLionel Sambuc   void setName(StringRef N) { Name.assign(N.begin(), N.end()); }
344f4a2713aSLionel Sambuc 
isLeaf()345*0a6a1f1dSLionel Sambuc   bool isLeaf() const { return Val != nullptr; }
346f4a2713aSLionel Sambuc 
347f4a2713aSLionel Sambuc   // Type accessors.
getNumTypes()348f4a2713aSLionel Sambuc   unsigned getNumTypes() const { return Types.size(); }
getType(unsigned ResNo)349f4a2713aSLionel Sambuc   MVT::SimpleValueType getType(unsigned ResNo) const {
350f4a2713aSLionel Sambuc     return Types[ResNo].getConcrete();
351f4a2713aSLionel Sambuc   }
getExtTypes()352f4a2713aSLionel Sambuc   const SmallVectorImpl<EEVT::TypeSet> &getExtTypes() const { return Types; }
getExtType(unsigned ResNo)353f4a2713aSLionel Sambuc   const EEVT::TypeSet &getExtType(unsigned ResNo) const { return Types[ResNo]; }
getExtType(unsigned ResNo)354f4a2713aSLionel Sambuc   EEVT::TypeSet &getExtType(unsigned ResNo) { return Types[ResNo]; }
setType(unsigned ResNo,const EEVT::TypeSet & T)355f4a2713aSLionel Sambuc   void setType(unsigned ResNo, const EEVT::TypeSet &T) { Types[ResNo] = T; }
356f4a2713aSLionel Sambuc 
hasTypeSet(unsigned ResNo)357f4a2713aSLionel Sambuc   bool hasTypeSet(unsigned ResNo) const {
358f4a2713aSLionel Sambuc     return Types[ResNo].isConcrete();
359f4a2713aSLionel Sambuc   }
isTypeCompletelyUnknown(unsigned ResNo)360f4a2713aSLionel Sambuc   bool isTypeCompletelyUnknown(unsigned ResNo) const {
361f4a2713aSLionel Sambuc     return Types[ResNo].isCompletelyUnknown();
362f4a2713aSLionel Sambuc   }
isTypeDynamicallyResolved(unsigned ResNo)363f4a2713aSLionel Sambuc   bool isTypeDynamicallyResolved(unsigned ResNo) const {
364f4a2713aSLionel Sambuc     return Types[ResNo].isDynamicallyResolved();
365f4a2713aSLionel Sambuc   }
366f4a2713aSLionel Sambuc 
getLeafValue()367f4a2713aSLionel Sambuc   Init *getLeafValue() const { assert(isLeaf()); return Val; }
getOperator()368f4a2713aSLionel Sambuc   Record *getOperator() const { assert(!isLeaf()); return Operator; }
369f4a2713aSLionel Sambuc 
getNumChildren()370f4a2713aSLionel Sambuc   unsigned getNumChildren() const { return Children.size(); }
getChild(unsigned N)371f4a2713aSLionel Sambuc   TreePatternNode *getChild(unsigned N) const { return Children[N]; }
setChild(unsigned i,TreePatternNode * N)372f4a2713aSLionel Sambuc   void setChild(unsigned i, TreePatternNode *N) {
373f4a2713aSLionel Sambuc     Children[i] = N;
374f4a2713aSLionel Sambuc   }
375f4a2713aSLionel Sambuc 
376f4a2713aSLionel Sambuc   /// hasChild - Return true if N is any of our children.
hasChild(const TreePatternNode * N)377f4a2713aSLionel Sambuc   bool hasChild(const TreePatternNode *N) const {
378f4a2713aSLionel Sambuc     for (unsigned i = 0, e = Children.size(); i != e; ++i)
379f4a2713aSLionel Sambuc       if (Children[i] == N) return true;
380f4a2713aSLionel Sambuc     return false;
381f4a2713aSLionel Sambuc   }
382f4a2713aSLionel Sambuc 
hasAnyPredicate()383f4a2713aSLionel Sambuc   bool hasAnyPredicate() const { return !PredicateFns.empty(); }
384f4a2713aSLionel Sambuc 
getPredicateFns()385f4a2713aSLionel Sambuc   const std::vector<TreePredicateFn> &getPredicateFns() const {
386f4a2713aSLionel Sambuc     return PredicateFns;
387f4a2713aSLionel Sambuc   }
clearPredicateFns()388f4a2713aSLionel Sambuc   void clearPredicateFns() { PredicateFns.clear(); }
setPredicateFns(const std::vector<TreePredicateFn> & Fns)389f4a2713aSLionel Sambuc   void setPredicateFns(const std::vector<TreePredicateFn> &Fns) {
390f4a2713aSLionel Sambuc     assert(PredicateFns.empty() && "Overwriting non-empty predicate list!");
391f4a2713aSLionel Sambuc     PredicateFns = Fns;
392f4a2713aSLionel Sambuc   }
addPredicateFn(const TreePredicateFn & Fn)393f4a2713aSLionel Sambuc   void addPredicateFn(const TreePredicateFn &Fn) {
394f4a2713aSLionel Sambuc     assert(!Fn.isAlwaysTrue() && "Empty predicate string!");
395f4a2713aSLionel Sambuc     if (std::find(PredicateFns.begin(), PredicateFns.end(), Fn) ==
396f4a2713aSLionel Sambuc           PredicateFns.end())
397f4a2713aSLionel Sambuc       PredicateFns.push_back(Fn);
398f4a2713aSLionel Sambuc   }
399f4a2713aSLionel Sambuc 
getTransformFn()400f4a2713aSLionel Sambuc   Record *getTransformFn() const { return TransformFn; }
setTransformFn(Record * Fn)401f4a2713aSLionel Sambuc   void setTransformFn(Record *Fn) { TransformFn = Fn; }
402f4a2713aSLionel Sambuc 
403f4a2713aSLionel Sambuc   /// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
404f4a2713aSLionel Sambuc   /// CodeGenIntrinsic information for it, otherwise return a null pointer.
405f4a2713aSLionel Sambuc   const CodeGenIntrinsic *getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const;
406f4a2713aSLionel Sambuc 
407f4a2713aSLionel Sambuc   /// getComplexPatternInfo - If this node corresponds to a ComplexPattern,
408f4a2713aSLionel Sambuc   /// return the ComplexPattern information, otherwise return null.
409f4a2713aSLionel Sambuc   const ComplexPattern *
410f4a2713aSLionel Sambuc   getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const;
411f4a2713aSLionel Sambuc 
412*0a6a1f1dSLionel Sambuc   /// Returns the number of MachineInstr operands that would be produced by this
413*0a6a1f1dSLionel Sambuc   /// node if it mapped directly to an output Instruction's
414*0a6a1f1dSLionel Sambuc   /// operand. ComplexPattern specifies this explicitly; MIOperandInfo gives it
415*0a6a1f1dSLionel Sambuc   /// for Operands; otherwise 1.
416*0a6a1f1dSLionel Sambuc   unsigned getNumMIResults(const CodeGenDAGPatterns &CGP) const;
417*0a6a1f1dSLionel Sambuc 
418f4a2713aSLionel Sambuc   /// NodeHasProperty - Return true if this node has the specified property.
419f4a2713aSLionel Sambuc   bool NodeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
420f4a2713aSLionel Sambuc 
421f4a2713aSLionel Sambuc   /// TreeHasProperty - Return true if any node in this tree has the specified
422f4a2713aSLionel Sambuc   /// property.
423f4a2713aSLionel Sambuc   bool TreeHasProperty(SDNP Property, const CodeGenDAGPatterns &CGP) const;
424f4a2713aSLionel Sambuc 
425f4a2713aSLionel Sambuc   /// isCommutativeIntrinsic - Return true if the node is an intrinsic which is
426f4a2713aSLionel Sambuc   /// marked isCommutative.
427f4a2713aSLionel Sambuc   bool isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const;
428f4a2713aSLionel Sambuc 
429f4a2713aSLionel Sambuc   void print(raw_ostream &OS) const;
430f4a2713aSLionel Sambuc   void dump() const;
431f4a2713aSLionel Sambuc 
432f4a2713aSLionel Sambuc public:   // Higher level manipulation routines.
433f4a2713aSLionel Sambuc 
434f4a2713aSLionel Sambuc   /// clone - Return a new copy of this tree.
435f4a2713aSLionel Sambuc   ///
436f4a2713aSLionel Sambuc   TreePatternNode *clone() const;
437f4a2713aSLionel Sambuc 
438f4a2713aSLionel Sambuc   /// RemoveAllTypes - Recursively strip all the types of this tree.
439f4a2713aSLionel Sambuc   void RemoveAllTypes();
440f4a2713aSLionel Sambuc 
441f4a2713aSLionel Sambuc   /// isIsomorphicTo - Return true if this node is recursively isomorphic to
442f4a2713aSLionel Sambuc   /// the specified node.  For this comparison, all of the state of the node
443f4a2713aSLionel Sambuc   /// is considered, except for the assigned name.  Nodes with differing names
444f4a2713aSLionel Sambuc   /// that are otherwise identical are considered isomorphic.
445f4a2713aSLionel Sambuc   bool isIsomorphicTo(const TreePatternNode *N,
446f4a2713aSLionel Sambuc                       const MultipleUseVarSet &DepVars) const;
447f4a2713aSLionel Sambuc 
448f4a2713aSLionel Sambuc   /// SubstituteFormalArguments - Replace the formal arguments in this tree
449f4a2713aSLionel Sambuc   /// with actual values specified by ArgMap.
450f4a2713aSLionel Sambuc   void SubstituteFormalArguments(std::map<std::string,
451f4a2713aSLionel Sambuc                                           TreePatternNode*> &ArgMap);
452f4a2713aSLionel Sambuc 
453f4a2713aSLionel Sambuc   /// InlinePatternFragments - If this pattern refers to any pattern
454f4a2713aSLionel Sambuc   /// fragments, inline them into place, giving us a pattern without any
455f4a2713aSLionel Sambuc   /// PatFrag references.
456f4a2713aSLionel Sambuc   TreePatternNode *InlinePatternFragments(TreePattern &TP);
457f4a2713aSLionel Sambuc 
458f4a2713aSLionel Sambuc   /// ApplyTypeConstraints - Apply all of the type constraints relevant to
459f4a2713aSLionel Sambuc   /// this node and its children in the tree.  This returns true if it makes a
460f4a2713aSLionel Sambuc   /// change, false otherwise.  If a type contradiction is found, flag an error.
461f4a2713aSLionel Sambuc   bool ApplyTypeConstraints(TreePattern &TP, bool NotRegisters);
462f4a2713aSLionel Sambuc 
463f4a2713aSLionel Sambuc   /// UpdateNodeType - Set the node type of N to VT if VT contains
464f4a2713aSLionel Sambuc   /// information.  If N already contains a conflicting type, then flag an
465f4a2713aSLionel Sambuc   /// error.  This returns true if any information was updated.
466f4a2713aSLionel Sambuc   ///
UpdateNodeType(unsigned ResNo,const EEVT::TypeSet & InTy,TreePattern & TP)467f4a2713aSLionel Sambuc   bool UpdateNodeType(unsigned ResNo, const EEVT::TypeSet &InTy,
468f4a2713aSLionel Sambuc                       TreePattern &TP) {
469f4a2713aSLionel Sambuc     return Types[ResNo].MergeInTypeInfo(InTy, TP);
470f4a2713aSLionel Sambuc   }
471f4a2713aSLionel Sambuc 
UpdateNodeType(unsigned ResNo,MVT::SimpleValueType InTy,TreePattern & TP)472f4a2713aSLionel Sambuc   bool UpdateNodeType(unsigned ResNo, MVT::SimpleValueType InTy,
473f4a2713aSLionel Sambuc                       TreePattern &TP) {
474f4a2713aSLionel Sambuc     return Types[ResNo].MergeInTypeInfo(EEVT::TypeSet(InTy, TP), TP);
475f4a2713aSLionel Sambuc   }
476f4a2713aSLionel Sambuc 
477f4a2713aSLionel Sambuc   // Update node type with types inferred from an instruction operand or result
478f4a2713aSLionel Sambuc   // def from the ins/outs lists.
479f4a2713aSLionel Sambuc   // Return true if the type changed.
480f4a2713aSLionel Sambuc   bool UpdateNodeTypeFromInst(unsigned ResNo, Record *Operand, TreePattern &TP);
481f4a2713aSLionel Sambuc 
482f4a2713aSLionel Sambuc   /// ContainsUnresolvedType - Return true if this tree contains any
483f4a2713aSLionel Sambuc   /// unresolved types.
ContainsUnresolvedType()484f4a2713aSLionel Sambuc   bool ContainsUnresolvedType() const {
485f4a2713aSLionel Sambuc     for (unsigned i = 0, e = Types.size(); i != e; ++i)
486f4a2713aSLionel Sambuc       if (!Types[i].isConcrete()) return true;
487f4a2713aSLionel Sambuc 
488f4a2713aSLionel Sambuc     for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
489f4a2713aSLionel Sambuc       if (getChild(i)->ContainsUnresolvedType()) return true;
490f4a2713aSLionel Sambuc     return false;
491f4a2713aSLionel Sambuc   }
492f4a2713aSLionel Sambuc 
493f4a2713aSLionel Sambuc   /// canPatternMatch - If it is impossible for this pattern to match on this
494f4a2713aSLionel Sambuc   /// target, fill in Reason and return false.  Otherwise, return true.
495f4a2713aSLionel Sambuc   bool canPatternMatch(std::string &Reason, const CodeGenDAGPatterns &CDP);
496f4a2713aSLionel Sambuc };
497f4a2713aSLionel Sambuc 
498f4a2713aSLionel Sambuc inline raw_ostream &operator<<(raw_ostream &OS, const TreePatternNode &TPN) {
499f4a2713aSLionel Sambuc   TPN.print(OS);
500f4a2713aSLionel Sambuc   return OS;
501f4a2713aSLionel Sambuc }
502f4a2713aSLionel Sambuc 
503f4a2713aSLionel Sambuc 
504f4a2713aSLionel Sambuc /// TreePattern - Represent a pattern, used for instructions, pattern
505f4a2713aSLionel Sambuc /// fragments, etc.
506f4a2713aSLionel Sambuc ///
507f4a2713aSLionel Sambuc class TreePattern {
508f4a2713aSLionel Sambuc   /// Trees - The list of pattern trees which corresponds to this pattern.
509f4a2713aSLionel Sambuc   /// Note that PatFrag's only have a single tree.
510f4a2713aSLionel Sambuc   ///
511f4a2713aSLionel Sambuc   std::vector<TreePatternNode*> Trees;
512f4a2713aSLionel Sambuc 
513f4a2713aSLionel Sambuc   /// NamedNodes - This is all of the nodes that have names in the trees in this
514f4a2713aSLionel Sambuc   /// pattern.
515f4a2713aSLionel Sambuc   StringMap<SmallVector<TreePatternNode*,1> > NamedNodes;
516f4a2713aSLionel Sambuc 
517f4a2713aSLionel Sambuc   /// TheRecord - The actual TableGen record corresponding to this pattern.
518f4a2713aSLionel Sambuc   ///
519f4a2713aSLionel Sambuc   Record *TheRecord;
520f4a2713aSLionel Sambuc 
521f4a2713aSLionel Sambuc   /// Args - This is a list of all of the arguments to this pattern (for
522f4a2713aSLionel Sambuc   /// PatFrag patterns), which are the 'node' markers in this pattern.
523f4a2713aSLionel Sambuc   std::vector<std::string> Args;
524f4a2713aSLionel Sambuc 
525f4a2713aSLionel Sambuc   /// CDP - the top-level object coordinating this madness.
526f4a2713aSLionel Sambuc   ///
527f4a2713aSLionel Sambuc   CodeGenDAGPatterns &CDP;
528f4a2713aSLionel Sambuc 
529f4a2713aSLionel Sambuc   /// isInputPattern - True if this is an input pattern, something to match.
530f4a2713aSLionel Sambuc   /// False if this is an output pattern, something to emit.
531f4a2713aSLionel Sambuc   bool isInputPattern;
532f4a2713aSLionel Sambuc 
533f4a2713aSLionel Sambuc   /// hasError - True if the currently processed nodes have unresolvable types
534f4a2713aSLionel Sambuc   /// or other non-fatal errors
535f4a2713aSLionel Sambuc   bool HasError;
536*0a6a1f1dSLionel Sambuc 
537*0a6a1f1dSLionel Sambuc   /// It's important that the usage of operands in ComplexPatterns is
538*0a6a1f1dSLionel Sambuc   /// consistent: each named operand can be defined by at most one
539*0a6a1f1dSLionel Sambuc   /// ComplexPattern. This records the ComplexPattern instance and the operand
540*0a6a1f1dSLionel Sambuc   /// number for each operand encountered in a ComplexPattern to aid in that
541*0a6a1f1dSLionel Sambuc   /// check.
542*0a6a1f1dSLionel Sambuc   StringMap<std::pair<Record *, unsigned>> ComplexPatternOperands;
543f4a2713aSLionel Sambuc public:
544f4a2713aSLionel Sambuc 
545f4a2713aSLionel Sambuc   /// TreePattern constructor - Parse the specified DagInits into the
546f4a2713aSLionel Sambuc   /// current record.
547f4a2713aSLionel Sambuc   TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
548f4a2713aSLionel Sambuc               CodeGenDAGPatterns &ise);
549f4a2713aSLionel Sambuc   TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
550f4a2713aSLionel Sambuc               CodeGenDAGPatterns &ise);
551f4a2713aSLionel Sambuc   TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
552f4a2713aSLionel Sambuc               CodeGenDAGPatterns &ise);
553f4a2713aSLionel Sambuc 
554f4a2713aSLionel Sambuc   /// getTrees - Return the tree patterns which corresponds to this pattern.
555f4a2713aSLionel Sambuc   ///
getTrees()556f4a2713aSLionel Sambuc   const std::vector<TreePatternNode*> &getTrees() const { return Trees; }
getNumTrees()557f4a2713aSLionel Sambuc   unsigned getNumTrees() const { return Trees.size(); }
getTree(unsigned i)558f4a2713aSLionel Sambuc   TreePatternNode *getTree(unsigned i) const { return Trees[i]; }
getOnlyTree()559f4a2713aSLionel Sambuc   TreePatternNode *getOnlyTree() const {
560f4a2713aSLionel Sambuc     assert(Trees.size() == 1 && "Doesn't have exactly one pattern!");
561f4a2713aSLionel Sambuc     return Trees[0];
562f4a2713aSLionel Sambuc   }
563f4a2713aSLionel Sambuc 
getNamedNodesMap()564f4a2713aSLionel Sambuc   const StringMap<SmallVector<TreePatternNode*,1> > &getNamedNodesMap() {
565f4a2713aSLionel Sambuc     if (NamedNodes.empty())
566f4a2713aSLionel Sambuc       ComputeNamedNodes();
567f4a2713aSLionel Sambuc     return NamedNodes;
568f4a2713aSLionel Sambuc   }
569f4a2713aSLionel Sambuc 
570f4a2713aSLionel Sambuc   /// getRecord - Return the actual TableGen record corresponding to this
571f4a2713aSLionel Sambuc   /// pattern.
572f4a2713aSLionel Sambuc   ///
getRecord()573f4a2713aSLionel Sambuc   Record *getRecord() const { return TheRecord; }
574f4a2713aSLionel Sambuc 
getNumArgs()575f4a2713aSLionel Sambuc   unsigned getNumArgs() const { return Args.size(); }
getArgName(unsigned i)576f4a2713aSLionel Sambuc   const std::string &getArgName(unsigned i) const {
577f4a2713aSLionel Sambuc     assert(i < Args.size() && "Argument reference out of range!");
578f4a2713aSLionel Sambuc     return Args[i];
579f4a2713aSLionel Sambuc   }
getArgList()580f4a2713aSLionel Sambuc   std::vector<std::string> &getArgList() { return Args; }
581f4a2713aSLionel Sambuc 
getDAGPatterns()582f4a2713aSLionel Sambuc   CodeGenDAGPatterns &getDAGPatterns() const { return CDP; }
583f4a2713aSLionel Sambuc 
584f4a2713aSLionel Sambuc   /// InlinePatternFragments - If this pattern refers to any pattern
585f4a2713aSLionel Sambuc   /// fragments, inline them into place, giving us a pattern without any
586f4a2713aSLionel Sambuc   /// PatFrag references.
InlinePatternFragments()587f4a2713aSLionel Sambuc   void InlinePatternFragments() {
588f4a2713aSLionel Sambuc     for (unsigned i = 0, e = Trees.size(); i != e; ++i)
589f4a2713aSLionel Sambuc       Trees[i] = Trees[i]->InlinePatternFragments(*this);
590f4a2713aSLionel Sambuc   }
591f4a2713aSLionel Sambuc 
592f4a2713aSLionel Sambuc   /// InferAllTypes - Infer/propagate as many types throughout the expression
593f4a2713aSLionel Sambuc   /// patterns as possible.  Return true if all types are inferred, false
594f4a2713aSLionel Sambuc   /// otherwise.  Bail out if a type contradiction is found.
595f4a2713aSLionel Sambuc   bool InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> >
596*0a6a1f1dSLionel Sambuc                           *NamedTypes=nullptr);
597f4a2713aSLionel Sambuc 
598f4a2713aSLionel Sambuc   /// error - If this is the first error in the current resolution step,
599f4a2713aSLionel Sambuc   /// print it and set the error flag.  Otherwise, continue silently.
600*0a6a1f1dSLionel Sambuc   void error(const Twine &Msg);
hasError()601f4a2713aSLionel Sambuc   bool hasError() const {
602f4a2713aSLionel Sambuc     return HasError;
603f4a2713aSLionel Sambuc   }
resetError()604f4a2713aSLionel Sambuc   void resetError() {
605f4a2713aSLionel Sambuc     HasError = false;
606f4a2713aSLionel Sambuc   }
607f4a2713aSLionel Sambuc 
608f4a2713aSLionel Sambuc   void print(raw_ostream &OS) const;
609f4a2713aSLionel Sambuc   void dump() const;
610f4a2713aSLionel Sambuc 
611f4a2713aSLionel Sambuc private:
612f4a2713aSLionel Sambuc   TreePatternNode *ParseTreePattern(Init *DI, StringRef OpName);
613f4a2713aSLionel Sambuc   void ComputeNamedNodes();
614f4a2713aSLionel Sambuc   void ComputeNamedNodes(TreePatternNode *N);
615f4a2713aSLionel Sambuc };
616f4a2713aSLionel Sambuc 
617f4a2713aSLionel Sambuc /// DAGDefaultOperand - One of these is created for each OperandWithDefaultOps
618f4a2713aSLionel Sambuc /// that has a set ExecuteAlways / DefaultOps field.
619f4a2713aSLionel Sambuc struct DAGDefaultOperand {
620f4a2713aSLionel Sambuc   std::vector<TreePatternNode*> DefaultOps;
621f4a2713aSLionel Sambuc };
622f4a2713aSLionel Sambuc 
623f4a2713aSLionel Sambuc class DAGInstruction {
624f4a2713aSLionel Sambuc   TreePattern *Pattern;
625f4a2713aSLionel Sambuc   std::vector<Record*> Results;
626f4a2713aSLionel Sambuc   std::vector<Record*> Operands;
627f4a2713aSLionel Sambuc   std::vector<Record*> ImpResults;
628f4a2713aSLionel Sambuc   TreePatternNode *ResultPattern;
629f4a2713aSLionel Sambuc public:
DAGInstruction(TreePattern * TP,const std::vector<Record * > & results,const std::vector<Record * > & operands,const std::vector<Record * > & impresults)630f4a2713aSLionel Sambuc   DAGInstruction(TreePattern *TP,
631f4a2713aSLionel Sambuc                  const std::vector<Record*> &results,
632f4a2713aSLionel Sambuc                  const std::vector<Record*> &operands,
633f4a2713aSLionel Sambuc                  const std::vector<Record*> &impresults)
634f4a2713aSLionel Sambuc     : Pattern(TP), Results(results), Operands(operands),
635*0a6a1f1dSLionel Sambuc       ImpResults(impresults), ResultPattern(nullptr) {}
636f4a2713aSLionel Sambuc 
getPattern()637f4a2713aSLionel Sambuc   TreePattern *getPattern() const { return Pattern; }
getNumResults()638f4a2713aSLionel Sambuc   unsigned getNumResults() const { return Results.size(); }
getNumOperands()639f4a2713aSLionel Sambuc   unsigned getNumOperands() const { return Operands.size(); }
getNumImpResults()640f4a2713aSLionel Sambuc   unsigned getNumImpResults() const { return ImpResults.size(); }
getImpResults()641f4a2713aSLionel Sambuc   const std::vector<Record*>& getImpResults() const { return ImpResults; }
642f4a2713aSLionel Sambuc 
setResultPattern(TreePatternNode * R)643f4a2713aSLionel Sambuc   void setResultPattern(TreePatternNode *R) { ResultPattern = R; }
644f4a2713aSLionel Sambuc 
getResult(unsigned RN)645f4a2713aSLionel Sambuc   Record *getResult(unsigned RN) const {
646f4a2713aSLionel Sambuc     assert(RN < Results.size());
647f4a2713aSLionel Sambuc     return Results[RN];
648f4a2713aSLionel Sambuc   }
649f4a2713aSLionel Sambuc 
getOperand(unsigned ON)650f4a2713aSLionel Sambuc   Record *getOperand(unsigned ON) const {
651f4a2713aSLionel Sambuc     assert(ON < Operands.size());
652f4a2713aSLionel Sambuc     return Operands[ON];
653f4a2713aSLionel Sambuc   }
654f4a2713aSLionel Sambuc 
getImpResult(unsigned RN)655f4a2713aSLionel Sambuc   Record *getImpResult(unsigned RN) const {
656f4a2713aSLionel Sambuc     assert(RN < ImpResults.size());
657f4a2713aSLionel Sambuc     return ImpResults[RN];
658f4a2713aSLionel Sambuc   }
659f4a2713aSLionel Sambuc 
getResultPattern()660f4a2713aSLionel Sambuc   TreePatternNode *getResultPattern() const { return ResultPattern; }
661f4a2713aSLionel Sambuc };
662f4a2713aSLionel Sambuc 
663f4a2713aSLionel Sambuc /// PatternToMatch - Used by CodeGenDAGPatterns to keep tab of patterns
664f4a2713aSLionel Sambuc /// processed to produce isel.
665f4a2713aSLionel Sambuc class PatternToMatch {
666f4a2713aSLionel Sambuc public:
PatternToMatch(Record * srcrecord,ListInit * preds,TreePatternNode * src,TreePatternNode * dst,const std::vector<Record * > & dstregs,int complexity,unsigned uid)667f4a2713aSLionel Sambuc   PatternToMatch(Record *srcrecord, ListInit *preds,
668f4a2713aSLionel Sambuc                  TreePatternNode *src, TreePatternNode *dst,
669f4a2713aSLionel Sambuc                  const std::vector<Record*> &dstregs,
670*0a6a1f1dSLionel Sambuc                  int complexity, unsigned uid)
671f4a2713aSLionel Sambuc     : SrcRecord(srcrecord), Predicates(preds), SrcPattern(src), DstPattern(dst),
672f4a2713aSLionel Sambuc       Dstregs(dstregs), AddedComplexity(complexity), ID(uid) {}
673f4a2713aSLionel Sambuc 
674f4a2713aSLionel Sambuc   Record          *SrcRecord;   // Originating Record for the pattern.
675f4a2713aSLionel Sambuc   ListInit        *Predicates;  // Top level predicate conditions to match.
676f4a2713aSLionel Sambuc   TreePatternNode *SrcPattern;  // Source pattern to match.
677f4a2713aSLionel Sambuc   TreePatternNode *DstPattern;  // Resulting pattern.
678f4a2713aSLionel Sambuc   std::vector<Record*> Dstregs; // Physical register defs being matched.
679*0a6a1f1dSLionel Sambuc   int              AddedComplexity; // Add to matching pattern complexity.
680f4a2713aSLionel Sambuc   unsigned         ID;          // Unique ID for the record.
681f4a2713aSLionel Sambuc 
getSrcRecord()682f4a2713aSLionel Sambuc   Record          *getSrcRecord()  const { return SrcRecord; }
getPredicates()683f4a2713aSLionel Sambuc   ListInit        *getPredicates() const { return Predicates; }
getSrcPattern()684f4a2713aSLionel Sambuc   TreePatternNode *getSrcPattern() const { return SrcPattern; }
getDstPattern()685f4a2713aSLionel Sambuc   TreePatternNode *getDstPattern() const { return DstPattern; }
getDstRegs()686f4a2713aSLionel Sambuc   const std::vector<Record*> &getDstRegs() const { return Dstregs; }
getAddedComplexity()687*0a6a1f1dSLionel Sambuc   int         getAddedComplexity() const { return AddedComplexity; }
688f4a2713aSLionel Sambuc 
689f4a2713aSLionel Sambuc   std::string getPredicateCheck() const;
690f4a2713aSLionel Sambuc 
691f4a2713aSLionel Sambuc   /// Compute the complexity metric for the input pattern.  This roughly
692f4a2713aSLionel Sambuc   /// corresponds to the number of nodes that are covered.
693*0a6a1f1dSLionel Sambuc   int getPatternComplexity(const CodeGenDAGPatterns &CGP) const;
694f4a2713aSLionel Sambuc };
695f4a2713aSLionel Sambuc 
696f4a2713aSLionel Sambuc class CodeGenDAGPatterns {
697f4a2713aSLionel Sambuc   RecordKeeper &Records;
698f4a2713aSLionel Sambuc   CodeGenTarget Target;
699f4a2713aSLionel Sambuc   std::vector<CodeGenIntrinsic> Intrinsics;
700f4a2713aSLionel Sambuc   std::vector<CodeGenIntrinsic> TgtIntrinsics;
701f4a2713aSLionel Sambuc 
702f4a2713aSLionel Sambuc   std::map<Record*, SDNodeInfo, LessRecordByID> SDNodes;
703f4a2713aSLionel Sambuc   std::map<Record*, std::pair<Record*, std::string>, LessRecordByID> SDNodeXForms;
704f4a2713aSLionel Sambuc   std::map<Record*, ComplexPattern, LessRecordByID> ComplexPatterns;
705*0a6a1f1dSLionel Sambuc   std::map<Record *, std::unique_ptr<TreePattern>, LessRecordByID>
706*0a6a1f1dSLionel Sambuc       PatternFragments;
707f4a2713aSLionel Sambuc   std::map<Record*, DAGDefaultOperand, LessRecordByID> DefaultOperands;
708f4a2713aSLionel Sambuc   std::map<Record*, DAGInstruction, LessRecordByID> Instructions;
709f4a2713aSLionel Sambuc 
710f4a2713aSLionel Sambuc   // Specific SDNode definitions:
711f4a2713aSLionel Sambuc   Record *intrinsic_void_sdnode;
712f4a2713aSLionel Sambuc   Record *intrinsic_w_chain_sdnode, *intrinsic_wo_chain_sdnode;
713f4a2713aSLionel Sambuc 
714f4a2713aSLionel Sambuc   /// PatternsToMatch - All of the things we are matching on the DAG.  The first
715f4a2713aSLionel Sambuc   /// value is the pattern to match, the second pattern is the result to
716f4a2713aSLionel Sambuc   /// emit.
717f4a2713aSLionel Sambuc   std::vector<PatternToMatch> PatternsToMatch;
718f4a2713aSLionel Sambuc public:
719f4a2713aSLionel Sambuc   CodeGenDAGPatterns(RecordKeeper &R);
720f4a2713aSLionel Sambuc 
getTargetInfo()721f4a2713aSLionel Sambuc   CodeGenTarget &getTargetInfo() { return Target; }
getTargetInfo()722f4a2713aSLionel Sambuc   const CodeGenTarget &getTargetInfo() const { return Target; }
723f4a2713aSLionel Sambuc 
724f4a2713aSLionel Sambuc   Record *getSDNodeNamed(const std::string &Name) const;
725f4a2713aSLionel Sambuc 
getSDNodeInfo(Record * R)726f4a2713aSLionel Sambuc   const SDNodeInfo &getSDNodeInfo(Record *R) const {
727f4a2713aSLionel Sambuc     assert(SDNodes.count(R) && "Unknown node!");
728f4a2713aSLionel Sambuc     return SDNodes.find(R)->second;
729f4a2713aSLionel Sambuc   }
730f4a2713aSLionel Sambuc 
731f4a2713aSLionel Sambuc   // Node transformation lookups.
732f4a2713aSLionel Sambuc   typedef std::pair<Record*, std::string> NodeXForm;
getSDNodeTransform(Record * R)733f4a2713aSLionel Sambuc   const NodeXForm &getSDNodeTransform(Record *R) const {
734f4a2713aSLionel Sambuc     assert(SDNodeXForms.count(R) && "Invalid transform!");
735f4a2713aSLionel Sambuc     return SDNodeXForms.find(R)->second;
736f4a2713aSLionel Sambuc   }
737f4a2713aSLionel Sambuc 
738f4a2713aSLionel Sambuc   typedef std::map<Record*, NodeXForm, LessRecordByID>::const_iterator
739f4a2713aSLionel Sambuc           nx_iterator;
nx_begin()740f4a2713aSLionel Sambuc   nx_iterator nx_begin() const { return SDNodeXForms.begin(); }
nx_end()741f4a2713aSLionel Sambuc   nx_iterator nx_end() const { return SDNodeXForms.end(); }
742f4a2713aSLionel Sambuc 
743f4a2713aSLionel Sambuc 
getComplexPattern(Record * R)744f4a2713aSLionel Sambuc   const ComplexPattern &getComplexPattern(Record *R) const {
745f4a2713aSLionel Sambuc     assert(ComplexPatterns.count(R) && "Unknown addressing mode!");
746f4a2713aSLionel Sambuc     return ComplexPatterns.find(R)->second;
747f4a2713aSLionel Sambuc   }
748f4a2713aSLionel Sambuc 
getIntrinsic(Record * R)749f4a2713aSLionel Sambuc   const CodeGenIntrinsic &getIntrinsic(Record *R) const {
750f4a2713aSLionel Sambuc     for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
751f4a2713aSLionel Sambuc       if (Intrinsics[i].TheDef == R) return Intrinsics[i];
752f4a2713aSLionel Sambuc     for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
753f4a2713aSLionel Sambuc       if (TgtIntrinsics[i].TheDef == R) return TgtIntrinsics[i];
754f4a2713aSLionel Sambuc     llvm_unreachable("Unknown intrinsic!");
755f4a2713aSLionel Sambuc   }
756f4a2713aSLionel Sambuc 
getIntrinsicInfo(unsigned IID)757f4a2713aSLionel Sambuc   const CodeGenIntrinsic &getIntrinsicInfo(unsigned IID) const {
758f4a2713aSLionel Sambuc     if (IID-1 < Intrinsics.size())
759f4a2713aSLionel Sambuc       return Intrinsics[IID-1];
760f4a2713aSLionel Sambuc     if (IID-Intrinsics.size()-1 < TgtIntrinsics.size())
761f4a2713aSLionel Sambuc       return TgtIntrinsics[IID-Intrinsics.size()-1];
762f4a2713aSLionel Sambuc     llvm_unreachable("Bad intrinsic ID!");
763f4a2713aSLionel Sambuc   }
764f4a2713aSLionel Sambuc 
getIntrinsicID(Record * R)765f4a2713aSLionel Sambuc   unsigned getIntrinsicID(Record *R) const {
766f4a2713aSLionel Sambuc     for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
767f4a2713aSLionel Sambuc       if (Intrinsics[i].TheDef == R) return i;
768f4a2713aSLionel Sambuc     for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
769f4a2713aSLionel Sambuc       if (TgtIntrinsics[i].TheDef == R) return i + Intrinsics.size();
770f4a2713aSLionel Sambuc     llvm_unreachable("Unknown intrinsic!");
771f4a2713aSLionel Sambuc   }
772f4a2713aSLionel Sambuc 
getDefaultOperand(Record * R)773f4a2713aSLionel Sambuc   const DAGDefaultOperand &getDefaultOperand(Record *R) const {
774f4a2713aSLionel Sambuc     assert(DefaultOperands.count(R) &&"Isn't an analyzed default operand!");
775f4a2713aSLionel Sambuc     return DefaultOperands.find(R)->second;
776f4a2713aSLionel Sambuc   }
777f4a2713aSLionel Sambuc 
778f4a2713aSLionel Sambuc   // Pattern Fragment information.
getPatternFragment(Record * R)779f4a2713aSLionel Sambuc   TreePattern *getPatternFragment(Record *R) const {
780f4a2713aSLionel Sambuc     assert(PatternFragments.count(R) && "Invalid pattern fragment request!");
781*0a6a1f1dSLionel Sambuc     return PatternFragments.find(R)->second.get();
782f4a2713aSLionel Sambuc   }
getPatternFragmentIfRead(Record * R)783f4a2713aSLionel Sambuc   TreePattern *getPatternFragmentIfRead(Record *R) const {
784*0a6a1f1dSLionel Sambuc     if (!PatternFragments.count(R))
785*0a6a1f1dSLionel Sambuc       return nullptr;
786*0a6a1f1dSLionel Sambuc     return PatternFragments.find(R)->second.get();
787f4a2713aSLionel Sambuc   }
788f4a2713aSLionel Sambuc 
789*0a6a1f1dSLionel Sambuc   typedef std::map<Record *, std::unique_ptr<TreePattern>,
790*0a6a1f1dSLionel Sambuc                    LessRecordByID>::const_iterator pf_iterator;
pf_begin()791f4a2713aSLionel Sambuc   pf_iterator pf_begin() const { return PatternFragments.begin(); }
pf_end()792f4a2713aSLionel Sambuc   pf_iterator pf_end() const { return PatternFragments.end(); }
793f4a2713aSLionel Sambuc 
794f4a2713aSLionel Sambuc   // Patterns to match information.
795f4a2713aSLionel Sambuc   typedef std::vector<PatternToMatch>::const_iterator ptm_iterator;
ptm_begin()796f4a2713aSLionel Sambuc   ptm_iterator ptm_begin() const { return PatternsToMatch.begin(); }
ptm_end()797f4a2713aSLionel Sambuc   ptm_iterator ptm_end() const { return PatternsToMatch.end(); }
798f4a2713aSLionel Sambuc 
799f4a2713aSLionel Sambuc   /// Parse the Pattern for an instruction, and insert the result in DAGInsts.
800f4a2713aSLionel Sambuc   typedef std::map<Record*, DAGInstruction, LessRecordByID> DAGInstMap;
801f4a2713aSLionel Sambuc   const DAGInstruction &parseInstructionPattern(
802f4a2713aSLionel Sambuc       CodeGenInstruction &CGI, ListInit *Pattern,
803f4a2713aSLionel Sambuc       DAGInstMap &DAGInsts);
804f4a2713aSLionel Sambuc 
getInstruction(Record * R)805f4a2713aSLionel Sambuc   const DAGInstruction &getInstruction(Record *R) const {
806f4a2713aSLionel Sambuc     assert(Instructions.count(R) && "Unknown instruction!");
807f4a2713aSLionel Sambuc     return Instructions.find(R)->second;
808f4a2713aSLionel Sambuc   }
809f4a2713aSLionel Sambuc 
get_intrinsic_void_sdnode()810f4a2713aSLionel Sambuc   Record *get_intrinsic_void_sdnode() const {
811f4a2713aSLionel Sambuc     return intrinsic_void_sdnode;
812f4a2713aSLionel Sambuc   }
get_intrinsic_w_chain_sdnode()813f4a2713aSLionel Sambuc   Record *get_intrinsic_w_chain_sdnode() const {
814f4a2713aSLionel Sambuc     return intrinsic_w_chain_sdnode;
815f4a2713aSLionel Sambuc   }
get_intrinsic_wo_chain_sdnode()816f4a2713aSLionel Sambuc   Record *get_intrinsic_wo_chain_sdnode() const {
817f4a2713aSLionel Sambuc     return intrinsic_wo_chain_sdnode;
818f4a2713aSLionel Sambuc   }
819f4a2713aSLionel Sambuc 
hasTargetIntrinsics()820f4a2713aSLionel Sambuc   bool hasTargetIntrinsics() { return !TgtIntrinsics.empty(); }
821f4a2713aSLionel Sambuc 
822f4a2713aSLionel Sambuc private:
823f4a2713aSLionel Sambuc   void ParseNodeInfo();
824f4a2713aSLionel Sambuc   void ParseNodeTransforms();
825f4a2713aSLionel Sambuc   void ParseComplexPatterns();
826*0a6a1f1dSLionel Sambuc   void ParsePatternFragments(bool OutFrags = false);
827f4a2713aSLionel Sambuc   void ParseDefaultOperands();
828f4a2713aSLionel Sambuc   void ParseInstructions();
829f4a2713aSLionel Sambuc   void ParsePatterns();
830f4a2713aSLionel Sambuc   void InferInstructionFlags();
831f4a2713aSLionel Sambuc   void GenerateVariants();
832f4a2713aSLionel Sambuc   void VerifyInstructionFlags();
833f4a2713aSLionel Sambuc 
834f4a2713aSLionel Sambuc   void AddPatternToMatch(TreePattern *Pattern, const PatternToMatch &PTM);
835f4a2713aSLionel Sambuc   void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
836f4a2713aSLionel Sambuc                                    std::map<std::string,
837f4a2713aSLionel Sambuc                                    TreePatternNode*> &InstInputs,
838f4a2713aSLionel Sambuc                                    std::map<std::string,
839f4a2713aSLionel Sambuc                                    TreePatternNode*> &InstResults,
840f4a2713aSLionel Sambuc                                    std::vector<Record*> &InstImpResults);
841f4a2713aSLionel Sambuc };
842f4a2713aSLionel Sambuc } // end namespace llvm
843f4a2713aSLionel Sambuc 
844f4a2713aSLionel Sambuc #endif
845