1f22ef01cSRoman Divacky //===- CodeGenDAGPatterns.cpp - Read DAG patterns from .td file -----------===// 2f22ef01cSRoman Divacky // 3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure 4f22ef01cSRoman Divacky // 5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source 6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details. 7f22ef01cSRoman Divacky // 8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 9f22ef01cSRoman Divacky // 10f22ef01cSRoman Divacky // This file implements the CodeGenDAGPatterns class, which is used to read and 11f22ef01cSRoman Divacky // represent the patterns present in a .td file for instructions. 12f22ef01cSRoman Divacky // 13f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 14f22ef01cSRoman Divacky 15f22ef01cSRoman Divacky #include "CodeGenDAGPatterns.h" 16f22ef01cSRoman Divacky #include "llvm/ADT/STLExtras.h" 177d523365SDimitry Andric #include "llvm/ADT/SmallString.h" 18139f7f9bSDimitry Andric #include "llvm/ADT/StringExtras.h" 19cb4dff85SDimitry Andric #include "llvm/ADT/Twine.h" 20f22ef01cSRoman Divacky #include "llvm/Support/Debug.h" 21dff0c46cSDimitry Andric #include "llvm/Support/ErrorHandling.h" 22139f7f9bSDimitry Andric #include "llvm/TableGen/Error.h" 23139f7f9bSDimitry Andric #include "llvm/TableGen/Record.h" 24f22ef01cSRoman Divacky #include <algorithm> 25dff0c46cSDimitry Andric #include <cstdio> 26dff0c46cSDimitry Andric #include <set> 27f22ef01cSRoman Divacky using namespace llvm; 28f22ef01cSRoman Divacky 2991bc56edSDimitry Andric #define DEBUG_TYPE "dag-patterns" 3091bc56edSDimitry Andric 31f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 32f22ef01cSRoman Divacky // EEVT::TypeSet Implementation 33f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 34f22ef01cSRoman Divacky 35f22ef01cSRoman Divacky static inline bool isInteger(MVT::SimpleValueType VT) { 36f785676fSDimitry Andric return MVT(VT).isInteger(); 37f22ef01cSRoman Divacky } 38f22ef01cSRoman Divacky static inline bool isFloatingPoint(MVT::SimpleValueType VT) { 39f785676fSDimitry Andric return MVT(VT).isFloatingPoint(); 40f22ef01cSRoman Divacky } 41f22ef01cSRoman Divacky static inline bool isVector(MVT::SimpleValueType VT) { 42f785676fSDimitry Andric return MVT(VT).isVector(); 43f22ef01cSRoman Divacky } 44f22ef01cSRoman Divacky static inline bool isScalar(MVT::SimpleValueType VT) { 45f785676fSDimitry Andric return !MVT(VT).isVector(); 46f22ef01cSRoman Divacky } 47f22ef01cSRoman Divacky 48f22ef01cSRoman Divacky EEVT::TypeSet::TypeSet(MVT::SimpleValueType VT, TreePattern &TP) { 49f22ef01cSRoman Divacky if (VT == MVT::iAny) 50f22ef01cSRoman Divacky EnforceInteger(TP); 51f22ef01cSRoman Divacky else if (VT == MVT::fAny) 52f22ef01cSRoman Divacky EnforceFloatingPoint(TP); 53f22ef01cSRoman Divacky else if (VT == MVT::vAny) 54f22ef01cSRoman Divacky EnforceVector(TP); 55f22ef01cSRoman Divacky else { 56f22ef01cSRoman Divacky assert((VT < MVT::LAST_VALUETYPE || VT == MVT::iPTR || 57ff0cc061SDimitry Andric VT == MVT::iPTRAny || VT == MVT::Any) && "Not a concrete type!"); 58f22ef01cSRoman Divacky TypeVec.push_back(VT); 59f22ef01cSRoman Divacky } 60f22ef01cSRoman Divacky } 61f22ef01cSRoman Divacky 62f22ef01cSRoman Divacky 63139f7f9bSDimitry Andric EEVT::TypeSet::TypeSet(ArrayRef<MVT::SimpleValueType> VTList) { 64f22ef01cSRoman Divacky assert(!VTList.empty() && "empty list?"); 65f22ef01cSRoman Divacky TypeVec.append(VTList.begin(), VTList.end()); 66f22ef01cSRoman Divacky 67f22ef01cSRoman Divacky if (!VTList.empty()) 68f22ef01cSRoman Divacky assert(VTList[0] != MVT::iAny && VTList[0] != MVT::vAny && 69f22ef01cSRoman Divacky VTList[0] != MVT::fAny); 70f22ef01cSRoman Divacky 71f22ef01cSRoman Divacky // Verify no duplicates. 72f22ef01cSRoman Divacky array_pod_sort(TypeVec.begin(), TypeVec.end()); 73f22ef01cSRoman Divacky assert(std::unique(TypeVec.begin(), TypeVec.end()) == TypeVec.end()); 74f22ef01cSRoman Divacky } 75f22ef01cSRoman Divacky 76f22ef01cSRoman Divacky /// FillWithPossibleTypes - Set to all legal types and return true, only valid 77f22ef01cSRoman Divacky /// on completely unknown type sets. 78f22ef01cSRoman Divacky bool EEVT::TypeSet::FillWithPossibleTypes(TreePattern &TP, 79f22ef01cSRoman Divacky bool (*Pred)(MVT::SimpleValueType), 80f22ef01cSRoman Divacky const char *PredicateName) { 81f22ef01cSRoman Divacky assert(isCompletelyUnknown()); 82139f7f9bSDimitry Andric ArrayRef<MVT::SimpleValueType> LegalTypes = 83f22ef01cSRoman Divacky TP.getDAGPatterns().getTargetInfo().getLegalValueTypes(); 84f22ef01cSRoman Divacky 853861d79fSDimitry Andric if (TP.hasError()) 863861d79fSDimitry Andric return false; 873861d79fSDimitry Andric 887d523365SDimitry Andric for (MVT::SimpleValueType VT : LegalTypes) 897d523365SDimitry Andric if (!Pred || Pred(VT)) 907d523365SDimitry Andric TypeVec.push_back(VT); 91f22ef01cSRoman Divacky 92f22ef01cSRoman Divacky // If we have nothing that matches the predicate, bail out. 933861d79fSDimitry Andric if (TypeVec.empty()) { 94f22ef01cSRoman Divacky TP.error("Type inference contradiction found, no " + 95f22ef01cSRoman Divacky std::string(PredicateName) + " types found"); 963861d79fSDimitry Andric return false; 973861d79fSDimitry Andric } 98f22ef01cSRoman Divacky // No need to sort with one element. 99f22ef01cSRoman Divacky if (TypeVec.size() == 1) return true; 100f22ef01cSRoman Divacky 101f22ef01cSRoman Divacky // Remove duplicates. 102f22ef01cSRoman Divacky array_pod_sort(TypeVec.begin(), TypeVec.end()); 103f22ef01cSRoman Divacky TypeVec.erase(std::unique(TypeVec.begin(), TypeVec.end()), TypeVec.end()); 104f22ef01cSRoman Divacky 105f22ef01cSRoman Divacky return true; 106f22ef01cSRoman Divacky } 107f22ef01cSRoman Divacky 108f22ef01cSRoman Divacky /// hasIntegerTypes - Return true if this TypeSet contains iAny or an 109f22ef01cSRoman Divacky /// integer value type. 110f22ef01cSRoman Divacky bool EEVT::TypeSet::hasIntegerTypes() const { 111d88c1a5aSDimitry Andric return any_of(TypeVec, isInteger); 112f22ef01cSRoman Divacky } 113f22ef01cSRoman Divacky 114f22ef01cSRoman Divacky /// hasFloatingPointTypes - Return true if this TypeSet contains an fAny or 115f22ef01cSRoman Divacky /// a floating point value type. 116f22ef01cSRoman Divacky bool EEVT::TypeSet::hasFloatingPointTypes() const { 117d88c1a5aSDimitry Andric return any_of(TypeVec, isFloatingPoint); 118f22ef01cSRoman Divacky } 119f22ef01cSRoman Divacky 12091bc56edSDimitry Andric /// hasScalarTypes - Return true if this TypeSet contains a scalar value type. 12191bc56edSDimitry Andric bool EEVT::TypeSet::hasScalarTypes() const { 122d88c1a5aSDimitry Andric return any_of(TypeVec, isScalar); 12391bc56edSDimitry Andric } 12491bc56edSDimitry Andric 125f22ef01cSRoman Divacky /// hasVectorTypes - Return true if this TypeSet contains a vAny or a vector 126f22ef01cSRoman Divacky /// value type. 127f22ef01cSRoman Divacky bool EEVT::TypeSet::hasVectorTypes() const { 128d88c1a5aSDimitry Andric return any_of(TypeVec, isVector); 129f22ef01cSRoman Divacky } 130f22ef01cSRoman Divacky 131f22ef01cSRoman Divacky 132f22ef01cSRoman Divacky std::string EEVT::TypeSet::getName() const { 133f22ef01cSRoman Divacky if (TypeVec.empty()) return "<empty>"; 134f22ef01cSRoman Divacky 135f22ef01cSRoman Divacky std::string Result; 136f22ef01cSRoman Divacky 137f22ef01cSRoman Divacky for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) { 138f22ef01cSRoman Divacky std::string VTName = llvm::getEnumName(TypeVec[i]); 139f22ef01cSRoman Divacky // Strip off MVT:: prefix if present. 140f22ef01cSRoman Divacky if (VTName.substr(0,5) == "MVT::") 141f22ef01cSRoman Divacky VTName = VTName.substr(5); 142f22ef01cSRoman Divacky if (i) Result += ':'; 143f22ef01cSRoman Divacky Result += VTName; 144f22ef01cSRoman Divacky } 145f22ef01cSRoman Divacky 146f22ef01cSRoman Divacky if (TypeVec.size() == 1) 147f22ef01cSRoman Divacky return Result; 148f22ef01cSRoman Divacky return "{" + Result + "}"; 149f22ef01cSRoman Divacky } 150f22ef01cSRoman Divacky 151f22ef01cSRoman Divacky /// MergeInTypeInfo - This merges in type information from the specified 152f22ef01cSRoman Divacky /// argument. If 'this' changes, it returns true. If the two types are 1533861d79fSDimitry Andric /// contradictory (e.g. merge f32 into i32) then this flags an error. 154f22ef01cSRoman Divacky bool EEVT::TypeSet::MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP){ 1553861d79fSDimitry Andric if (InVT.isCompletelyUnknown() || *this == InVT || TP.hasError()) 156f22ef01cSRoman Divacky return false; 157f22ef01cSRoman Divacky 158f22ef01cSRoman Divacky if (isCompletelyUnknown()) { 159f22ef01cSRoman Divacky *this = InVT; 160f22ef01cSRoman Divacky return true; 161f22ef01cSRoman Divacky } 162f22ef01cSRoman Divacky 1637d523365SDimitry Andric assert(!TypeVec.empty() && !InVT.TypeVec.empty() && "No unknowns"); 164f22ef01cSRoman Divacky 165f22ef01cSRoman Divacky // Handle the abstract cases, seeing if we can resolve them better. 166f22ef01cSRoman Divacky switch (TypeVec[0]) { 167f22ef01cSRoman Divacky default: break; 168f22ef01cSRoman Divacky case MVT::iPTR: 169f22ef01cSRoman Divacky case MVT::iPTRAny: 170f22ef01cSRoman Divacky if (InVT.hasIntegerTypes()) { 171f22ef01cSRoman Divacky EEVT::TypeSet InCopy(InVT); 172f22ef01cSRoman Divacky InCopy.EnforceInteger(TP); 173f22ef01cSRoman Divacky InCopy.EnforceScalar(TP); 174f22ef01cSRoman Divacky 175f22ef01cSRoman Divacky if (InCopy.isConcrete()) { 176f22ef01cSRoman Divacky // If the RHS has one integer type, upgrade iPTR to i32. 177f22ef01cSRoman Divacky TypeVec[0] = InVT.TypeVec[0]; 178f22ef01cSRoman Divacky return true; 179f22ef01cSRoman Divacky } 180f22ef01cSRoman Divacky 181f22ef01cSRoman Divacky // If the input has multiple scalar integers, this doesn't add any info. 182f22ef01cSRoman Divacky if (!InCopy.isCompletelyUnknown()) 183f22ef01cSRoman Divacky return false; 184f22ef01cSRoman Divacky } 185f22ef01cSRoman Divacky break; 186f22ef01cSRoman Divacky } 187f22ef01cSRoman Divacky 188f22ef01cSRoman Divacky // If the input constraint is iAny/iPTR and this is an integer type list, 189f22ef01cSRoman Divacky // remove non-integer types from the list. 190f22ef01cSRoman Divacky if ((InVT.TypeVec[0] == MVT::iPTR || InVT.TypeVec[0] == MVT::iPTRAny) && 191f22ef01cSRoman Divacky hasIntegerTypes()) { 192f22ef01cSRoman Divacky bool MadeChange = EnforceInteger(TP); 193f22ef01cSRoman Divacky 194f22ef01cSRoman Divacky // If we're merging in iPTR/iPTRAny and the node currently has a list of 195f22ef01cSRoman Divacky // multiple different integer types, replace them with a single iPTR. 196f22ef01cSRoman Divacky if ((InVT.TypeVec[0] == MVT::iPTR || InVT.TypeVec[0] == MVT::iPTRAny) && 197f22ef01cSRoman Divacky TypeVec.size() != 1) { 1987d523365SDimitry Andric TypeVec.assign(1, InVT.TypeVec[0]); 199f22ef01cSRoman Divacky MadeChange = true; 200f22ef01cSRoman Divacky } 201f22ef01cSRoman Divacky 202f22ef01cSRoman Divacky return MadeChange; 203f22ef01cSRoman Divacky } 204f22ef01cSRoman Divacky 205f22ef01cSRoman Divacky // If this is a type list and the RHS is a typelist as well, eliminate entries 206f22ef01cSRoman Divacky // from this list that aren't in the other one. 207f22ef01cSRoman Divacky TypeSet InputSet(*this); 208f22ef01cSRoman Divacky 2097d523365SDimitry Andric TypeVec.clear(); 2107d523365SDimitry Andric std::set_intersection(InputSet.TypeVec.begin(), InputSet.TypeVec.end(), 2117d523365SDimitry Andric InVT.TypeVec.begin(), InVT.TypeVec.end(), 2127d523365SDimitry Andric std::back_inserter(TypeVec)); 213f22ef01cSRoman Divacky 2147d523365SDimitry Andric // If the intersection is the same size as the original set then we're done. 2157d523365SDimitry Andric if (TypeVec.size() == InputSet.TypeVec.size()) 2167d523365SDimitry Andric return false; 217f22ef01cSRoman Divacky 218f22ef01cSRoman Divacky // If we removed all of our types, we have a type contradiction. 219f22ef01cSRoman Divacky if (!TypeVec.empty()) 2207d523365SDimitry Andric return true; 221f22ef01cSRoman Divacky 222f22ef01cSRoman Divacky // FIXME: Really want an SMLoc here! 223f22ef01cSRoman Divacky TP.error("Type inference contradiction found, merging '" + 224f22ef01cSRoman Divacky InVT.getName() + "' into '" + InputSet.getName() + "'"); 2253861d79fSDimitry Andric return false; 226f22ef01cSRoman Divacky } 227f22ef01cSRoman Divacky 228f22ef01cSRoman Divacky /// EnforceInteger - Remove all non-integer types from this set. 229f22ef01cSRoman Divacky bool EEVT::TypeSet::EnforceInteger(TreePattern &TP) { 2303861d79fSDimitry Andric if (TP.hasError()) 2313861d79fSDimitry Andric return false; 232f22ef01cSRoman Divacky // If we know nothing, then get the full set. 233f22ef01cSRoman Divacky if (TypeVec.empty()) 234f22ef01cSRoman Divacky return FillWithPossibleTypes(TP, isInteger, "integer"); 2357d523365SDimitry Andric 236f22ef01cSRoman Divacky if (!hasFloatingPointTypes()) 237f22ef01cSRoman Divacky return false; 238f22ef01cSRoman Divacky 239f22ef01cSRoman Divacky TypeSet InputSet(*this); 240f22ef01cSRoman Divacky 241f22ef01cSRoman Divacky // Filter out all the fp types. 242d88c1a5aSDimitry Andric TypeVec.erase(remove_if(TypeVec, std::not1(std::ptr_fun(isInteger))), 2437d523365SDimitry Andric TypeVec.end()); 244f22ef01cSRoman Divacky 2453861d79fSDimitry Andric if (TypeVec.empty()) { 246f22ef01cSRoman Divacky TP.error("Type inference contradiction found, '" + 247f22ef01cSRoman Divacky InputSet.getName() + "' needs to be integer"); 2483861d79fSDimitry Andric return false; 2493861d79fSDimitry Andric } 250f22ef01cSRoman Divacky return true; 251f22ef01cSRoman Divacky } 252f22ef01cSRoman Divacky 253f22ef01cSRoman Divacky /// EnforceFloatingPoint - Remove all integer types from this set. 254f22ef01cSRoman Divacky bool EEVT::TypeSet::EnforceFloatingPoint(TreePattern &TP) { 2553861d79fSDimitry Andric if (TP.hasError()) 2563861d79fSDimitry Andric return false; 257f22ef01cSRoman Divacky // If we know nothing, then get the full set. 258f22ef01cSRoman Divacky if (TypeVec.empty()) 259f22ef01cSRoman Divacky return FillWithPossibleTypes(TP, isFloatingPoint, "floating point"); 260f22ef01cSRoman Divacky 261f22ef01cSRoman Divacky if (!hasIntegerTypes()) 262f22ef01cSRoman Divacky return false; 263f22ef01cSRoman Divacky 264f22ef01cSRoman Divacky TypeSet InputSet(*this); 265f22ef01cSRoman Divacky 2667d523365SDimitry Andric // Filter out all the integer types. 267d88c1a5aSDimitry Andric TypeVec.erase(remove_if(TypeVec, std::not1(std::ptr_fun(isFloatingPoint))), 2687d523365SDimitry Andric TypeVec.end()); 269f22ef01cSRoman Divacky 2703861d79fSDimitry Andric if (TypeVec.empty()) { 271f22ef01cSRoman Divacky TP.error("Type inference contradiction found, '" + 272f22ef01cSRoman Divacky InputSet.getName() + "' needs to be floating point"); 2733861d79fSDimitry Andric return false; 2743861d79fSDimitry Andric } 275f22ef01cSRoman Divacky return true; 276f22ef01cSRoman Divacky } 277f22ef01cSRoman Divacky 278f22ef01cSRoman Divacky /// EnforceScalar - Remove all vector types from this. 279f22ef01cSRoman Divacky bool EEVT::TypeSet::EnforceScalar(TreePattern &TP) { 2803861d79fSDimitry Andric if (TP.hasError()) 2813861d79fSDimitry Andric return false; 2823861d79fSDimitry Andric 283f22ef01cSRoman Divacky // If we know nothing, then get the full set. 284f22ef01cSRoman Divacky if (TypeVec.empty()) 285f22ef01cSRoman Divacky return FillWithPossibleTypes(TP, isScalar, "scalar"); 286f22ef01cSRoman Divacky 287f22ef01cSRoman Divacky if (!hasVectorTypes()) 288f22ef01cSRoman Divacky return false; 289f22ef01cSRoman Divacky 290f22ef01cSRoman Divacky TypeSet InputSet(*this); 291f22ef01cSRoman Divacky 292f22ef01cSRoman Divacky // Filter out all the vector types. 293d88c1a5aSDimitry Andric TypeVec.erase(remove_if(TypeVec, std::not1(std::ptr_fun(isScalar))), 2947d523365SDimitry Andric TypeVec.end()); 295f22ef01cSRoman Divacky 2963861d79fSDimitry Andric if (TypeVec.empty()) { 297f22ef01cSRoman Divacky TP.error("Type inference contradiction found, '" + 298f22ef01cSRoman Divacky InputSet.getName() + "' needs to be scalar"); 2993861d79fSDimitry Andric return false; 3003861d79fSDimitry Andric } 301f22ef01cSRoman Divacky return true; 302f22ef01cSRoman Divacky } 303f22ef01cSRoman Divacky 304f22ef01cSRoman Divacky /// EnforceVector - Remove all vector types from this. 305f22ef01cSRoman Divacky bool EEVT::TypeSet::EnforceVector(TreePattern &TP) { 3063861d79fSDimitry Andric if (TP.hasError()) 3073861d79fSDimitry Andric return false; 3083861d79fSDimitry Andric 309f22ef01cSRoman Divacky // If we know nothing, then get the full set. 310f22ef01cSRoman Divacky if (TypeVec.empty()) 311f22ef01cSRoman Divacky return FillWithPossibleTypes(TP, isVector, "vector"); 312f22ef01cSRoman Divacky 313f22ef01cSRoman Divacky TypeSet InputSet(*this); 314f22ef01cSRoman Divacky bool MadeChange = false; 315f22ef01cSRoman Divacky 316f22ef01cSRoman Divacky // Filter out all the scalar types. 317d88c1a5aSDimitry Andric TypeVec.erase(remove_if(TypeVec, std::not1(std::ptr_fun(isVector))), 3187d523365SDimitry Andric TypeVec.end()); 319f22ef01cSRoman Divacky 3203861d79fSDimitry Andric if (TypeVec.empty()) { 321f22ef01cSRoman Divacky TP.error("Type inference contradiction found, '" + 322f22ef01cSRoman Divacky InputSet.getName() + "' needs to be a vector"); 3233861d79fSDimitry Andric return false; 3243861d79fSDimitry Andric } 325f22ef01cSRoman Divacky return MadeChange; 326f22ef01cSRoman Divacky } 327f22ef01cSRoman Divacky 328f22ef01cSRoman Divacky 329f22ef01cSRoman Divacky 33091bc56edSDimitry Andric /// EnforceSmallerThan - 'this' must be a smaller VT than Other. For vectors 3317d523365SDimitry Andric /// this should be based on the element type. Update this and other based on 33291bc56edSDimitry Andric /// this information. 333f22ef01cSRoman Divacky bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { 3343861d79fSDimitry Andric if (TP.hasError()) 3353861d79fSDimitry Andric return false; 3363861d79fSDimitry Andric 337f22ef01cSRoman Divacky // Both operands must be integer or FP, but we don't care which. 338f22ef01cSRoman Divacky bool MadeChange = false; 339f22ef01cSRoman Divacky 340f22ef01cSRoman Divacky if (isCompletelyUnknown()) 341f22ef01cSRoman Divacky MadeChange = FillWithPossibleTypes(TP); 342f22ef01cSRoman Divacky 343f22ef01cSRoman Divacky if (Other.isCompletelyUnknown()) 344f22ef01cSRoman Divacky MadeChange = Other.FillWithPossibleTypes(TP); 345f22ef01cSRoman Divacky 346f22ef01cSRoman Divacky // If one side is known to be integer or known to be FP but the other side has 347f22ef01cSRoman Divacky // no information, get at least the type integrality info in there. 348f22ef01cSRoman Divacky if (!hasFloatingPointTypes()) 349f22ef01cSRoman Divacky MadeChange |= Other.EnforceInteger(TP); 350f22ef01cSRoman Divacky else if (!hasIntegerTypes()) 351f22ef01cSRoman Divacky MadeChange |= Other.EnforceFloatingPoint(TP); 352f22ef01cSRoman Divacky if (!Other.hasFloatingPointTypes()) 353f22ef01cSRoman Divacky MadeChange |= EnforceInteger(TP); 354f22ef01cSRoman Divacky else if (!Other.hasIntegerTypes()) 355f22ef01cSRoman Divacky MadeChange |= EnforceFloatingPoint(TP); 356f22ef01cSRoman Divacky 357f22ef01cSRoman Divacky assert(!isCompletelyUnknown() && !Other.isCompletelyUnknown() && 358f22ef01cSRoman Divacky "Should have a type list now"); 359f22ef01cSRoman Divacky 360f22ef01cSRoman Divacky // If one contains vectors but the other doesn't pull vectors out. 361f22ef01cSRoman Divacky if (!hasVectorTypes()) 362f22ef01cSRoman Divacky MadeChange |= Other.EnforceScalar(TP); 36391bc56edSDimitry Andric else if (!hasScalarTypes()) 36491bc56edSDimitry Andric MadeChange |= Other.EnforceVector(TP); 36591bc56edSDimitry Andric if (!Other.hasVectorTypes()) 366f22ef01cSRoman Divacky MadeChange |= EnforceScalar(TP); 36791bc56edSDimitry Andric else if (!Other.hasScalarTypes()) 36891bc56edSDimitry Andric MadeChange |= EnforceVector(TP); 369f22ef01cSRoman Divacky 37091bc56edSDimitry Andric // This code does not currently handle nodes which have multiple types, 37191bc56edSDimitry Andric // where some types are integer, and some are fp. Assert that this is not 37291bc56edSDimitry Andric // the case. 373f22ef01cSRoman Divacky assert(!(hasIntegerTypes() && hasFloatingPointTypes()) && 374f22ef01cSRoman Divacky !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) && 375f22ef01cSRoman Divacky "SDTCisOpSmallerThanOp does not handle mixed int/fp types!"); 376f22ef01cSRoman Divacky 37791bc56edSDimitry Andric if (TP.hasError()) 3783861d79fSDimitry Andric return false; 3792754fe60SDimitry Andric 380ff0cc061SDimitry Andric // Okay, find the smallest type from current set and remove anything the 381ff0cc061SDimitry Andric // same or smaller from the other set. We need to ensure that the scalar 382ff0cc061SDimitry Andric // type size is smaller than the scalar size of the smallest type. For 383ff0cc061SDimitry Andric // vectors, we also need to make sure that the total size is no larger than 384ff0cc061SDimitry Andric // the size of the smallest type. 3857d523365SDimitry Andric { 38691bc56edSDimitry Andric TypeSet InputSet(Other); 3877d523365SDimitry Andric MVT Smallest = *std::min_element(TypeVec.begin(), TypeVec.end(), 3887d523365SDimitry Andric [](MVT A, MVT B) { 3897d523365SDimitry Andric return A.getScalarSizeInBits() < B.getScalarSizeInBits() || 3907d523365SDimitry Andric (A.getScalarSizeInBits() == B.getScalarSizeInBits() && 3917d523365SDimitry Andric A.getSizeInBits() < B.getSizeInBits()); 3927d523365SDimitry Andric }); 3937d523365SDimitry Andric 394d88c1a5aSDimitry Andric auto I = remove_if(Other.TypeVec, [Smallest](MVT OtherVT) { 395ff0cc061SDimitry Andric // Don't compare vector and non-vector types. 396ff0cc061SDimitry Andric if (OtherVT.isVector() != Smallest.isVector()) 3977d523365SDimitry Andric return false; 398ff0cc061SDimitry Andric // The getSizeInBits() check here is only needed for vectors, but is 399ff0cc061SDimitry Andric // a subset of the scalar check for scalars so no need to qualify. 4007d523365SDimitry Andric return OtherVT.getScalarSizeInBits() <= Smallest.getScalarSizeInBits() || 4017d523365SDimitry Andric OtherVT.getSizeInBits() < Smallest.getSizeInBits(); 4027d523365SDimitry Andric }); 4037d523365SDimitry Andric MadeChange |= I != Other.TypeVec.end(); // If we're about to remove types. 4047d523365SDimitry Andric Other.TypeVec.erase(I, Other.TypeVec.end()); 405f22ef01cSRoman Divacky 40691bc56edSDimitry Andric if (Other.TypeVec.empty()) { 40791bc56edSDimitry Andric TP.error("Type inference contradiction found, '" + InputSet.getName() + 40891bc56edSDimitry Andric "' has nothing larger than '" + getName() +"'!"); 4093861d79fSDimitry Andric return false; 4103861d79fSDimitry Andric } 4117d523365SDimitry Andric } 412f22ef01cSRoman Divacky 413ff0cc061SDimitry Andric // Okay, find the largest type from the other set and remove anything the 414ff0cc061SDimitry Andric // same or smaller from the current set. We need to ensure that the scalar 415ff0cc061SDimitry Andric // type size is larger than the scalar size of the largest type. For 416ff0cc061SDimitry Andric // vectors, we also need to make sure that the total size is no smaller than 417ff0cc061SDimitry Andric // the size of the largest type. 4187d523365SDimitry Andric { 4197d523365SDimitry Andric TypeSet InputSet(*this); 4207d523365SDimitry Andric MVT Largest = *std::max_element(Other.TypeVec.begin(), Other.TypeVec.end(), 4217d523365SDimitry Andric [](MVT A, MVT B) { 4227d523365SDimitry Andric return A.getScalarSizeInBits() < B.getScalarSizeInBits() || 4237d523365SDimitry Andric (A.getScalarSizeInBits() == B.getScalarSizeInBits() && 4247d523365SDimitry Andric A.getSizeInBits() < B.getSizeInBits()); 4257d523365SDimitry Andric }); 426d88c1a5aSDimitry Andric auto I = remove_if(TypeVec, [Largest](MVT OtherVT) { 427ff0cc061SDimitry Andric // Don't compare vector and non-vector types. 428ff0cc061SDimitry Andric if (OtherVT.isVector() != Largest.isVector()) 4297d523365SDimitry Andric return false; 4307d523365SDimitry Andric return OtherVT.getScalarSizeInBits() >= Largest.getScalarSizeInBits() || 4317d523365SDimitry Andric OtherVT.getSizeInBits() > Largest.getSizeInBits(); 4327d523365SDimitry Andric }); 4337d523365SDimitry Andric MadeChange |= I != TypeVec.end(); // If we're about to remove types. 4347d523365SDimitry Andric TypeVec.erase(I, TypeVec.end()); 435f22ef01cSRoman Divacky 43691bc56edSDimitry Andric if (TypeVec.empty()) { 43791bc56edSDimitry Andric TP.error("Type inference contradiction found, '" + InputSet.getName() + 43891bc56edSDimitry Andric "' has nothing smaller than '" + Other.getName() +"'!"); 4393861d79fSDimitry Andric return false; 4403861d79fSDimitry Andric } 4417d523365SDimitry Andric } 442f22ef01cSRoman Divacky 443f22ef01cSRoman Divacky return MadeChange; 444f22ef01cSRoman Divacky } 445f22ef01cSRoman Divacky 4467d523365SDimitry Andric /// EnforceVectorEltTypeIs - 'this' is now constrained to be a vector type 447f22ef01cSRoman Divacky /// whose element is specified by VTOperand. 448ff0cc061SDimitry Andric bool EEVT::TypeSet::EnforceVectorEltTypeIs(MVT::SimpleValueType VT, 449ff0cc061SDimitry Andric TreePattern &TP) { 450ff0cc061SDimitry Andric bool MadeChange = false; 451ff0cc061SDimitry Andric 452ff0cc061SDimitry Andric MadeChange |= EnforceVector(TP); 453ff0cc061SDimitry Andric 454ff0cc061SDimitry Andric TypeSet InputSet(*this); 455ff0cc061SDimitry Andric 456ff0cc061SDimitry Andric // Filter out all the types which don't have the right element type. 457d88c1a5aSDimitry Andric auto I = remove_if(TypeVec, [VT](MVT VVT) { 4587d523365SDimitry Andric return VVT.getVectorElementType().SimpleTy != VT; 4597d523365SDimitry Andric }); 4607d523365SDimitry Andric MadeChange |= I != TypeVec.end(); 4617d523365SDimitry Andric TypeVec.erase(I, TypeVec.end()); 462ff0cc061SDimitry Andric 463ff0cc061SDimitry Andric if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! 464ff0cc061SDimitry Andric TP.error("Type inference contradiction found, forcing '" + 4657d523365SDimitry Andric InputSet.getName() + "' to have a vector element of type " + 4667d523365SDimitry Andric getEnumName(VT)); 467ff0cc061SDimitry Andric return false; 468ff0cc061SDimitry Andric } 469ff0cc061SDimitry Andric 470ff0cc061SDimitry Andric return MadeChange; 471ff0cc061SDimitry Andric } 472ff0cc061SDimitry Andric 4737d523365SDimitry Andric /// EnforceVectorEltTypeIs - 'this' is now constrained to be a vector type 474ff0cc061SDimitry Andric /// whose element is specified by VTOperand. 475f22ef01cSRoman Divacky bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand, 476f22ef01cSRoman Divacky TreePattern &TP) { 4773861d79fSDimitry Andric if (TP.hasError()) 4783861d79fSDimitry Andric return false; 4793861d79fSDimitry Andric 480f22ef01cSRoman Divacky // "This" must be a vector and "VTOperand" must be a scalar. 481f22ef01cSRoman Divacky bool MadeChange = false; 482f22ef01cSRoman Divacky MadeChange |= EnforceVector(TP); 483f22ef01cSRoman Divacky MadeChange |= VTOperand.EnforceScalar(TP); 484f22ef01cSRoman Divacky 485f22ef01cSRoman Divacky // If we know the vector type, it forces the scalar to agree. 486f22ef01cSRoman Divacky if (isConcrete()) { 487f785676fSDimitry Andric MVT IVT = getConcrete(); 488f22ef01cSRoman Divacky IVT = IVT.getVectorElementType(); 4897d523365SDimitry Andric return MadeChange || VTOperand.MergeInTypeInfo(IVT.SimpleTy, TP); 490f22ef01cSRoman Divacky } 491f22ef01cSRoman Divacky 492f22ef01cSRoman Divacky // If the scalar type is known, filter out vector types whose element types 493f22ef01cSRoman Divacky // disagree. 494f22ef01cSRoman Divacky if (!VTOperand.isConcrete()) 495f22ef01cSRoman Divacky return MadeChange; 496f22ef01cSRoman Divacky 497f22ef01cSRoman Divacky MVT::SimpleValueType VT = VTOperand.getConcrete(); 498f22ef01cSRoman Divacky 4997d523365SDimitry Andric MadeChange |= EnforceVectorEltTypeIs(VT, TP); 500f22ef01cSRoman Divacky 501f22ef01cSRoman Divacky return MadeChange; 502f22ef01cSRoman Divacky } 503f22ef01cSRoman Divacky 5047d523365SDimitry Andric /// EnforceVectorSubVectorTypeIs - 'this' is now constrained to be a 5052754fe60SDimitry Andric /// vector type specified by VTOperand. 5062754fe60SDimitry Andric bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand, 5072754fe60SDimitry Andric TreePattern &TP) { 50891bc56edSDimitry Andric if (TP.hasError()) 50991bc56edSDimitry Andric return false; 51091bc56edSDimitry Andric 5112754fe60SDimitry Andric // "This" must be a vector and "VTOperand" must be a vector. 5122754fe60SDimitry Andric bool MadeChange = false; 5132754fe60SDimitry Andric MadeChange |= EnforceVector(TP); 5142754fe60SDimitry Andric MadeChange |= VTOperand.EnforceVector(TP); 5152754fe60SDimitry Andric 51691bc56edSDimitry Andric // If one side is known to be integer or known to be FP but the other side has 51791bc56edSDimitry Andric // no information, get at least the type integrality info in there. 51891bc56edSDimitry Andric if (!hasFloatingPointTypes()) 51991bc56edSDimitry Andric MadeChange |= VTOperand.EnforceInteger(TP); 52091bc56edSDimitry Andric else if (!hasIntegerTypes()) 52191bc56edSDimitry Andric MadeChange |= VTOperand.EnforceFloatingPoint(TP); 52291bc56edSDimitry Andric if (!VTOperand.hasFloatingPointTypes()) 52391bc56edSDimitry Andric MadeChange |= EnforceInteger(TP); 52491bc56edSDimitry Andric else if (!VTOperand.hasIntegerTypes()) 52591bc56edSDimitry Andric MadeChange |= EnforceFloatingPoint(TP); 52691bc56edSDimitry Andric 52791bc56edSDimitry Andric assert(!isCompletelyUnknown() && !VTOperand.isCompletelyUnknown() && 52891bc56edSDimitry Andric "Should have a type list now"); 5292754fe60SDimitry Andric 5302754fe60SDimitry Andric // If we know the vector type, it forces the scalar types to agree. 53191bc56edSDimitry Andric // Also force one vector to have more elements than the other. 5322754fe60SDimitry Andric if (isConcrete()) { 533f785676fSDimitry Andric MVT IVT = getConcrete(); 53491bc56edSDimitry Andric unsigned NumElems = IVT.getVectorNumElements(); 5352754fe60SDimitry Andric IVT = IVT.getVectorElementType(); 5362754fe60SDimitry Andric 537f785676fSDimitry Andric EEVT::TypeSet EltTypeSet(IVT.SimpleTy, TP); 5382754fe60SDimitry Andric MadeChange |= VTOperand.EnforceVectorEltTypeIs(EltTypeSet, TP); 53991bc56edSDimitry Andric 54091bc56edSDimitry Andric // Only keep types that have less elements than VTOperand. 54191bc56edSDimitry Andric TypeSet InputSet(VTOperand); 54291bc56edSDimitry Andric 543d88c1a5aSDimitry Andric auto I = remove_if(VTOperand.TypeVec, [NumElems](MVT VVT) { 5447d523365SDimitry Andric return VVT.getVectorNumElements() >= NumElems; 5457d523365SDimitry Andric }); 5467d523365SDimitry Andric MadeChange |= I != VTOperand.TypeVec.end(); 5477d523365SDimitry Andric VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end()); 5487d523365SDimitry Andric 54991bc56edSDimitry Andric if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here! 55091bc56edSDimitry Andric TP.error("Type inference contradiction found, forcing '" + 55191bc56edSDimitry Andric InputSet.getName() + "' to have less vector elements than '" + 55291bc56edSDimitry Andric getName() + "'"); 55391bc56edSDimitry Andric return false; 55491bc56edSDimitry Andric } 5552754fe60SDimitry Andric } else if (VTOperand.isConcrete()) { 556f785676fSDimitry Andric MVT IVT = VTOperand.getConcrete(); 55791bc56edSDimitry Andric unsigned NumElems = IVT.getVectorNumElements(); 5582754fe60SDimitry Andric IVT = IVT.getVectorElementType(); 5592754fe60SDimitry Andric 560f785676fSDimitry Andric EEVT::TypeSet EltTypeSet(IVT.SimpleTy, TP); 5612754fe60SDimitry Andric MadeChange |= EnforceVectorEltTypeIs(EltTypeSet, TP); 56291bc56edSDimitry Andric 56391bc56edSDimitry Andric // Only keep types that have more elements than 'this'. 56491bc56edSDimitry Andric TypeSet InputSet(*this); 56591bc56edSDimitry Andric 566d88c1a5aSDimitry Andric auto I = remove_if(TypeVec, [NumElems](MVT VVT) { 5677d523365SDimitry Andric return VVT.getVectorNumElements() <= NumElems; 5687d523365SDimitry Andric }); 5697d523365SDimitry Andric MadeChange |= I != TypeVec.end(); 5707d523365SDimitry Andric TypeVec.erase(I, TypeVec.end()); 5717d523365SDimitry Andric 57291bc56edSDimitry Andric if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! 57391bc56edSDimitry Andric TP.error("Type inference contradiction found, forcing '" + 57491bc56edSDimitry Andric InputSet.getName() + "' to have more vector elements than '" + 57591bc56edSDimitry Andric VTOperand.getName() + "'"); 57691bc56edSDimitry Andric return false; 57791bc56edSDimitry Andric } 5782754fe60SDimitry Andric } 5792754fe60SDimitry Andric 5802754fe60SDimitry Andric return MadeChange; 5812754fe60SDimitry Andric } 5822754fe60SDimitry Andric 5837a7e6055SDimitry Andric /// EnforceameNumElts - If VTOperand is a scalar, then 'this' is a scalar. If 5847a7e6055SDimitry Andric /// VTOperand is a vector, then 'this' must have the same number of elements. 5857a7e6055SDimitry Andric bool EEVT::TypeSet::EnforceSameNumElts(EEVT::TypeSet &VTOperand, 586ff0cc061SDimitry Andric TreePattern &TP) { 587ff0cc061SDimitry Andric if (TP.hasError()) 588ff0cc061SDimitry Andric return false; 589ff0cc061SDimitry Andric 590ff0cc061SDimitry Andric bool MadeChange = false; 591ff0cc061SDimitry Andric 5927a7e6055SDimitry Andric if (isCompletelyUnknown()) 5937a7e6055SDimitry Andric MadeChange = FillWithPossibleTypes(TP); 5947a7e6055SDimitry Andric 5957a7e6055SDimitry Andric if (VTOperand.isCompletelyUnknown()) 5967a7e6055SDimitry Andric MadeChange = VTOperand.FillWithPossibleTypes(TP); 5977a7e6055SDimitry Andric 5987a7e6055SDimitry Andric // If one contains vectors but the other doesn't pull vectors out. 5997a7e6055SDimitry Andric if (!hasVectorTypes()) 6007a7e6055SDimitry Andric MadeChange |= VTOperand.EnforceScalar(TP); 6017a7e6055SDimitry Andric else if (!hasScalarTypes()) 6027a7e6055SDimitry Andric MadeChange |= VTOperand.EnforceVector(TP); 6037a7e6055SDimitry Andric if (!VTOperand.hasVectorTypes()) 6047a7e6055SDimitry Andric MadeChange |= EnforceScalar(TP); 6057a7e6055SDimitry Andric else if (!VTOperand.hasScalarTypes()) 6067a7e6055SDimitry Andric MadeChange |= EnforceVector(TP); 6077a7e6055SDimitry Andric 6087a7e6055SDimitry Andric // If one type is a vector, make sure the other has the same element count. 6097a7e6055SDimitry Andric // If this a scalar, then we are already done with the above. 610ff0cc061SDimitry Andric if (isConcrete()) { 611ff0cc061SDimitry Andric MVT IVT = getConcrete(); 6127a7e6055SDimitry Andric if (IVT.isVector()) { 613ff0cc061SDimitry Andric unsigned NumElems = IVT.getVectorNumElements(); 614ff0cc061SDimitry Andric 6157d523365SDimitry Andric // Only keep types that have same elements as 'this'. 616ff0cc061SDimitry Andric TypeSet InputSet(VTOperand); 617ff0cc061SDimitry Andric 618d88c1a5aSDimitry Andric auto I = remove_if(VTOperand.TypeVec, [NumElems](MVT VVT) { 6197d523365SDimitry Andric return VVT.getVectorNumElements() != NumElems; 6207d523365SDimitry Andric }); 6217d523365SDimitry Andric MadeChange |= I != VTOperand.TypeVec.end(); 6227d523365SDimitry Andric VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end()); 6237d523365SDimitry Andric 624ff0cc061SDimitry Andric if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here! 625ff0cc061SDimitry Andric TP.error("Type inference contradiction found, forcing '" + 626ff0cc061SDimitry Andric InputSet.getName() + "' to have same number elements as '" + 627ff0cc061SDimitry Andric getName() + "'"); 628ff0cc061SDimitry Andric return false; 629ff0cc061SDimitry Andric } 6307a7e6055SDimitry Andric } 631ff0cc061SDimitry Andric } else if (VTOperand.isConcrete()) { 632ff0cc061SDimitry Andric MVT IVT = VTOperand.getConcrete(); 6337a7e6055SDimitry Andric if (IVT.isVector()) { 634ff0cc061SDimitry Andric unsigned NumElems = IVT.getVectorNumElements(); 635ff0cc061SDimitry Andric 6367d523365SDimitry Andric // Only keep types that have same elements as VTOperand. 637ff0cc061SDimitry Andric TypeSet InputSet(*this); 638ff0cc061SDimitry Andric 639d88c1a5aSDimitry Andric auto I = remove_if(TypeVec, [NumElems](MVT VVT) { 6407d523365SDimitry Andric return VVT.getVectorNumElements() != NumElems; 6417d523365SDimitry Andric }); 6427d523365SDimitry Andric MadeChange |= I != TypeVec.end(); 6437d523365SDimitry Andric TypeVec.erase(I, TypeVec.end()); 6447d523365SDimitry Andric 645ff0cc061SDimitry Andric if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! 646ff0cc061SDimitry Andric TP.error("Type inference contradiction found, forcing '" + 647ff0cc061SDimitry Andric InputSet.getName() + "' to have same number elements than '" + 648ff0cc061SDimitry Andric VTOperand.getName() + "'"); 649ff0cc061SDimitry Andric return false; 650ff0cc061SDimitry Andric } 651ff0cc061SDimitry Andric } 6527a7e6055SDimitry Andric } 653ff0cc061SDimitry Andric 654ff0cc061SDimitry Andric return MadeChange; 655ff0cc061SDimitry Andric } 656ff0cc061SDimitry Andric 6577d523365SDimitry Andric /// EnforceSameSize - 'this' is now constrained to be same size as VTOperand. 6587d523365SDimitry Andric bool EEVT::TypeSet::EnforceSameSize(EEVT::TypeSet &VTOperand, 6597d523365SDimitry Andric TreePattern &TP) { 6607d523365SDimitry Andric if (TP.hasError()) 6617d523365SDimitry Andric return false; 6627d523365SDimitry Andric 6637d523365SDimitry Andric bool MadeChange = false; 6647d523365SDimitry Andric 6657a7e6055SDimitry Andric if (isCompletelyUnknown()) 6667a7e6055SDimitry Andric MadeChange = FillWithPossibleTypes(TP); 6677a7e6055SDimitry Andric 6687a7e6055SDimitry Andric if (VTOperand.isCompletelyUnknown()) 6697a7e6055SDimitry Andric MadeChange = VTOperand.FillWithPossibleTypes(TP); 6707a7e6055SDimitry Andric 6717d523365SDimitry Andric // If we know one of the types, it forces the other type agree. 6727d523365SDimitry Andric if (isConcrete()) { 6737d523365SDimitry Andric MVT IVT = getConcrete(); 6747d523365SDimitry Andric unsigned Size = IVT.getSizeInBits(); 6757d523365SDimitry Andric 6767d523365SDimitry Andric // Only keep types that have the same size as 'this'. 6777d523365SDimitry Andric TypeSet InputSet(VTOperand); 6787d523365SDimitry Andric 679d88c1a5aSDimitry Andric auto I = remove_if(VTOperand.TypeVec, 680d88c1a5aSDimitry Andric [&](MVT VT) { return VT.getSizeInBits() != Size; }); 6817d523365SDimitry Andric MadeChange |= I != VTOperand.TypeVec.end(); 6827d523365SDimitry Andric VTOperand.TypeVec.erase(I, VTOperand.TypeVec.end()); 6837d523365SDimitry Andric 6847d523365SDimitry Andric if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here! 6857d523365SDimitry Andric TP.error("Type inference contradiction found, forcing '" + 6867d523365SDimitry Andric InputSet.getName() + "' to have same size as '" + 6877d523365SDimitry Andric getName() + "'"); 6887d523365SDimitry Andric return false; 6897d523365SDimitry Andric } 6907d523365SDimitry Andric } else if (VTOperand.isConcrete()) { 6917d523365SDimitry Andric MVT IVT = VTOperand.getConcrete(); 6927d523365SDimitry Andric unsigned Size = IVT.getSizeInBits(); 6937d523365SDimitry Andric 6947d523365SDimitry Andric // Only keep types that have the same size as VTOperand. 6957d523365SDimitry Andric TypeSet InputSet(*this); 6967d523365SDimitry Andric 697d88c1a5aSDimitry Andric auto I = 698d88c1a5aSDimitry Andric remove_if(TypeVec, [&](MVT VT) { return VT.getSizeInBits() != Size; }); 6997d523365SDimitry Andric MadeChange |= I != TypeVec.end(); 7007d523365SDimitry Andric TypeVec.erase(I, TypeVec.end()); 7017d523365SDimitry Andric 7027d523365SDimitry Andric if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! 7037d523365SDimitry Andric TP.error("Type inference contradiction found, forcing '" + 7047d523365SDimitry Andric InputSet.getName() + "' to have same size as '" + 7057d523365SDimitry Andric VTOperand.getName() + "'"); 7067d523365SDimitry Andric return false; 7077d523365SDimitry Andric } 7087d523365SDimitry Andric } 7097d523365SDimitry Andric 7107d523365SDimitry Andric return MadeChange; 7117d523365SDimitry Andric } 7127d523365SDimitry Andric 713f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 714f22ef01cSRoman Divacky // Helpers for working with extended types. 715f22ef01cSRoman Divacky 716f22ef01cSRoman Divacky /// Dependent variable map for CodeGenDAGPattern variant generation 717f22ef01cSRoman Divacky typedef std::map<std::string, int> DepVarMap; 718f22ef01cSRoman Divacky 7193b0f4066SDimitry Andric static void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) { 720f22ef01cSRoman Divacky if (N->isLeaf()) { 7213861d79fSDimitry Andric if (isa<DefInit>(N->getLeafValue())) 722f22ef01cSRoman Divacky DepMap[N->getName()]++; 723f22ef01cSRoman Divacky } else { 724f22ef01cSRoman Divacky for (size_t i = 0, e = N->getNumChildren(); i != e; ++i) 725f22ef01cSRoman Divacky FindDepVarsOf(N->getChild(i), DepMap); 726f22ef01cSRoman Divacky } 727f22ef01cSRoman Divacky } 728f22ef01cSRoman Divacky 7293b0f4066SDimitry Andric /// Find dependent variables within child patterns 7303b0f4066SDimitry Andric static void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) { 731f22ef01cSRoman Divacky DepVarMap depcounts; 732f22ef01cSRoman Divacky FindDepVarsOf(N, depcounts); 7337d523365SDimitry Andric for (const std::pair<std::string, int> &Pair : depcounts) { 7347d523365SDimitry Andric if (Pair.second > 1) 7357d523365SDimitry Andric DepVars.insert(Pair.first); 736f22ef01cSRoman Divacky } 737f22ef01cSRoman Divacky } 738f22ef01cSRoman Divacky 7392754fe60SDimitry Andric #ifndef NDEBUG 7403b0f4066SDimitry Andric /// Dump the dependent variable set: 7413b0f4066SDimitry Andric static void DumpDepVars(MultipleUseVarSet &DepVars) { 742f22ef01cSRoman Divacky if (DepVars.empty()) { 743f22ef01cSRoman Divacky DEBUG(errs() << "<empty set>"); 744f22ef01cSRoman Divacky } else { 745f22ef01cSRoman Divacky DEBUG(errs() << "[ "); 7467d523365SDimitry Andric for (const std::string &DepVar : DepVars) { 7477d523365SDimitry Andric DEBUG(errs() << DepVar << " "); 748f22ef01cSRoman Divacky } 749f22ef01cSRoman Divacky DEBUG(errs() << "]"); 750f22ef01cSRoman Divacky } 751f22ef01cSRoman Divacky } 7522754fe60SDimitry Andric #endif 7532754fe60SDimitry Andric 7543b0f4066SDimitry Andric 7553b0f4066SDimitry Andric //===----------------------------------------------------------------------===// 7563b0f4066SDimitry Andric // TreePredicateFn Implementation 7573b0f4066SDimitry Andric //===----------------------------------------------------------------------===// 7583b0f4066SDimitry Andric 7593b0f4066SDimitry Andric /// TreePredicateFn constructor. Here 'N' is a subclass of PatFrag. 7603b0f4066SDimitry Andric TreePredicateFn::TreePredicateFn(TreePattern *N) : PatFragRec(N) { 7613b0f4066SDimitry Andric assert((getPredCode().empty() || getImmCode().empty()) && 7623b0f4066SDimitry Andric ".td file corrupt: can't have a node predicate *and* an imm predicate"); 7633b0f4066SDimitry Andric } 7643b0f4066SDimitry Andric 7653b0f4066SDimitry Andric std::string TreePredicateFn::getPredCode() const { 766dff0c46cSDimitry Andric return PatFragRec->getRecord()->getValueAsString("PredicateCode"); 7673b0f4066SDimitry Andric } 7683b0f4066SDimitry Andric 7693b0f4066SDimitry Andric std::string TreePredicateFn::getImmCode() const { 770dff0c46cSDimitry Andric return PatFragRec->getRecord()->getValueAsString("ImmediateCode"); 7713b0f4066SDimitry Andric } 7723b0f4066SDimitry Andric 7733b0f4066SDimitry Andric 7743b0f4066SDimitry Andric /// isAlwaysTrue - Return true if this is a noop predicate. 7753b0f4066SDimitry Andric bool TreePredicateFn::isAlwaysTrue() const { 7763b0f4066SDimitry Andric return getPredCode().empty() && getImmCode().empty(); 7773b0f4066SDimitry Andric } 7783b0f4066SDimitry Andric 7793b0f4066SDimitry Andric /// Return the name to use in the generated code to reference this, this is 7803b0f4066SDimitry Andric /// "Predicate_foo" if from a pattern fragment "foo". 7813b0f4066SDimitry Andric std::string TreePredicateFn::getFnName() const { 782d88c1a5aSDimitry Andric return "Predicate_" + PatFragRec->getRecord()->getName().str(); 7833b0f4066SDimitry Andric } 7843b0f4066SDimitry Andric 7853b0f4066SDimitry Andric /// getCodeToRunOnSDNode - Return the code for the function body that 7863b0f4066SDimitry Andric /// evaluates this predicate. The argument is expected to be in "Node", 7873b0f4066SDimitry Andric /// not N. This handles casting and conversion to a concrete node type as 7883b0f4066SDimitry Andric /// appropriate. 7893b0f4066SDimitry Andric std::string TreePredicateFn::getCodeToRunOnSDNode() const { 7903b0f4066SDimitry Andric // Handle immediate predicates first. 7913b0f4066SDimitry Andric std::string ImmCode = getImmCode(); 7923b0f4066SDimitry Andric if (!ImmCode.empty()) { 7933b0f4066SDimitry Andric std::string Result = 7943b0f4066SDimitry Andric " int64_t Imm = cast<ConstantSDNode>(Node)->getSExtValue();\n"; 7953b0f4066SDimitry Andric return Result + ImmCode; 7963b0f4066SDimitry Andric } 7973b0f4066SDimitry Andric 7983b0f4066SDimitry Andric // Handle arbitrary node predicates. 7993b0f4066SDimitry Andric assert(!getPredCode().empty() && "Don't have any predicate code!"); 8003b0f4066SDimitry Andric std::string ClassName; 8013b0f4066SDimitry Andric if (PatFragRec->getOnlyTree()->isLeaf()) 8023b0f4066SDimitry Andric ClassName = "SDNode"; 8033b0f4066SDimitry Andric else { 8043b0f4066SDimitry Andric Record *Op = PatFragRec->getOnlyTree()->getOperator(); 8053b0f4066SDimitry Andric ClassName = PatFragRec->getDAGPatterns().getSDNodeInfo(Op).getSDClassName(); 8063b0f4066SDimitry Andric } 8073b0f4066SDimitry Andric std::string Result; 8083b0f4066SDimitry Andric if (ClassName == "SDNode") 8093b0f4066SDimitry Andric Result = " SDNode *N = Node;\n"; 8103b0f4066SDimitry Andric else 8117d523365SDimitry Andric Result = " auto *N = cast<" + ClassName + ">(Node);\n"; 8123b0f4066SDimitry Andric 8133b0f4066SDimitry Andric return Result + getPredCode(); 814f22ef01cSRoman Divacky } 815f22ef01cSRoman Divacky 816f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 817f22ef01cSRoman Divacky // PatternToMatch implementation 818f22ef01cSRoman Divacky // 819f22ef01cSRoman Divacky 820f22ef01cSRoman Divacky 821f22ef01cSRoman Divacky /// getPatternSize - Return the 'size' of this pattern. We want to match large 822f22ef01cSRoman Divacky /// patterns before small ones. This is used to determine the size of a 823f22ef01cSRoman Divacky /// pattern. 824f22ef01cSRoman Divacky static unsigned getPatternSize(const TreePatternNode *P, 825f22ef01cSRoman Divacky const CodeGenDAGPatterns &CGP) { 826f22ef01cSRoman Divacky unsigned Size = 3; // The node itself. 827f22ef01cSRoman Divacky // If the root node is a ConstantSDNode, increases its size. 828f22ef01cSRoman Divacky // e.g. (set R32:$dst, 0). 8293861d79fSDimitry Andric if (P->isLeaf() && isa<IntInit>(P->getLeafValue())) 830f22ef01cSRoman Divacky Size += 2; 831f22ef01cSRoman Divacky 832f22ef01cSRoman Divacky const ComplexPattern *AM = P->getComplexPatternInfo(CGP); 83391bc56edSDimitry Andric if (AM) { 834d88c1a5aSDimitry Andric Size += AM->getComplexity(); 835f22ef01cSRoman Divacky 83691bc56edSDimitry Andric // We don't want to count any children twice, so return early. 83791bc56edSDimitry Andric return Size; 83891bc56edSDimitry Andric } 83991bc56edSDimitry Andric 840f22ef01cSRoman Divacky // If this node has some predicate function that must match, it adds to the 841f22ef01cSRoman Divacky // complexity of this node. 842f22ef01cSRoman Divacky if (!P->getPredicateFns().empty()) 843f22ef01cSRoman Divacky ++Size; 844f22ef01cSRoman Divacky 845f22ef01cSRoman Divacky // Count children in the count if they are also nodes. 846f22ef01cSRoman Divacky for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) { 847f22ef01cSRoman Divacky TreePatternNode *Child = P->getChild(i); 848f22ef01cSRoman Divacky if (!Child->isLeaf() && Child->getNumTypes() && 849f22ef01cSRoman Divacky Child->getType(0) != MVT::Other) 850f22ef01cSRoman Divacky Size += getPatternSize(Child, CGP); 851f22ef01cSRoman Divacky else if (Child->isLeaf()) { 8523861d79fSDimitry Andric if (isa<IntInit>(Child->getLeafValue())) 853f22ef01cSRoman Divacky Size += 5; // Matches a ConstantSDNode (+3) and a specific value (+2). 854f22ef01cSRoman Divacky else if (Child->getComplexPatternInfo(CGP)) 855f22ef01cSRoman Divacky Size += getPatternSize(Child, CGP); 856f22ef01cSRoman Divacky else if (!Child->getPredicateFns().empty()) 857f22ef01cSRoman Divacky ++Size; 858f22ef01cSRoman Divacky } 859f22ef01cSRoman Divacky } 860f22ef01cSRoman Divacky 861f22ef01cSRoman Divacky return Size; 862f22ef01cSRoman Divacky } 863f22ef01cSRoman Divacky 864f22ef01cSRoman Divacky /// Compute the complexity metric for the input pattern. This roughly 865f22ef01cSRoman Divacky /// corresponds to the number of nodes that are covered. 86639d628a0SDimitry Andric int PatternToMatch:: 867f22ef01cSRoman Divacky getPatternComplexity(const CodeGenDAGPatterns &CGP) const { 868f22ef01cSRoman Divacky return getPatternSize(getSrcPattern(), CGP) + getAddedComplexity(); 869f22ef01cSRoman Divacky } 870f22ef01cSRoman Divacky 871f22ef01cSRoman Divacky 872f22ef01cSRoman Divacky /// getPredicateCheck - Return a single string containing all of this 873f22ef01cSRoman Divacky /// pattern's predicates concatenated with "&&" operators. 874f22ef01cSRoman Divacky /// 875f22ef01cSRoman Divacky std::string PatternToMatch::getPredicateCheck() const { 8767d523365SDimitry Andric SmallVector<Record *, 4> PredicateRecs; 87797bc6c73SDimitry Andric for (Init *I : Predicates->getValues()) { 87897bc6c73SDimitry Andric if (DefInit *Pred = dyn_cast<DefInit>(I)) { 879f22ef01cSRoman Divacky Record *Def = Pred->getDef(); 880f22ef01cSRoman Divacky if (!Def->isSubClassOf("Predicate")) { 881f22ef01cSRoman Divacky #ifndef NDEBUG 882f22ef01cSRoman Divacky Def->dump(); 883f22ef01cSRoman Divacky #endif 884dff0c46cSDimitry Andric llvm_unreachable("Unknown predicate type!"); 885f22ef01cSRoman Divacky } 8867d523365SDimitry Andric PredicateRecs.push_back(Def); 8877d523365SDimitry Andric } 8887d523365SDimitry Andric } 8897d523365SDimitry Andric // Sort so that different orders get canonicalized to the same string. 8907d523365SDimitry Andric std::sort(PredicateRecs.begin(), PredicateRecs.end(), LessRecord()); 8917d523365SDimitry Andric 8927d523365SDimitry Andric SmallString<128> PredicateCheck; 8937d523365SDimitry Andric for (Record *Pred : PredicateRecs) { 894f22ef01cSRoman Divacky if (!PredicateCheck.empty()) 895f22ef01cSRoman Divacky PredicateCheck += " && "; 896f9448bf3SDimitry Andric PredicateCheck += "("; 897f9448bf3SDimitry Andric PredicateCheck += Pred->getValueAsString("CondString"); 898f9448bf3SDimitry Andric PredicateCheck += ")"; 899f22ef01cSRoman Divacky } 900f22ef01cSRoman Divacky 9017d523365SDimitry Andric return PredicateCheck.str(); 902f22ef01cSRoman Divacky } 903f22ef01cSRoman Divacky 904f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 905f22ef01cSRoman Divacky // SDTypeConstraint implementation 906f22ef01cSRoman Divacky // 907f22ef01cSRoman Divacky 908f22ef01cSRoman Divacky SDTypeConstraint::SDTypeConstraint(Record *R) { 909f22ef01cSRoman Divacky OperandNo = R->getValueAsInt("OperandNum"); 910f22ef01cSRoman Divacky 911f22ef01cSRoman Divacky if (R->isSubClassOf("SDTCisVT")) { 912f22ef01cSRoman Divacky ConstraintType = SDTCisVT; 913f22ef01cSRoman Divacky x.SDTCisVT_Info.VT = getValueType(R->getValueAsDef("VT")); 914f22ef01cSRoman Divacky if (x.SDTCisVT_Info.VT == MVT::isVoid) 9153861d79fSDimitry Andric PrintFatalError(R->getLoc(), "Cannot use 'Void' as type to SDTCisVT"); 916f22ef01cSRoman Divacky 917f22ef01cSRoman Divacky } else if (R->isSubClassOf("SDTCisPtrTy")) { 918f22ef01cSRoman Divacky ConstraintType = SDTCisPtrTy; 919f22ef01cSRoman Divacky } else if (R->isSubClassOf("SDTCisInt")) { 920f22ef01cSRoman Divacky ConstraintType = SDTCisInt; 921f22ef01cSRoman Divacky } else if (R->isSubClassOf("SDTCisFP")) { 922f22ef01cSRoman Divacky ConstraintType = SDTCisFP; 923f22ef01cSRoman Divacky } else if (R->isSubClassOf("SDTCisVec")) { 924f22ef01cSRoman Divacky ConstraintType = SDTCisVec; 925f22ef01cSRoman Divacky } else if (R->isSubClassOf("SDTCisSameAs")) { 926f22ef01cSRoman Divacky ConstraintType = SDTCisSameAs; 927f22ef01cSRoman Divacky x.SDTCisSameAs_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum"); 928f22ef01cSRoman Divacky } else if (R->isSubClassOf("SDTCisVTSmallerThanOp")) { 929f22ef01cSRoman Divacky ConstraintType = SDTCisVTSmallerThanOp; 930f22ef01cSRoman Divacky x.SDTCisVTSmallerThanOp_Info.OtherOperandNum = 931f22ef01cSRoman Divacky R->getValueAsInt("OtherOperandNum"); 932f22ef01cSRoman Divacky } else if (R->isSubClassOf("SDTCisOpSmallerThanOp")) { 933f22ef01cSRoman Divacky ConstraintType = SDTCisOpSmallerThanOp; 934f22ef01cSRoman Divacky x.SDTCisOpSmallerThanOp_Info.BigOperandNum = 935f22ef01cSRoman Divacky R->getValueAsInt("BigOperandNum"); 936f22ef01cSRoman Divacky } else if (R->isSubClassOf("SDTCisEltOfVec")) { 937f22ef01cSRoman Divacky ConstraintType = SDTCisEltOfVec; 938f22ef01cSRoman Divacky x.SDTCisEltOfVec_Info.OtherOperandNum = R->getValueAsInt("OtherOpNum"); 9392754fe60SDimitry Andric } else if (R->isSubClassOf("SDTCisSubVecOfVec")) { 9402754fe60SDimitry Andric ConstraintType = SDTCisSubVecOfVec; 9412754fe60SDimitry Andric x.SDTCisSubVecOfVec_Info.OtherOperandNum = 9422754fe60SDimitry Andric R->getValueAsInt("OtherOpNum"); 943ff0cc061SDimitry Andric } else if (R->isSubClassOf("SDTCVecEltisVT")) { 944ff0cc061SDimitry Andric ConstraintType = SDTCVecEltisVT; 945ff0cc061SDimitry Andric x.SDTCVecEltisVT_Info.VT = getValueType(R->getValueAsDef("VT")); 946ff0cc061SDimitry Andric if (MVT(x.SDTCVecEltisVT_Info.VT).isVector()) 947ff0cc061SDimitry Andric PrintFatalError(R->getLoc(), "Cannot use vector type as SDTCVecEltisVT"); 948ff0cc061SDimitry Andric if (!MVT(x.SDTCVecEltisVT_Info.VT).isInteger() && 949ff0cc061SDimitry Andric !MVT(x.SDTCVecEltisVT_Info.VT).isFloatingPoint()) 950ff0cc061SDimitry Andric PrintFatalError(R->getLoc(), "Must use integer or floating point type " 951ff0cc061SDimitry Andric "as SDTCVecEltisVT"); 952ff0cc061SDimitry Andric } else if (R->isSubClassOf("SDTCisSameNumEltsAs")) { 953ff0cc061SDimitry Andric ConstraintType = SDTCisSameNumEltsAs; 954ff0cc061SDimitry Andric x.SDTCisSameNumEltsAs_Info.OtherOperandNum = 955ff0cc061SDimitry Andric R->getValueAsInt("OtherOperandNum"); 9567d523365SDimitry Andric } else if (R->isSubClassOf("SDTCisSameSizeAs")) { 9577d523365SDimitry Andric ConstraintType = SDTCisSameSizeAs; 9587d523365SDimitry Andric x.SDTCisSameSizeAs_Info.OtherOperandNum = 9597d523365SDimitry Andric R->getValueAsInt("OtherOperandNum"); 960f22ef01cSRoman Divacky } else { 961ff0cc061SDimitry Andric PrintFatalError("Unrecognized SDTypeConstraint '" + R->getName() + "'!\n"); 962f22ef01cSRoman Divacky } 963f22ef01cSRoman Divacky } 964f22ef01cSRoman Divacky 965f22ef01cSRoman Divacky /// getOperandNum - Return the node corresponding to operand #OpNo in tree 966f22ef01cSRoman Divacky /// N, and the result number in ResNo. 967f22ef01cSRoman Divacky static TreePatternNode *getOperandNum(unsigned OpNo, TreePatternNode *N, 968f22ef01cSRoman Divacky const SDNodeInfo &NodeInfo, 969f22ef01cSRoman Divacky unsigned &ResNo) { 970f22ef01cSRoman Divacky unsigned NumResults = NodeInfo.getNumResults(); 971f22ef01cSRoman Divacky if (OpNo < NumResults) { 972f22ef01cSRoman Divacky ResNo = OpNo; 973f22ef01cSRoman Divacky return N; 974f22ef01cSRoman Divacky } 975f22ef01cSRoman Divacky 976f22ef01cSRoman Divacky OpNo -= NumResults; 977f22ef01cSRoman Divacky 978f22ef01cSRoman Divacky if (OpNo >= N->getNumChildren()) { 979ff0cc061SDimitry Andric std::string S; 980ff0cc061SDimitry Andric raw_string_ostream OS(S); 981ff0cc061SDimitry Andric OS << "Invalid operand number in type constraint " 982f22ef01cSRoman Divacky << (OpNo+NumResults) << " "; 983ff0cc061SDimitry Andric N->print(OS); 984ff0cc061SDimitry Andric PrintFatalError(OS.str()); 985f22ef01cSRoman Divacky } 986f22ef01cSRoman Divacky 987f22ef01cSRoman Divacky return N->getChild(OpNo); 988f22ef01cSRoman Divacky } 989f22ef01cSRoman Divacky 990f22ef01cSRoman Divacky /// ApplyTypeConstraint - Given a node in a pattern, apply this type 991f22ef01cSRoman Divacky /// constraint to the nodes operands. This returns true if it makes a 9923861d79fSDimitry Andric /// change, false otherwise. If a type contradiction is found, flag an error. 993f22ef01cSRoman Divacky bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, 994f22ef01cSRoman Divacky const SDNodeInfo &NodeInfo, 995f22ef01cSRoman Divacky TreePattern &TP) const { 9963861d79fSDimitry Andric if (TP.hasError()) 9973861d79fSDimitry Andric return false; 9983861d79fSDimitry Andric 999f22ef01cSRoman Divacky unsigned ResNo = 0; // The result number being referenced. 1000f22ef01cSRoman Divacky TreePatternNode *NodeToApply = getOperandNum(OperandNo, N, NodeInfo, ResNo); 1001f22ef01cSRoman Divacky 1002f22ef01cSRoman Divacky switch (ConstraintType) { 1003f22ef01cSRoman Divacky case SDTCisVT: 1004f22ef01cSRoman Divacky // Operand must be a particular type. 1005f22ef01cSRoman Divacky return NodeToApply->UpdateNodeType(ResNo, x.SDTCisVT_Info.VT, TP); 1006f22ef01cSRoman Divacky case SDTCisPtrTy: 1007f22ef01cSRoman Divacky // Operand must be same as target pointer type. 1008f22ef01cSRoman Divacky return NodeToApply->UpdateNodeType(ResNo, MVT::iPTR, TP); 1009f22ef01cSRoman Divacky case SDTCisInt: 1010f22ef01cSRoman Divacky // Require it to be one of the legal integer VTs. 1011f22ef01cSRoman Divacky return NodeToApply->getExtType(ResNo).EnforceInteger(TP); 1012f22ef01cSRoman Divacky case SDTCisFP: 1013f22ef01cSRoman Divacky // Require it to be one of the legal fp VTs. 1014f22ef01cSRoman Divacky return NodeToApply->getExtType(ResNo).EnforceFloatingPoint(TP); 1015f22ef01cSRoman Divacky case SDTCisVec: 1016f22ef01cSRoman Divacky // Require it to be one of the legal vector VTs. 1017f22ef01cSRoman Divacky return NodeToApply->getExtType(ResNo).EnforceVector(TP); 1018f22ef01cSRoman Divacky case SDTCisSameAs: { 1019f22ef01cSRoman Divacky unsigned OResNo = 0; 1020f22ef01cSRoman Divacky TreePatternNode *OtherNode = 1021f22ef01cSRoman Divacky getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NodeInfo, OResNo); 1022ff0cc061SDimitry Andric return NodeToApply->UpdateNodeType(ResNo, OtherNode->getExtType(OResNo),TP)| 1023ff0cc061SDimitry Andric OtherNode->UpdateNodeType(OResNo,NodeToApply->getExtType(ResNo),TP); 1024f22ef01cSRoman Divacky } 1025f22ef01cSRoman Divacky case SDTCisVTSmallerThanOp: { 1026f22ef01cSRoman Divacky // The NodeToApply must be a leaf node that is a VT. OtherOperandNum must 1027f22ef01cSRoman Divacky // have an integer type that is smaller than the VT. 1028f22ef01cSRoman Divacky if (!NodeToApply->isLeaf() || 10293861d79fSDimitry Andric !isa<DefInit>(NodeToApply->getLeafValue()) || 1030f22ef01cSRoman Divacky !static_cast<DefInit*>(NodeToApply->getLeafValue())->getDef() 10313861d79fSDimitry Andric ->isSubClassOf("ValueType")) { 1032f22ef01cSRoman Divacky TP.error(N->getOperator()->getName() + " expects a VT operand!"); 10333861d79fSDimitry Andric return false; 10343861d79fSDimitry Andric } 1035f22ef01cSRoman Divacky MVT::SimpleValueType VT = 1036f22ef01cSRoman Divacky getValueType(static_cast<DefInit*>(NodeToApply->getLeafValue())->getDef()); 1037f22ef01cSRoman Divacky 1038f22ef01cSRoman Divacky EEVT::TypeSet TypeListTmp(VT, TP); 1039f22ef01cSRoman Divacky 1040f22ef01cSRoman Divacky unsigned OResNo = 0; 1041f22ef01cSRoman Divacky TreePatternNode *OtherNode = 1042f22ef01cSRoman Divacky getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N, NodeInfo, 1043f22ef01cSRoman Divacky OResNo); 1044f22ef01cSRoman Divacky 1045f22ef01cSRoman Divacky return TypeListTmp.EnforceSmallerThan(OtherNode->getExtType(OResNo), TP); 1046f22ef01cSRoman Divacky } 1047f22ef01cSRoman Divacky case SDTCisOpSmallerThanOp: { 1048f22ef01cSRoman Divacky unsigned BResNo = 0; 1049f22ef01cSRoman Divacky TreePatternNode *BigOperand = 1050f22ef01cSRoman Divacky getOperandNum(x.SDTCisOpSmallerThanOp_Info.BigOperandNum, N, NodeInfo, 1051f22ef01cSRoman Divacky BResNo); 1052f22ef01cSRoman Divacky return NodeToApply->getExtType(ResNo). 1053f22ef01cSRoman Divacky EnforceSmallerThan(BigOperand->getExtType(BResNo), TP); 1054f22ef01cSRoman Divacky } 1055f22ef01cSRoman Divacky case SDTCisEltOfVec: { 1056f22ef01cSRoman Divacky unsigned VResNo = 0; 1057f22ef01cSRoman Divacky TreePatternNode *VecOperand = 1058f22ef01cSRoman Divacky getOperandNum(x.SDTCisEltOfVec_Info.OtherOperandNum, N, NodeInfo, 1059f22ef01cSRoman Divacky VResNo); 1060f22ef01cSRoman Divacky 1061f22ef01cSRoman Divacky // Filter vector types out of VecOperand that don't have the right element 1062f22ef01cSRoman Divacky // type. 1063f22ef01cSRoman Divacky return VecOperand->getExtType(VResNo). 1064f22ef01cSRoman Divacky EnforceVectorEltTypeIs(NodeToApply->getExtType(ResNo), TP); 1065f22ef01cSRoman Divacky } 10662754fe60SDimitry Andric case SDTCisSubVecOfVec: { 10672754fe60SDimitry Andric unsigned VResNo = 0; 10682754fe60SDimitry Andric TreePatternNode *BigVecOperand = 10692754fe60SDimitry Andric getOperandNum(x.SDTCisSubVecOfVec_Info.OtherOperandNum, N, NodeInfo, 10702754fe60SDimitry Andric VResNo); 10712754fe60SDimitry Andric 10722754fe60SDimitry Andric // Filter vector types out of BigVecOperand that don't have the 10732754fe60SDimitry Andric // right subvector type. 10742754fe60SDimitry Andric return BigVecOperand->getExtType(VResNo). 10752754fe60SDimitry Andric EnforceVectorSubVectorTypeIs(NodeToApply->getExtType(ResNo), TP); 10762754fe60SDimitry Andric } 1077ff0cc061SDimitry Andric case SDTCVecEltisVT: { 1078ff0cc061SDimitry Andric return NodeToApply->getExtType(ResNo). 1079ff0cc061SDimitry Andric EnforceVectorEltTypeIs(x.SDTCVecEltisVT_Info.VT, TP); 1080ff0cc061SDimitry Andric } 1081ff0cc061SDimitry Andric case SDTCisSameNumEltsAs: { 1082ff0cc061SDimitry Andric unsigned OResNo = 0; 1083ff0cc061SDimitry Andric TreePatternNode *OtherNode = 1084ff0cc061SDimitry Andric getOperandNum(x.SDTCisSameNumEltsAs_Info.OtherOperandNum, 1085ff0cc061SDimitry Andric N, NodeInfo, OResNo); 1086ff0cc061SDimitry Andric return OtherNode->getExtType(OResNo). 10877a7e6055SDimitry Andric EnforceSameNumElts(NodeToApply->getExtType(ResNo), TP); 1088ff0cc061SDimitry Andric } 10897d523365SDimitry Andric case SDTCisSameSizeAs: { 10907d523365SDimitry Andric unsigned OResNo = 0; 10917d523365SDimitry Andric TreePatternNode *OtherNode = 10927d523365SDimitry Andric getOperandNum(x.SDTCisSameSizeAs_Info.OtherOperandNum, 10937d523365SDimitry Andric N, NodeInfo, OResNo); 10947d523365SDimitry Andric return OtherNode->getExtType(OResNo). 10957d523365SDimitry Andric EnforceSameSize(NodeToApply->getExtType(ResNo), TP); 10967d523365SDimitry Andric } 1097f22ef01cSRoman Divacky } 1098dff0c46cSDimitry Andric llvm_unreachable("Invalid ConstraintType!"); 1099f22ef01cSRoman Divacky } 1100f22ef01cSRoman Divacky 1101139f7f9bSDimitry Andric // Update the node type to match an instruction operand or result as specified 1102139f7f9bSDimitry Andric // in the ins or outs lists on the instruction definition. Return true if the 1103139f7f9bSDimitry Andric // type was actually changed. 1104139f7f9bSDimitry Andric bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo, 1105139f7f9bSDimitry Andric Record *Operand, 1106139f7f9bSDimitry Andric TreePattern &TP) { 1107139f7f9bSDimitry Andric // The 'unknown' operand indicates that types should be inferred from the 1108139f7f9bSDimitry Andric // context. 1109139f7f9bSDimitry Andric if (Operand->isSubClassOf("unknown_class")) 1110139f7f9bSDimitry Andric return false; 1111139f7f9bSDimitry Andric 1112139f7f9bSDimitry Andric // The Operand class specifies a type directly. 1113139f7f9bSDimitry Andric if (Operand->isSubClassOf("Operand")) 1114139f7f9bSDimitry Andric return UpdateNodeType(ResNo, getValueType(Operand->getValueAsDef("Type")), 1115139f7f9bSDimitry Andric TP); 1116139f7f9bSDimitry Andric 1117139f7f9bSDimitry Andric // PointerLikeRegClass has a type that is determined at runtime. 1118139f7f9bSDimitry Andric if (Operand->isSubClassOf("PointerLikeRegClass")) 1119139f7f9bSDimitry Andric return UpdateNodeType(ResNo, MVT::iPTR, TP); 1120139f7f9bSDimitry Andric 1121139f7f9bSDimitry Andric // Both RegisterClass and RegisterOperand operands derive their types from a 1122139f7f9bSDimitry Andric // register class def. 112391bc56edSDimitry Andric Record *RC = nullptr; 1124139f7f9bSDimitry Andric if (Operand->isSubClassOf("RegisterClass")) 1125139f7f9bSDimitry Andric RC = Operand; 1126139f7f9bSDimitry Andric else if (Operand->isSubClassOf("RegisterOperand")) 1127139f7f9bSDimitry Andric RC = Operand->getValueAsDef("RegClass"); 1128139f7f9bSDimitry Andric 1129139f7f9bSDimitry Andric assert(RC && "Unknown operand type"); 1130139f7f9bSDimitry Andric CodeGenTarget &Tgt = TP.getDAGPatterns().getTargetInfo(); 1131139f7f9bSDimitry Andric return UpdateNodeType(ResNo, Tgt.getRegisterClass(RC).getValueTypes(), TP); 1132139f7f9bSDimitry Andric } 1133139f7f9bSDimitry Andric 1134139f7f9bSDimitry Andric 1135f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 1136f22ef01cSRoman Divacky // SDNodeInfo implementation 1137f22ef01cSRoman Divacky // 1138f22ef01cSRoman Divacky SDNodeInfo::SDNodeInfo(Record *R) : Def(R) { 1139f22ef01cSRoman Divacky EnumName = R->getValueAsString("Opcode"); 1140f22ef01cSRoman Divacky SDClassName = R->getValueAsString("SDClass"); 1141f22ef01cSRoman Divacky Record *TypeProfile = R->getValueAsDef("TypeProfile"); 1142f22ef01cSRoman Divacky NumResults = TypeProfile->getValueAsInt("NumResults"); 1143f22ef01cSRoman Divacky NumOperands = TypeProfile->getValueAsInt("NumOperands"); 1144f22ef01cSRoman Divacky 1145f22ef01cSRoman Divacky // Parse the properties. 1146f22ef01cSRoman Divacky Properties = 0; 11477d523365SDimitry Andric for (Record *Property : R->getValueAsListOfDefs("Properties")) { 11487d523365SDimitry Andric if (Property->getName() == "SDNPCommutative") { 1149f22ef01cSRoman Divacky Properties |= 1 << SDNPCommutative; 11507d523365SDimitry Andric } else if (Property->getName() == "SDNPAssociative") { 1151f22ef01cSRoman Divacky Properties |= 1 << SDNPAssociative; 11527d523365SDimitry Andric } else if (Property->getName() == "SDNPHasChain") { 1153f22ef01cSRoman Divacky Properties |= 1 << SDNPHasChain; 11547d523365SDimitry Andric } else if (Property->getName() == "SDNPOutGlue") { 11552754fe60SDimitry Andric Properties |= 1 << SDNPOutGlue; 11567d523365SDimitry Andric } else if (Property->getName() == "SDNPInGlue") { 11572754fe60SDimitry Andric Properties |= 1 << SDNPInGlue; 11587d523365SDimitry Andric } else if (Property->getName() == "SDNPOptInGlue") { 11592754fe60SDimitry Andric Properties |= 1 << SDNPOptInGlue; 11607d523365SDimitry Andric } else if (Property->getName() == "SDNPMayStore") { 1161f22ef01cSRoman Divacky Properties |= 1 << SDNPMayStore; 11627d523365SDimitry Andric } else if (Property->getName() == "SDNPMayLoad") { 1163f22ef01cSRoman Divacky Properties |= 1 << SDNPMayLoad; 11647d523365SDimitry Andric } else if (Property->getName() == "SDNPSideEffect") { 1165f22ef01cSRoman Divacky Properties |= 1 << SDNPSideEffect; 11667d523365SDimitry Andric } else if (Property->getName() == "SDNPMemOperand") { 1167f22ef01cSRoman Divacky Properties |= 1 << SDNPMemOperand; 11687d523365SDimitry Andric } else if (Property->getName() == "SDNPVariadic") { 1169f22ef01cSRoman Divacky Properties |= 1 << SDNPVariadic; 1170f22ef01cSRoman Divacky } else { 1171ff0cc061SDimitry Andric PrintFatalError("Unknown SD Node property '" + 11727d523365SDimitry Andric Property->getName() + "' on node '" + 1173ff0cc061SDimitry Andric R->getName() + "'!"); 1174f22ef01cSRoman Divacky } 1175f22ef01cSRoman Divacky } 1176f22ef01cSRoman Divacky 1177f22ef01cSRoman Divacky 1178f22ef01cSRoman Divacky // Parse the type constraints. 1179f22ef01cSRoman Divacky std::vector<Record*> ConstraintList = 1180f22ef01cSRoman Divacky TypeProfile->getValueAsListOfDefs("Constraints"); 1181f22ef01cSRoman Divacky TypeConstraints.assign(ConstraintList.begin(), ConstraintList.end()); 1182f22ef01cSRoman Divacky } 1183f22ef01cSRoman Divacky 1184f22ef01cSRoman Divacky /// getKnownType - If the type constraints on this node imply a fixed type 1185f22ef01cSRoman Divacky /// (e.g. all stores return void, etc), then return it as an 1186f22ef01cSRoman Divacky /// MVT::SimpleValueType. Otherwise, return EEVT::Other. 1187f22ef01cSRoman Divacky MVT::SimpleValueType SDNodeInfo::getKnownType(unsigned ResNo) const { 1188f22ef01cSRoman Divacky unsigned NumResults = getNumResults(); 1189f22ef01cSRoman Divacky assert(NumResults <= 1 && 1190f22ef01cSRoman Divacky "We only work with nodes with zero or one result so far!"); 1191f22ef01cSRoman Divacky assert(ResNo == 0 && "Only handles single result nodes so far"); 1192f22ef01cSRoman Divacky 11937d523365SDimitry Andric for (const SDTypeConstraint &Constraint : TypeConstraints) { 1194f22ef01cSRoman Divacky // Make sure that this applies to the correct node result. 11957d523365SDimitry Andric if (Constraint.OperandNo >= NumResults) // FIXME: need value # 1196f22ef01cSRoman Divacky continue; 1197f22ef01cSRoman Divacky 11987d523365SDimitry Andric switch (Constraint.ConstraintType) { 1199f22ef01cSRoman Divacky default: break; 1200f22ef01cSRoman Divacky case SDTypeConstraint::SDTCisVT: 12017d523365SDimitry Andric return Constraint.x.SDTCisVT_Info.VT; 1202f22ef01cSRoman Divacky case SDTypeConstraint::SDTCisPtrTy: 1203f22ef01cSRoman Divacky return MVT::iPTR; 1204f22ef01cSRoman Divacky } 1205f22ef01cSRoman Divacky } 1206f22ef01cSRoman Divacky return MVT::Other; 1207f22ef01cSRoman Divacky } 1208f22ef01cSRoman Divacky 1209f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 1210f22ef01cSRoman Divacky // TreePatternNode implementation 1211f22ef01cSRoman Divacky // 1212f22ef01cSRoman Divacky 1213f22ef01cSRoman Divacky TreePatternNode::~TreePatternNode() { 1214f22ef01cSRoman Divacky #if 0 // FIXME: implement refcounted tree nodes! 1215f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumChildren(); i != e; ++i) 1216f22ef01cSRoman Divacky delete getChild(i); 1217f22ef01cSRoman Divacky #endif 1218f22ef01cSRoman Divacky } 1219f22ef01cSRoman Divacky 1220f22ef01cSRoman Divacky static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { 1221f22ef01cSRoman Divacky if (Operator->getName() == "set" || 1222f22ef01cSRoman Divacky Operator->getName() == "implicit") 1223f22ef01cSRoman Divacky return 0; // All return nothing. 1224f22ef01cSRoman Divacky 1225f22ef01cSRoman Divacky if (Operator->isSubClassOf("Intrinsic")) 1226f22ef01cSRoman Divacky return CDP.getIntrinsic(Operator).IS.RetVTs.size(); 1227f22ef01cSRoman Divacky 1228f22ef01cSRoman Divacky if (Operator->isSubClassOf("SDNode")) 1229f22ef01cSRoman Divacky return CDP.getSDNodeInfo(Operator).getNumResults(); 1230f22ef01cSRoman Divacky 1231f22ef01cSRoman Divacky if (Operator->isSubClassOf("PatFrag")) { 1232f22ef01cSRoman Divacky // If we've already parsed this pattern fragment, get it. Otherwise, handle 1233f22ef01cSRoman Divacky // the forward reference case where one pattern fragment references another 1234f22ef01cSRoman Divacky // before it is processed. 1235f22ef01cSRoman Divacky if (TreePattern *PFRec = CDP.getPatternFragmentIfRead(Operator)) 1236f22ef01cSRoman Divacky return PFRec->getOnlyTree()->getNumTypes(); 1237f22ef01cSRoman Divacky 1238f22ef01cSRoman Divacky // Get the result tree. 1239f22ef01cSRoman Divacky DagInit *Tree = Operator->getValueAsDag("Fragment"); 124091bc56edSDimitry Andric Record *Op = nullptr; 12413861d79fSDimitry Andric if (Tree) 12423861d79fSDimitry Andric if (DefInit *DI = dyn_cast<DefInit>(Tree->getOperator())) 12433861d79fSDimitry Andric Op = DI->getDef(); 1244f22ef01cSRoman Divacky assert(Op && "Invalid Fragment"); 1245f22ef01cSRoman Divacky return GetNumNodeResults(Op, CDP); 1246f22ef01cSRoman Divacky } 1247f22ef01cSRoman Divacky 1248f22ef01cSRoman Divacky if (Operator->isSubClassOf("Instruction")) { 1249f22ef01cSRoman Divacky CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator); 1250f22ef01cSRoman Divacky 1251ff0cc061SDimitry Andric unsigned NumDefsToAdd = InstInfo.Operands.NumDefs; 1252ff0cc061SDimitry Andric 1253ff0cc061SDimitry Andric // Subtract any defaulted outputs. 1254ff0cc061SDimitry Andric for (unsigned i = 0; i != InstInfo.Operands.NumDefs; ++i) { 1255ff0cc061SDimitry Andric Record *OperandNode = InstInfo.Operands[i].Rec; 1256ff0cc061SDimitry Andric 1257ff0cc061SDimitry Andric if (OperandNode->isSubClassOf("OperandWithDefaultOps") && 1258ff0cc061SDimitry Andric !CDP.getDefaultOperand(OperandNode).DefaultOps.empty()) 1259ff0cc061SDimitry Andric --NumDefsToAdd; 1260ff0cc061SDimitry Andric } 1261f22ef01cSRoman Divacky 1262f22ef01cSRoman Divacky // Add on one implicit def if it has a resolvable type. 1263f22ef01cSRoman Divacky if (InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()) !=MVT::Other) 1264f22ef01cSRoman Divacky ++NumDefsToAdd; 1265f22ef01cSRoman Divacky return NumDefsToAdd; 1266f22ef01cSRoman Divacky } 1267f22ef01cSRoman Divacky 1268f22ef01cSRoman Divacky if (Operator->isSubClassOf("SDNodeXForm")) 1269f22ef01cSRoman Divacky return 1; // FIXME: Generalize SDNodeXForm 1270f22ef01cSRoman Divacky 127191bc56edSDimitry Andric if (Operator->isSubClassOf("ValueType")) 127291bc56edSDimitry Andric return 1; // A type-cast of one result. 127391bc56edSDimitry Andric 127491bc56edSDimitry Andric if (Operator->isSubClassOf("ComplexPattern")) 127591bc56edSDimitry Andric return 1; 127691bc56edSDimitry Andric 12777a7e6055SDimitry Andric errs() << *Operator; 1278ff0cc061SDimitry Andric PrintFatalError("Unhandled node in GetNumNodeResults"); 1279f22ef01cSRoman Divacky } 1280f22ef01cSRoman Divacky 1281f22ef01cSRoman Divacky void TreePatternNode::print(raw_ostream &OS) const { 1282f22ef01cSRoman Divacky if (isLeaf()) 1283f22ef01cSRoman Divacky OS << *getLeafValue(); 1284f22ef01cSRoman Divacky else 1285f22ef01cSRoman Divacky OS << '(' << getOperator()->getName(); 1286f22ef01cSRoman Divacky 1287f22ef01cSRoman Divacky for (unsigned i = 0, e = Types.size(); i != e; ++i) 1288f22ef01cSRoman Divacky OS << ':' << getExtType(i).getName(); 1289f22ef01cSRoman Divacky 1290f22ef01cSRoman Divacky if (!isLeaf()) { 1291f22ef01cSRoman Divacky if (getNumChildren() != 0) { 1292f22ef01cSRoman Divacky OS << " "; 1293f22ef01cSRoman Divacky getChild(0)->print(OS); 1294f22ef01cSRoman Divacky for (unsigned i = 1, e = getNumChildren(); i != e; ++i) { 1295f22ef01cSRoman Divacky OS << ", "; 1296f22ef01cSRoman Divacky getChild(i)->print(OS); 1297f22ef01cSRoman Divacky } 1298f22ef01cSRoman Divacky } 1299f22ef01cSRoman Divacky OS << ")"; 1300f22ef01cSRoman Divacky } 1301f22ef01cSRoman Divacky 13027d523365SDimitry Andric for (const TreePredicateFn &Pred : PredicateFns) 13037d523365SDimitry Andric OS << "<<P:" << Pred.getFnName() << ">>"; 1304f22ef01cSRoman Divacky if (TransformFn) 1305f22ef01cSRoman Divacky OS << "<<X:" << TransformFn->getName() << ">>"; 1306f22ef01cSRoman Divacky if (!getName().empty()) 1307f22ef01cSRoman Divacky OS << ":$" << getName(); 1308f22ef01cSRoman Divacky 1309f22ef01cSRoman Divacky } 1310f22ef01cSRoman Divacky void TreePatternNode::dump() const { 1311f22ef01cSRoman Divacky print(errs()); 1312f22ef01cSRoman Divacky } 1313f22ef01cSRoman Divacky 1314f22ef01cSRoman Divacky /// isIsomorphicTo - Return true if this node is recursively 1315f22ef01cSRoman Divacky /// isomorphic to the specified node. For this comparison, the node's 1316f22ef01cSRoman Divacky /// entire state is considered. The assigned name is ignored, since 1317f22ef01cSRoman Divacky /// nodes with differing names are considered isomorphic. However, if 1318f22ef01cSRoman Divacky /// the assigned name is present in the dependent variable set, then 1319f22ef01cSRoman Divacky /// the assigned name is considered significant and the node is 1320f22ef01cSRoman Divacky /// isomorphic if the names match. 1321f22ef01cSRoman Divacky bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N, 1322f22ef01cSRoman Divacky const MultipleUseVarSet &DepVars) const { 1323f22ef01cSRoman Divacky if (N == this) return true; 1324f22ef01cSRoman Divacky if (N->isLeaf() != isLeaf() || getExtTypes() != N->getExtTypes() || 1325f22ef01cSRoman Divacky getPredicateFns() != N->getPredicateFns() || 1326f22ef01cSRoman Divacky getTransformFn() != N->getTransformFn()) 1327f22ef01cSRoman Divacky return false; 1328f22ef01cSRoman Divacky 1329f22ef01cSRoman Divacky if (isLeaf()) { 13303861d79fSDimitry Andric if (DefInit *DI = dyn_cast<DefInit>(getLeafValue())) { 13313861d79fSDimitry Andric if (DefInit *NDI = dyn_cast<DefInit>(N->getLeafValue())) { 1332f22ef01cSRoman Divacky return ((DI->getDef() == NDI->getDef()) 1333f22ef01cSRoman Divacky && (DepVars.find(getName()) == DepVars.end() 1334f22ef01cSRoman Divacky || getName() == N->getName())); 1335f22ef01cSRoman Divacky } 1336f22ef01cSRoman Divacky } 1337f22ef01cSRoman Divacky return getLeafValue() == N->getLeafValue(); 1338f22ef01cSRoman Divacky } 1339f22ef01cSRoman Divacky 1340f22ef01cSRoman Divacky if (N->getOperator() != getOperator() || 1341f22ef01cSRoman Divacky N->getNumChildren() != getNumChildren()) return false; 1342f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumChildren(); i != e; ++i) 1343f22ef01cSRoman Divacky if (!getChild(i)->isIsomorphicTo(N->getChild(i), DepVars)) 1344f22ef01cSRoman Divacky return false; 1345f22ef01cSRoman Divacky return true; 1346f22ef01cSRoman Divacky } 1347f22ef01cSRoman Divacky 1348f22ef01cSRoman Divacky /// clone - Make a copy of this tree and all of its children. 1349f22ef01cSRoman Divacky /// 1350f22ef01cSRoman Divacky TreePatternNode *TreePatternNode::clone() const { 1351f22ef01cSRoman Divacky TreePatternNode *New; 1352f22ef01cSRoman Divacky if (isLeaf()) { 1353f22ef01cSRoman Divacky New = new TreePatternNode(getLeafValue(), getNumTypes()); 1354f22ef01cSRoman Divacky } else { 1355f22ef01cSRoman Divacky std::vector<TreePatternNode*> CChildren; 1356f22ef01cSRoman Divacky CChildren.reserve(Children.size()); 1357f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumChildren(); i != e; ++i) 1358f22ef01cSRoman Divacky CChildren.push_back(getChild(i)->clone()); 1359f22ef01cSRoman Divacky New = new TreePatternNode(getOperator(), CChildren, getNumTypes()); 1360f22ef01cSRoman Divacky } 1361f22ef01cSRoman Divacky New->setName(getName()); 1362f22ef01cSRoman Divacky New->Types = Types; 1363f22ef01cSRoman Divacky New->setPredicateFns(getPredicateFns()); 1364f22ef01cSRoman Divacky New->setTransformFn(getTransformFn()); 1365f22ef01cSRoman Divacky return New; 1366f22ef01cSRoman Divacky } 1367f22ef01cSRoman Divacky 1368f22ef01cSRoman Divacky /// RemoveAllTypes - Recursively strip all the types of this tree. 1369f22ef01cSRoman Divacky void TreePatternNode::RemoveAllTypes() { 13707d523365SDimitry Andric // Reset to unknown type. 13717d523365SDimitry Andric std::fill(Types.begin(), Types.end(), EEVT::TypeSet()); 1372f22ef01cSRoman Divacky if (isLeaf()) return; 1373f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumChildren(); i != e; ++i) 1374f22ef01cSRoman Divacky getChild(i)->RemoveAllTypes(); 1375f22ef01cSRoman Divacky } 1376f22ef01cSRoman Divacky 1377f22ef01cSRoman Divacky 1378f22ef01cSRoman Divacky /// SubstituteFormalArguments - Replace the formal arguments in this tree 1379f22ef01cSRoman Divacky /// with actual values specified by ArgMap. 1380f22ef01cSRoman Divacky void TreePatternNode:: 1381f22ef01cSRoman Divacky SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) { 1382f22ef01cSRoman Divacky if (isLeaf()) return; 1383f22ef01cSRoman Divacky 1384f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { 1385f22ef01cSRoman Divacky TreePatternNode *Child = getChild(i); 1386f22ef01cSRoman Divacky if (Child->isLeaf()) { 1387f22ef01cSRoman Divacky Init *Val = Child->getLeafValue(); 138891bc56edSDimitry Andric // Note that, when substituting into an output pattern, Val might be an 138991bc56edSDimitry Andric // UnsetInit. 139091bc56edSDimitry Andric if (isa<UnsetInit>(Val) || (isa<DefInit>(Val) && 139191bc56edSDimitry Andric cast<DefInit>(Val)->getDef()->getName() == "node")) { 1392f22ef01cSRoman Divacky // We found a use of a formal argument, replace it with its value. 1393f22ef01cSRoman Divacky TreePatternNode *NewChild = ArgMap[Child->getName()]; 1394f22ef01cSRoman Divacky assert(NewChild && "Couldn't find formal argument!"); 1395f22ef01cSRoman Divacky assert((Child->getPredicateFns().empty() || 1396f22ef01cSRoman Divacky NewChild->getPredicateFns() == Child->getPredicateFns()) && 1397f22ef01cSRoman Divacky "Non-empty child predicate clobbered!"); 1398f22ef01cSRoman Divacky setChild(i, NewChild); 1399f22ef01cSRoman Divacky } 1400f22ef01cSRoman Divacky } else { 1401f22ef01cSRoman Divacky getChild(i)->SubstituteFormalArguments(ArgMap); 1402f22ef01cSRoman Divacky } 1403f22ef01cSRoman Divacky } 1404f22ef01cSRoman Divacky } 1405f22ef01cSRoman Divacky 1406f22ef01cSRoman Divacky 1407f22ef01cSRoman Divacky /// InlinePatternFragments - If this pattern refers to any pattern 1408f22ef01cSRoman Divacky /// fragments, inline them into place, giving us a pattern without any 1409f22ef01cSRoman Divacky /// PatFrag references. 1410f22ef01cSRoman Divacky TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { 14113861d79fSDimitry Andric if (TP.hasError()) 141291bc56edSDimitry Andric return nullptr; 14133861d79fSDimitry Andric 14143861d79fSDimitry Andric if (isLeaf()) 14153861d79fSDimitry Andric return this; // nothing to do. 1416f22ef01cSRoman Divacky Record *Op = getOperator(); 1417f22ef01cSRoman Divacky 1418f22ef01cSRoman Divacky if (!Op->isSubClassOf("PatFrag")) { 1419f22ef01cSRoman Divacky // Just recursively inline children nodes. 1420f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { 1421f22ef01cSRoman Divacky TreePatternNode *Child = getChild(i); 1422f22ef01cSRoman Divacky TreePatternNode *NewChild = Child->InlinePatternFragments(TP); 1423f22ef01cSRoman Divacky 1424f22ef01cSRoman Divacky assert((Child->getPredicateFns().empty() || 1425f22ef01cSRoman Divacky NewChild->getPredicateFns() == Child->getPredicateFns()) && 1426f22ef01cSRoman Divacky "Non-empty child predicate clobbered!"); 1427f22ef01cSRoman Divacky 1428f22ef01cSRoman Divacky setChild(i, NewChild); 1429f22ef01cSRoman Divacky } 1430f22ef01cSRoman Divacky return this; 1431f22ef01cSRoman Divacky } 1432f22ef01cSRoman Divacky 1433f22ef01cSRoman Divacky // Otherwise, we found a reference to a fragment. First, look up its 1434f22ef01cSRoman Divacky // TreePattern record. 1435f22ef01cSRoman Divacky TreePattern *Frag = TP.getDAGPatterns().getPatternFragment(Op); 1436f22ef01cSRoman Divacky 1437f22ef01cSRoman Divacky // Verify that we are passing the right number of operands. 14383861d79fSDimitry Andric if (Frag->getNumArgs() != Children.size()) { 1439f22ef01cSRoman Divacky TP.error("'" + Op->getName() + "' fragment requires " + 1440f22ef01cSRoman Divacky utostr(Frag->getNumArgs()) + " operands!"); 144191bc56edSDimitry Andric return nullptr; 14423861d79fSDimitry Andric } 1443f22ef01cSRoman Divacky 1444f22ef01cSRoman Divacky TreePatternNode *FragTree = Frag->getOnlyTree()->clone(); 1445f22ef01cSRoman Divacky 14463b0f4066SDimitry Andric TreePredicateFn PredFn(Frag); 14473b0f4066SDimitry Andric if (!PredFn.isAlwaysTrue()) 14483b0f4066SDimitry Andric FragTree->addPredicateFn(PredFn); 1449f22ef01cSRoman Divacky 1450f22ef01cSRoman Divacky // Resolve formal arguments to their actual value. 1451f22ef01cSRoman Divacky if (Frag->getNumArgs()) { 1452f22ef01cSRoman Divacky // Compute the map of formal to actual arguments. 1453f22ef01cSRoman Divacky std::map<std::string, TreePatternNode*> ArgMap; 1454f22ef01cSRoman Divacky for (unsigned i = 0, e = Frag->getNumArgs(); i != e; ++i) 1455f22ef01cSRoman Divacky ArgMap[Frag->getArgName(i)] = getChild(i)->InlinePatternFragments(TP); 1456f22ef01cSRoman Divacky 1457f22ef01cSRoman Divacky FragTree->SubstituteFormalArguments(ArgMap); 1458f22ef01cSRoman Divacky } 1459f22ef01cSRoman Divacky 1460f22ef01cSRoman Divacky FragTree->setName(getName()); 1461f22ef01cSRoman Divacky for (unsigned i = 0, e = Types.size(); i != e; ++i) 1462f22ef01cSRoman Divacky FragTree->UpdateNodeType(i, getExtType(i), TP); 1463f22ef01cSRoman Divacky 1464f22ef01cSRoman Divacky // Transfer in the old predicates. 14657d523365SDimitry Andric for (const TreePredicateFn &Pred : getPredicateFns()) 14667d523365SDimitry Andric FragTree->addPredicateFn(Pred); 1467f22ef01cSRoman Divacky 1468f22ef01cSRoman Divacky // Get a new copy of this fragment to stitch into here. 1469f22ef01cSRoman Divacky //delete this; // FIXME: implement refcounting! 1470f22ef01cSRoman Divacky 1471f22ef01cSRoman Divacky // The fragment we inlined could have recursive inlining that is needed. See 1472f22ef01cSRoman Divacky // if there are any pattern fragments in it and inline them as needed. 1473f22ef01cSRoman Divacky return FragTree->InlinePatternFragments(TP); 1474f22ef01cSRoman Divacky } 1475f22ef01cSRoman Divacky 1476f22ef01cSRoman Divacky /// getImplicitType - Check to see if the specified record has an implicit 1477f22ef01cSRoman Divacky /// type which should be applied to it. This will infer the type of register 1478f22ef01cSRoman Divacky /// references from the register file information, for example. 1479f22ef01cSRoman Divacky /// 1480139f7f9bSDimitry Andric /// When Unnamed is set, return the type of a DAG operand with no name, such as 1481139f7f9bSDimitry Andric /// the F8RC register class argument in: 1482139f7f9bSDimitry Andric /// 1483139f7f9bSDimitry Andric /// (COPY_TO_REGCLASS GPR:$src, F8RC) 1484139f7f9bSDimitry Andric /// 1485139f7f9bSDimitry Andric /// When Unnamed is false, return the type of a named DAG operand such as the 1486139f7f9bSDimitry Andric /// GPR:$src operand above. 1487139f7f9bSDimitry Andric /// 1488f22ef01cSRoman Divacky static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo, 1489139f7f9bSDimitry Andric bool NotRegisters, 1490139f7f9bSDimitry Andric bool Unnamed, 1491139f7f9bSDimitry Andric TreePattern &TP) { 149217a519f9SDimitry Andric // Check to see if this is a register operand. 149317a519f9SDimitry Andric if (R->isSubClassOf("RegisterOperand")) { 149417a519f9SDimitry Andric assert(ResNo == 0 && "Regoperand ref only has one result!"); 149517a519f9SDimitry Andric if (NotRegisters) 149617a519f9SDimitry Andric return EEVT::TypeSet(); // Unknown. 149717a519f9SDimitry Andric Record *RegClass = R->getValueAsDef("RegClass"); 149817a519f9SDimitry Andric const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); 149917a519f9SDimitry Andric return EEVT::TypeSet(T.getRegisterClass(RegClass).getValueTypes()); 150017a519f9SDimitry Andric } 150117a519f9SDimitry Andric 1502f22ef01cSRoman Divacky // Check to see if this is a register or a register class. 1503f22ef01cSRoman Divacky if (R->isSubClassOf("RegisterClass")) { 1504f22ef01cSRoman Divacky assert(ResNo == 0 && "Regclass ref only has one result!"); 1505139f7f9bSDimitry Andric // An unnamed register class represents itself as an i32 immediate, for 1506139f7f9bSDimitry Andric // example on a COPY_TO_REGCLASS instruction. 1507139f7f9bSDimitry Andric if (Unnamed) 1508139f7f9bSDimitry Andric return EEVT::TypeSet(MVT::i32, TP); 1509139f7f9bSDimitry Andric 1510139f7f9bSDimitry Andric // In a named operand, the register class provides the possible set of 1511139f7f9bSDimitry Andric // types. 1512f22ef01cSRoman Divacky if (NotRegisters) 1513f22ef01cSRoman Divacky return EEVT::TypeSet(); // Unknown. 1514f22ef01cSRoman Divacky const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); 1515f22ef01cSRoman Divacky return EEVT::TypeSet(T.getRegisterClass(R).getValueTypes()); 1516f22ef01cSRoman Divacky } 1517f22ef01cSRoman Divacky 1518f22ef01cSRoman Divacky if (R->isSubClassOf("PatFrag")) { 1519f22ef01cSRoman Divacky assert(ResNo == 0 && "FIXME: PatFrag with multiple results?"); 1520f22ef01cSRoman Divacky // Pattern fragment types will be resolved when they are inlined. 1521f22ef01cSRoman Divacky return EEVT::TypeSet(); // Unknown. 1522f22ef01cSRoman Divacky } 1523f22ef01cSRoman Divacky 1524f22ef01cSRoman Divacky if (R->isSubClassOf("Register")) { 1525f22ef01cSRoman Divacky assert(ResNo == 0 && "Registers only produce one result!"); 1526f22ef01cSRoman Divacky if (NotRegisters) 1527f22ef01cSRoman Divacky return EEVT::TypeSet(); // Unknown. 1528f22ef01cSRoman Divacky const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); 1529f22ef01cSRoman Divacky return EEVT::TypeSet(T.getRegisterVTs(R)); 1530f22ef01cSRoman Divacky } 1531f22ef01cSRoman Divacky 1532f22ef01cSRoman Divacky if (R->isSubClassOf("SubRegIndex")) { 1533f22ef01cSRoman Divacky assert(ResNo == 0 && "SubRegisterIndices only produce one result!"); 153439d628a0SDimitry Andric return EEVT::TypeSet(MVT::i32, TP); 1535f22ef01cSRoman Divacky } 1536f22ef01cSRoman Divacky 1537139f7f9bSDimitry Andric if (R->isSubClassOf("ValueType")) { 1538f22ef01cSRoman Divacky assert(ResNo == 0 && "This node only has one result!"); 1539139f7f9bSDimitry Andric // An unnamed VTSDNode represents itself as an MVT::Other immediate. 1540139f7f9bSDimitry Andric // 1541139f7f9bSDimitry Andric // (sext_inreg GPR:$src, i16) 1542139f7f9bSDimitry Andric // ~~~ 1543139f7f9bSDimitry Andric if (Unnamed) 1544139f7f9bSDimitry Andric return EEVT::TypeSet(MVT::Other, TP); 1545139f7f9bSDimitry Andric // With a name, the ValueType simply provides the type of the named 1546139f7f9bSDimitry Andric // variable. 1547139f7f9bSDimitry Andric // 1548139f7f9bSDimitry Andric // (sext_inreg i32:$src, i16) 1549139f7f9bSDimitry Andric // ~~~~~~~~ 1550139f7f9bSDimitry Andric if (NotRegisters) 1551139f7f9bSDimitry Andric return EEVT::TypeSet(); // Unknown. 1552139f7f9bSDimitry Andric return EEVT::TypeSet(getValueType(R), TP); 1553139f7f9bSDimitry Andric } 1554139f7f9bSDimitry Andric 1555139f7f9bSDimitry Andric if (R->isSubClassOf("CondCode")) { 1556139f7f9bSDimitry Andric assert(ResNo == 0 && "This node only has one result!"); 1557139f7f9bSDimitry Andric // Using a CondCodeSDNode. 1558f22ef01cSRoman Divacky return EEVT::TypeSet(MVT::Other, TP); 1559f22ef01cSRoman Divacky } 1560f22ef01cSRoman Divacky 1561f22ef01cSRoman Divacky if (R->isSubClassOf("ComplexPattern")) { 1562f22ef01cSRoman Divacky assert(ResNo == 0 && "FIXME: ComplexPattern with multiple results?"); 1563f22ef01cSRoman Divacky if (NotRegisters) 1564f22ef01cSRoman Divacky return EEVT::TypeSet(); // Unknown. 1565f22ef01cSRoman Divacky return EEVT::TypeSet(TP.getDAGPatterns().getComplexPattern(R).getValueType(), 1566f22ef01cSRoman Divacky TP); 1567f22ef01cSRoman Divacky } 1568f22ef01cSRoman Divacky if (R->isSubClassOf("PointerLikeRegClass")) { 1569f22ef01cSRoman Divacky assert(ResNo == 0 && "Regclass can only have one result!"); 1570f22ef01cSRoman Divacky return EEVT::TypeSet(MVT::iPTR, TP); 1571f22ef01cSRoman Divacky } 1572f22ef01cSRoman Divacky 1573f22ef01cSRoman Divacky if (R->getName() == "node" || R->getName() == "srcvalue" || 1574f22ef01cSRoman Divacky R->getName() == "zero_reg") { 1575f22ef01cSRoman Divacky // Placeholder. 1576f22ef01cSRoman Divacky return EEVT::TypeSet(); // Unknown. 1577f22ef01cSRoman Divacky } 1578f22ef01cSRoman Divacky 157991bc56edSDimitry Andric if (R->isSubClassOf("Operand")) 158091bc56edSDimitry Andric return EEVT::TypeSet(getValueType(R->getValueAsDef("Type"))); 158191bc56edSDimitry Andric 1582f22ef01cSRoman Divacky TP.error("Unknown node flavor used in pattern: " + R->getName()); 1583f22ef01cSRoman Divacky return EEVT::TypeSet(MVT::Other, TP); 1584f22ef01cSRoman Divacky } 1585f22ef01cSRoman Divacky 1586f22ef01cSRoman Divacky 1587f22ef01cSRoman Divacky /// getIntrinsicInfo - If this node corresponds to an intrinsic, return the 1588f22ef01cSRoman Divacky /// CodeGenIntrinsic information for it, otherwise return a null pointer. 1589f22ef01cSRoman Divacky const CodeGenIntrinsic *TreePatternNode:: 1590f22ef01cSRoman Divacky getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const { 1591f22ef01cSRoman Divacky if (getOperator() != CDP.get_intrinsic_void_sdnode() && 1592f22ef01cSRoman Divacky getOperator() != CDP.get_intrinsic_w_chain_sdnode() && 1593f22ef01cSRoman Divacky getOperator() != CDP.get_intrinsic_wo_chain_sdnode()) 159491bc56edSDimitry Andric return nullptr; 1595f22ef01cSRoman Divacky 15963861d79fSDimitry Andric unsigned IID = cast<IntInit>(getChild(0)->getLeafValue())->getValue(); 1597f22ef01cSRoman Divacky return &CDP.getIntrinsicInfo(IID); 1598f22ef01cSRoman Divacky } 1599f22ef01cSRoman Divacky 1600f22ef01cSRoman Divacky /// getComplexPatternInfo - If this node corresponds to a ComplexPattern, 1601f22ef01cSRoman Divacky /// return the ComplexPattern information, otherwise return null. 1602f22ef01cSRoman Divacky const ComplexPattern * 1603f22ef01cSRoman Divacky TreePatternNode::getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const { 160491bc56edSDimitry Andric Record *Rec; 160591bc56edSDimitry Andric if (isLeaf()) { 16063861d79fSDimitry Andric DefInit *DI = dyn_cast<DefInit>(getLeafValue()); 160791bc56edSDimitry Andric if (!DI) 160891bc56edSDimitry Andric return nullptr; 160991bc56edSDimitry Andric Rec = DI->getDef(); 161091bc56edSDimitry Andric } else 161191bc56edSDimitry Andric Rec = getOperator(); 161291bc56edSDimitry Andric 161391bc56edSDimitry Andric if (!Rec->isSubClassOf("ComplexPattern")) 161491bc56edSDimitry Andric return nullptr; 161591bc56edSDimitry Andric return &CGP.getComplexPattern(Rec); 161691bc56edSDimitry Andric } 161791bc56edSDimitry Andric 161891bc56edSDimitry Andric unsigned TreePatternNode::getNumMIResults(const CodeGenDAGPatterns &CGP) const { 161991bc56edSDimitry Andric // A ComplexPattern specifically declares how many results it fills in. 162091bc56edSDimitry Andric if (const ComplexPattern *CP = getComplexPatternInfo(CGP)) 162191bc56edSDimitry Andric return CP->getNumOperands(); 162291bc56edSDimitry Andric 162391bc56edSDimitry Andric // If MIOperandInfo is specified, that gives the count. 162491bc56edSDimitry Andric if (isLeaf()) { 162591bc56edSDimitry Andric DefInit *DI = dyn_cast<DefInit>(getLeafValue()); 162691bc56edSDimitry Andric if (DI && DI->getDef()->isSubClassOf("Operand")) { 162791bc56edSDimitry Andric DagInit *MIOps = DI->getDef()->getValueAsDag("MIOperandInfo"); 162891bc56edSDimitry Andric if (MIOps->getNumArgs()) 162991bc56edSDimitry Andric return MIOps->getNumArgs(); 163091bc56edSDimitry Andric } 163191bc56edSDimitry Andric } 163291bc56edSDimitry Andric 163391bc56edSDimitry Andric // Otherwise there is just one result. 163491bc56edSDimitry Andric return 1; 1635f22ef01cSRoman Divacky } 1636f22ef01cSRoman Divacky 1637f22ef01cSRoman Divacky /// NodeHasProperty - Return true if this node has the specified property. 1638f22ef01cSRoman Divacky bool TreePatternNode::NodeHasProperty(SDNP Property, 1639f22ef01cSRoman Divacky const CodeGenDAGPatterns &CGP) const { 1640f22ef01cSRoman Divacky if (isLeaf()) { 1641f22ef01cSRoman Divacky if (const ComplexPattern *CP = getComplexPatternInfo(CGP)) 1642f22ef01cSRoman Divacky return CP->hasProperty(Property); 1643f22ef01cSRoman Divacky return false; 1644f22ef01cSRoman Divacky } 1645f22ef01cSRoman Divacky 1646f22ef01cSRoman Divacky Record *Operator = getOperator(); 1647f22ef01cSRoman Divacky if (!Operator->isSubClassOf("SDNode")) return false; 1648f22ef01cSRoman Divacky 1649f22ef01cSRoman Divacky return CGP.getSDNodeInfo(Operator).hasProperty(Property); 1650f22ef01cSRoman Divacky } 1651f22ef01cSRoman Divacky 1652f22ef01cSRoman Divacky 1653f22ef01cSRoman Divacky 1654f22ef01cSRoman Divacky 1655f22ef01cSRoman Divacky /// TreeHasProperty - Return true if any node in this tree has the specified 1656f22ef01cSRoman Divacky /// property. 1657f22ef01cSRoman Divacky bool TreePatternNode::TreeHasProperty(SDNP Property, 1658f22ef01cSRoman Divacky const CodeGenDAGPatterns &CGP) const { 1659f22ef01cSRoman Divacky if (NodeHasProperty(Property, CGP)) 1660f22ef01cSRoman Divacky return true; 1661f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumChildren(); i != e; ++i) 1662f22ef01cSRoman Divacky if (getChild(i)->TreeHasProperty(Property, CGP)) 1663f22ef01cSRoman Divacky return true; 1664f22ef01cSRoman Divacky return false; 1665f22ef01cSRoman Divacky } 1666f22ef01cSRoman Divacky 1667f22ef01cSRoman Divacky /// isCommutativeIntrinsic - Return true if the node corresponds to a 1668f22ef01cSRoman Divacky /// commutative intrinsic. 1669f22ef01cSRoman Divacky bool 1670f22ef01cSRoman Divacky TreePatternNode::isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const { 1671f22ef01cSRoman Divacky if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) 1672f22ef01cSRoman Divacky return Int->isCommutative; 1673f22ef01cSRoman Divacky return false; 1674f22ef01cSRoman Divacky } 1675f22ef01cSRoman Divacky 167639d628a0SDimitry Andric static bool isOperandClass(const TreePatternNode *N, StringRef Class) { 167739d628a0SDimitry Andric if (!N->isLeaf()) 167839d628a0SDimitry Andric return N->getOperator()->isSubClassOf(Class); 167939d628a0SDimitry Andric 168039d628a0SDimitry Andric DefInit *DI = dyn_cast<DefInit>(N->getLeafValue()); 168139d628a0SDimitry Andric if (DI && DI->getDef()->isSubClassOf(Class)) 168239d628a0SDimitry Andric return true; 168339d628a0SDimitry Andric 168439d628a0SDimitry Andric return false; 168539d628a0SDimitry Andric } 168639d628a0SDimitry Andric 168739d628a0SDimitry Andric static void emitTooManyOperandsError(TreePattern &TP, 168839d628a0SDimitry Andric StringRef InstName, 168939d628a0SDimitry Andric unsigned Expected, 169039d628a0SDimitry Andric unsigned Actual) { 169139d628a0SDimitry Andric TP.error("Instruction '" + InstName + "' was provided " + Twine(Actual) + 169239d628a0SDimitry Andric " operands but expected only " + Twine(Expected) + "!"); 169339d628a0SDimitry Andric } 169439d628a0SDimitry Andric 169539d628a0SDimitry Andric static void emitTooFewOperandsError(TreePattern &TP, 169639d628a0SDimitry Andric StringRef InstName, 169739d628a0SDimitry Andric unsigned Actual) { 169839d628a0SDimitry Andric TP.error("Instruction '" + InstName + 169939d628a0SDimitry Andric "' expects more than the provided " + Twine(Actual) + " operands!"); 170039d628a0SDimitry Andric } 1701f22ef01cSRoman Divacky 1702f22ef01cSRoman Divacky /// ApplyTypeConstraints - Apply all of the type constraints relevant to 1703f22ef01cSRoman Divacky /// this node and its children in the tree. This returns true if it makes a 17043861d79fSDimitry Andric /// change, false otherwise. If a type contradiction is found, flag an error. 1705f22ef01cSRoman Divacky bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { 17063861d79fSDimitry Andric if (TP.hasError()) 17073861d79fSDimitry Andric return false; 17083861d79fSDimitry Andric 1709f22ef01cSRoman Divacky CodeGenDAGPatterns &CDP = TP.getDAGPatterns(); 1710f22ef01cSRoman Divacky if (isLeaf()) { 17113861d79fSDimitry Andric if (DefInit *DI = dyn_cast<DefInit>(getLeafValue())) { 1712f22ef01cSRoman Divacky // If it's a regclass or something else known, include the type. 1713f22ef01cSRoman Divacky bool MadeChange = false; 1714f22ef01cSRoman Divacky for (unsigned i = 0, e = Types.size(); i != e; ++i) 1715f22ef01cSRoman Divacky MadeChange |= UpdateNodeType(i, getImplicitType(DI->getDef(), i, 1716139f7f9bSDimitry Andric NotRegisters, 1717139f7f9bSDimitry Andric !hasName(), TP), TP); 1718f22ef01cSRoman Divacky return MadeChange; 1719f22ef01cSRoman Divacky } 1720f22ef01cSRoman Divacky 17213861d79fSDimitry Andric if (IntInit *II = dyn_cast<IntInit>(getLeafValue())) { 1722f22ef01cSRoman Divacky assert(Types.size() == 1 && "Invalid IntInit"); 1723f22ef01cSRoman Divacky 1724f22ef01cSRoman Divacky // Int inits are always integers. :) 1725f22ef01cSRoman Divacky bool MadeChange = Types[0].EnforceInteger(TP); 1726f22ef01cSRoman Divacky 1727f22ef01cSRoman Divacky if (!Types[0].isConcrete()) 1728f22ef01cSRoman Divacky return MadeChange; 1729f22ef01cSRoman Divacky 1730f22ef01cSRoman Divacky MVT::SimpleValueType VT = getType(0); 1731f22ef01cSRoman Divacky if (VT == MVT::iPTR || VT == MVT::iPTRAny) 1732f22ef01cSRoman Divacky return MadeChange; 1733f22ef01cSRoman Divacky 1734f785676fSDimitry Andric unsigned Size = MVT(VT).getSizeInBits(); 1735f22ef01cSRoman Divacky // Make sure that the value is representable for this type. 1736f22ef01cSRoman Divacky if (Size >= 32) return MadeChange; 1737f22ef01cSRoman Divacky 17383861d79fSDimitry Andric // Check that the value doesn't use more bits than we have. It must either 17393861d79fSDimitry Andric // be a sign- or zero-extended equivalent of the original. 17403861d79fSDimitry Andric int64_t SignBitAndAbove = II->getValue() >> (Size - 1); 17413861d79fSDimitry Andric if (SignBitAndAbove == -1 || SignBitAndAbove == 0 || SignBitAndAbove == 1) 1742f22ef01cSRoman Divacky return MadeChange; 1743f22ef01cSRoman Divacky 1744f22ef01cSRoman Divacky TP.error("Integer value '" + itostr(II->getValue()) + 1745f22ef01cSRoman Divacky "' is out of range for type '" + getEnumName(getType(0)) + "'!"); 17463861d79fSDimitry Andric return false; 1747f22ef01cSRoman Divacky } 1748f22ef01cSRoman Divacky return false; 1749f22ef01cSRoman Divacky } 1750f22ef01cSRoman Divacky 1751f22ef01cSRoman Divacky // special handling for set, which isn't really an SDNode. 1752f22ef01cSRoman Divacky if (getOperator()->getName() == "set") { 1753f22ef01cSRoman Divacky assert(getNumTypes() == 0 && "Set doesn't produce a value"); 1754f22ef01cSRoman Divacky assert(getNumChildren() >= 2 && "Missing RHS of a set?"); 1755f22ef01cSRoman Divacky unsigned NC = getNumChildren(); 1756f22ef01cSRoman Divacky 1757f22ef01cSRoman Divacky TreePatternNode *SetVal = getChild(NC-1); 1758f22ef01cSRoman Divacky bool MadeChange = SetVal->ApplyTypeConstraints(TP, NotRegisters); 1759f22ef01cSRoman Divacky 1760f22ef01cSRoman Divacky for (unsigned i = 0; i < NC-1; ++i) { 1761f22ef01cSRoman Divacky TreePatternNode *Child = getChild(i); 1762f22ef01cSRoman Divacky MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters); 1763f22ef01cSRoman Divacky 1764f22ef01cSRoman Divacky // Types of operands must match. 1765f22ef01cSRoman Divacky MadeChange |= Child->UpdateNodeType(0, SetVal->getExtType(i), TP); 1766f22ef01cSRoman Divacky MadeChange |= SetVal->UpdateNodeType(i, Child->getExtType(0), TP); 1767f22ef01cSRoman Divacky } 1768f22ef01cSRoman Divacky return MadeChange; 1769f22ef01cSRoman Divacky } 1770f22ef01cSRoman Divacky 1771f22ef01cSRoman Divacky if (getOperator()->getName() == "implicit") { 1772f22ef01cSRoman Divacky assert(getNumTypes() == 0 && "Node doesn't produce a value"); 1773f22ef01cSRoman Divacky 1774f22ef01cSRoman Divacky bool MadeChange = false; 1775f22ef01cSRoman Divacky for (unsigned i = 0; i < getNumChildren(); ++i) 1776f22ef01cSRoman Divacky MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters); 1777f22ef01cSRoman Divacky return MadeChange; 1778f22ef01cSRoman Divacky } 1779f22ef01cSRoman Divacky 1780f22ef01cSRoman Divacky if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) { 1781f22ef01cSRoman Divacky bool MadeChange = false; 1782f22ef01cSRoman Divacky 1783f22ef01cSRoman Divacky // Apply the result type to the node. 1784f22ef01cSRoman Divacky unsigned NumRetVTs = Int->IS.RetVTs.size(); 1785f22ef01cSRoman Divacky unsigned NumParamVTs = Int->IS.ParamVTs.size(); 1786f22ef01cSRoman Divacky 1787f22ef01cSRoman Divacky for (unsigned i = 0, e = NumRetVTs; i != e; ++i) 1788f22ef01cSRoman Divacky MadeChange |= UpdateNodeType(i, Int->IS.RetVTs[i], TP); 1789f22ef01cSRoman Divacky 17903861d79fSDimitry Andric if (getNumChildren() != NumParamVTs + 1) { 1791f22ef01cSRoman Divacky TP.error("Intrinsic '" + Int->Name + "' expects " + 1792f22ef01cSRoman Divacky utostr(NumParamVTs) + " operands, not " + 1793f22ef01cSRoman Divacky utostr(getNumChildren() - 1) + " operands!"); 17943861d79fSDimitry Andric return false; 17953861d79fSDimitry Andric } 1796f22ef01cSRoman Divacky 1797f22ef01cSRoman Divacky // Apply type info to the intrinsic ID. 1798f22ef01cSRoman Divacky MadeChange |= getChild(0)->UpdateNodeType(0, MVT::iPTR, TP); 1799f22ef01cSRoman Divacky 1800f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i) { 1801f22ef01cSRoman Divacky MadeChange |= getChild(i+1)->ApplyTypeConstraints(TP, NotRegisters); 1802f22ef01cSRoman Divacky 1803f22ef01cSRoman Divacky MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i]; 1804f22ef01cSRoman Divacky assert(getChild(i+1)->getNumTypes() == 1 && "Unhandled case"); 1805f22ef01cSRoman Divacky MadeChange |= getChild(i+1)->UpdateNodeType(0, OpVT, TP); 1806f22ef01cSRoman Divacky } 1807f22ef01cSRoman Divacky return MadeChange; 1808f22ef01cSRoman Divacky } 1809f22ef01cSRoman Divacky 1810f22ef01cSRoman Divacky if (getOperator()->isSubClassOf("SDNode")) { 1811f22ef01cSRoman Divacky const SDNodeInfo &NI = CDP.getSDNodeInfo(getOperator()); 1812f22ef01cSRoman Divacky 1813f22ef01cSRoman Divacky // Check that the number of operands is sane. Negative operands -> varargs. 1814f22ef01cSRoman Divacky if (NI.getNumOperands() >= 0 && 18153861d79fSDimitry Andric getNumChildren() != (unsigned)NI.getNumOperands()) { 1816f22ef01cSRoman Divacky TP.error(getOperator()->getName() + " node requires exactly " + 1817f22ef01cSRoman Divacky itostr(NI.getNumOperands()) + " operands!"); 18183861d79fSDimitry Andric return false; 18193861d79fSDimitry Andric } 1820f22ef01cSRoman Divacky 1821f22ef01cSRoman Divacky bool MadeChange = NI.ApplyTypeConstraints(this, TP); 1822f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumChildren(); i != e; ++i) 1823f22ef01cSRoman Divacky MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); 1824f22ef01cSRoman Divacky return MadeChange; 1825f22ef01cSRoman Divacky } 1826f22ef01cSRoman Divacky 1827f22ef01cSRoman Divacky if (getOperator()->isSubClassOf("Instruction")) { 1828f22ef01cSRoman Divacky const DAGInstruction &Inst = CDP.getInstruction(getOperator()); 1829f22ef01cSRoman Divacky CodeGenInstruction &InstInfo = 1830f22ef01cSRoman Divacky CDP.getTargetInfo().getInstruction(getOperator()); 1831f22ef01cSRoman Divacky 1832f22ef01cSRoman Divacky bool MadeChange = false; 1833f22ef01cSRoman Divacky 1834f22ef01cSRoman Divacky // Apply the result types to the node, these come from the things in the 1835f22ef01cSRoman Divacky // (outs) list of the instruction. 1836ff0cc061SDimitry Andric unsigned NumResultsToAdd = std::min(InstInfo.Operands.NumDefs, 1837ff0cc061SDimitry Andric Inst.getNumResults()); 1838139f7f9bSDimitry Andric for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) 1839139f7f9bSDimitry Andric MadeChange |= UpdateNodeTypeFromInst(ResNo, Inst.getResult(ResNo), TP); 1840f22ef01cSRoman Divacky 1841f22ef01cSRoman Divacky // If the instruction has implicit defs, we apply the first one as a result. 1842f22ef01cSRoman Divacky // FIXME: This sucks, it should apply all implicit defs. 1843f22ef01cSRoman Divacky if (!InstInfo.ImplicitDefs.empty()) { 1844f22ef01cSRoman Divacky unsigned ResNo = NumResultsToAdd; 1845f22ef01cSRoman Divacky 1846f22ef01cSRoman Divacky // FIXME: Generalize to multiple possible types and multiple possible 1847f22ef01cSRoman Divacky // ImplicitDefs. 1848f22ef01cSRoman Divacky MVT::SimpleValueType VT = 1849f22ef01cSRoman Divacky InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()); 1850f22ef01cSRoman Divacky 1851f22ef01cSRoman Divacky if (VT != MVT::Other) 1852f22ef01cSRoman Divacky MadeChange |= UpdateNodeType(ResNo, VT, TP); 1853f22ef01cSRoman Divacky } 1854f22ef01cSRoman Divacky 1855f22ef01cSRoman Divacky // If this is an INSERT_SUBREG, constrain the source and destination VTs to 1856f22ef01cSRoman Divacky // be the same. 1857f22ef01cSRoman Divacky if (getOperator()->getName() == "INSERT_SUBREG") { 1858f22ef01cSRoman Divacky assert(getChild(0)->getNumTypes() == 1 && "FIXME: Unhandled"); 1859f22ef01cSRoman Divacky MadeChange |= UpdateNodeType(0, getChild(0)->getExtType(0), TP); 1860f22ef01cSRoman Divacky MadeChange |= getChild(0)->UpdateNodeType(0, getExtType(0), TP); 186139d628a0SDimitry Andric } else if (getOperator()->getName() == "REG_SEQUENCE") { 186239d628a0SDimitry Andric // We need to do extra, custom typechecking for REG_SEQUENCE since it is 186339d628a0SDimitry Andric // variadic. 186439d628a0SDimitry Andric 186539d628a0SDimitry Andric unsigned NChild = getNumChildren(); 186639d628a0SDimitry Andric if (NChild < 3) { 186739d628a0SDimitry Andric TP.error("REG_SEQUENCE requires at least 3 operands!"); 186839d628a0SDimitry Andric return false; 186939d628a0SDimitry Andric } 187039d628a0SDimitry Andric 187139d628a0SDimitry Andric if (NChild % 2 == 0) { 187239d628a0SDimitry Andric TP.error("REG_SEQUENCE requires an odd number of operands!"); 187339d628a0SDimitry Andric return false; 187439d628a0SDimitry Andric } 187539d628a0SDimitry Andric 187639d628a0SDimitry Andric if (!isOperandClass(getChild(0), "RegisterClass")) { 187739d628a0SDimitry Andric TP.error("REG_SEQUENCE requires a RegisterClass for first operand!"); 187839d628a0SDimitry Andric return false; 187939d628a0SDimitry Andric } 188039d628a0SDimitry Andric 188139d628a0SDimitry Andric for (unsigned I = 1; I < NChild; I += 2) { 188239d628a0SDimitry Andric TreePatternNode *SubIdxChild = getChild(I + 1); 188339d628a0SDimitry Andric if (!isOperandClass(SubIdxChild, "SubRegIndex")) { 188439d628a0SDimitry Andric TP.error("REG_SEQUENCE requires a SubRegIndex for operand " + 188539d628a0SDimitry Andric itostr(I + 1) + "!"); 188639d628a0SDimitry Andric return false; 188739d628a0SDimitry Andric } 188839d628a0SDimitry Andric } 1889f22ef01cSRoman Divacky } 1890f22ef01cSRoman Divacky 1891f22ef01cSRoman Divacky unsigned ChildNo = 0; 1892f22ef01cSRoman Divacky for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) { 1893f22ef01cSRoman Divacky Record *OperandNode = Inst.getOperand(i); 1894f22ef01cSRoman Divacky 1895f22ef01cSRoman Divacky // If the instruction expects a predicate or optional def operand, we 1896f22ef01cSRoman Divacky // codegen this by setting the operand to it's default value if it has a 1897f22ef01cSRoman Divacky // non-empty DefaultOps field. 18983861d79fSDimitry Andric if (OperandNode->isSubClassOf("OperandWithDefaultOps") && 1899f22ef01cSRoman Divacky !CDP.getDefaultOperand(OperandNode).DefaultOps.empty()) 1900f22ef01cSRoman Divacky continue; 1901f22ef01cSRoman Divacky 1902f22ef01cSRoman Divacky // Verify that we didn't run out of provided operands. 19033861d79fSDimitry Andric if (ChildNo >= getNumChildren()) { 190439d628a0SDimitry Andric emitTooFewOperandsError(TP, getOperator()->getName(), getNumChildren()); 19053861d79fSDimitry Andric return false; 19063861d79fSDimitry Andric } 1907f22ef01cSRoman Divacky 1908f22ef01cSRoman Divacky TreePatternNode *Child = getChild(ChildNo++); 1909f22ef01cSRoman Divacky unsigned ChildResNo = 0; // Instructions always use res #0 of their op. 1910f22ef01cSRoman Divacky 1911139f7f9bSDimitry Andric // If the operand has sub-operands, they may be provided by distinct 1912139f7f9bSDimitry Andric // child patterns, so attempt to match each sub-operand separately. 1913139f7f9bSDimitry Andric if (OperandNode->isSubClassOf("Operand")) { 1914139f7f9bSDimitry Andric DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo"); 1915139f7f9bSDimitry Andric if (unsigned NumArgs = MIOpInfo->getNumArgs()) { 1916139f7f9bSDimitry Andric // But don't do that if the whole operand is being provided by 191791bc56edSDimitry Andric // a single ComplexPattern-related Operand. 191891bc56edSDimitry Andric 191991bc56edSDimitry Andric if (Child->getNumMIResults(CDP) < NumArgs) { 1920139f7f9bSDimitry Andric // Match first sub-operand against the child we already have. 1921139f7f9bSDimitry Andric Record *SubRec = cast<DefInit>(MIOpInfo->getArg(0))->getDef(); 1922139f7f9bSDimitry Andric MadeChange |= 1923139f7f9bSDimitry Andric Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP); 1924dff0c46cSDimitry Andric 1925139f7f9bSDimitry Andric // And the remaining sub-operands against subsequent children. 1926139f7f9bSDimitry Andric for (unsigned Arg = 1; Arg < NumArgs; ++Arg) { 1927139f7f9bSDimitry Andric if (ChildNo >= getNumChildren()) { 192839d628a0SDimitry Andric emitTooFewOperandsError(TP, getOperator()->getName(), 192939d628a0SDimitry Andric getNumChildren()); 1930139f7f9bSDimitry Andric return false; 1931139f7f9bSDimitry Andric } 1932139f7f9bSDimitry Andric Child = getChild(ChildNo++); 1933139f7f9bSDimitry Andric 1934139f7f9bSDimitry Andric SubRec = cast<DefInit>(MIOpInfo->getArg(Arg))->getDef(); 1935139f7f9bSDimitry Andric MadeChange |= 1936139f7f9bSDimitry Andric Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP); 1937139f7f9bSDimitry Andric } 1938139f7f9bSDimitry Andric continue; 1939139f7f9bSDimitry Andric } 1940139f7f9bSDimitry Andric } 1941139f7f9bSDimitry Andric } 1942139f7f9bSDimitry Andric 1943139f7f9bSDimitry Andric // If we didn't match by pieces above, attempt to match the whole 1944139f7f9bSDimitry Andric // operand now. 1945139f7f9bSDimitry Andric MadeChange |= Child->UpdateNodeTypeFromInst(ChildResNo, OperandNode, TP); 1946f22ef01cSRoman Divacky } 1947f22ef01cSRoman Divacky 194839d628a0SDimitry Andric if (!InstInfo.Operands.isVariadic && ChildNo != getNumChildren()) { 194939d628a0SDimitry Andric emitTooManyOperandsError(TP, getOperator()->getName(), 195039d628a0SDimitry Andric ChildNo, getNumChildren()); 19513861d79fSDimitry Andric return false; 19523861d79fSDimitry Andric } 1953f22ef01cSRoman Divacky 1954139f7f9bSDimitry Andric for (unsigned i = 0, e = getNumChildren(); i != e; ++i) 1955139f7f9bSDimitry Andric MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); 1956f22ef01cSRoman Divacky return MadeChange; 1957f22ef01cSRoman Divacky } 1958f22ef01cSRoman Divacky 195991bc56edSDimitry Andric if (getOperator()->isSubClassOf("ComplexPattern")) { 196091bc56edSDimitry Andric bool MadeChange = false; 196191bc56edSDimitry Andric 196291bc56edSDimitry Andric for (unsigned i = 0; i < getNumChildren(); ++i) 196391bc56edSDimitry Andric MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); 196491bc56edSDimitry Andric 196591bc56edSDimitry Andric return MadeChange; 196691bc56edSDimitry Andric } 196791bc56edSDimitry Andric 1968f22ef01cSRoman Divacky assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!"); 1969f22ef01cSRoman Divacky 1970f22ef01cSRoman Divacky // Node transforms always take one operand. 19713861d79fSDimitry Andric if (getNumChildren() != 1) { 1972f22ef01cSRoman Divacky TP.error("Node transform '" + getOperator()->getName() + 1973f22ef01cSRoman Divacky "' requires one operand!"); 19743861d79fSDimitry Andric return false; 19753861d79fSDimitry Andric } 1976f22ef01cSRoman Divacky 1977f22ef01cSRoman Divacky bool MadeChange = getChild(0)->ApplyTypeConstraints(TP, NotRegisters); 1978f22ef01cSRoman Divacky 1979f22ef01cSRoman Divacky 1980f22ef01cSRoman Divacky // If either the output or input of the xform does not have exact 1981f22ef01cSRoman Divacky // type info. We assume they must be the same. Otherwise, it is perfectly 1982f22ef01cSRoman Divacky // legal to transform from one type to a completely different type. 1983f22ef01cSRoman Divacky #if 0 1984f22ef01cSRoman Divacky if (!hasTypeSet() || !getChild(0)->hasTypeSet()) { 1985f22ef01cSRoman Divacky bool MadeChange = UpdateNodeType(getChild(0)->getExtType(), TP); 1986f22ef01cSRoman Divacky MadeChange |= getChild(0)->UpdateNodeType(getExtType(), TP); 1987f22ef01cSRoman Divacky return MadeChange; 1988f22ef01cSRoman Divacky } 1989f22ef01cSRoman Divacky #endif 1990f22ef01cSRoman Divacky return MadeChange; 1991f22ef01cSRoman Divacky } 1992f22ef01cSRoman Divacky 1993f22ef01cSRoman Divacky /// OnlyOnRHSOfCommutative - Return true if this value is only allowed on the 1994f22ef01cSRoman Divacky /// RHS of a commutative operation, not the on LHS. 1995f22ef01cSRoman Divacky static bool OnlyOnRHSOfCommutative(TreePatternNode *N) { 1996f22ef01cSRoman Divacky if (!N->isLeaf() && N->getOperator()->getName() == "imm") 1997f22ef01cSRoman Divacky return true; 19983861d79fSDimitry Andric if (N->isLeaf() && isa<IntInit>(N->getLeafValue())) 1999f22ef01cSRoman Divacky return true; 2000f22ef01cSRoman Divacky return false; 2001f22ef01cSRoman Divacky } 2002f22ef01cSRoman Divacky 2003f22ef01cSRoman Divacky 2004f22ef01cSRoman Divacky /// canPatternMatch - If it is impossible for this pattern to match on this 2005f22ef01cSRoman Divacky /// target, fill in Reason and return false. Otherwise, return true. This is 2006f22ef01cSRoman Divacky /// used as a sanity check for .td files (to prevent people from writing stuff 2007f22ef01cSRoman Divacky /// that can never possibly work), and to prevent the pattern permuter from 2008f22ef01cSRoman Divacky /// generating stuff that is useless. 2009f22ef01cSRoman Divacky bool TreePatternNode::canPatternMatch(std::string &Reason, 2010f22ef01cSRoman Divacky const CodeGenDAGPatterns &CDP) { 2011f22ef01cSRoman Divacky if (isLeaf()) return true; 2012f22ef01cSRoman Divacky 2013f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumChildren(); i != e; ++i) 2014f22ef01cSRoman Divacky if (!getChild(i)->canPatternMatch(Reason, CDP)) 2015f22ef01cSRoman Divacky return false; 2016f22ef01cSRoman Divacky 2017f22ef01cSRoman Divacky // If this is an intrinsic, handle cases that would make it not match. For 2018f22ef01cSRoman Divacky // example, if an operand is required to be an immediate. 2019f22ef01cSRoman Divacky if (getOperator()->isSubClassOf("Intrinsic")) { 2020f22ef01cSRoman Divacky // TODO: 2021f22ef01cSRoman Divacky return true; 2022f22ef01cSRoman Divacky } 2023f22ef01cSRoman Divacky 202491bc56edSDimitry Andric if (getOperator()->isSubClassOf("ComplexPattern")) 202591bc56edSDimitry Andric return true; 202691bc56edSDimitry Andric 2027f22ef01cSRoman Divacky // If this node is a commutative operator, check that the LHS isn't an 2028f22ef01cSRoman Divacky // immediate. 2029f22ef01cSRoman Divacky const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(getOperator()); 2030f22ef01cSRoman Divacky bool isCommIntrinsic = isCommutativeIntrinsic(CDP); 2031f22ef01cSRoman Divacky if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) { 2032f22ef01cSRoman Divacky // Scan all of the operands of the node and make sure that only the last one 2033f22ef01cSRoman Divacky // is a constant node, unless the RHS also is. 2034f22ef01cSRoman Divacky if (!OnlyOnRHSOfCommutative(getChild(getNumChildren()-1))) { 2035d88c1a5aSDimitry Andric unsigned Skip = isCommIntrinsic ? 1 : 0; // First operand is intrinsic id. 2036f22ef01cSRoman Divacky for (unsigned i = Skip, e = getNumChildren()-1; i != e; ++i) 2037f22ef01cSRoman Divacky if (OnlyOnRHSOfCommutative(getChild(i))) { 2038f22ef01cSRoman Divacky Reason="Immediate value must be on the RHS of commutative operators!"; 2039f22ef01cSRoman Divacky return false; 2040f22ef01cSRoman Divacky } 2041f22ef01cSRoman Divacky } 2042f22ef01cSRoman Divacky } 2043f22ef01cSRoman Divacky 2044f22ef01cSRoman Divacky return true; 2045f22ef01cSRoman Divacky } 2046f22ef01cSRoman Divacky 2047f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 2048f22ef01cSRoman Divacky // TreePattern implementation 2049f22ef01cSRoman Divacky // 2050f22ef01cSRoman Divacky 2051f22ef01cSRoman Divacky TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput, 20523861d79fSDimitry Andric CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp), 20533861d79fSDimitry Andric isInputPattern(isInput), HasError(false) { 205497bc6c73SDimitry Andric for (Init *I : RawPat->getValues()) 205597bc6c73SDimitry Andric Trees.push_back(ParseTreePattern(I, "")); 2056f22ef01cSRoman Divacky } 2057f22ef01cSRoman Divacky 2058f22ef01cSRoman Divacky TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput, 20593861d79fSDimitry Andric CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp), 20603861d79fSDimitry Andric isInputPattern(isInput), HasError(false) { 2061f22ef01cSRoman Divacky Trees.push_back(ParseTreePattern(Pat, "")); 2062f22ef01cSRoman Divacky } 2063f22ef01cSRoman Divacky 2064f22ef01cSRoman Divacky TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput, 20653861d79fSDimitry Andric CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp), 20663861d79fSDimitry Andric isInputPattern(isInput), HasError(false) { 2067f22ef01cSRoman Divacky Trees.push_back(Pat); 2068f22ef01cSRoman Divacky } 2069f22ef01cSRoman Divacky 207039d628a0SDimitry Andric void TreePattern::error(const Twine &Msg) { 20713861d79fSDimitry Andric if (HasError) 20723861d79fSDimitry Andric return; 2073f22ef01cSRoman Divacky dump(); 20743861d79fSDimitry Andric PrintError(TheRecord->getLoc(), "In " + TheRecord->getName() + ": " + Msg); 20753861d79fSDimitry Andric HasError = true; 2076f22ef01cSRoman Divacky } 2077f22ef01cSRoman Divacky 2078f22ef01cSRoman Divacky void TreePattern::ComputeNamedNodes() { 20797d523365SDimitry Andric for (TreePatternNode *Tree : Trees) 20807d523365SDimitry Andric ComputeNamedNodes(Tree); 2081f22ef01cSRoman Divacky } 2082f22ef01cSRoman Divacky 2083f22ef01cSRoman Divacky void TreePattern::ComputeNamedNodes(TreePatternNode *N) { 2084f22ef01cSRoman Divacky if (!N->getName().empty()) 2085f22ef01cSRoman Divacky NamedNodes[N->getName()].push_back(N); 2086f22ef01cSRoman Divacky 2087f22ef01cSRoman Divacky for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) 2088f22ef01cSRoman Divacky ComputeNamedNodes(N->getChild(i)); 2089f22ef01cSRoman Divacky } 2090f22ef01cSRoman Divacky 2091f22ef01cSRoman Divacky 2092f22ef01cSRoman Divacky TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ 20933861d79fSDimitry Andric if (DefInit *DI = dyn_cast<DefInit>(TheInit)) { 2094f22ef01cSRoman Divacky Record *R = DI->getDef(); 2095f22ef01cSRoman Divacky 2096f22ef01cSRoman Divacky // Direct reference to a leaf DagNode or PatFrag? Turn it into a 209717a519f9SDimitry Andric // TreePatternNode of its own. For example: 2098f22ef01cSRoman Divacky /// (foo GPR, imm) -> (foo GPR, (imm)) 2099f22ef01cSRoman Divacky if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) 21006122f3e6SDimitry Andric return ParseTreePattern( 2101d88c1a5aSDimitry Andric DagInit::get(DI, nullptr, 2102d88c1a5aSDimitry Andric std::vector<std::pair<Init*, StringInit*> >()), 2103f22ef01cSRoman Divacky OpName); 2104f22ef01cSRoman Divacky 2105f22ef01cSRoman Divacky // Input argument? 2106f22ef01cSRoman Divacky TreePatternNode *Res = new TreePatternNode(DI, 1); 2107f22ef01cSRoman Divacky if (R->getName() == "node" && !OpName.empty()) { 2108f22ef01cSRoman Divacky if (OpName.empty()) 2109f22ef01cSRoman Divacky error("'node' argument requires a name to match with operand list"); 2110f22ef01cSRoman Divacky Args.push_back(OpName); 2111f22ef01cSRoman Divacky } 2112f22ef01cSRoman Divacky 2113f22ef01cSRoman Divacky Res->setName(OpName); 2114f22ef01cSRoman Divacky return Res; 2115f22ef01cSRoman Divacky } 2116f22ef01cSRoman Divacky 2117139f7f9bSDimitry Andric // ?:$name or just $name. 2118ff0cc061SDimitry Andric if (isa<UnsetInit>(TheInit)) { 2119139f7f9bSDimitry Andric if (OpName.empty()) 2120139f7f9bSDimitry Andric error("'?' argument requires a name to match with operand list"); 2121139f7f9bSDimitry Andric TreePatternNode *Res = new TreePatternNode(TheInit, 1); 2122139f7f9bSDimitry Andric Args.push_back(OpName); 2123139f7f9bSDimitry Andric Res->setName(OpName); 2124139f7f9bSDimitry Andric return Res; 2125139f7f9bSDimitry Andric } 2126139f7f9bSDimitry Andric 21273861d79fSDimitry Andric if (IntInit *II = dyn_cast<IntInit>(TheInit)) { 2128f22ef01cSRoman Divacky if (!OpName.empty()) 2129f22ef01cSRoman Divacky error("Constant int argument should not have a name!"); 2130f22ef01cSRoman Divacky return new TreePatternNode(II, 1); 2131f22ef01cSRoman Divacky } 2132f22ef01cSRoman Divacky 21333861d79fSDimitry Andric if (BitsInit *BI = dyn_cast<BitsInit>(TheInit)) { 2134f22ef01cSRoman Divacky // Turn this into an IntInit. 21356122f3e6SDimitry Andric Init *II = BI->convertInitializerTo(IntRecTy::get()); 213691bc56edSDimitry Andric if (!II || !isa<IntInit>(II)) 2137f22ef01cSRoman Divacky error("Bits value must be constants!"); 2138f22ef01cSRoman Divacky return ParseTreePattern(II, OpName); 2139f22ef01cSRoman Divacky } 2140f22ef01cSRoman Divacky 21413861d79fSDimitry Andric DagInit *Dag = dyn_cast<DagInit>(TheInit); 2142f22ef01cSRoman Divacky if (!Dag) { 21437a7e6055SDimitry Andric TheInit->print(errs()); 2144f22ef01cSRoman Divacky error("Pattern has unexpected init kind!"); 2145f22ef01cSRoman Divacky } 21463861d79fSDimitry Andric DefInit *OpDef = dyn_cast<DefInit>(Dag->getOperator()); 2147f22ef01cSRoman Divacky if (!OpDef) error("Pattern has unexpected operator type!"); 2148f22ef01cSRoman Divacky Record *Operator = OpDef->getDef(); 2149f22ef01cSRoman Divacky 2150f22ef01cSRoman Divacky if (Operator->isSubClassOf("ValueType")) { 2151f22ef01cSRoman Divacky // If the operator is a ValueType, then this must be "type cast" of a leaf 2152f22ef01cSRoman Divacky // node. 2153f22ef01cSRoman Divacky if (Dag->getNumArgs() != 1) 2154f22ef01cSRoman Divacky error("Type cast only takes one operand!"); 2155f22ef01cSRoman Divacky 2156d88c1a5aSDimitry Andric TreePatternNode *New = ParseTreePattern(Dag->getArg(0), 2157d88c1a5aSDimitry Andric Dag->getArgNameStr(0)); 2158f22ef01cSRoman Divacky 2159f22ef01cSRoman Divacky // Apply the type cast. 2160f22ef01cSRoman Divacky assert(New->getNumTypes() == 1 && "FIXME: Unhandled"); 2161f22ef01cSRoman Divacky New->UpdateNodeType(0, getValueType(Operator), *this); 2162f22ef01cSRoman Divacky 2163f22ef01cSRoman Divacky if (!OpName.empty()) 2164f22ef01cSRoman Divacky error("ValueType cast should not have a name!"); 2165f22ef01cSRoman Divacky return New; 2166f22ef01cSRoman Divacky } 2167f22ef01cSRoman Divacky 2168f22ef01cSRoman Divacky // Verify that this is something that makes sense for an operator. 2169f22ef01cSRoman Divacky if (!Operator->isSubClassOf("PatFrag") && 2170f22ef01cSRoman Divacky !Operator->isSubClassOf("SDNode") && 2171f22ef01cSRoman Divacky !Operator->isSubClassOf("Instruction") && 2172f22ef01cSRoman Divacky !Operator->isSubClassOf("SDNodeXForm") && 2173f22ef01cSRoman Divacky !Operator->isSubClassOf("Intrinsic") && 217491bc56edSDimitry Andric !Operator->isSubClassOf("ComplexPattern") && 2175f22ef01cSRoman Divacky Operator->getName() != "set" && 2176f22ef01cSRoman Divacky Operator->getName() != "implicit") 2177f22ef01cSRoman Divacky error("Unrecognized node '" + Operator->getName() + "'!"); 2178f22ef01cSRoman Divacky 2179f22ef01cSRoman Divacky // Check to see if this is something that is illegal in an input pattern. 2180f22ef01cSRoman Divacky if (isInputPattern) { 2181f22ef01cSRoman Divacky if (Operator->isSubClassOf("Instruction") || 2182f22ef01cSRoman Divacky Operator->isSubClassOf("SDNodeXForm")) 2183f22ef01cSRoman Divacky error("Cannot use '" + Operator->getName() + "' in an input pattern!"); 2184f22ef01cSRoman Divacky } else { 2185f22ef01cSRoman Divacky if (Operator->isSubClassOf("Intrinsic")) 2186f22ef01cSRoman Divacky error("Cannot use '" + Operator->getName() + "' in an output pattern!"); 2187f22ef01cSRoman Divacky 2188f22ef01cSRoman Divacky if (Operator->isSubClassOf("SDNode") && 2189f22ef01cSRoman Divacky Operator->getName() != "imm" && 2190f22ef01cSRoman Divacky Operator->getName() != "fpimm" && 2191f22ef01cSRoman Divacky Operator->getName() != "tglobaltlsaddr" && 2192f22ef01cSRoman Divacky Operator->getName() != "tconstpool" && 2193f22ef01cSRoman Divacky Operator->getName() != "tjumptable" && 2194f22ef01cSRoman Divacky Operator->getName() != "tframeindex" && 2195f22ef01cSRoman Divacky Operator->getName() != "texternalsym" && 2196f22ef01cSRoman Divacky Operator->getName() != "tblockaddress" && 2197f22ef01cSRoman Divacky Operator->getName() != "tglobaladdr" && 2198f22ef01cSRoman Divacky Operator->getName() != "bb" && 21993dac3a9bSDimitry Andric Operator->getName() != "vt" && 22003dac3a9bSDimitry Andric Operator->getName() != "mcsym") 2201f22ef01cSRoman Divacky error("Cannot use '" + Operator->getName() + "' in an output pattern!"); 2202f22ef01cSRoman Divacky } 2203f22ef01cSRoman Divacky 2204f22ef01cSRoman Divacky std::vector<TreePatternNode*> Children; 2205f22ef01cSRoman Divacky 2206f22ef01cSRoman Divacky // Parse all the operands. 2207f22ef01cSRoman Divacky for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) 2208d88c1a5aSDimitry Andric Children.push_back(ParseTreePattern(Dag->getArg(i), Dag->getArgNameStr(i))); 2209f22ef01cSRoman Divacky 2210f22ef01cSRoman Divacky // If the operator is an intrinsic, then this is just syntactic sugar for for 2211f22ef01cSRoman Divacky // (intrinsic_* <number>, ..children..). Pick the right intrinsic node, and 2212f22ef01cSRoman Divacky // convert the intrinsic name to a number. 2213f22ef01cSRoman Divacky if (Operator->isSubClassOf("Intrinsic")) { 2214f22ef01cSRoman Divacky const CodeGenIntrinsic &Int = getDAGPatterns().getIntrinsic(Operator); 2215f22ef01cSRoman Divacky unsigned IID = getDAGPatterns().getIntrinsicID(Operator)+1; 2216f22ef01cSRoman Divacky 2217f22ef01cSRoman Divacky // If this intrinsic returns void, it must have side-effects and thus a 2218f22ef01cSRoman Divacky // chain. 2219f22ef01cSRoman Divacky if (Int.IS.RetVTs.empty()) 2220f22ef01cSRoman Divacky Operator = getDAGPatterns().get_intrinsic_void_sdnode(); 2221f22ef01cSRoman Divacky else if (Int.ModRef != CodeGenIntrinsic::NoMem) 2222f22ef01cSRoman Divacky // Has side-effects, requires chain. 2223f22ef01cSRoman Divacky Operator = getDAGPatterns().get_intrinsic_w_chain_sdnode(); 2224f22ef01cSRoman Divacky else // Otherwise, no chain. 2225f22ef01cSRoman Divacky Operator = getDAGPatterns().get_intrinsic_wo_chain_sdnode(); 2226f22ef01cSRoman Divacky 22276122f3e6SDimitry Andric TreePatternNode *IIDNode = new TreePatternNode(IntInit::get(IID), 1); 2228f22ef01cSRoman Divacky Children.insert(Children.begin(), IIDNode); 2229f22ef01cSRoman Divacky } 2230f22ef01cSRoman Divacky 223191bc56edSDimitry Andric if (Operator->isSubClassOf("ComplexPattern")) { 223291bc56edSDimitry Andric for (unsigned i = 0; i < Children.size(); ++i) { 223391bc56edSDimitry Andric TreePatternNode *Child = Children[i]; 223491bc56edSDimitry Andric 223591bc56edSDimitry Andric if (Child->getName().empty()) 223691bc56edSDimitry Andric error("All arguments to a ComplexPattern must be named"); 223791bc56edSDimitry Andric 223891bc56edSDimitry Andric // Check that the ComplexPattern uses are consistent: "(MY_PAT $a, $b)" 223991bc56edSDimitry Andric // and "(MY_PAT $b, $a)" should not be allowed in the same pattern; 224091bc56edSDimitry Andric // neither should "(MY_PAT_1 $a, $b)" and "(MY_PAT_2 $a, $b)". 224191bc56edSDimitry Andric auto OperandId = std::make_pair(Operator, i); 224291bc56edSDimitry Andric auto PrevOp = ComplexPatternOperands.find(Child->getName()); 224391bc56edSDimitry Andric if (PrevOp != ComplexPatternOperands.end()) { 224491bc56edSDimitry Andric if (PrevOp->getValue() != OperandId) 224591bc56edSDimitry Andric error("All ComplexPattern operands must appear consistently: " 224691bc56edSDimitry Andric "in the same order in just one ComplexPattern instance."); 224791bc56edSDimitry Andric } else 224891bc56edSDimitry Andric ComplexPatternOperands[Child->getName()] = OperandId; 224991bc56edSDimitry Andric } 225091bc56edSDimitry Andric } 225191bc56edSDimitry Andric 2252f22ef01cSRoman Divacky unsigned NumResults = GetNumNodeResults(Operator, CDP); 2253f22ef01cSRoman Divacky TreePatternNode *Result = new TreePatternNode(Operator, Children, NumResults); 2254f22ef01cSRoman Divacky Result->setName(OpName); 2255f22ef01cSRoman Divacky 2256d88c1a5aSDimitry Andric if (Dag->getName()) { 2257f22ef01cSRoman Divacky assert(Result->getName().empty()); 2258d88c1a5aSDimitry Andric Result->setName(Dag->getNameStr()); 2259f22ef01cSRoman Divacky } 2260f22ef01cSRoman Divacky return Result; 2261f22ef01cSRoman Divacky } 2262f22ef01cSRoman Divacky 2263f22ef01cSRoman Divacky /// SimplifyTree - See if we can simplify this tree to eliminate something that 2264f22ef01cSRoman Divacky /// will never match in favor of something obvious that will. This is here 2265f22ef01cSRoman Divacky /// strictly as a convenience to target authors because it allows them to write 2266f22ef01cSRoman Divacky /// more type generic things and have useless type casts fold away. 2267f22ef01cSRoman Divacky /// 2268f22ef01cSRoman Divacky /// This returns true if any change is made. 2269f22ef01cSRoman Divacky static bool SimplifyTree(TreePatternNode *&N) { 2270f22ef01cSRoman Divacky if (N->isLeaf()) 2271f22ef01cSRoman Divacky return false; 2272f22ef01cSRoman Divacky 2273f22ef01cSRoman Divacky // If we have a bitconvert with a resolved type and if the source and 2274f22ef01cSRoman Divacky // destination types are the same, then the bitconvert is useless, remove it. 2275f22ef01cSRoman Divacky if (N->getOperator()->getName() == "bitconvert" && 2276f22ef01cSRoman Divacky N->getExtType(0).isConcrete() && 2277f22ef01cSRoman Divacky N->getExtType(0) == N->getChild(0)->getExtType(0) && 2278f22ef01cSRoman Divacky N->getName().empty()) { 2279f22ef01cSRoman Divacky N = N->getChild(0); 2280f22ef01cSRoman Divacky SimplifyTree(N); 2281f22ef01cSRoman Divacky return true; 2282f22ef01cSRoman Divacky } 2283f22ef01cSRoman Divacky 2284f22ef01cSRoman Divacky // Walk all children. 2285f22ef01cSRoman Divacky bool MadeChange = false; 2286f22ef01cSRoman Divacky for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { 2287f22ef01cSRoman Divacky TreePatternNode *Child = N->getChild(i); 2288f22ef01cSRoman Divacky MadeChange |= SimplifyTree(Child); 2289f22ef01cSRoman Divacky N->setChild(i, Child); 2290f22ef01cSRoman Divacky } 2291f22ef01cSRoman Divacky return MadeChange; 2292f22ef01cSRoman Divacky } 2293f22ef01cSRoman Divacky 2294f22ef01cSRoman Divacky 2295f22ef01cSRoman Divacky 2296f22ef01cSRoman Divacky /// InferAllTypes - Infer/propagate as many types throughout the expression 2297f22ef01cSRoman Divacky /// patterns as possible. Return true if all types are inferred, false 22983861d79fSDimitry Andric /// otherwise. Flags an error if a type contradiction is found. 2299f22ef01cSRoman Divacky bool TreePattern:: 2300f22ef01cSRoman Divacky InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) { 2301f22ef01cSRoman Divacky if (NamedNodes.empty()) 2302f22ef01cSRoman Divacky ComputeNamedNodes(); 2303f22ef01cSRoman Divacky 2304f22ef01cSRoman Divacky bool MadeChange = true; 2305f22ef01cSRoman Divacky while (MadeChange) { 2306f22ef01cSRoman Divacky MadeChange = false; 23077d523365SDimitry Andric for (TreePatternNode *Tree : Trees) { 23087d523365SDimitry Andric MadeChange |= Tree->ApplyTypeConstraints(*this, false); 23097d523365SDimitry Andric MadeChange |= SimplifyTree(Tree); 2310f22ef01cSRoman Divacky } 2311f22ef01cSRoman Divacky 2312f22ef01cSRoman Divacky // If there are constraints on our named nodes, apply them. 23137d523365SDimitry Andric for (auto &Entry : NamedNodes) { 23147d523365SDimitry Andric SmallVectorImpl<TreePatternNode*> &Nodes = Entry.second; 2315f22ef01cSRoman Divacky 2316f22ef01cSRoman Divacky // If we have input named node types, propagate their types to the named 2317f22ef01cSRoman Divacky // values here. 2318f22ef01cSRoman Divacky if (InNamedTypes) { 23197d523365SDimitry Andric if (!InNamedTypes->count(Entry.getKey())) { 23207d523365SDimitry Andric error("Node '" + std::string(Entry.getKey()) + 232191bc56edSDimitry Andric "' in output pattern but not input pattern"); 232291bc56edSDimitry Andric return true; 232391bc56edSDimitry Andric } 2324f22ef01cSRoman Divacky 2325f22ef01cSRoman Divacky const SmallVectorImpl<TreePatternNode*> &InNodes = 23267d523365SDimitry Andric InNamedTypes->find(Entry.getKey())->second; 2327f22ef01cSRoman Divacky 2328f22ef01cSRoman Divacky // The input types should be fully resolved by now. 23297d523365SDimitry Andric for (TreePatternNode *Node : Nodes) { 2330f22ef01cSRoman Divacky // If this node is a register class, and it is the root of the pattern 2331f22ef01cSRoman Divacky // then we're mapping something onto an input register. We allow 2332f22ef01cSRoman Divacky // changing the type of the input register in this case. This allows 2333f22ef01cSRoman Divacky // us to match things like: 2334f22ef01cSRoman Divacky // def : Pat<(v1i64 (bitconvert(v2i32 DPR:$src))), (v1i64 DPR:$src)>; 23357d523365SDimitry Andric if (Node == Trees[0] && Node->isLeaf()) { 23367d523365SDimitry Andric DefInit *DI = dyn_cast<DefInit>(Node->getLeafValue()); 233717a519f9SDimitry Andric if (DI && (DI->getDef()->isSubClassOf("RegisterClass") || 233817a519f9SDimitry Andric DI->getDef()->isSubClassOf("RegisterOperand"))) 2339f22ef01cSRoman Divacky continue; 2340f22ef01cSRoman Divacky } 2341f22ef01cSRoman Divacky 23427d523365SDimitry Andric assert(Node->getNumTypes() == 1 && 2343f22ef01cSRoman Divacky InNodes[0]->getNumTypes() == 1 && 2344f22ef01cSRoman Divacky "FIXME: cannot name multiple result nodes yet"); 23457d523365SDimitry Andric MadeChange |= Node->UpdateNodeType(0, InNodes[0]->getExtType(0), 2346f22ef01cSRoman Divacky *this); 2347f22ef01cSRoman Divacky } 2348f22ef01cSRoman Divacky } 2349f22ef01cSRoman Divacky 2350f22ef01cSRoman Divacky // If there are multiple nodes with the same name, they must all have the 2351f22ef01cSRoman Divacky // same type. 23527d523365SDimitry Andric if (Entry.second.size() > 1) { 2353f22ef01cSRoman Divacky for (unsigned i = 0, e = Nodes.size()-1; i != e; ++i) { 2354f22ef01cSRoman Divacky TreePatternNode *N1 = Nodes[i], *N2 = Nodes[i+1]; 2355f22ef01cSRoman Divacky assert(N1->getNumTypes() == 1 && N2->getNumTypes() == 1 && 2356f22ef01cSRoman Divacky "FIXME: cannot name multiple result nodes yet"); 2357f22ef01cSRoman Divacky 2358f22ef01cSRoman Divacky MadeChange |= N1->UpdateNodeType(0, N2->getExtType(0), *this); 2359f22ef01cSRoman Divacky MadeChange |= N2->UpdateNodeType(0, N1->getExtType(0), *this); 2360f22ef01cSRoman Divacky } 2361f22ef01cSRoman Divacky } 2362f22ef01cSRoman Divacky } 2363f22ef01cSRoman Divacky } 2364f22ef01cSRoman Divacky 2365f22ef01cSRoman Divacky bool HasUnresolvedTypes = false; 23667d523365SDimitry Andric for (const TreePatternNode *Tree : Trees) 23677d523365SDimitry Andric HasUnresolvedTypes |= Tree->ContainsUnresolvedType(); 2368f22ef01cSRoman Divacky return !HasUnresolvedTypes; 2369f22ef01cSRoman Divacky } 2370f22ef01cSRoman Divacky 2371f22ef01cSRoman Divacky void TreePattern::print(raw_ostream &OS) const { 2372f22ef01cSRoman Divacky OS << getRecord()->getName(); 2373f22ef01cSRoman Divacky if (!Args.empty()) { 2374f22ef01cSRoman Divacky OS << "(" << Args[0]; 2375f22ef01cSRoman Divacky for (unsigned i = 1, e = Args.size(); i != e; ++i) 2376f22ef01cSRoman Divacky OS << ", " << Args[i]; 2377f22ef01cSRoman Divacky OS << ")"; 2378f22ef01cSRoman Divacky } 2379f22ef01cSRoman Divacky OS << ": "; 2380f22ef01cSRoman Divacky 2381f22ef01cSRoman Divacky if (Trees.size() > 1) 2382f22ef01cSRoman Divacky OS << "[\n"; 23837d523365SDimitry Andric for (const TreePatternNode *Tree : Trees) { 2384f22ef01cSRoman Divacky OS << "\t"; 23857d523365SDimitry Andric Tree->print(OS); 2386f22ef01cSRoman Divacky OS << "\n"; 2387f22ef01cSRoman Divacky } 2388f22ef01cSRoman Divacky 2389f22ef01cSRoman Divacky if (Trees.size() > 1) 2390f22ef01cSRoman Divacky OS << "]\n"; 2391f22ef01cSRoman Divacky } 2392f22ef01cSRoman Divacky 2393f22ef01cSRoman Divacky void TreePattern::dump() const { print(errs()); } 2394f22ef01cSRoman Divacky 2395f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 2396f22ef01cSRoman Divacky // CodeGenDAGPatterns implementation 2397f22ef01cSRoman Divacky // 2398f22ef01cSRoman Divacky 23992754fe60SDimitry Andric CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : 24002754fe60SDimitry Andric Records(R), Target(R) { 24012754fe60SDimitry Andric 24023ca95b02SDimitry Andric Intrinsics = CodeGenIntrinsicTable(Records, false); 24033ca95b02SDimitry Andric TgtIntrinsics = CodeGenIntrinsicTable(Records, true); 2404f22ef01cSRoman Divacky ParseNodeInfo(); 2405f22ef01cSRoman Divacky ParseNodeTransforms(); 2406f22ef01cSRoman Divacky ParseComplexPatterns(); 2407f22ef01cSRoman Divacky ParsePatternFragments(); 2408f22ef01cSRoman Divacky ParseDefaultOperands(); 2409f22ef01cSRoman Divacky ParseInstructions(); 241091bc56edSDimitry Andric ParsePatternFragments(/*OutFrags*/true); 2411f22ef01cSRoman Divacky ParsePatterns(); 2412f22ef01cSRoman Divacky 2413f22ef01cSRoman Divacky // Generate variants. For example, commutative patterns can match 2414f22ef01cSRoman Divacky // multiple ways. Add them to PatternsToMatch as well. 2415f22ef01cSRoman Divacky GenerateVariants(); 2416f22ef01cSRoman Divacky 2417f22ef01cSRoman Divacky // Infer instruction flags. For example, we can detect loads, 2418f22ef01cSRoman Divacky // stores, and side effects in many cases by examining an 2419f22ef01cSRoman Divacky // instruction's pattern. 2420f22ef01cSRoman Divacky InferInstructionFlags(); 24213861d79fSDimitry Andric 24223861d79fSDimitry Andric // Verify that instruction flags match the patterns. 24233861d79fSDimitry Andric VerifyInstructionFlags(); 2424f22ef01cSRoman Divacky } 2425f22ef01cSRoman Divacky 2426f22ef01cSRoman Divacky Record *CodeGenDAGPatterns::getSDNodeNamed(const std::string &Name) const { 2427f22ef01cSRoman Divacky Record *N = Records.getDef(Name); 2428ff0cc061SDimitry Andric if (!N || !N->isSubClassOf("SDNode")) 2429ff0cc061SDimitry Andric PrintFatalError("Error getting SDNode '" + Name + "'!"); 2430ff0cc061SDimitry Andric 2431f22ef01cSRoman Divacky return N; 2432f22ef01cSRoman Divacky } 2433f22ef01cSRoman Divacky 2434f22ef01cSRoman Divacky // Parse all of the SDNode definitions for the target, populating SDNodes. 2435f22ef01cSRoman Divacky void CodeGenDAGPatterns::ParseNodeInfo() { 2436f22ef01cSRoman Divacky std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("SDNode"); 2437f22ef01cSRoman Divacky while (!Nodes.empty()) { 2438f22ef01cSRoman Divacky SDNodes.insert(std::make_pair(Nodes.back(), Nodes.back())); 2439f22ef01cSRoman Divacky Nodes.pop_back(); 2440f22ef01cSRoman Divacky } 2441f22ef01cSRoman Divacky 2442f22ef01cSRoman Divacky // Get the builtin intrinsic nodes. 2443f22ef01cSRoman Divacky intrinsic_void_sdnode = getSDNodeNamed("intrinsic_void"); 2444f22ef01cSRoman Divacky intrinsic_w_chain_sdnode = getSDNodeNamed("intrinsic_w_chain"); 2445f22ef01cSRoman Divacky intrinsic_wo_chain_sdnode = getSDNodeNamed("intrinsic_wo_chain"); 2446f22ef01cSRoman Divacky } 2447f22ef01cSRoman Divacky 2448f22ef01cSRoman Divacky /// ParseNodeTransforms - Parse all SDNodeXForm instances into the SDNodeXForms 2449f22ef01cSRoman Divacky /// map, and emit them to the file as functions. 2450f22ef01cSRoman Divacky void CodeGenDAGPatterns::ParseNodeTransforms() { 2451f22ef01cSRoman Divacky std::vector<Record*> Xforms = Records.getAllDerivedDefinitions("SDNodeXForm"); 2452f22ef01cSRoman Divacky while (!Xforms.empty()) { 2453f22ef01cSRoman Divacky Record *XFormNode = Xforms.back(); 2454f22ef01cSRoman Divacky Record *SDNode = XFormNode->getValueAsDef("Opcode"); 2455f9448bf3SDimitry Andric StringRef Code = XFormNode->getValueAsString("XFormFunction"); 2456f22ef01cSRoman Divacky SDNodeXForms.insert(std::make_pair(XFormNode, NodeXForm(SDNode, Code))); 2457f22ef01cSRoman Divacky 2458f22ef01cSRoman Divacky Xforms.pop_back(); 2459f22ef01cSRoman Divacky } 2460f22ef01cSRoman Divacky } 2461f22ef01cSRoman Divacky 2462f22ef01cSRoman Divacky void CodeGenDAGPatterns::ParseComplexPatterns() { 2463f22ef01cSRoman Divacky std::vector<Record*> AMs = Records.getAllDerivedDefinitions("ComplexPattern"); 2464f22ef01cSRoman Divacky while (!AMs.empty()) { 2465f22ef01cSRoman Divacky ComplexPatterns.insert(std::make_pair(AMs.back(), AMs.back())); 2466f22ef01cSRoman Divacky AMs.pop_back(); 2467f22ef01cSRoman Divacky } 2468f22ef01cSRoman Divacky } 2469f22ef01cSRoman Divacky 2470f22ef01cSRoman Divacky 2471f22ef01cSRoman Divacky /// ParsePatternFragments - Parse all of the PatFrag definitions in the .td 2472f22ef01cSRoman Divacky /// file, building up the PatternFragments map. After we've collected them all, 2473f22ef01cSRoman Divacky /// inline fragments together as necessary, so that there are no references left 2474f22ef01cSRoman Divacky /// inside a pattern fragment to a pattern fragment. 2475f22ef01cSRoman Divacky /// 247691bc56edSDimitry Andric void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) { 2477f22ef01cSRoman Divacky std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrag"); 2478f22ef01cSRoman Divacky 2479f22ef01cSRoman Divacky // First step, parse all of the fragments. 24807d523365SDimitry Andric for (Record *Frag : Fragments) { 24817d523365SDimitry Andric if (OutFrags != Frag->isSubClassOf("OutPatFrag")) 248291bc56edSDimitry Andric continue; 248391bc56edSDimitry Andric 24847d523365SDimitry Andric DagInit *Tree = Frag->getValueAsDag("Fragment"); 248591bc56edSDimitry Andric TreePattern *P = 24867d523365SDimitry Andric (PatternFragments[Frag] = llvm::make_unique<TreePattern>( 24877d523365SDimitry Andric Frag, Tree, !Frag->isSubClassOf("OutPatFrag"), 248839d628a0SDimitry Andric *this)).get(); 2489f22ef01cSRoman Divacky 2490f22ef01cSRoman Divacky // Validate the argument list, converting it to set, to discard duplicates. 2491f22ef01cSRoman Divacky std::vector<std::string> &Args = P->getArgList(); 2492f22ef01cSRoman Divacky std::set<std::string> OperandsSet(Args.begin(), Args.end()); 2493f22ef01cSRoman Divacky 2494f22ef01cSRoman Divacky if (OperandsSet.count("")) 2495f22ef01cSRoman Divacky P->error("Cannot have unnamed 'node' values in pattern fragment!"); 2496f22ef01cSRoman Divacky 2497f22ef01cSRoman Divacky // Parse the operands list. 24987d523365SDimitry Andric DagInit *OpsList = Frag->getValueAsDag("Operands"); 24993861d79fSDimitry Andric DefInit *OpsOp = dyn_cast<DefInit>(OpsList->getOperator()); 2500f22ef01cSRoman Divacky // Special cases: ops == outs == ins. Different names are used to 2501f22ef01cSRoman Divacky // improve readability. 2502f22ef01cSRoman Divacky if (!OpsOp || 2503f22ef01cSRoman Divacky (OpsOp->getDef()->getName() != "ops" && 2504f22ef01cSRoman Divacky OpsOp->getDef()->getName() != "outs" && 2505f22ef01cSRoman Divacky OpsOp->getDef()->getName() != "ins")) 2506f22ef01cSRoman Divacky P->error("Operands list should start with '(ops ... '!"); 2507f22ef01cSRoman Divacky 2508f22ef01cSRoman Divacky // Copy over the arguments. 2509f22ef01cSRoman Divacky Args.clear(); 2510f22ef01cSRoman Divacky for (unsigned j = 0, e = OpsList->getNumArgs(); j != e; ++j) { 25113861d79fSDimitry Andric if (!isa<DefInit>(OpsList->getArg(j)) || 25123861d79fSDimitry Andric cast<DefInit>(OpsList->getArg(j))->getDef()->getName() != "node") 2513f22ef01cSRoman Divacky P->error("Operands list should all be 'node' values."); 2514d88c1a5aSDimitry Andric if (!OpsList->getArgName(j)) 2515f22ef01cSRoman Divacky P->error("Operands list should have names for each operand!"); 2516d88c1a5aSDimitry Andric StringRef ArgNameStr = OpsList->getArgNameStr(j); 2517d88c1a5aSDimitry Andric if (!OperandsSet.count(ArgNameStr)) 2518d88c1a5aSDimitry Andric P->error("'" + ArgNameStr + 2519f22ef01cSRoman Divacky "' does not occur in pattern or was multiply specified!"); 2520d88c1a5aSDimitry Andric OperandsSet.erase(ArgNameStr); 2521d88c1a5aSDimitry Andric Args.push_back(ArgNameStr); 2522f22ef01cSRoman Divacky } 2523f22ef01cSRoman Divacky 2524f22ef01cSRoman Divacky if (!OperandsSet.empty()) 2525f22ef01cSRoman Divacky P->error("Operands list does not contain an entry for operand '" + 2526f22ef01cSRoman Divacky *OperandsSet.begin() + "'!"); 2527f22ef01cSRoman Divacky 2528f22ef01cSRoman Divacky // If there is a code init for this fragment, keep track of the fact that 2529f22ef01cSRoman Divacky // this fragment uses it. 25303b0f4066SDimitry Andric TreePredicateFn PredFn(P); 25313b0f4066SDimitry Andric if (!PredFn.isAlwaysTrue()) 25323b0f4066SDimitry Andric P->getOnlyTree()->addPredicateFn(PredFn); 2533f22ef01cSRoman Divacky 2534f22ef01cSRoman Divacky // If there is a node transformation corresponding to this, keep track of 2535f22ef01cSRoman Divacky // it. 25367d523365SDimitry Andric Record *Transform = Frag->getValueAsDef("OperandTransform"); 2537f22ef01cSRoman Divacky if (!getSDNodeTransform(Transform).second.empty()) // not noop xform? 2538f22ef01cSRoman Divacky P->getOnlyTree()->setTransformFn(Transform); 2539f22ef01cSRoman Divacky } 2540f22ef01cSRoman Divacky 2541f22ef01cSRoman Divacky // Now that we've parsed all of the tree fragments, do a closure on them so 2542f22ef01cSRoman Divacky // that there are not references to PatFrags left inside of them. 25437d523365SDimitry Andric for (Record *Frag : Fragments) { 25447d523365SDimitry Andric if (OutFrags != Frag->isSubClassOf("OutPatFrag")) 254591bc56edSDimitry Andric continue; 254691bc56edSDimitry Andric 25477d523365SDimitry Andric TreePattern &ThePat = *PatternFragments[Frag]; 254839d628a0SDimitry Andric ThePat.InlinePatternFragments(); 2549f22ef01cSRoman Divacky 2550f22ef01cSRoman Divacky // Infer as many types as possible. Don't worry about it if we don't infer 2551f22ef01cSRoman Divacky // all of them, some may depend on the inputs of the pattern. 255239d628a0SDimitry Andric ThePat.InferAllTypes(); 255339d628a0SDimitry Andric ThePat.resetError(); 2554f22ef01cSRoman Divacky 2555f22ef01cSRoman Divacky // If debugging, print out the pattern fragment result. 255639d628a0SDimitry Andric DEBUG(ThePat.dump()); 2557f22ef01cSRoman Divacky } 2558f22ef01cSRoman Divacky } 2559f22ef01cSRoman Divacky 2560f22ef01cSRoman Divacky void CodeGenDAGPatterns::ParseDefaultOperands() { 25613861d79fSDimitry Andric std::vector<Record*> DefaultOps; 25623861d79fSDimitry Andric DefaultOps = Records.getAllDerivedDefinitions("OperandWithDefaultOps"); 2563f22ef01cSRoman Divacky 2564f22ef01cSRoman Divacky // Find some SDNode. 2565f22ef01cSRoman Divacky assert(!SDNodes.empty() && "No SDNodes parsed?"); 25666122f3e6SDimitry Andric Init *SomeSDNode = DefInit::get(SDNodes.begin()->first); 2567f22ef01cSRoman Divacky 25683861d79fSDimitry Andric for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) { 25693861d79fSDimitry Andric DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps"); 2570f22ef01cSRoman Divacky 2571f22ef01cSRoman Divacky // Clone the DefaultInfo dag node, changing the operator from 'ops' to 2572f22ef01cSRoman Divacky // SomeSDnode so that we can parse this. 2573d88c1a5aSDimitry Andric std::vector<std::pair<Init*, StringInit*> > Ops; 2574f22ef01cSRoman Divacky for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op) 2575f22ef01cSRoman Divacky Ops.push_back(std::make_pair(DefaultInfo->getArg(op), 2576f22ef01cSRoman Divacky DefaultInfo->getArgName(op))); 2577d88c1a5aSDimitry Andric DagInit *DI = DagInit::get(SomeSDNode, nullptr, Ops); 2578f22ef01cSRoman Divacky 2579f22ef01cSRoman Divacky // Create a TreePattern to parse this. 25803861d79fSDimitry Andric TreePattern P(DefaultOps[i], DI, false, *this); 2581f22ef01cSRoman Divacky assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!"); 2582f22ef01cSRoman Divacky 2583f22ef01cSRoman Divacky // Copy the operands over into a DAGDefaultOperand. 2584f22ef01cSRoman Divacky DAGDefaultOperand DefaultOpInfo; 2585f22ef01cSRoman Divacky 2586f22ef01cSRoman Divacky TreePatternNode *T = P.getTree(0); 2587f22ef01cSRoman Divacky for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) { 2588f22ef01cSRoman Divacky TreePatternNode *TPN = T->getChild(op); 2589f22ef01cSRoman Divacky while (TPN->ApplyTypeConstraints(P, false)) 2590f22ef01cSRoman Divacky /* Resolve all types */; 2591f22ef01cSRoman Divacky 2592f22ef01cSRoman Divacky if (TPN->ContainsUnresolvedType()) { 259391bc56edSDimitry Andric PrintFatalError("Value #" + Twine(i) + " of OperandWithDefaultOps '" + 259491bc56edSDimitry Andric DefaultOps[i]->getName() + 259591bc56edSDimitry Andric "' doesn't have a concrete type!"); 2596f22ef01cSRoman Divacky } 2597f22ef01cSRoman Divacky DefaultOpInfo.DefaultOps.push_back(TPN); 2598f22ef01cSRoman Divacky } 2599f22ef01cSRoman Divacky 2600f22ef01cSRoman Divacky // Insert it into the DefaultOperands map so we can find it later. 26013861d79fSDimitry Andric DefaultOperands[DefaultOps[i]] = DefaultOpInfo; 2602f22ef01cSRoman Divacky } 2603f22ef01cSRoman Divacky } 2604f22ef01cSRoman Divacky 2605f22ef01cSRoman Divacky /// HandleUse - Given "Pat" a leaf in the pattern, check to see if it is an 2606f22ef01cSRoman Divacky /// instruction input. Return true if this is a real use. 2607f22ef01cSRoman Divacky static bool HandleUse(TreePattern *I, TreePatternNode *Pat, 2608f22ef01cSRoman Divacky std::map<std::string, TreePatternNode*> &InstInputs) { 2609f22ef01cSRoman Divacky // No name -> not interesting. 2610f22ef01cSRoman Divacky if (Pat->getName().empty()) { 2611f22ef01cSRoman Divacky if (Pat->isLeaf()) { 26123861d79fSDimitry Andric DefInit *DI = dyn_cast<DefInit>(Pat->getLeafValue()); 261317a519f9SDimitry Andric if (DI && (DI->getDef()->isSubClassOf("RegisterClass") || 261417a519f9SDimitry Andric DI->getDef()->isSubClassOf("RegisterOperand"))) 2615f22ef01cSRoman Divacky I->error("Input " + DI->getDef()->getName() + " must be named!"); 2616f22ef01cSRoman Divacky } 2617f22ef01cSRoman Divacky return false; 2618f22ef01cSRoman Divacky } 2619f22ef01cSRoman Divacky 2620f22ef01cSRoman Divacky Record *Rec; 2621f22ef01cSRoman Divacky if (Pat->isLeaf()) { 26223861d79fSDimitry Andric DefInit *DI = dyn_cast<DefInit>(Pat->getLeafValue()); 2623f22ef01cSRoman Divacky if (!DI) I->error("Input $" + Pat->getName() + " must be an identifier!"); 2624f22ef01cSRoman Divacky Rec = DI->getDef(); 2625f22ef01cSRoman Divacky } else { 2626f22ef01cSRoman Divacky Rec = Pat->getOperator(); 2627f22ef01cSRoman Divacky } 2628f22ef01cSRoman Divacky 2629f22ef01cSRoman Divacky // SRCVALUE nodes are ignored. 2630f22ef01cSRoman Divacky if (Rec->getName() == "srcvalue") 2631f22ef01cSRoman Divacky return false; 2632f22ef01cSRoman Divacky 2633f22ef01cSRoman Divacky TreePatternNode *&Slot = InstInputs[Pat->getName()]; 2634f22ef01cSRoman Divacky if (!Slot) { 2635f22ef01cSRoman Divacky Slot = Pat; 2636f22ef01cSRoman Divacky return true; 2637f22ef01cSRoman Divacky } 2638f22ef01cSRoman Divacky Record *SlotRec; 2639f22ef01cSRoman Divacky if (Slot->isLeaf()) { 26403861d79fSDimitry Andric SlotRec = cast<DefInit>(Slot->getLeafValue())->getDef(); 2641f22ef01cSRoman Divacky } else { 2642f22ef01cSRoman Divacky assert(Slot->getNumChildren() == 0 && "can't be a use with children!"); 2643f22ef01cSRoman Divacky SlotRec = Slot->getOperator(); 2644f22ef01cSRoman Divacky } 2645f22ef01cSRoman Divacky 2646f22ef01cSRoman Divacky // Ensure that the inputs agree if we've already seen this input. 2647f22ef01cSRoman Divacky if (Rec != SlotRec) 2648f22ef01cSRoman Divacky I->error("All $" + Pat->getName() + " inputs must agree with each other"); 2649f22ef01cSRoman Divacky if (Slot->getExtTypes() != Pat->getExtTypes()) 2650f22ef01cSRoman Divacky I->error("All $" + Pat->getName() + " inputs must agree with each other"); 2651f22ef01cSRoman Divacky return true; 2652f22ef01cSRoman Divacky } 2653f22ef01cSRoman Divacky 2654f22ef01cSRoman Divacky /// FindPatternInputsAndOutputs - Scan the specified TreePatternNode (which is 2655f22ef01cSRoman Divacky /// part of "I", the instruction), computing the set of inputs and outputs of 2656f22ef01cSRoman Divacky /// the pattern. Report errors if we see anything naughty. 2657f22ef01cSRoman Divacky void CodeGenDAGPatterns:: 2658f22ef01cSRoman Divacky FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, 2659f22ef01cSRoman Divacky std::map<std::string, TreePatternNode*> &InstInputs, 2660f22ef01cSRoman Divacky std::map<std::string, TreePatternNode*>&InstResults, 2661f22ef01cSRoman Divacky std::vector<Record*> &InstImpResults) { 2662f22ef01cSRoman Divacky if (Pat->isLeaf()) { 2663f22ef01cSRoman Divacky bool isUse = HandleUse(I, Pat, InstInputs); 2664f22ef01cSRoman Divacky if (!isUse && Pat->getTransformFn()) 2665f22ef01cSRoman Divacky I->error("Cannot specify a transform function for a non-input value!"); 2666f22ef01cSRoman Divacky return; 2667f22ef01cSRoman Divacky } 2668f22ef01cSRoman Divacky 2669f22ef01cSRoman Divacky if (Pat->getOperator()->getName() == "implicit") { 2670f22ef01cSRoman Divacky for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) { 2671f22ef01cSRoman Divacky TreePatternNode *Dest = Pat->getChild(i); 2672f22ef01cSRoman Divacky if (!Dest->isLeaf()) 2673f22ef01cSRoman Divacky I->error("implicitly defined value should be a register!"); 2674f22ef01cSRoman Divacky 26753861d79fSDimitry Andric DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue()); 2676f22ef01cSRoman Divacky if (!Val || !Val->getDef()->isSubClassOf("Register")) 2677f22ef01cSRoman Divacky I->error("implicitly defined value should be a register!"); 2678f22ef01cSRoman Divacky InstImpResults.push_back(Val->getDef()); 2679f22ef01cSRoman Divacky } 2680f22ef01cSRoman Divacky return; 2681f22ef01cSRoman Divacky } 2682f22ef01cSRoman Divacky 2683f22ef01cSRoman Divacky if (Pat->getOperator()->getName() != "set") { 2684f22ef01cSRoman Divacky // If this is not a set, verify that the children nodes are not void typed, 2685f22ef01cSRoman Divacky // and recurse. 2686f22ef01cSRoman Divacky for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) { 2687f22ef01cSRoman Divacky if (Pat->getChild(i)->getNumTypes() == 0) 2688f22ef01cSRoman Divacky I->error("Cannot have void nodes inside of patterns!"); 2689f22ef01cSRoman Divacky FindPatternInputsAndOutputs(I, Pat->getChild(i), InstInputs, InstResults, 2690f22ef01cSRoman Divacky InstImpResults); 2691f22ef01cSRoman Divacky } 2692f22ef01cSRoman Divacky 2693f22ef01cSRoman Divacky // If this is a non-leaf node with no children, treat it basically as if 2694f22ef01cSRoman Divacky // it were a leaf. This handles nodes like (imm). 2695f22ef01cSRoman Divacky bool isUse = HandleUse(I, Pat, InstInputs); 2696f22ef01cSRoman Divacky 2697f22ef01cSRoman Divacky if (!isUse && Pat->getTransformFn()) 2698f22ef01cSRoman Divacky I->error("Cannot specify a transform function for a non-input value!"); 2699f22ef01cSRoman Divacky return; 2700f22ef01cSRoman Divacky } 2701f22ef01cSRoman Divacky 2702f22ef01cSRoman Divacky // Otherwise, this is a set, validate and collect instruction results. 2703f22ef01cSRoman Divacky if (Pat->getNumChildren() == 0) 2704f22ef01cSRoman Divacky I->error("set requires operands!"); 2705f22ef01cSRoman Divacky 2706f22ef01cSRoman Divacky if (Pat->getTransformFn()) 2707f22ef01cSRoman Divacky I->error("Cannot specify a transform function on a set node!"); 2708f22ef01cSRoman Divacky 2709f22ef01cSRoman Divacky // Check the set destinations. 2710f22ef01cSRoman Divacky unsigned NumDests = Pat->getNumChildren()-1; 2711f22ef01cSRoman Divacky for (unsigned i = 0; i != NumDests; ++i) { 2712f22ef01cSRoman Divacky TreePatternNode *Dest = Pat->getChild(i); 2713f22ef01cSRoman Divacky if (!Dest->isLeaf()) 2714f22ef01cSRoman Divacky I->error("set destination should be a register!"); 2715f22ef01cSRoman Divacky 27163861d79fSDimitry Andric DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue()); 271739d628a0SDimitry Andric if (!Val) { 2718f22ef01cSRoman Divacky I->error("set destination should be a register!"); 271939d628a0SDimitry Andric continue; 272039d628a0SDimitry Andric } 2721f22ef01cSRoman Divacky 2722f22ef01cSRoman Divacky if (Val->getDef()->isSubClassOf("RegisterClass") || 2723139f7f9bSDimitry Andric Val->getDef()->isSubClassOf("ValueType") || 272417a519f9SDimitry Andric Val->getDef()->isSubClassOf("RegisterOperand") || 2725f22ef01cSRoman Divacky Val->getDef()->isSubClassOf("PointerLikeRegClass")) { 2726f22ef01cSRoman Divacky if (Dest->getName().empty()) 2727f22ef01cSRoman Divacky I->error("set destination must have a name!"); 2728f22ef01cSRoman Divacky if (InstResults.count(Dest->getName())) 2729f22ef01cSRoman Divacky I->error("cannot set '" + Dest->getName() +"' multiple times"); 2730f22ef01cSRoman Divacky InstResults[Dest->getName()] = Dest; 2731f22ef01cSRoman Divacky } else if (Val->getDef()->isSubClassOf("Register")) { 2732f22ef01cSRoman Divacky InstImpResults.push_back(Val->getDef()); 2733f22ef01cSRoman Divacky } else { 2734f22ef01cSRoman Divacky I->error("set destination should be a register!"); 2735f22ef01cSRoman Divacky } 2736f22ef01cSRoman Divacky } 2737f22ef01cSRoman Divacky 2738f22ef01cSRoman Divacky // Verify and collect info from the computation. 2739f22ef01cSRoman Divacky FindPatternInputsAndOutputs(I, Pat->getChild(NumDests), 2740f22ef01cSRoman Divacky InstInputs, InstResults, InstImpResults); 2741f22ef01cSRoman Divacky } 2742f22ef01cSRoman Divacky 2743f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 2744f22ef01cSRoman Divacky // Instruction Analysis 2745f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 2746f22ef01cSRoman Divacky 2747f22ef01cSRoman Divacky class InstAnalyzer { 2748f22ef01cSRoman Divacky const CodeGenDAGPatterns &CDP; 2749f22ef01cSRoman Divacky public: 27503861d79fSDimitry Andric bool hasSideEffects; 27513861d79fSDimitry Andric bool mayStore; 27523861d79fSDimitry Andric bool mayLoad; 27533861d79fSDimitry Andric bool isBitcast; 27543861d79fSDimitry Andric bool isVariadic; 27553861d79fSDimitry Andric 27563861d79fSDimitry Andric InstAnalyzer(const CodeGenDAGPatterns &cdp) 27573861d79fSDimitry Andric : CDP(cdp), hasSideEffects(false), mayStore(false), mayLoad(false), 27583861d79fSDimitry Andric isBitcast(false), isVariadic(false) {} 27593861d79fSDimitry Andric 27603861d79fSDimitry Andric void Analyze(const TreePattern *Pat) { 27613861d79fSDimitry Andric // Assume only the first tree is the pattern. The others are clobber nodes. 27623861d79fSDimitry Andric AnalyzeNode(Pat->getTree(0)); 2763f22ef01cSRoman Divacky } 2764f22ef01cSRoman Divacky 2765edd7eaddSDimitry Andric void Analyze(const PatternToMatch &Pat) { 2766edd7eaddSDimitry Andric AnalyzeNode(Pat.getSrcPattern()); 2767f22ef01cSRoman Divacky } 2768f22ef01cSRoman Divacky 2769f22ef01cSRoman Divacky private: 27703b0f4066SDimitry Andric bool IsNodeBitcast(const TreePatternNode *N) const { 27713861d79fSDimitry Andric if (hasSideEffects || mayLoad || mayStore || isVariadic) 27723b0f4066SDimitry Andric return false; 27733b0f4066SDimitry Andric 27743b0f4066SDimitry Andric if (N->getNumChildren() != 2) 27753b0f4066SDimitry Andric return false; 27763b0f4066SDimitry Andric 27773b0f4066SDimitry Andric const TreePatternNode *N0 = N->getChild(0); 27783861d79fSDimitry Andric if (!N0->isLeaf() || !isa<DefInit>(N0->getLeafValue())) 27793b0f4066SDimitry Andric return false; 27803b0f4066SDimitry Andric 27813b0f4066SDimitry Andric const TreePatternNode *N1 = N->getChild(1); 27823b0f4066SDimitry Andric if (N1->isLeaf()) 27833b0f4066SDimitry Andric return false; 27843b0f4066SDimitry Andric if (N1->getNumChildren() != 1 || !N1->getChild(0)->isLeaf()) 27853b0f4066SDimitry Andric return false; 27863b0f4066SDimitry Andric 27873b0f4066SDimitry Andric const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N1->getOperator()); 27883b0f4066SDimitry Andric if (OpInfo.getNumResults() != 1 || OpInfo.getNumOperands() != 1) 27893b0f4066SDimitry Andric return false; 27903b0f4066SDimitry Andric return OpInfo.getEnumName() == "ISD::BITCAST"; 27913b0f4066SDimitry Andric } 27923b0f4066SDimitry Andric 27933861d79fSDimitry Andric public: 2794f22ef01cSRoman Divacky void AnalyzeNode(const TreePatternNode *N) { 2795f22ef01cSRoman Divacky if (N->isLeaf()) { 27963861d79fSDimitry Andric if (DefInit *DI = dyn_cast<DefInit>(N->getLeafValue())) { 2797f22ef01cSRoman Divacky Record *LeafRec = DI->getDef(); 2798f22ef01cSRoman Divacky // Handle ComplexPattern leaves. 2799f22ef01cSRoman Divacky if (LeafRec->isSubClassOf("ComplexPattern")) { 2800f22ef01cSRoman Divacky const ComplexPattern &CP = CDP.getComplexPattern(LeafRec); 2801f22ef01cSRoman Divacky if (CP.hasProperty(SDNPMayStore)) mayStore = true; 2802f22ef01cSRoman Divacky if (CP.hasProperty(SDNPMayLoad)) mayLoad = true; 28033861d79fSDimitry Andric if (CP.hasProperty(SDNPSideEffect)) hasSideEffects = true; 2804f22ef01cSRoman Divacky } 2805f22ef01cSRoman Divacky } 2806f22ef01cSRoman Divacky return; 2807f22ef01cSRoman Divacky } 2808f22ef01cSRoman Divacky 2809f22ef01cSRoman Divacky // Analyze children. 2810f22ef01cSRoman Divacky for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) 2811f22ef01cSRoman Divacky AnalyzeNode(N->getChild(i)); 2812f22ef01cSRoman Divacky 2813f22ef01cSRoman Divacky // Ignore set nodes, which are not SDNodes. 28143b0f4066SDimitry Andric if (N->getOperator()->getName() == "set") { 28153861d79fSDimitry Andric isBitcast = IsNodeBitcast(N); 2816f22ef01cSRoman Divacky return; 28173b0f4066SDimitry Andric } 2818f22ef01cSRoman Divacky 2819f22ef01cSRoman Divacky // Notice properties of the node. 282091bc56edSDimitry Andric if (N->NodeHasProperty(SDNPMayStore, CDP)) mayStore = true; 282191bc56edSDimitry Andric if (N->NodeHasProperty(SDNPMayLoad, CDP)) mayLoad = true; 282291bc56edSDimitry Andric if (N->NodeHasProperty(SDNPSideEffect, CDP)) hasSideEffects = true; 282391bc56edSDimitry Andric if (N->NodeHasProperty(SDNPVariadic, CDP)) isVariadic = true; 2824f22ef01cSRoman Divacky 2825f22ef01cSRoman Divacky if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { 2826f22ef01cSRoman Divacky // If this is an intrinsic, analyze it. 28273ca95b02SDimitry Andric if (IntInfo->ModRef & CodeGenIntrinsic::MR_Ref) 2828f22ef01cSRoman Divacky mayLoad = true;// These may load memory. 2829f22ef01cSRoman Divacky 28303ca95b02SDimitry Andric if (IntInfo->ModRef & CodeGenIntrinsic::MR_Mod) 2831f22ef01cSRoman Divacky mayStore = true;// Intrinsics that can write to memory are 'mayStore'. 2832f22ef01cSRoman Divacky 2833f37b6182SDimitry Andric if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem || 2834f37b6182SDimitry Andric IntInfo->hasSideEffects) 28353ca95b02SDimitry Andric // ReadWriteMem intrinsics can have other strange effects. 28363861d79fSDimitry Andric hasSideEffects = true; 2837f22ef01cSRoman Divacky } 2838f22ef01cSRoman Divacky } 2839f22ef01cSRoman Divacky 2840f22ef01cSRoman Divacky }; 2841f22ef01cSRoman Divacky 28423861d79fSDimitry Andric static bool InferFromPattern(CodeGenInstruction &InstInfo, 28433861d79fSDimitry Andric const InstAnalyzer &PatInfo, 28443861d79fSDimitry Andric Record *PatDef) { 28453861d79fSDimitry Andric bool Error = false; 2846f22ef01cSRoman Divacky 28473861d79fSDimitry Andric // Remember where InstInfo got its flags. 28483861d79fSDimitry Andric if (InstInfo.hasUndefFlags()) 28493861d79fSDimitry Andric InstInfo.InferredFrom = PatDef; 2850f22ef01cSRoman Divacky 28513861d79fSDimitry Andric // Check explicitly set flags for consistency. 28523861d79fSDimitry Andric if (InstInfo.hasSideEffects != PatInfo.hasSideEffects && 28533861d79fSDimitry Andric !InstInfo.hasSideEffects_Unset) { 28543861d79fSDimitry Andric // Allow explicitly setting hasSideEffects = 1 on instructions, even when 28553861d79fSDimitry Andric // the pattern has no side effects. That could be useful for div/rem 28563861d79fSDimitry Andric // instructions that may trap. 28573861d79fSDimitry Andric if (!InstInfo.hasSideEffects) { 28583861d79fSDimitry Andric Error = true; 28593861d79fSDimitry Andric PrintError(PatDef->getLoc(), "Pattern doesn't match hasSideEffects = " + 28603861d79fSDimitry Andric Twine(InstInfo.hasSideEffects)); 28613861d79fSDimitry Andric } 2862f22ef01cSRoman Divacky } 2863f22ef01cSRoman Divacky 28643861d79fSDimitry Andric if (InstInfo.mayStore != PatInfo.mayStore && !InstInfo.mayStore_Unset) { 28653861d79fSDimitry Andric Error = true; 28663861d79fSDimitry Andric PrintError(PatDef->getLoc(), "Pattern doesn't match mayStore = " + 28673861d79fSDimitry Andric Twine(InstInfo.mayStore)); 2868f22ef01cSRoman Divacky } 2869f22ef01cSRoman Divacky 28703861d79fSDimitry Andric if (InstInfo.mayLoad != PatInfo.mayLoad && !InstInfo.mayLoad_Unset) { 28713861d79fSDimitry Andric // Allow explicitly setting mayLoad = 1, even when the pattern has no loads. 28727d523365SDimitry Andric // Some targets translate immediates to loads. 28733861d79fSDimitry Andric if (!InstInfo.mayLoad) { 28743861d79fSDimitry Andric Error = true; 28753861d79fSDimitry Andric PrintError(PatDef->getLoc(), "Pattern doesn't match mayLoad = " + 28763861d79fSDimitry Andric Twine(InstInfo.mayLoad)); 28773861d79fSDimitry Andric } 2878f22ef01cSRoman Divacky } 2879f22ef01cSRoman Divacky 28803861d79fSDimitry Andric // Transfer inferred flags. 28813861d79fSDimitry Andric InstInfo.hasSideEffects |= PatInfo.hasSideEffects; 28823861d79fSDimitry Andric InstInfo.mayStore |= PatInfo.mayStore; 28833861d79fSDimitry Andric InstInfo.mayLoad |= PatInfo.mayLoad; 2884f22ef01cSRoman Divacky 28853861d79fSDimitry Andric // These flags are silently added without any verification. 28863861d79fSDimitry Andric InstInfo.isBitcast |= PatInfo.isBitcast; 28873861d79fSDimitry Andric 28883861d79fSDimitry Andric // Don't infer isVariadic. This flag means something different on SDNodes and 28893861d79fSDimitry Andric // instructions. For example, a CALL SDNode is variadic because it has the 28903861d79fSDimitry Andric // call arguments as operands, but a CALL instruction is not variadic - it 28913861d79fSDimitry Andric // has argument registers as implicit, not explicit uses. 28923861d79fSDimitry Andric 28933861d79fSDimitry Andric return Error; 2894f22ef01cSRoman Divacky } 2895f22ef01cSRoman Divacky 28967ae0e2c9SDimitry Andric /// hasNullFragReference - Return true if the DAG has any reference to the 28977ae0e2c9SDimitry Andric /// null_frag operator. 28987ae0e2c9SDimitry Andric static bool hasNullFragReference(DagInit *DI) { 28993861d79fSDimitry Andric DefInit *OpDef = dyn_cast<DefInit>(DI->getOperator()); 29007ae0e2c9SDimitry Andric if (!OpDef) return false; 29017ae0e2c9SDimitry Andric Record *Operator = OpDef->getDef(); 29027ae0e2c9SDimitry Andric 29037ae0e2c9SDimitry Andric // If this is the null fragment, return true. 29047ae0e2c9SDimitry Andric if (Operator->getName() == "null_frag") return true; 29057ae0e2c9SDimitry Andric // If any of the arguments reference the null fragment, return true. 29067ae0e2c9SDimitry Andric for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) { 29073861d79fSDimitry Andric DagInit *Arg = dyn_cast<DagInit>(DI->getArg(i)); 29087ae0e2c9SDimitry Andric if (Arg && hasNullFragReference(Arg)) 29097ae0e2c9SDimitry Andric return true; 29107ae0e2c9SDimitry Andric } 29117ae0e2c9SDimitry Andric 29127ae0e2c9SDimitry Andric return false; 29137ae0e2c9SDimitry Andric } 29147ae0e2c9SDimitry Andric 29157ae0e2c9SDimitry Andric /// hasNullFragReference - Return true if any DAG in the list references 29167ae0e2c9SDimitry Andric /// the null_frag operator. 29177ae0e2c9SDimitry Andric static bool hasNullFragReference(ListInit *LI) { 291897bc6c73SDimitry Andric for (Init *I : LI->getValues()) { 291997bc6c73SDimitry Andric DagInit *DI = dyn_cast<DagInit>(I); 29207ae0e2c9SDimitry Andric assert(DI && "non-dag in an instruction Pattern list?!"); 29217ae0e2c9SDimitry Andric if (hasNullFragReference(DI)) 29227ae0e2c9SDimitry Andric return true; 29237ae0e2c9SDimitry Andric } 29247ae0e2c9SDimitry Andric return false; 29257ae0e2c9SDimitry Andric } 29267ae0e2c9SDimitry Andric 29273861d79fSDimitry Andric /// Get all the instructions in a tree. 29283861d79fSDimitry Andric static void 29293861d79fSDimitry Andric getInstructionsInTree(TreePatternNode *Tree, SmallVectorImpl<Record*> &Instrs) { 29303861d79fSDimitry Andric if (Tree->isLeaf()) 29313861d79fSDimitry Andric return; 29323861d79fSDimitry Andric if (Tree->getOperator()->isSubClassOf("Instruction")) 29333861d79fSDimitry Andric Instrs.push_back(Tree->getOperator()); 29343861d79fSDimitry Andric for (unsigned i = 0, e = Tree->getNumChildren(); i != e; ++i) 29353861d79fSDimitry Andric getInstructionsInTree(Tree->getChild(i), Instrs); 29363861d79fSDimitry Andric } 29373861d79fSDimitry Andric 2938139f7f9bSDimitry Andric /// Check the class of a pattern leaf node against the instruction operand it 2939139f7f9bSDimitry Andric /// represents. 2940139f7f9bSDimitry Andric static bool checkOperandClass(CGIOperandList::OperandInfo &OI, 2941139f7f9bSDimitry Andric Record *Leaf) { 2942139f7f9bSDimitry Andric if (OI.Rec == Leaf) 2943139f7f9bSDimitry Andric return true; 2944139f7f9bSDimitry Andric 2945139f7f9bSDimitry Andric // Allow direct value types to be used in instruction set patterns. 2946139f7f9bSDimitry Andric // The type will be checked later. 2947139f7f9bSDimitry Andric if (Leaf->isSubClassOf("ValueType")) 2948139f7f9bSDimitry Andric return true; 2949139f7f9bSDimitry Andric 2950139f7f9bSDimitry Andric // Patterns can also be ComplexPattern instances. 2951139f7f9bSDimitry Andric if (Leaf->isSubClassOf("ComplexPattern")) 2952139f7f9bSDimitry Andric return true; 2953139f7f9bSDimitry Andric 2954139f7f9bSDimitry Andric return false; 2955139f7f9bSDimitry Andric } 2956139f7f9bSDimitry Andric 2957f785676fSDimitry Andric const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( 2958f785676fSDimitry Andric CodeGenInstruction &CGI, ListInit *Pat, DAGInstMap &DAGInsts) { 2959f22ef01cSRoman Divacky 2960f785676fSDimitry Andric assert(!DAGInsts.count(CGI.TheDef) && "Instruction already parsed!"); 2961f22ef01cSRoman Divacky 2962f22ef01cSRoman Divacky // Parse the instruction. 2963f785676fSDimitry Andric TreePattern *I = new TreePattern(CGI.TheDef, Pat, true, *this); 2964f22ef01cSRoman Divacky // Inline pattern fragments into it. 2965f22ef01cSRoman Divacky I->InlinePatternFragments(); 2966f22ef01cSRoman Divacky 2967f22ef01cSRoman Divacky // Infer as many types as possible. If we cannot infer all of them, we can 2968f22ef01cSRoman Divacky // never do anything with this instruction pattern: report it to the user. 2969f22ef01cSRoman Divacky if (!I->InferAllTypes()) 2970f22ef01cSRoman Divacky I->error("Could not infer all types in pattern!"); 2971f22ef01cSRoman Divacky 2972f22ef01cSRoman Divacky // InstInputs - Keep track of all of the inputs of the instruction, along 2973f22ef01cSRoman Divacky // with the record they are declared as. 2974f22ef01cSRoman Divacky std::map<std::string, TreePatternNode*> InstInputs; 2975f22ef01cSRoman Divacky 2976f22ef01cSRoman Divacky // InstResults - Keep track of all the virtual registers that are 'set' 2977f22ef01cSRoman Divacky // in the instruction, including what reg class they are. 2978f22ef01cSRoman Divacky std::map<std::string, TreePatternNode*> InstResults; 2979f22ef01cSRoman Divacky 2980f22ef01cSRoman Divacky std::vector<Record*> InstImpResults; 2981f22ef01cSRoman Divacky 2982f22ef01cSRoman Divacky // Verify that the top-level forms in the instruction are of void type, and 2983f22ef01cSRoman Divacky // fill in the InstResults map. 2984f22ef01cSRoman Divacky for (unsigned j = 0, e = I->getNumTrees(); j != e; ++j) { 2985f22ef01cSRoman Divacky TreePatternNode *Pat = I->getTree(j); 29863ca95b02SDimitry Andric if (Pat->getNumTypes() != 0) { 29873ca95b02SDimitry Andric std::string Types; 29883ca95b02SDimitry Andric for (unsigned k = 0, ke = Pat->getNumTypes(); k != ke; ++k) { 29893ca95b02SDimitry Andric if (k > 0) 29903ca95b02SDimitry Andric Types += ", "; 29913ca95b02SDimitry Andric Types += Pat->getExtType(k).getName(); 29923ca95b02SDimitry Andric } 2993f22ef01cSRoman Divacky I->error("Top-level forms in instruction pattern should have" 29943ca95b02SDimitry Andric " void types, has types " + Types); 29953ca95b02SDimitry Andric } 2996f22ef01cSRoman Divacky 2997f22ef01cSRoman Divacky // Find inputs and outputs, and verify the structure of the uses/defs. 2998f22ef01cSRoman Divacky FindPatternInputsAndOutputs(I, Pat, InstInputs, InstResults, 2999f22ef01cSRoman Divacky InstImpResults); 3000f22ef01cSRoman Divacky } 3001f22ef01cSRoman Divacky 3002f22ef01cSRoman Divacky // Now that we have inputs and outputs of the pattern, inspect the operands 3003f22ef01cSRoman Divacky // list for the instruction. This determines the order that operands are 3004f22ef01cSRoman Divacky // added to the machine instruction the node corresponds to. 3005f22ef01cSRoman Divacky unsigned NumResults = InstResults.size(); 3006f22ef01cSRoman Divacky 3007f22ef01cSRoman Divacky // Parse the operands list from the (ops) list, validating it. 3008f22ef01cSRoman Divacky assert(I->getArgList().empty() && "Args list should still be empty here!"); 3009f22ef01cSRoman Divacky 3010f22ef01cSRoman Divacky // Check that all of the results occur first in the list. 3011f22ef01cSRoman Divacky std::vector<Record*> Results; 3012ff0cc061SDimitry Andric SmallVector<TreePatternNode *, 2> ResNodes; 3013f22ef01cSRoman Divacky for (unsigned i = 0; i != NumResults; ++i) { 30142754fe60SDimitry Andric if (i == CGI.Operands.size()) 3015f22ef01cSRoman Divacky I->error("'" + InstResults.begin()->first + 3016f22ef01cSRoman Divacky "' set but does not appear in operand list!"); 30172754fe60SDimitry Andric const std::string &OpName = CGI.Operands[i].Name; 3018f22ef01cSRoman Divacky 3019f22ef01cSRoman Divacky // Check that it exists in InstResults. 3020f22ef01cSRoman Divacky TreePatternNode *RNode = InstResults[OpName]; 302191bc56edSDimitry Andric if (!RNode) 3022f22ef01cSRoman Divacky I->error("Operand $" + OpName + " does not exist in operand list!"); 3023f22ef01cSRoman Divacky 3024ff0cc061SDimitry Andric ResNodes.push_back(RNode); 3025ff0cc061SDimitry Andric 30263861d79fSDimitry Andric Record *R = cast<DefInit>(RNode->getLeafValue())->getDef(); 302791bc56edSDimitry Andric if (!R) 3028f22ef01cSRoman Divacky I->error("Operand $" + OpName + " should be a set destination: all " 3029f22ef01cSRoman Divacky "outputs must occur before inputs in operand list!"); 3030f22ef01cSRoman Divacky 3031139f7f9bSDimitry Andric if (!checkOperandClass(CGI.Operands[i], R)) 3032f22ef01cSRoman Divacky I->error("Operand $" + OpName + " class mismatch!"); 3033f22ef01cSRoman Divacky 3034f22ef01cSRoman Divacky // Remember the return type. 30352754fe60SDimitry Andric Results.push_back(CGI.Operands[i].Rec); 3036f22ef01cSRoman Divacky 3037f22ef01cSRoman Divacky // Okay, this one checks out. 3038f22ef01cSRoman Divacky InstResults.erase(OpName); 3039f22ef01cSRoman Divacky } 3040f22ef01cSRoman Divacky 3041f22ef01cSRoman Divacky // Loop over the inputs next. Make a copy of InstInputs so we can destroy 3042f22ef01cSRoman Divacky // the copy while we're checking the inputs. 3043f22ef01cSRoman Divacky std::map<std::string, TreePatternNode*> InstInputsCheck(InstInputs); 3044f22ef01cSRoman Divacky 3045f22ef01cSRoman Divacky std::vector<TreePatternNode*> ResultNodeOperands; 3046f22ef01cSRoman Divacky std::vector<Record*> Operands; 30472754fe60SDimitry Andric for (unsigned i = NumResults, e = CGI.Operands.size(); i != e; ++i) { 30482754fe60SDimitry Andric CGIOperandList::OperandInfo &Op = CGI.Operands[i]; 3049f22ef01cSRoman Divacky const std::string &OpName = Op.Name; 3050f22ef01cSRoman Divacky if (OpName.empty()) 3051f22ef01cSRoman Divacky I->error("Operand #" + utostr(i) + " in operands list has no name!"); 3052f22ef01cSRoman Divacky 3053f22ef01cSRoman Divacky if (!InstInputsCheck.count(OpName)) { 30543861d79fSDimitry Andric // If this is an operand with a DefaultOps set filled in, we can ignore 30553861d79fSDimitry Andric // this. When we codegen it, we will do so as always executed. 30563861d79fSDimitry Andric if (Op.Rec->isSubClassOf("OperandWithDefaultOps")) { 3057f22ef01cSRoman Divacky // Does it have a non-empty DefaultOps field? If so, ignore this 3058f22ef01cSRoman Divacky // operand. 3059f22ef01cSRoman Divacky if (!getDefaultOperand(Op.Rec).DefaultOps.empty()) 3060f22ef01cSRoman Divacky continue; 3061f22ef01cSRoman Divacky } 3062f22ef01cSRoman Divacky I->error("Operand $" + OpName + 3063f22ef01cSRoman Divacky " does not appear in the instruction pattern"); 3064f22ef01cSRoman Divacky } 3065f22ef01cSRoman Divacky TreePatternNode *InVal = InstInputsCheck[OpName]; 3066f22ef01cSRoman Divacky InstInputsCheck.erase(OpName); // It occurred, remove from map. 3067f22ef01cSRoman Divacky 30683861d79fSDimitry Andric if (InVal->isLeaf() && isa<DefInit>(InVal->getLeafValue())) { 3069f22ef01cSRoman Divacky Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef(); 3070139f7f9bSDimitry Andric if (!checkOperandClass(Op, InRec)) 3071f22ef01cSRoman Divacky I->error("Operand $" + OpName + "'s register class disagrees" 3072f22ef01cSRoman Divacky " between the operand and pattern"); 3073f22ef01cSRoman Divacky } 3074f22ef01cSRoman Divacky Operands.push_back(Op.Rec); 3075f22ef01cSRoman Divacky 3076f22ef01cSRoman Divacky // Construct the result for the dest-pattern operand list. 3077f22ef01cSRoman Divacky TreePatternNode *OpNode = InVal->clone(); 3078f22ef01cSRoman Divacky 3079f22ef01cSRoman Divacky // No predicate is useful on the result. 3080f22ef01cSRoman Divacky OpNode->clearPredicateFns(); 3081f22ef01cSRoman Divacky 3082f22ef01cSRoman Divacky // Promote the xform function to be an explicit node if set. 3083f22ef01cSRoman Divacky if (Record *Xform = OpNode->getTransformFn()) { 308491bc56edSDimitry Andric OpNode->setTransformFn(nullptr); 3085f22ef01cSRoman Divacky std::vector<TreePatternNode*> Children; 3086f22ef01cSRoman Divacky Children.push_back(OpNode); 3087f22ef01cSRoman Divacky OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes()); 3088f22ef01cSRoman Divacky } 3089f22ef01cSRoman Divacky 3090f22ef01cSRoman Divacky ResultNodeOperands.push_back(OpNode); 3091f22ef01cSRoman Divacky } 3092f22ef01cSRoman Divacky 3093f22ef01cSRoman Divacky if (!InstInputsCheck.empty()) 3094f22ef01cSRoman Divacky I->error("Input operand $" + InstInputsCheck.begin()->first + 3095f22ef01cSRoman Divacky " occurs in pattern but not in operands list!"); 3096f22ef01cSRoman Divacky 3097f22ef01cSRoman Divacky TreePatternNode *ResultPattern = 3098f22ef01cSRoman Divacky new TreePatternNode(I->getRecord(), ResultNodeOperands, 3099f22ef01cSRoman Divacky GetNumNodeResults(I->getRecord(), *this)); 3100ff0cc061SDimitry Andric // Copy fully inferred output node types to instruction result pattern. 3101ff0cc061SDimitry Andric for (unsigned i = 0; i != NumResults; ++i) { 3102ff0cc061SDimitry Andric assert(ResNodes[i]->getNumTypes() == 1 && "FIXME: Unhandled"); 3103ff0cc061SDimitry Andric ResultPattern->setType(i, ResNodes[i]->getExtType(0)); 3104ff0cc061SDimitry Andric } 3105f22ef01cSRoman Divacky 3106f22ef01cSRoman Divacky // Create and insert the instruction. 3107f22ef01cSRoman Divacky // FIXME: InstImpResults should not be part of DAGInstruction. 3108f22ef01cSRoman Divacky DAGInstruction TheInst(I, Results, Operands, InstImpResults); 3109f785676fSDimitry Andric DAGInsts.insert(std::make_pair(I->getRecord(), TheInst)); 3110f22ef01cSRoman Divacky 3111f22ef01cSRoman Divacky // Use a temporary tree pattern to infer all types and make sure that the 3112f22ef01cSRoman Divacky // constructed result is correct. This depends on the instruction already 3113f785676fSDimitry Andric // being inserted into the DAGInsts map. 3114f22ef01cSRoman Divacky TreePattern Temp(I->getRecord(), ResultPattern, false, *this); 3115f22ef01cSRoman Divacky Temp.InferAllTypes(&I->getNamedNodesMap()); 3116f22ef01cSRoman Divacky 3117f785676fSDimitry Andric DAGInstruction &TheInsertedInst = DAGInsts.find(I->getRecord())->second; 3118f22ef01cSRoman Divacky TheInsertedInst.setResultPattern(Temp.getOnlyTree()); 3119f22ef01cSRoman Divacky 3120f785676fSDimitry Andric return TheInsertedInst; 3121f785676fSDimitry Andric } 3122f785676fSDimitry Andric 3123f785676fSDimitry Andric /// ParseInstructions - Parse all of the instructions, inlining and resolving 3124f785676fSDimitry Andric /// any fragments involved. This populates the Instructions list with fully 3125f785676fSDimitry Andric /// resolved instructions. 3126f785676fSDimitry Andric void CodeGenDAGPatterns::ParseInstructions() { 3127f785676fSDimitry Andric std::vector<Record*> Instrs = Records.getAllDerivedDefinitions("Instruction"); 3128f785676fSDimitry Andric 31297d523365SDimitry Andric for (Record *Instr : Instrs) { 313091bc56edSDimitry Andric ListInit *LI = nullptr; 3131f785676fSDimitry Andric 31327d523365SDimitry Andric if (isa<ListInit>(Instr->getValueInit("Pattern"))) 31337d523365SDimitry Andric LI = Instr->getValueAsListInit("Pattern"); 3134f785676fSDimitry Andric 3135f785676fSDimitry Andric // If there is no pattern, only collect minimal information about the 3136f785676fSDimitry Andric // instruction for its operand list. We have to assume that there is one 3137f785676fSDimitry Andric // result, as we have no detailed info. A pattern which references the 3138f785676fSDimitry Andric // null_frag operator is as-if no pattern were specified. Normally this 3139f785676fSDimitry Andric // is from a multiclass expansion w/ a SDPatternOperator passed in as 3140f785676fSDimitry Andric // null_frag. 3141ff0cc061SDimitry Andric if (!LI || LI->empty() || hasNullFragReference(LI)) { 3142f785676fSDimitry Andric std::vector<Record*> Results; 3143f785676fSDimitry Andric std::vector<Record*> Operands; 3144f785676fSDimitry Andric 31457d523365SDimitry Andric CodeGenInstruction &InstInfo = Target.getInstruction(Instr); 3146f785676fSDimitry Andric 3147f785676fSDimitry Andric if (InstInfo.Operands.size() != 0) { 3148ff0cc061SDimitry Andric for (unsigned j = 0, e = InstInfo.Operands.NumDefs; j < e; ++j) 3149ff0cc061SDimitry Andric Results.push_back(InstInfo.Operands[j].Rec); 3150f785676fSDimitry Andric 3151f785676fSDimitry Andric // The rest are inputs. 3152ff0cc061SDimitry Andric for (unsigned j = InstInfo.Operands.NumDefs, 3153ff0cc061SDimitry Andric e = InstInfo.Operands.size(); j < e; ++j) 3154f785676fSDimitry Andric Operands.push_back(InstInfo.Operands[j].Rec); 3155f785676fSDimitry Andric } 3156f785676fSDimitry Andric 3157f785676fSDimitry Andric // Create and insert the instruction. 3158f785676fSDimitry Andric std::vector<Record*> ImpResults; 31597d523365SDimitry Andric Instructions.insert(std::make_pair(Instr, 316091bc56edSDimitry Andric DAGInstruction(nullptr, Results, Operands, ImpResults))); 3161f785676fSDimitry Andric continue; // no pattern. 3162f785676fSDimitry Andric } 3163f785676fSDimitry Andric 31647d523365SDimitry Andric CodeGenInstruction &CGI = Target.getInstruction(Instr); 3165f785676fSDimitry Andric const DAGInstruction &DI = parseInstructionPattern(CGI, LI, Instructions); 3166f785676fSDimitry Andric 3167f785676fSDimitry Andric (void)DI; 3168f785676fSDimitry Andric DEBUG(DI.getPattern()->dump()); 3169f22ef01cSRoman Divacky } 3170f22ef01cSRoman Divacky 3171f22ef01cSRoman Divacky // If we can, convert the instructions to be patterns that are matched! 31727d523365SDimitry Andric for (auto &Entry : Instructions) { 31737d523365SDimitry Andric DAGInstruction &TheInst = Entry.second; 31743861d79fSDimitry Andric TreePattern *I = TheInst.getPattern(); 317591bc56edSDimitry Andric if (!I) continue; // No pattern. 3176f22ef01cSRoman Divacky 3177f22ef01cSRoman Divacky // FIXME: Assume only the first tree is the pattern. The others are clobber 3178f22ef01cSRoman Divacky // nodes. 3179f22ef01cSRoman Divacky TreePatternNode *Pattern = I->getTree(0); 3180f22ef01cSRoman Divacky TreePatternNode *SrcPattern; 3181f22ef01cSRoman Divacky if (Pattern->getOperator()->getName() == "set") { 3182f22ef01cSRoman Divacky SrcPattern = Pattern->getChild(Pattern->getNumChildren()-1)->clone(); 3183f22ef01cSRoman Divacky } else{ 3184f22ef01cSRoman Divacky // Not a set (store or something?) 3185f22ef01cSRoman Divacky SrcPattern = Pattern; 3186f22ef01cSRoman Divacky } 3187f22ef01cSRoman Divacky 31887d523365SDimitry Andric Record *Instr = Entry.first; 3189f22ef01cSRoman Divacky AddPatternToMatch(I, 31902754fe60SDimitry Andric PatternToMatch(Instr, 31912754fe60SDimitry Andric Instr->getValueAsListInit("Predicates"), 3192f22ef01cSRoman Divacky SrcPattern, 3193f22ef01cSRoman Divacky TheInst.getResultPattern(), 3194f22ef01cSRoman Divacky TheInst.getImpResults(), 3195f22ef01cSRoman Divacky Instr->getValueAsInt("AddedComplexity"), 3196f22ef01cSRoman Divacky Instr->getID())); 3197f22ef01cSRoman Divacky } 3198f22ef01cSRoman Divacky } 3199f22ef01cSRoman Divacky 3200f22ef01cSRoman Divacky 3201f22ef01cSRoman Divacky typedef std::pair<const TreePatternNode*, unsigned> NameRecord; 3202f22ef01cSRoman Divacky 3203f22ef01cSRoman Divacky static void FindNames(const TreePatternNode *P, 3204f22ef01cSRoman Divacky std::map<std::string, NameRecord> &Names, 32053861d79fSDimitry Andric TreePattern *PatternTop) { 3206f22ef01cSRoman Divacky if (!P->getName().empty()) { 3207f22ef01cSRoman Divacky NameRecord &Rec = Names[P->getName()]; 3208f22ef01cSRoman Divacky // If this is the first instance of the name, remember the node. 3209f22ef01cSRoman Divacky if (Rec.second++ == 0) 3210f22ef01cSRoman Divacky Rec.first = P; 3211f22ef01cSRoman Divacky else if (Rec.first->getExtTypes() != P->getExtTypes()) 3212f22ef01cSRoman Divacky PatternTop->error("repetition of value: $" + P->getName() + 3213f22ef01cSRoman Divacky " where different uses have different types!"); 3214f22ef01cSRoman Divacky } 3215f22ef01cSRoman Divacky 3216f22ef01cSRoman Divacky if (!P->isLeaf()) { 3217f22ef01cSRoman Divacky for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) 3218f22ef01cSRoman Divacky FindNames(P->getChild(i), Names, PatternTop); 3219f22ef01cSRoman Divacky } 3220f22ef01cSRoman Divacky } 3221f22ef01cSRoman Divacky 32223861d79fSDimitry Andric void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern, 3223edd7eaddSDimitry Andric PatternToMatch &&PTM) { 3224f22ef01cSRoman Divacky // Do some sanity checking on the pattern we're about to match. 3225f22ef01cSRoman Divacky std::string Reason; 32263861d79fSDimitry Andric if (!PTM.getSrcPattern()->canPatternMatch(Reason, *this)) { 32273861d79fSDimitry Andric PrintWarning(Pattern->getRecord()->getLoc(), 32283861d79fSDimitry Andric Twine("Pattern can never match: ") + Reason); 32293861d79fSDimitry Andric return; 32303861d79fSDimitry Andric } 3231f22ef01cSRoman Divacky 3232f22ef01cSRoman Divacky // If the source pattern's root is a complex pattern, that complex pattern 3233f22ef01cSRoman Divacky // must specify the nodes it can potentially match. 3234f22ef01cSRoman Divacky if (const ComplexPattern *CP = 3235f22ef01cSRoman Divacky PTM.getSrcPattern()->getComplexPatternInfo(*this)) 3236f22ef01cSRoman Divacky if (CP->getRootNodes().empty()) 3237f22ef01cSRoman Divacky Pattern->error("ComplexPattern at root must specify list of opcodes it" 3238f22ef01cSRoman Divacky " could match"); 3239f22ef01cSRoman Divacky 3240f22ef01cSRoman Divacky 3241f22ef01cSRoman Divacky // Find all of the named values in the input and output, ensure they have the 3242f22ef01cSRoman Divacky // same type. 3243f22ef01cSRoman Divacky std::map<std::string, NameRecord> SrcNames, DstNames; 3244f22ef01cSRoman Divacky FindNames(PTM.getSrcPattern(), SrcNames, Pattern); 3245f22ef01cSRoman Divacky FindNames(PTM.getDstPattern(), DstNames, Pattern); 3246f22ef01cSRoman Divacky 3247f22ef01cSRoman Divacky // Scan all of the named values in the destination pattern, rejecting them if 3248f22ef01cSRoman Divacky // they don't exist in the input pattern. 32497d523365SDimitry Andric for (const auto &Entry : DstNames) { 32507d523365SDimitry Andric if (SrcNames[Entry.first].first == nullptr) 3251f22ef01cSRoman Divacky Pattern->error("Pattern has input without matching name in output: $" + 32527d523365SDimitry Andric Entry.first); 3253f22ef01cSRoman Divacky } 3254f22ef01cSRoman Divacky 3255f22ef01cSRoman Divacky // Scan all of the named values in the source pattern, rejecting them if the 3256f22ef01cSRoman Divacky // name isn't used in the dest, and isn't used to tie two values together. 32577d523365SDimitry Andric for (const auto &Entry : SrcNames) 32587d523365SDimitry Andric if (DstNames[Entry.first].first == nullptr && 32597d523365SDimitry Andric SrcNames[Entry.first].second == 1) 32607d523365SDimitry Andric Pattern->error("Pattern has dead named input: $" + Entry.first); 3261f22ef01cSRoman Divacky 3262edd7eaddSDimitry Andric PatternsToMatch.push_back(std::move(PTM)); 3263f22ef01cSRoman Divacky } 3264f22ef01cSRoman Divacky 3265f22ef01cSRoman Divacky 3266f22ef01cSRoman Divacky 3267f22ef01cSRoman Divacky void CodeGenDAGPatterns::InferInstructionFlags() { 32683ca95b02SDimitry Andric ArrayRef<const CodeGenInstruction*> Instructions = 3269f22ef01cSRoman Divacky Target.getInstructionsByEnumValue(); 32703861d79fSDimitry Andric 32713861d79fSDimitry Andric // First try to infer flags from the primary instruction pattern, if any. 32723861d79fSDimitry Andric SmallVector<CodeGenInstruction*, 8> Revisit; 32733861d79fSDimitry Andric unsigned Errors = 0; 3274f22ef01cSRoman Divacky for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { 3275f22ef01cSRoman Divacky CodeGenInstruction &InstInfo = 3276f22ef01cSRoman Divacky const_cast<CodeGenInstruction &>(*Instructions[i]); 32776122f3e6SDimitry Andric 32783861d79fSDimitry Andric // Get the primary instruction pattern. 32793861d79fSDimitry Andric const TreePattern *Pattern = getInstruction(InstInfo.TheDef).getPattern(); 32803861d79fSDimitry Andric if (!Pattern) { 32813861d79fSDimitry Andric if (InstInfo.hasUndefFlags()) 32823861d79fSDimitry Andric Revisit.push_back(&InstInfo); 32833861d79fSDimitry Andric continue; 32843861d79fSDimitry Andric } 32853861d79fSDimitry Andric InstAnalyzer PatInfo(*this); 32863861d79fSDimitry Andric PatInfo.Analyze(Pattern); 32873861d79fSDimitry Andric Errors += InferFromPattern(InstInfo, PatInfo, InstInfo.TheDef); 32883861d79fSDimitry Andric } 32893861d79fSDimitry Andric 32903861d79fSDimitry Andric // Second, look for single-instruction patterns defined outside the 32913861d79fSDimitry Andric // instruction. 3292edd7eaddSDimitry Andric for (const PatternToMatch &PTM : ptms()) { 32933861d79fSDimitry Andric // We can only infer from single-instruction patterns, otherwise we won't 32943861d79fSDimitry Andric // know which instruction should get the flags. 32953861d79fSDimitry Andric SmallVector<Record*, 8> PatInstrs; 32963861d79fSDimitry Andric getInstructionsInTree(PTM.getDstPattern(), PatInstrs); 32973861d79fSDimitry Andric if (PatInstrs.size() != 1) 32983861d79fSDimitry Andric continue; 32993861d79fSDimitry Andric 33003861d79fSDimitry Andric // Get the single instruction. 33013861d79fSDimitry Andric CodeGenInstruction &InstInfo = Target.getInstruction(PatInstrs.front()); 33023861d79fSDimitry Andric 33033861d79fSDimitry Andric // Only infer properties from the first pattern. We'll verify the others. 33043861d79fSDimitry Andric if (InstInfo.InferredFrom) 33053861d79fSDimitry Andric continue; 33063861d79fSDimitry Andric 33073861d79fSDimitry Andric InstAnalyzer PatInfo(*this); 3308edd7eaddSDimitry Andric PatInfo.Analyze(PTM); 33093861d79fSDimitry Andric Errors += InferFromPattern(InstInfo, PatInfo, PTM.getSrcRecord()); 33103861d79fSDimitry Andric } 33113861d79fSDimitry Andric 33123861d79fSDimitry Andric if (Errors) 33133861d79fSDimitry Andric PrintFatalError("pattern conflicts"); 33143861d79fSDimitry Andric 33153861d79fSDimitry Andric // Revisit instructions with undefined flags and no pattern. 33163861d79fSDimitry Andric if (Target.guessInstructionProperties()) { 33177d523365SDimitry Andric for (CodeGenInstruction *InstInfo : Revisit) { 33187d523365SDimitry Andric if (InstInfo->InferredFrom) 33193861d79fSDimitry Andric continue; 33203861d79fSDimitry Andric // The mayLoad and mayStore flags default to false. 33213861d79fSDimitry Andric // Conservatively assume hasSideEffects if it wasn't explicit. 33227d523365SDimitry Andric if (InstInfo->hasSideEffects_Unset) 33237d523365SDimitry Andric InstInfo->hasSideEffects = true; 33243861d79fSDimitry Andric } 33253861d79fSDimitry Andric return; 33263861d79fSDimitry Andric } 33273861d79fSDimitry Andric 33283861d79fSDimitry Andric // Complain about any flags that are still undefined. 33297d523365SDimitry Andric for (CodeGenInstruction *InstInfo : Revisit) { 33307d523365SDimitry Andric if (InstInfo->InferredFrom) 33313861d79fSDimitry Andric continue; 33327d523365SDimitry Andric if (InstInfo->hasSideEffects_Unset) 33337d523365SDimitry Andric PrintError(InstInfo->TheDef->getLoc(), 33343861d79fSDimitry Andric "Can't infer hasSideEffects from patterns"); 33357d523365SDimitry Andric if (InstInfo->mayStore_Unset) 33367d523365SDimitry Andric PrintError(InstInfo->TheDef->getLoc(), 33373861d79fSDimitry Andric "Can't infer mayStore from patterns"); 33387d523365SDimitry Andric if (InstInfo->mayLoad_Unset) 33397d523365SDimitry Andric PrintError(InstInfo->TheDef->getLoc(), 33403861d79fSDimitry Andric "Can't infer mayLoad from patterns"); 33413861d79fSDimitry Andric } 33423861d79fSDimitry Andric } 33433861d79fSDimitry Andric 33443861d79fSDimitry Andric 33453861d79fSDimitry Andric /// Verify instruction flags against pattern node properties. 33463861d79fSDimitry Andric void CodeGenDAGPatterns::VerifyInstructionFlags() { 33473861d79fSDimitry Andric unsigned Errors = 0; 33483861d79fSDimitry Andric for (ptm_iterator I = ptm_begin(), E = ptm_end(); I != E; ++I) { 33493861d79fSDimitry Andric const PatternToMatch &PTM = *I; 33503861d79fSDimitry Andric SmallVector<Record*, 8> Instrs; 33513861d79fSDimitry Andric getInstructionsInTree(PTM.getDstPattern(), Instrs); 33523861d79fSDimitry Andric if (Instrs.empty()) 33533861d79fSDimitry Andric continue; 33543861d79fSDimitry Andric 33553861d79fSDimitry Andric // Count the number of instructions with each flag set. 33563861d79fSDimitry Andric unsigned NumSideEffects = 0; 33573861d79fSDimitry Andric unsigned NumStores = 0; 33583861d79fSDimitry Andric unsigned NumLoads = 0; 33597d523365SDimitry Andric for (const Record *Instr : Instrs) { 33607d523365SDimitry Andric const CodeGenInstruction &InstInfo = Target.getInstruction(Instr); 33613861d79fSDimitry Andric NumSideEffects += InstInfo.hasSideEffects; 33623861d79fSDimitry Andric NumStores += InstInfo.mayStore; 33633861d79fSDimitry Andric NumLoads += InstInfo.mayLoad; 33643861d79fSDimitry Andric } 33653861d79fSDimitry Andric 33663861d79fSDimitry Andric // Analyze the source pattern. 33673861d79fSDimitry Andric InstAnalyzer PatInfo(*this); 3368edd7eaddSDimitry Andric PatInfo.Analyze(PTM); 33693861d79fSDimitry Andric 33703861d79fSDimitry Andric // Collect error messages. 33713861d79fSDimitry Andric SmallVector<std::string, 4> Msgs; 33723861d79fSDimitry Andric 33733861d79fSDimitry Andric // Check for missing flags in the output. 33743861d79fSDimitry Andric // Permit extra flags for now at least. 33753861d79fSDimitry Andric if (PatInfo.hasSideEffects && !NumSideEffects) 33763861d79fSDimitry Andric Msgs.push_back("pattern has side effects, but hasSideEffects isn't set"); 33773861d79fSDimitry Andric 33783861d79fSDimitry Andric // Don't verify store flags on instructions with side effects. At least for 33793861d79fSDimitry Andric // intrinsics, side effects implies mayStore. 33803861d79fSDimitry Andric if (!PatInfo.hasSideEffects && PatInfo.mayStore && !NumStores) 33813861d79fSDimitry Andric Msgs.push_back("pattern may store, but mayStore isn't set"); 33823861d79fSDimitry Andric 33833861d79fSDimitry Andric // Similarly, mayStore implies mayLoad on intrinsics. 33843861d79fSDimitry Andric if (!PatInfo.mayStore && PatInfo.mayLoad && !NumLoads) 33853861d79fSDimitry Andric Msgs.push_back("pattern may load, but mayLoad isn't set"); 33863861d79fSDimitry Andric 33873861d79fSDimitry Andric // Print error messages. 33883861d79fSDimitry Andric if (Msgs.empty()) 33893861d79fSDimitry Andric continue; 33903861d79fSDimitry Andric ++Errors; 33913861d79fSDimitry Andric 33927d523365SDimitry Andric for (const std::string &Msg : Msgs) 33937d523365SDimitry Andric PrintError(PTM.getSrcRecord()->getLoc(), Twine(Msg) + " on the " + 33943861d79fSDimitry Andric (Instrs.size() == 1 ? 33953861d79fSDimitry Andric "instruction" : "output instructions")); 33963861d79fSDimitry Andric // Provide the location of the relevant instruction definitions. 33977d523365SDimitry Andric for (const Record *Instr : Instrs) { 33987d523365SDimitry Andric if (Instr != PTM.getSrcRecord()) 33997d523365SDimitry Andric PrintError(Instr->getLoc(), "defined here"); 34007d523365SDimitry Andric const CodeGenInstruction &InstInfo = Target.getInstruction(Instr); 34013861d79fSDimitry Andric if (InstInfo.InferredFrom && 34023861d79fSDimitry Andric InstInfo.InferredFrom != InstInfo.TheDef && 34033861d79fSDimitry Andric InstInfo.InferredFrom != PTM.getSrcRecord()) 34047d523365SDimitry Andric PrintError(InstInfo.InferredFrom->getLoc(), "inferred from pattern"); 34053861d79fSDimitry Andric } 34063861d79fSDimitry Andric } 34073861d79fSDimitry Andric if (Errors) 34083861d79fSDimitry Andric PrintFatalError("Errors in DAG patterns"); 3409f22ef01cSRoman Divacky } 3410f22ef01cSRoman Divacky 3411f22ef01cSRoman Divacky /// Given a pattern result with an unresolved type, see if we can find one 3412f22ef01cSRoman Divacky /// instruction with an unresolved result type. Force this result type to an 3413f22ef01cSRoman Divacky /// arbitrary element if it's possible types to converge results. 3414f22ef01cSRoman Divacky static bool ForceArbitraryInstResultType(TreePatternNode *N, TreePattern &TP) { 3415f22ef01cSRoman Divacky if (N->isLeaf()) 3416f22ef01cSRoman Divacky return false; 3417f22ef01cSRoman Divacky 3418f22ef01cSRoman Divacky // Analyze children. 3419f22ef01cSRoman Divacky for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) 3420f22ef01cSRoman Divacky if (ForceArbitraryInstResultType(N->getChild(i), TP)) 3421f22ef01cSRoman Divacky return true; 3422f22ef01cSRoman Divacky 3423f22ef01cSRoman Divacky if (!N->getOperator()->isSubClassOf("Instruction")) 3424f22ef01cSRoman Divacky return false; 3425f22ef01cSRoman Divacky 3426f22ef01cSRoman Divacky // If this type is already concrete or completely unknown we can't do 3427f22ef01cSRoman Divacky // anything. 3428f22ef01cSRoman Divacky for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i) { 3429f22ef01cSRoman Divacky if (N->getExtType(i).isCompletelyUnknown() || N->getExtType(i).isConcrete()) 3430f22ef01cSRoman Divacky continue; 3431f22ef01cSRoman Divacky 3432f22ef01cSRoman Divacky // Otherwise, force its type to the first possibility (an arbitrary choice). 3433f22ef01cSRoman Divacky if (N->getExtType(i).MergeInTypeInfo(N->getExtType(i).getTypeList()[0], TP)) 3434f22ef01cSRoman Divacky return true; 3435f22ef01cSRoman Divacky } 3436f22ef01cSRoman Divacky 3437f22ef01cSRoman Divacky return false; 3438f22ef01cSRoman Divacky } 3439f22ef01cSRoman Divacky 3440f22ef01cSRoman Divacky void CodeGenDAGPatterns::ParsePatterns() { 3441f22ef01cSRoman Divacky std::vector<Record*> Patterns = Records.getAllDerivedDefinitions("Pattern"); 3442f22ef01cSRoman Divacky 34437d523365SDimitry Andric for (Record *CurPattern : Patterns) { 3444f22ef01cSRoman Divacky DagInit *Tree = CurPattern->getValueAsDag("PatternToMatch"); 34457ae0e2c9SDimitry Andric 34467ae0e2c9SDimitry Andric // If the pattern references the null_frag, there's nothing to do. 34477ae0e2c9SDimitry Andric if (hasNullFragReference(Tree)) 34487ae0e2c9SDimitry Andric continue; 34497ae0e2c9SDimitry Andric 3450f22ef01cSRoman Divacky TreePattern *Pattern = new TreePattern(CurPattern, Tree, true, *this); 3451f22ef01cSRoman Divacky 3452f22ef01cSRoman Divacky // Inline pattern fragments into it. 3453f22ef01cSRoman Divacky Pattern->InlinePatternFragments(); 3454f22ef01cSRoman Divacky 3455f22ef01cSRoman Divacky ListInit *LI = CurPattern->getValueAsListInit("ResultInstrs"); 3456ff0cc061SDimitry Andric if (LI->empty()) continue; // no pattern. 3457f22ef01cSRoman Divacky 3458f22ef01cSRoman Divacky // Parse the instruction. 345939d628a0SDimitry Andric TreePattern Result(CurPattern, LI, false, *this); 3460f22ef01cSRoman Divacky 3461f22ef01cSRoman Divacky // Inline pattern fragments into it. 346239d628a0SDimitry Andric Result.InlinePatternFragments(); 3463f22ef01cSRoman Divacky 346439d628a0SDimitry Andric if (Result.getNumTrees() != 1) 346539d628a0SDimitry Andric Result.error("Cannot handle instructions producing instructions " 3466f22ef01cSRoman Divacky "with temporaries yet!"); 3467f22ef01cSRoman Divacky 3468f22ef01cSRoman Divacky bool IterateInference; 3469f22ef01cSRoman Divacky bool InferredAllPatternTypes, InferredAllResultTypes; 3470f22ef01cSRoman Divacky do { 3471f22ef01cSRoman Divacky // Infer as many types as possible. If we cannot infer all of them, we 3472f22ef01cSRoman Divacky // can never do anything with this pattern: report it to the user. 3473f22ef01cSRoman Divacky InferredAllPatternTypes = 3474f22ef01cSRoman Divacky Pattern->InferAllTypes(&Pattern->getNamedNodesMap()); 3475f22ef01cSRoman Divacky 3476f22ef01cSRoman Divacky // Infer as many types as possible. If we cannot infer all of them, we 3477f22ef01cSRoman Divacky // can never do anything with this pattern: report it to the user. 3478f22ef01cSRoman Divacky InferredAllResultTypes = 347939d628a0SDimitry Andric Result.InferAllTypes(&Pattern->getNamedNodesMap()); 3480f22ef01cSRoman Divacky 3481f22ef01cSRoman Divacky IterateInference = false; 3482f22ef01cSRoman Divacky 3483f22ef01cSRoman Divacky // Apply the type of the result to the source pattern. This helps us 3484f22ef01cSRoman Divacky // resolve cases where the input type is known to be a pointer type (which 3485f22ef01cSRoman Divacky // is considered resolved), but the result knows it needs to be 32- or 3486f22ef01cSRoman Divacky // 64-bits. Infer the other way for good measure. 348739d628a0SDimitry Andric for (unsigned i = 0, e = std::min(Result.getTree(0)->getNumTypes(), 3488f22ef01cSRoman Divacky Pattern->getTree(0)->getNumTypes()); 3489f22ef01cSRoman Divacky i != e; ++i) { 349039d628a0SDimitry Andric IterateInference = Pattern->getTree(0)->UpdateNodeType( 349139d628a0SDimitry Andric i, Result.getTree(0)->getExtType(i), Result); 349239d628a0SDimitry Andric IterateInference |= Result.getTree(0)->UpdateNodeType( 349339d628a0SDimitry Andric i, Pattern->getTree(0)->getExtType(i), Result); 3494f22ef01cSRoman Divacky } 3495f22ef01cSRoman Divacky 3496f22ef01cSRoman Divacky // If our iteration has converged and the input pattern's types are fully 3497f22ef01cSRoman Divacky // resolved but the result pattern is not fully resolved, we may have a 3498f22ef01cSRoman Divacky // situation where we have two instructions in the result pattern and 3499f22ef01cSRoman Divacky // the instructions require a common register class, but don't care about 3500f22ef01cSRoman Divacky // what actual MVT is used. This is actually a bug in our modelling: 3501f22ef01cSRoman Divacky // output patterns should have register classes, not MVTs. 3502f22ef01cSRoman Divacky // 3503f22ef01cSRoman Divacky // In any case, to handle this, we just go through and disambiguate some 3504f22ef01cSRoman Divacky // arbitrary types to the result pattern's nodes. 3505f22ef01cSRoman Divacky if (!IterateInference && InferredAllPatternTypes && 3506f22ef01cSRoman Divacky !InferredAllResultTypes) 350739d628a0SDimitry Andric IterateInference = 350839d628a0SDimitry Andric ForceArbitraryInstResultType(Result.getTree(0), Result); 3509f22ef01cSRoman Divacky } while (IterateInference); 3510f22ef01cSRoman Divacky 3511f22ef01cSRoman Divacky // Verify that we inferred enough types that we can do something with the 3512f22ef01cSRoman Divacky // pattern and result. If these fire the user has to add type casts. 3513f22ef01cSRoman Divacky if (!InferredAllPatternTypes) 3514f22ef01cSRoman Divacky Pattern->error("Could not infer all types in pattern!"); 3515f22ef01cSRoman Divacky if (!InferredAllResultTypes) { 3516f22ef01cSRoman Divacky Pattern->dump(); 351739d628a0SDimitry Andric Result.error("Could not infer all types in pattern result!"); 3518f22ef01cSRoman Divacky } 3519f22ef01cSRoman Divacky 3520f22ef01cSRoman Divacky // Validate that the input pattern is correct. 3521f22ef01cSRoman Divacky std::map<std::string, TreePatternNode*> InstInputs; 3522f22ef01cSRoman Divacky std::map<std::string, TreePatternNode*> InstResults; 3523f22ef01cSRoman Divacky std::vector<Record*> InstImpResults; 3524f22ef01cSRoman Divacky for (unsigned j = 0, ee = Pattern->getNumTrees(); j != ee; ++j) 3525f22ef01cSRoman Divacky FindPatternInputsAndOutputs(Pattern, Pattern->getTree(j), 3526f22ef01cSRoman Divacky InstInputs, InstResults, 3527f22ef01cSRoman Divacky InstImpResults); 3528f22ef01cSRoman Divacky 3529f22ef01cSRoman Divacky // Promote the xform function to be an explicit node if set. 353039d628a0SDimitry Andric TreePatternNode *DstPattern = Result.getOnlyTree(); 3531f22ef01cSRoman Divacky std::vector<TreePatternNode*> ResultNodeOperands; 3532f22ef01cSRoman Divacky for (unsigned ii = 0, ee = DstPattern->getNumChildren(); ii != ee; ++ii) { 3533f22ef01cSRoman Divacky TreePatternNode *OpNode = DstPattern->getChild(ii); 3534f22ef01cSRoman Divacky if (Record *Xform = OpNode->getTransformFn()) { 353591bc56edSDimitry Andric OpNode->setTransformFn(nullptr); 3536f22ef01cSRoman Divacky std::vector<TreePatternNode*> Children; 3537f22ef01cSRoman Divacky Children.push_back(OpNode); 3538f22ef01cSRoman Divacky OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes()); 3539f22ef01cSRoman Divacky } 3540f22ef01cSRoman Divacky ResultNodeOperands.push_back(OpNode); 3541f22ef01cSRoman Divacky } 354239d628a0SDimitry Andric DstPattern = Result.getOnlyTree(); 3543f22ef01cSRoman Divacky if (!DstPattern->isLeaf()) 3544f22ef01cSRoman Divacky DstPattern = new TreePatternNode(DstPattern->getOperator(), 3545f22ef01cSRoman Divacky ResultNodeOperands, 3546f22ef01cSRoman Divacky DstPattern->getNumTypes()); 3547f22ef01cSRoman Divacky 354839d628a0SDimitry Andric for (unsigned i = 0, e = Result.getOnlyTree()->getNumTypes(); i != e; ++i) 354939d628a0SDimitry Andric DstPattern->setType(i, Result.getOnlyTree()->getExtType(i)); 3550f22ef01cSRoman Divacky 355139d628a0SDimitry Andric TreePattern Temp(Result.getRecord(), DstPattern, false, *this); 3552f22ef01cSRoman Divacky Temp.InferAllTypes(); 3553f22ef01cSRoman Divacky 3554edd7eaddSDimitry Andric AddPatternToMatch( 3555edd7eaddSDimitry Andric Pattern, 3556edd7eaddSDimitry Andric PatternToMatch( 3557edd7eaddSDimitry Andric CurPattern, CurPattern->getValueAsListInit("Predicates"), 3558edd7eaddSDimitry Andric Pattern->getTree(0), Temp.getOnlyTree(), std::move(InstImpResults), 3559edd7eaddSDimitry Andric CurPattern->getValueAsInt("AddedComplexity"), CurPattern->getID())); 3560f22ef01cSRoman Divacky } 3561f22ef01cSRoman Divacky } 3562f22ef01cSRoman Divacky 3563f22ef01cSRoman Divacky /// CombineChildVariants - Given a bunch of permutations of each child of the 3564f22ef01cSRoman Divacky /// 'operator' node, put them together in all possible ways. 3565f22ef01cSRoman Divacky static void CombineChildVariants(TreePatternNode *Orig, 3566f22ef01cSRoman Divacky const std::vector<std::vector<TreePatternNode*> > &ChildVariants, 3567f22ef01cSRoman Divacky std::vector<TreePatternNode*> &OutVariants, 3568f22ef01cSRoman Divacky CodeGenDAGPatterns &CDP, 3569f22ef01cSRoman Divacky const MultipleUseVarSet &DepVars) { 3570f22ef01cSRoman Divacky // Make sure that each operand has at least one variant to choose from. 35717d523365SDimitry Andric for (const auto &Variants : ChildVariants) 35727d523365SDimitry Andric if (Variants.empty()) 3573f22ef01cSRoman Divacky return; 3574f22ef01cSRoman Divacky 3575f22ef01cSRoman Divacky // The end result is an all-pairs construction of the resultant pattern. 3576f22ef01cSRoman Divacky std::vector<unsigned> Idxs; 3577f22ef01cSRoman Divacky Idxs.resize(ChildVariants.size()); 3578f22ef01cSRoman Divacky bool NotDone; 3579f22ef01cSRoman Divacky do { 3580f22ef01cSRoman Divacky #ifndef NDEBUG 3581f22ef01cSRoman Divacky DEBUG(if (!Idxs.empty()) { 3582f22ef01cSRoman Divacky errs() << Orig->getOperator()->getName() << ": Idxs = [ "; 35837d523365SDimitry Andric for (unsigned Idx : Idxs) { 35847d523365SDimitry Andric errs() << Idx << " "; 3585f22ef01cSRoman Divacky } 3586f22ef01cSRoman Divacky errs() << "]\n"; 3587f22ef01cSRoman Divacky }); 3588f22ef01cSRoman Divacky #endif 3589f22ef01cSRoman Divacky // Create the variant and add it to the output list. 3590f22ef01cSRoman Divacky std::vector<TreePatternNode*> NewChildren; 3591f22ef01cSRoman Divacky for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i) 3592f22ef01cSRoman Divacky NewChildren.push_back(ChildVariants[i][Idxs[i]]); 35937d523365SDimitry Andric auto R = llvm::make_unique<TreePatternNode>( 35947d523365SDimitry Andric Orig->getOperator(), NewChildren, Orig->getNumTypes()); 3595f22ef01cSRoman Divacky 3596f22ef01cSRoman Divacky // Copy over properties. 3597f22ef01cSRoman Divacky R->setName(Orig->getName()); 3598f22ef01cSRoman Divacky R->setPredicateFns(Orig->getPredicateFns()); 3599f22ef01cSRoman Divacky R->setTransformFn(Orig->getTransformFn()); 3600f22ef01cSRoman Divacky for (unsigned i = 0, e = Orig->getNumTypes(); i != e; ++i) 3601f22ef01cSRoman Divacky R->setType(i, Orig->getExtType(i)); 3602f22ef01cSRoman Divacky 3603f22ef01cSRoman Divacky // If this pattern cannot match, do not include it as a variant. 3604f22ef01cSRoman Divacky std::string ErrString; 3605f22ef01cSRoman Divacky // Scan to see if this pattern has already been emitted. We can get 3606f22ef01cSRoman Divacky // duplication due to things like commuting: 3607f22ef01cSRoman Divacky // (and GPRC:$a, GPRC:$b) -> (and GPRC:$b, GPRC:$a) 3608f22ef01cSRoman Divacky // which are the same pattern. Ignore the dups. 36097d523365SDimitry Andric if (R->canPatternMatch(ErrString, CDP) && 3610d88c1a5aSDimitry Andric none_of(OutVariants, [&](TreePatternNode *Variant) { 36117d523365SDimitry Andric return R->isIsomorphicTo(Variant, DepVars); 36127d523365SDimitry Andric })) 36137d523365SDimitry Andric OutVariants.push_back(R.release()); 3614f22ef01cSRoman Divacky 3615f22ef01cSRoman Divacky // Increment indices to the next permutation by incrementing the 36167d523365SDimitry Andric // indices from last index backward, e.g., generate the sequence 3617f22ef01cSRoman Divacky // [0, 0], [0, 1], [1, 0], [1, 1]. 3618f22ef01cSRoman Divacky int IdxsIdx; 3619f22ef01cSRoman Divacky for (IdxsIdx = Idxs.size() - 1; IdxsIdx >= 0; --IdxsIdx) { 3620f22ef01cSRoman Divacky if (++Idxs[IdxsIdx] == ChildVariants[IdxsIdx].size()) 3621f22ef01cSRoman Divacky Idxs[IdxsIdx] = 0; 3622f22ef01cSRoman Divacky else 3623f22ef01cSRoman Divacky break; 3624f22ef01cSRoman Divacky } 3625f22ef01cSRoman Divacky NotDone = (IdxsIdx >= 0); 3626f22ef01cSRoman Divacky } while (NotDone); 3627f22ef01cSRoman Divacky } 3628f22ef01cSRoman Divacky 3629f22ef01cSRoman Divacky /// CombineChildVariants - A helper function for binary operators. 3630f22ef01cSRoman Divacky /// 3631f22ef01cSRoman Divacky static void CombineChildVariants(TreePatternNode *Orig, 3632f22ef01cSRoman Divacky const std::vector<TreePatternNode*> &LHS, 3633f22ef01cSRoman Divacky const std::vector<TreePatternNode*> &RHS, 3634f22ef01cSRoman Divacky std::vector<TreePatternNode*> &OutVariants, 3635f22ef01cSRoman Divacky CodeGenDAGPatterns &CDP, 3636f22ef01cSRoman Divacky const MultipleUseVarSet &DepVars) { 3637f22ef01cSRoman Divacky std::vector<std::vector<TreePatternNode*> > ChildVariants; 3638f22ef01cSRoman Divacky ChildVariants.push_back(LHS); 3639f22ef01cSRoman Divacky ChildVariants.push_back(RHS); 3640f22ef01cSRoman Divacky CombineChildVariants(Orig, ChildVariants, OutVariants, CDP, DepVars); 3641f22ef01cSRoman Divacky } 3642f22ef01cSRoman Divacky 3643f22ef01cSRoman Divacky 3644f22ef01cSRoman Divacky static void GatherChildrenOfAssociativeOpcode(TreePatternNode *N, 3645f22ef01cSRoman Divacky std::vector<TreePatternNode *> &Children) { 3646f22ef01cSRoman Divacky assert(N->getNumChildren()==2 &&"Associative but doesn't have 2 children!"); 3647f22ef01cSRoman Divacky Record *Operator = N->getOperator(); 3648f22ef01cSRoman Divacky 3649f22ef01cSRoman Divacky // Only permit raw nodes. 3650f22ef01cSRoman Divacky if (!N->getName().empty() || !N->getPredicateFns().empty() || 3651f22ef01cSRoman Divacky N->getTransformFn()) { 3652f22ef01cSRoman Divacky Children.push_back(N); 3653f22ef01cSRoman Divacky return; 3654f22ef01cSRoman Divacky } 3655f22ef01cSRoman Divacky 3656f22ef01cSRoman Divacky if (N->getChild(0)->isLeaf() || N->getChild(0)->getOperator() != Operator) 3657f22ef01cSRoman Divacky Children.push_back(N->getChild(0)); 3658f22ef01cSRoman Divacky else 3659f22ef01cSRoman Divacky GatherChildrenOfAssociativeOpcode(N->getChild(0), Children); 3660f22ef01cSRoman Divacky 3661f22ef01cSRoman Divacky if (N->getChild(1)->isLeaf() || N->getChild(1)->getOperator() != Operator) 3662f22ef01cSRoman Divacky Children.push_back(N->getChild(1)); 3663f22ef01cSRoman Divacky else 3664f22ef01cSRoman Divacky GatherChildrenOfAssociativeOpcode(N->getChild(1), Children); 3665f22ef01cSRoman Divacky } 3666f22ef01cSRoman Divacky 3667f22ef01cSRoman Divacky /// GenerateVariantsOf - Given a pattern N, generate all permutations we can of 3668f22ef01cSRoman Divacky /// the (potentially recursive) pattern by using algebraic laws. 3669f22ef01cSRoman Divacky /// 3670f22ef01cSRoman Divacky static void GenerateVariantsOf(TreePatternNode *N, 3671f22ef01cSRoman Divacky std::vector<TreePatternNode*> &OutVariants, 3672f22ef01cSRoman Divacky CodeGenDAGPatterns &CDP, 3673f22ef01cSRoman Divacky const MultipleUseVarSet &DepVars) { 367491bc56edSDimitry Andric // We cannot permute leaves or ComplexPattern uses. 367591bc56edSDimitry Andric if (N->isLeaf() || N->getOperator()->isSubClassOf("ComplexPattern")) { 3676f22ef01cSRoman Divacky OutVariants.push_back(N); 3677f22ef01cSRoman Divacky return; 3678f22ef01cSRoman Divacky } 3679f22ef01cSRoman Divacky 3680f22ef01cSRoman Divacky // Look up interesting info about the node. 3681f22ef01cSRoman Divacky const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(N->getOperator()); 3682f22ef01cSRoman Divacky 3683f22ef01cSRoman Divacky // If this node is associative, re-associate. 3684f22ef01cSRoman Divacky if (NodeInfo.hasProperty(SDNPAssociative)) { 3685f22ef01cSRoman Divacky // Re-associate by pulling together all of the linked operators 3686f22ef01cSRoman Divacky std::vector<TreePatternNode*> MaximalChildren; 3687f22ef01cSRoman Divacky GatherChildrenOfAssociativeOpcode(N, MaximalChildren); 3688f22ef01cSRoman Divacky 3689f22ef01cSRoman Divacky // Only handle child sizes of 3. Otherwise we'll end up trying too many 3690f22ef01cSRoman Divacky // permutations. 3691f22ef01cSRoman Divacky if (MaximalChildren.size() == 3) { 3692f22ef01cSRoman Divacky // Find the variants of all of our maximal children. 3693f22ef01cSRoman Divacky std::vector<TreePatternNode*> AVariants, BVariants, CVariants; 3694f22ef01cSRoman Divacky GenerateVariantsOf(MaximalChildren[0], AVariants, CDP, DepVars); 3695f22ef01cSRoman Divacky GenerateVariantsOf(MaximalChildren[1], BVariants, CDP, DepVars); 3696f22ef01cSRoman Divacky GenerateVariantsOf(MaximalChildren[2], CVariants, CDP, DepVars); 3697f22ef01cSRoman Divacky 3698f22ef01cSRoman Divacky // There are only two ways we can permute the tree: 3699f22ef01cSRoman Divacky // (A op B) op C and A op (B op C) 3700f22ef01cSRoman Divacky // Within these forms, we can also permute A/B/C. 3701f22ef01cSRoman Divacky 3702f22ef01cSRoman Divacky // Generate legal pair permutations of A/B/C. 3703f22ef01cSRoman Divacky std::vector<TreePatternNode*> ABVariants; 3704f22ef01cSRoman Divacky std::vector<TreePatternNode*> BAVariants; 3705f22ef01cSRoman Divacky std::vector<TreePatternNode*> ACVariants; 3706f22ef01cSRoman Divacky std::vector<TreePatternNode*> CAVariants; 3707f22ef01cSRoman Divacky std::vector<TreePatternNode*> BCVariants; 3708f22ef01cSRoman Divacky std::vector<TreePatternNode*> CBVariants; 3709f22ef01cSRoman Divacky CombineChildVariants(N, AVariants, BVariants, ABVariants, CDP, DepVars); 3710f22ef01cSRoman Divacky CombineChildVariants(N, BVariants, AVariants, BAVariants, CDP, DepVars); 3711f22ef01cSRoman Divacky CombineChildVariants(N, AVariants, CVariants, ACVariants, CDP, DepVars); 3712f22ef01cSRoman Divacky CombineChildVariants(N, CVariants, AVariants, CAVariants, CDP, DepVars); 3713f22ef01cSRoman Divacky CombineChildVariants(N, BVariants, CVariants, BCVariants, CDP, DepVars); 3714f22ef01cSRoman Divacky CombineChildVariants(N, CVariants, BVariants, CBVariants, CDP, DepVars); 3715f22ef01cSRoman Divacky 3716f22ef01cSRoman Divacky // Combine those into the result: (x op x) op x 3717f22ef01cSRoman Divacky CombineChildVariants(N, ABVariants, CVariants, OutVariants, CDP, DepVars); 3718f22ef01cSRoman Divacky CombineChildVariants(N, BAVariants, CVariants, OutVariants, CDP, DepVars); 3719f22ef01cSRoman Divacky CombineChildVariants(N, ACVariants, BVariants, OutVariants, CDP, DepVars); 3720f22ef01cSRoman Divacky CombineChildVariants(N, CAVariants, BVariants, OutVariants, CDP, DepVars); 3721f22ef01cSRoman Divacky CombineChildVariants(N, BCVariants, AVariants, OutVariants, CDP, DepVars); 3722f22ef01cSRoman Divacky CombineChildVariants(N, CBVariants, AVariants, OutVariants, CDP, DepVars); 3723f22ef01cSRoman Divacky 3724f22ef01cSRoman Divacky // Combine those into the result: x op (x op x) 3725f22ef01cSRoman Divacky CombineChildVariants(N, CVariants, ABVariants, OutVariants, CDP, DepVars); 3726f22ef01cSRoman Divacky CombineChildVariants(N, CVariants, BAVariants, OutVariants, CDP, DepVars); 3727f22ef01cSRoman Divacky CombineChildVariants(N, BVariants, ACVariants, OutVariants, CDP, DepVars); 3728f22ef01cSRoman Divacky CombineChildVariants(N, BVariants, CAVariants, OutVariants, CDP, DepVars); 3729f22ef01cSRoman Divacky CombineChildVariants(N, AVariants, BCVariants, OutVariants, CDP, DepVars); 3730f22ef01cSRoman Divacky CombineChildVariants(N, AVariants, CBVariants, OutVariants, CDP, DepVars); 3731f22ef01cSRoman Divacky return; 3732f22ef01cSRoman Divacky } 3733f22ef01cSRoman Divacky } 3734f22ef01cSRoman Divacky 3735f22ef01cSRoman Divacky // Compute permutations of all children. 3736f22ef01cSRoman Divacky std::vector<std::vector<TreePatternNode*> > ChildVariants; 3737f22ef01cSRoman Divacky ChildVariants.resize(N->getNumChildren()); 3738f22ef01cSRoman Divacky for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) 3739f22ef01cSRoman Divacky GenerateVariantsOf(N->getChild(i), ChildVariants[i], CDP, DepVars); 3740f22ef01cSRoman Divacky 3741f22ef01cSRoman Divacky // Build all permutations based on how the children were formed. 3742f22ef01cSRoman Divacky CombineChildVariants(N, ChildVariants, OutVariants, CDP, DepVars); 3743f22ef01cSRoman Divacky 3744f22ef01cSRoman Divacky // If this node is commutative, consider the commuted order. 3745f22ef01cSRoman Divacky bool isCommIntrinsic = N->isCommutativeIntrinsic(CDP); 3746f22ef01cSRoman Divacky if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) { 3747f22ef01cSRoman Divacky assert((N->getNumChildren()==2 || isCommIntrinsic) && 3748f22ef01cSRoman Divacky "Commutative but doesn't have 2 children!"); 3749f22ef01cSRoman Divacky // Don't count children which are actually register references. 3750f22ef01cSRoman Divacky unsigned NC = 0; 3751f22ef01cSRoman Divacky for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { 3752f22ef01cSRoman Divacky TreePatternNode *Child = N->getChild(i); 3753f22ef01cSRoman Divacky if (Child->isLeaf()) 37543861d79fSDimitry Andric if (DefInit *DI = dyn_cast<DefInit>(Child->getLeafValue())) { 3755f22ef01cSRoman Divacky Record *RR = DI->getDef(); 3756f22ef01cSRoman Divacky if (RR->isSubClassOf("Register")) 3757f22ef01cSRoman Divacky continue; 3758f22ef01cSRoman Divacky } 3759f22ef01cSRoman Divacky NC++; 3760f22ef01cSRoman Divacky } 3761f22ef01cSRoman Divacky // Consider the commuted order. 3762f22ef01cSRoman Divacky if (isCommIntrinsic) { 3763f22ef01cSRoman Divacky // Commutative intrinsic. First operand is the intrinsic id, 2nd and 3rd 3764f22ef01cSRoman Divacky // operands are the commutative operands, and there might be more operands 3765f22ef01cSRoman Divacky // after those. 3766f22ef01cSRoman Divacky assert(NC >= 3 && 37677d523365SDimitry Andric "Commutative intrinsic should have at least 3 children!"); 3768f22ef01cSRoman Divacky std::vector<std::vector<TreePatternNode*> > Variants; 3769f22ef01cSRoman Divacky Variants.push_back(ChildVariants[0]); // Intrinsic id. 3770f22ef01cSRoman Divacky Variants.push_back(ChildVariants[2]); 3771f22ef01cSRoman Divacky Variants.push_back(ChildVariants[1]); 3772f22ef01cSRoman Divacky for (unsigned i = 3; i != NC; ++i) 3773f22ef01cSRoman Divacky Variants.push_back(ChildVariants[i]); 3774f22ef01cSRoman Divacky CombineChildVariants(N, Variants, OutVariants, CDP, DepVars); 3775f22ef01cSRoman Divacky } else if (NC == 2) 3776f22ef01cSRoman Divacky CombineChildVariants(N, ChildVariants[1], ChildVariants[0], 3777f22ef01cSRoman Divacky OutVariants, CDP, DepVars); 3778f22ef01cSRoman Divacky } 3779f22ef01cSRoman Divacky } 3780f22ef01cSRoman Divacky 3781f22ef01cSRoman Divacky 3782f22ef01cSRoman Divacky // GenerateVariants - Generate variants. For example, commutative patterns can 3783f22ef01cSRoman Divacky // match multiple ways. Add them to PatternsToMatch as well. 3784f22ef01cSRoman Divacky void CodeGenDAGPatterns::GenerateVariants() { 3785f22ef01cSRoman Divacky DEBUG(errs() << "Generating instruction variants.\n"); 3786f22ef01cSRoman Divacky 3787f22ef01cSRoman Divacky // Loop over all of the patterns we've collected, checking to see if we can 3788f22ef01cSRoman Divacky // generate variants of the instruction, through the exploitation of 3789f22ef01cSRoman Divacky // identities. This permits the target to provide aggressive matching without 3790f22ef01cSRoman Divacky // the .td file having to contain tons of variants of instructions. 3791f22ef01cSRoman Divacky // 3792f22ef01cSRoman Divacky // Note that this loop adds new patterns to the PatternsToMatch list, but we 3793f22ef01cSRoman Divacky // intentionally do not reconsider these. Any variants of added patterns have 3794f22ef01cSRoman Divacky // already been added. 3795f22ef01cSRoman Divacky // 3796f22ef01cSRoman Divacky for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { 3797f22ef01cSRoman Divacky MultipleUseVarSet DepVars; 3798f22ef01cSRoman Divacky std::vector<TreePatternNode*> Variants; 3799f22ef01cSRoman Divacky FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars); 3800f22ef01cSRoman Divacky DEBUG(errs() << "Dependent/multiply used variables: "); 3801f22ef01cSRoman Divacky DEBUG(DumpDepVars(DepVars)); 3802f22ef01cSRoman Divacky DEBUG(errs() << "\n"); 38032754fe60SDimitry Andric GenerateVariantsOf(PatternsToMatch[i].getSrcPattern(), Variants, *this, 38042754fe60SDimitry Andric DepVars); 3805f22ef01cSRoman Divacky 3806f22ef01cSRoman Divacky assert(!Variants.empty() && "Must create at least original variant!"); 380724d58133SDimitry Andric if (Variants.size() == 1) // No additional variants for this pattern. 3808f22ef01cSRoman Divacky continue; 3809f22ef01cSRoman Divacky 3810f22ef01cSRoman Divacky DEBUG(errs() << "FOUND VARIANTS OF: "; 3811f22ef01cSRoman Divacky PatternsToMatch[i].getSrcPattern()->dump(); 3812f22ef01cSRoman Divacky errs() << "\n"); 3813f22ef01cSRoman Divacky 3814f22ef01cSRoman Divacky for (unsigned v = 0, e = Variants.size(); v != e; ++v) { 3815f22ef01cSRoman Divacky TreePatternNode *Variant = Variants[v]; 3816f22ef01cSRoman Divacky 3817f22ef01cSRoman Divacky DEBUG(errs() << " VAR#" << v << ": "; 3818f22ef01cSRoman Divacky Variant->dump(); 3819f22ef01cSRoman Divacky errs() << "\n"); 3820f22ef01cSRoman Divacky 3821f22ef01cSRoman Divacky // Scan to see if an instruction or explicit pattern already matches this. 3822f22ef01cSRoman Divacky bool AlreadyExists = false; 3823f22ef01cSRoman Divacky for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) { 3824f22ef01cSRoman Divacky // Skip if the top level predicates do not match. 3825f22ef01cSRoman Divacky if (PatternsToMatch[i].getPredicates() != 3826f22ef01cSRoman Divacky PatternsToMatch[p].getPredicates()) 3827f22ef01cSRoman Divacky continue; 3828f22ef01cSRoman Divacky // Check to see if this variant already exists. 38292754fe60SDimitry Andric if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern(), 38302754fe60SDimitry Andric DepVars)) { 3831f22ef01cSRoman Divacky DEBUG(errs() << " *** ALREADY EXISTS, ignoring variant.\n"); 3832f22ef01cSRoman Divacky AlreadyExists = true; 3833f22ef01cSRoman Divacky break; 3834f22ef01cSRoman Divacky } 3835f22ef01cSRoman Divacky } 3836f22ef01cSRoman Divacky // If we already have it, ignore the variant. 3837f22ef01cSRoman Divacky if (AlreadyExists) continue; 3838f22ef01cSRoman Divacky 3839f22ef01cSRoman Divacky // Otherwise, add it to the list of patterns we have. 384097bc6c73SDimitry Andric PatternsToMatch.emplace_back( 384197bc6c73SDimitry Andric PatternsToMatch[i].getSrcRecord(), PatternsToMatch[i].getPredicates(), 3842f22ef01cSRoman Divacky Variant, PatternsToMatch[i].getDstPattern(), 3843f22ef01cSRoman Divacky PatternsToMatch[i].getDstRegs(), 384497bc6c73SDimitry Andric PatternsToMatch[i].getAddedComplexity(), Record::getNewUID()); 3845f22ef01cSRoman Divacky } 3846f22ef01cSRoman Divacky 3847f22ef01cSRoman Divacky DEBUG(errs() << "\n"); 3848f22ef01cSRoman Divacky } 3849f22ef01cSRoman Divacky } 3850