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