xref: /netbsd-src/external/apache2/llvm/dist/llvm/utils/TableGen/CodeGenDAGPatterns.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg //===- CodeGenDAGPatterns.cpp - Read DAG patterns from .td file -----------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements the CodeGenDAGPatterns class, which is used to read and
107330f729Sjoerg // represent the patterns present in a .td file for instructions.
117330f729Sjoerg //
127330f729Sjoerg //===----------------------------------------------------------------------===//
137330f729Sjoerg 
147330f729Sjoerg #include "CodeGenDAGPatterns.h"
157330f729Sjoerg #include "llvm/ADT/DenseSet.h"
167330f729Sjoerg #include "llvm/ADT/MapVector.h"
177330f729Sjoerg #include "llvm/ADT/STLExtras.h"
187330f729Sjoerg #include "llvm/ADT/SmallSet.h"
197330f729Sjoerg #include "llvm/ADT/SmallString.h"
207330f729Sjoerg #include "llvm/ADT/StringExtras.h"
217330f729Sjoerg #include "llvm/ADT/StringMap.h"
227330f729Sjoerg #include "llvm/ADT/Twine.h"
237330f729Sjoerg #include "llvm/Support/Debug.h"
247330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
25*82d56013Sjoerg #include "llvm/Support/TypeSize.h"
267330f729Sjoerg #include "llvm/TableGen/Error.h"
277330f729Sjoerg #include "llvm/TableGen/Record.h"
287330f729Sjoerg #include <algorithm>
297330f729Sjoerg #include <cstdio>
307330f729Sjoerg #include <iterator>
317330f729Sjoerg #include <set>
327330f729Sjoerg using namespace llvm;
337330f729Sjoerg 
347330f729Sjoerg #define DEBUG_TYPE "dag-patterns"
357330f729Sjoerg 
isIntegerOrPtr(MVT VT)367330f729Sjoerg static inline bool isIntegerOrPtr(MVT VT) {
377330f729Sjoerg   return VT.isInteger() || VT == MVT::iPTR;
387330f729Sjoerg }
isFloatingPoint(MVT VT)397330f729Sjoerg static inline bool isFloatingPoint(MVT VT) {
407330f729Sjoerg   return VT.isFloatingPoint();
417330f729Sjoerg }
isVector(MVT VT)427330f729Sjoerg static inline bool isVector(MVT VT) {
437330f729Sjoerg   return VT.isVector();
447330f729Sjoerg }
isScalar(MVT VT)457330f729Sjoerg static inline bool isScalar(MVT VT) {
467330f729Sjoerg   return !VT.isVector();
477330f729Sjoerg }
487330f729Sjoerg 
497330f729Sjoerg template <typename Predicate>
berase_if(MachineValueTypeSet & S,Predicate P)507330f729Sjoerg static bool berase_if(MachineValueTypeSet &S, Predicate P) {
517330f729Sjoerg   bool Erased = false;
527330f729Sjoerg   // It is ok to iterate over MachineValueTypeSet and remove elements from it
537330f729Sjoerg   // at the same time.
547330f729Sjoerg   for (MVT T : S) {
557330f729Sjoerg     if (!P(T))
567330f729Sjoerg       continue;
577330f729Sjoerg     Erased = true;
587330f729Sjoerg     S.erase(T);
597330f729Sjoerg   }
607330f729Sjoerg   return Erased;
617330f729Sjoerg }
627330f729Sjoerg 
637330f729Sjoerg // --- TypeSetByHwMode
647330f729Sjoerg 
657330f729Sjoerg // This is a parameterized type-set class. For each mode there is a list
667330f729Sjoerg // of types that are currently possible for a given tree node. Type
677330f729Sjoerg // inference will apply to each mode separately.
687330f729Sjoerg 
TypeSetByHwMode(ArrayRef<ValueTypeByHwMode> VTList)697330f729Sjoerg TypeSetByHwMode::TypeSetByHwMode(ArrayRef<ValueTypeByHwMode> VTList) {
707330f729Sjoerg   for (const ValueTypeByHwMode &VVT : VTList) {
717330f729Sjoerg     insert(VVT);
727330f729Sjoerg     AddrSpaces.push_back(VVT.PtrAddrSpace);
737330f729Sjoerg   }
747330f729Sjoerg }
757330f729Sjoerg 
isValueTypeByHwMode(bool AllowEmpty) const767330f729Sjoerg bool TypeSetByHwMode::isValueTypeByHwMode(bool AllowEmpty) const {
777330f729Sjoerg   for (const auto &I : *this) {
787330f729Sjoerg     if (I.second.size() > 1)
797330f729Sjoerg       return false;
807330f729Sjoerg     if (!AllowEmpty && I.second.empty())
817330f729Sjoerg       return false;
827330f729Sjoerg   }
837330f729Sjoerg   return true;
847330f729Sjoerg }
857330f729Sjoerg 
getValueTypeByHwMode() const867330f729Sjoerg ValueTypeByHwMode TypeSetByHwMode::getValueTypeByHwMode() const {
877330f729Sjoerg   assert(isValueTypeByHwMode(true) &&
887330f729Sjoerg          "The type set has multiple types for at least one HW mode");
897330f729Sjoerg   ValueTypeByHwMode VVT;
907330f729Sjoerg   auto ASI = AddrSpaces.begin();
917330f729Sjoerg 
927330f729Sjoerg   for (const auto &I : *this) {
937330f729Sjoerg     MVT T = I.second.empty() ? MVT::Other : *I.second.begin();
947330f729Sjoerg     VVT.getOrCreateTypeForMode(I.first, T);
957330f729Sjoerg     if (ASI != AddrSpaces.end())
967330f729Sjoerg       VVT.PtrAddrSpace = *ASI++;
977330f729Sjoerg   }
987330f729Sjoerg   return VVT;
997330f729Sjoerg }
1007330f729Sjoerg 
isPossible() const1017330f729Sjoerg bool TypeSetByHwMode::isPossible() const {
1027330f729Sjoerg   for (const auto &I : *this)
1037330f729Sjoerg     if (!I.second.empty())
1047330f729Sjoerg       return true;
1057330f729Sjoerg   return false;
1067330f729Sjoerg }
1077330f729Sjoerg 
insert(const ValueTypeByHwMode & VVT)1087330f729Sjoerg bool TypeSetByHwMode::insert(const ValueTypeByHwMode &VVT) {
1097330f729Sjoerg   bool Changed = false;
1107330f729Sjoerg   bool ContainsDefault = false;
1117330f729Sjoerg   MVT DT = MVT::Other;
1127330f729Sjoerg 
1137330f729Sjoerg   for (const auto &P : VVT) {
1147330f729Sjoerg     unsigned M = P.first;
1157330f729Sjoerg     // Make sure there exists a set for each specific mode from VVT.
1167330f729Sjoerg     Changed |= getOrCreate(M).insert(P.second).second;
1177330f729Sjoerg     // Cache VVT's default mode.
1187330f729Sjoerg     if (DefaultMode == M) {
1197330f729Sjoerg       ContainsDefault = true;
1207330f729Sjoerg       DT = P.second;
1217330f729Sjoerg     }
1227330f729Sjoerg   }
1237330f729Sjoerg 
1247330f729Sjoerg   // If VVT has a default mode, add the corresponding type to all
1257330f729Sjoerg   // modes in "this" that do not exist in VVT.
1267330f729Sjoerg   if (ContainsDefault)
1277330f729Sjoerg     for (auto &I : *this)
128*82d56013Sjoerg       if (!VVT.hasMode(I.first))
1297330f729Sjoerg         Changed |= I.second.insert(DT).second;
1307330f729Sjoerg 
1317330f729Sjoerg   return Changed;
1327330f729Sjoerg }
1337330f729Sjoerg 
1347330f729Sjoerg // Constrain the type set to be the intersection with VTS.
constrain(const TypeSetByHwMode & VTS)1357330f729Sjoerg bool TypeSetByHwMode::constrain(const TypeSetByHwMode &VTS) {
1367330f729Sjoerg   bool Changed = false;
1377330f729Sjoerg   if (hasDefault()) {
1387330f729Sjoerg     for (const auto &I : VTS) {
1397330f729Sjoerg       unsigned M = I.first;
1407330f729Sjoerg       if (M == DefaultMode || hasMode(M))
1417330f729Sjoerg         continue;
1427330f729Sjoerg       Map.insert({M, Map.at(DefaultMode)});
1437330f729Sjoerg       Changed = true;
1447330f729Sjoerg     }
1457330f729Sjoerg   }
1467330f729Sjoerg 
1477330f729Sjoerg   for (auto &I : *this) {
1487330f729Sjoerg     unsigned M = I.first;
1497330f729Sjoerg     SetType &S = I.second;
1507330f729Sjoerg     if (VTS.hasMode(M) || VTS.hasDefault()) {
1517330f729Sjoerg       Changed |= intersect(I.second, VTS.get(M));
1527330f729Sjoerg     } else if (!S.empty()) {
1537330f729Sjoerg       S.clear();
1547330f729Sjoerg       Changed = true;
1557330f729Sjoerg     }
1567330f729Sjoerg   }
1577330f729Sjoerg   return Changed;
1587330f729Sjoerg }
1597330f729Sjoerg 
1607330f729Sjoerg template <typename Predicate>
constrain(Predicate P)1617330f729Sjoerg bool TypeSetByHwMode::constrain(Predicate P) {
1627330f729Sjoerg   bool Changed = false;
1637330f729Sjoerg   for (auto &I : *this)
1647330f729Sjoerg     Changed |= berase_if(I.second, [&P](MVT VT) { return !P(VT); });
1657330f729Sjoerg   return Changed;
1667330f729Sjoerg }
1677330f729Sjoerg 
1687330f729Sjoerg template <typename Predicate>
assign_if(const TypeSetByHwMode & VTS,Predicate P)1697330f729Sjoerg bool TypeSetByHwMode::assign_if(const TypeSetByHwMode &VTS, Predicate P) {
1707330f729Sjoerg   assert(empty());
1717330f729Sjoerg   for (const auto &I : VTS) {
1727330f729Sjoerg     SetType &S = getOrCreate(I.first);
1737330f729Sjoerg     for (auto J : I.second)
1747330f729Sjoerg       if (P(J))
1757330f729Sjoerg         S.insert(J);
1767330f729Sjoerg   }
1777330f729Sjoerg   return !empty();
1787330f729Sjoerg }
1797330f729Sjoerg 
writeToStream(raw_ostream & OS) const1807330f729Sjoerg void TypeSetByHwMode::writeToStream(raw_ostream &OS) const {
1817330f729Sjoerg   SmallVector<unsigned, 4> Modes;
1827330f729Sjoerg   Modes.reserve(Map.size());
1837330f729Sjoerg 
1847330f729Sjoerg   for (const auto &I : *this)
1857330f729Sjoerg     Modes.push_back(I.first);
1867330f729Sjoerg   if (Modes.empty()) {
1877330f729Sjoerg     OS << "{}";
1887330f729Sjoerg     return;
1897330f729Sjoerg   }
1907330f729Sjoerg   array_pod_sort(Modes.begin(), Modes.end());
1917330f729Sjoerg 
1927330f729Sjoerg   OS << '{';
1937330f729Sjoerg   for (unsigned M : Modes) {
1947330f729Sjoerg     OS << ' ' << getModeName(M) << ':';
1957330f729Sjoerg     writeToStream(get(M), OS);
1967330f729Sjoerg   }
1977330f729Sjoerg   OS << " }";
1987330f729Sjoerg }
1997330f729Sjoerg 
writeToStream(const SetType & S,raw_ostream & OS)2007330f729Sjoerg void TypeSetByHwMode::writeToStream(const SetType &S, raw_ostream &OS) {
2017330f729Sjoerg   SmallVector<MVT, 4> Types(S.begin(), S.end());
2027330f729Sjoerg   array_pod_sort(Types.begin(), Types.end());
2037330f729Sjoerg 
2047330f729Sjoerg   OS << '[';
205*82d56013Sjoerg   ListSeparator LS(" ");
206*82d56013Sjoerg   for (const MVT &T : Types)
207*82d56013Sjoerg     OS << LS << ValueTypeByHwMode::getMVTName(T);
2087330f729Sjoerg   OS << ']';
2097330f729Sjoerg }
2107330f729Sjoerg 
operator ==(const TypeSetByHwMode & VTS) const2117330f729Sjoerg bool TypeSetByHwMode::operator==(const TypeSetByHwMode &VTS) const {
2127330f729Sjoerg   // The isSimple call is much quicker than hasDefault - check this first.
2137330f729Sjoerg   bool IsSimple = isSimple();
2147330f729Sjoerg   bool VTSIsSimple = VTS.isSimple();
2157330f729Sjoerg   if (IsSimple && VTSIsSimple)
2167330f729Sjoerg     return *begin() == *VTS.begin();
2177330f729Sjoerg 
2187330f729Sjoerg   // Speedup: We have a default if the set is simple.
2197330f729Sjoerg   bool HaveDefault = IsSimple || hasDefault();
2207330f729Sjoerg   bool VTSHaveDefault = VTSIsSimple || VTS.hasDefault();
2217330f729Sjoerg   if (HaveDefault != VTSHaveDefault)
2227330f729Sjoerg     return false;
2237330f729Sjoerg 
224*82d56013Sjoerg   SmallSet<unsigned, 4> Modes;
2257330f729Sjoerg   for (auto &I : *this)
2267330f729Sjoerg     Modes.insert(I.first);
2277330f729Sjoerg   for (const auto &I : VTS)
2287330f729Sjoerg     Modes.insert(I.first);
2297330f729Sjoerg 
2307330f729Sjoerg   if (HaveDefault) {
2317330f729Sjoerg     // Both sets have default mode.
2327330f729Sjoerg     for (unsigned M : Modes) {
2337330f729Sjoerg       if (get(M) != VTS.get(M))
2347330f729Sjoerg         return false;
2357330f729Sjoerg     }
2367330f729Sjoerg   } else {
2377330f729Sjoerg     // Neither set has default mode.
2387330f729Sjoerg     for (unsigned M : Modes) {
2397330f729Sjoerg       // If there is no default mode, an empty set is equivalent to not having
2407330f729Sjoerg       // the corresponding mode.
2417330f729Sjoerg       bool NoModeThis = !hasMode(M) || get(M).empty();
2427330f729Sjoerg       bool NoModeVTS = !VTS.hasMode(M) || VTS.get(M).empty();
2437330f729Sjoerg       if (NoModeThis != NoModeVTS)
2447330f729Sjoerg         return false;
2457330f729Sjoerg       if (!NoModeThis)
2467330f729Sjoerg         if (get(M) != VTS.get(M))
2477330f729Sjoerg           return false;
2487330f729Sjoerg     }
2497330f729Sjoerg   }
2507330f729Sjoerg 
2517330f729Sjoerg   return true;
2527330f729Sjoerg }
2537330f729Sjoerg 
2547330f729Sjoerg namespace llvm {
operator <<(raw_ostream & OS,const TypeSetByHwMode & T)2557330f729Sjoerg   raw_ostream &operator<<(raw_ostream &OS, const TypeSetByHwMode &T) {
2567330f729Sjoerg     T.writeToStream(OS);
2577330f729Sjoerg     return OS;
2587330f729Sjoerg   }
2597330f729Sjoerg }
2607330f729Sjoerg 
2617330f729Sjoerg LLVM_DUMP_METHOD
dump() const2627330f729Sjoerg void TypeSetByHwMode::dump() const {
2637330f729Sjoerg   dbgs() << *this << '\n';
2647330f729Sjoerg }
2657330f729Sjoerg 
intersect(SetType & Out,const SetType & In)2667330f729Sjoerg bool TypeSetByHwMode::intersect(SetType &Out, const SetType &In) {
2677330f729Sjoerg   bool OutP = Out.count(MVT::iPTR), InP = In.count(MVT::iPTR);
2687330f729Sjoerg   auto Int = [&In](MVT T) -> bool { return !In.count(T); };
2697330f729Sjoerg 
2707330f729Sjoerg   if (OutP == InP)
2717330f729Sjoerg     return berase_if(Out, Int);
2727330f729Sjoerg 
2737330f729Sjoerg   // Compute the intersection of scalars separately to account for only
2747330f729Sjoerg   // one set containing iPTR.
275*82d56013Sjoerg   // The intersection of iPTR with a set of integer scalar types that does not
2767330f729Sjoerg   // include iPTR will result in the most specific scalar type:
2777330f729Sjoerg   // - iPTR is more specific than any set with two elements or more
2787330f729Sjoerg   // - iPTR is less specific than any single integer scalar type.
2797330f729Sjoerg   // For example
2807330f729Sjoerg   // { iPTR } * { i32 }     -> { i32 }
2817330f729Sjoerg   // { iPTR } * { i32 i64 } -> { iPTR }
2827330f729Sjoerg   // and
2837330f729Sjoerg   // { iPTR i32 } * { i32 }          -> { i32 }
2847330f729Sjoerg   // { iPTR i32 } * { i32 i64 }      -> { i32 i64 }
2857330f729Sjoerg   // { iPTR i32 } * { i32 i64 i128 } -> { iPTR i32 }
2867330f729Sjoerg 
2877330f729Sjoerg   // Compute the difference between the two sets in such a way that the
2887330f729Sjoerg   // iPTR is in the set that is being subtracted. This is to see if there
2897330f729Sjoerg   // are any extra scalars in the set without iPTR that are not in the
2907330f729Sjoerg   // set containing iPTR. Then the iPTR could be considered a "wildcard"
2917330f729Sjoerg   // matching these scalars. If there is only one such scalar, it would
2927330f729Sjoerg   // replace the iPTR, if there are more, the iPTR would be retained.
2937330f729Sjoerg   SetType Diff;
2947330f729Sjoerg   if (InP) {
2957330f729Sjoerg     Diff = Out;
2967330f729Sjoerg     berase_if(Diff, [&In](MVT T) { return In.count(T); });
2977330f729Sjoerg     // Pre-remove these elements and rely only on InP/OutP to determine
2987330f729Sjoerg     // whether a change has been made.
2997330f729Sjoerg     berase_if(Out, [&Diff](MVT T) { return Diff.count(T); });
3007330f729Sjoerg   } else {
3017330f729Sjoerg     Diff = In;
3027330f729Sjoerg     berase_if(Diff, [&Out](MVT T) { return Out.count(T); });
3037330f729Sjoerg     Out.erase(MVT::iPTR);
3047330f729Sjoerg   }
3057330f729Sjoerg 
3067330f729Sjoerg   // The actual intersection.
3077330f729Sjoerg   bool Changed = berase_if(Out, Int);
3087330f729Sjoerg   unsigned NumD = Diff.size();
3097330f729Sjoerg   if (NumD == 0)
3107330f729Sjoerg     return Changed;
3117330f729Sjoerg 
3127330f729Sjoerg   if (NumD == 1) {
3137330f729Sjoerg     Out.insert(*Diff.begin());
3147330f729Sjoerg     // This is a change only if Out was the one with iPTR (which is now
3157330f729Sjoerg     // being replaced).
3167330f729Sjoerg     Changed |= OutP;
3177330f729Sjoerg   } else {
3187330f729Sjoerg     // Multiple elements from Out are now replaced with iPTR.
3197330f729Sjoerg     Out.insert(MVT::iPTR);
3207330f729Sjoerg     Changed |= !OutP;
3217330f729Sjoerg   }
3227330f729Sjoerg   return Changed;
3237330f729Sjoerg }
3247330f729Sjoerg 
validate() const3257330f729Sjoerg bool TypeSetByHwMode::validate() const {
3267330f729Sjoerg #ifndef NDEBUG
3277330f729Sjoerg   if (empty())
3287330f729Sjoerg     return true;
3297330f729Sjoerg   bool AllEmpty = true;
3307330f729Sjoerg   for (const auto &I : *this)
3317330f729Sjoerg     AllEmpty &= I.second.empty();
3327330f729Sjoerg   return !AllEmpty;
3337330f729Sjoerg #endif
3347330f729Sjoerg   return true;
3357330f729Sjoerg }
3367330f729Sjoerg 
3377330f729Sjoerg // --- TypeInfer
3387330f729Sjoerg 
MergeInTypeInfo(TypeSetByHwMode & Out,const TypeSetByHwMode & In)3397330f729Sjoerg bool TypeInfer::MergeInTypeInfo(TypeSetByHwMode &Out,
3407330f729Sjoerg                                 const TypeSetByHwMode &In) {
3417330f729Sjoerg   ValidateOnExit _1(Out, *this);
3427330f729Sjoerg   In.validate();
3437330f729Sjoerg   if (In.empty() || Out == In || TP.hasError())
3447330f729Sjoerg     return false;
3457330f729Sjoerg   if (Out.empty()) {
3467330f729Sjoerg     Out = In;
3477330f729Sjoerg     return true;
3487330f729Sjoerg   }
3497330f729Sjoerg 
3507330f729Sjoerg   bool Changed = Out.constrain(In);
3517330f729Sjoerg   if (Changed && Out.empty())
3527330f729Sjoerg     TP.error("Type contradiction");
3537330f729Sjoerg 
3547330f729Sjoerg   return Changed;
3557330f729Sjoerg }
3567330f729Sjoerg 
forceArbitrary(TypeSetByHwMode & Out)3577330f729Sjoerg bool TypeInfer::forceArbitrary(TypeSetByHwMode &Out) {
3587330f729Sjoerg   ValidateOnExit _1(Out, *this);
3597330f729Sjoerg   if (TP.hasError())
3607330f729Sjoerg     return false;
3617330f729Sjoerg   assert(!Out.empty() && "cannot pick from an empty set");
3627330f729Sjoerg 
3637330f729Sjoerg   bool Changed = false;
3647330f729Sjoerg   for (auto &I : Out) {
3657330f729Sjoerg     TypeSetByHwMode::SetType &S = I.second;
3667330f729Sjoerg     if (S.size() <= 1)
3677330f729Sjoerg       continue;
3687330f729Sjoerg     MVT T = *S.begin(); // Pick the first element.
3697330f729Sjoerg     S.clear();
3707330f729Sjoerg     S.insert(T);
3717330f729Sjoerg     Changed = true;
3727330f729Sjoerg   }
3737330f729Sjoerg   return Changed;
3747330f729Sjoerg }
3757330f729Sjoerg 
EnforceInteger(TypeSetByHwMode & Out)3767330f729Sjoerg bool TypeInfer::EnforceInteger(TypeSetByHwMode &Out) {
3777330f729Sjoerg   ValidateOnExit _1(Out, *this);
3787330f729Sjoerg   if (TP.hasError())
3797330f729Sjoerg     return false;
3807330f729Sjoerg   if (!Out.empty())
3817330f729Sjoerg     return Out.constrain(isIntegerOrPtr);
3827330f729Sjoerg 
3837330f729Sjoerg   return Out.assign_if(getLegalTypes(), isIntegerOrPtr);
3847330f729Sjoerg }
3857330f729Sjoerg 
EnforceFloatingPoint(TypeSetByHwMode & Out)3867330f729Sjoerg bool TypeInfer::EnforceFloatingPoint(TypeSetByHwMode &Out) {
3877330f729Sjoerg   ValidateOnExit _1(Out, *this);
3887330f729Sjoerg   if (TP.hasError())
3897330f729Sjoerg     return false;
3907330f729Sjoerg   if (!Out.empty())
3917330f729Sjoerg     return Out.constrain(isFloatingPoint);
3927330f729Sjoerg 
3937330f729Sjoerg   return Out.assign_if(getLegalTypes(), isFloatingPoint);
3947330f729Sjoerg }
3957330f729Sjoerg 
EnforceScalar(TypeSetByHwMode & Out)3967330f729Sjoerg bool TypeInfer::EnforceScalar(TypeSetByHwMode &Out) {
3977330f729Sjoerg   ValidateOnExit _1(Out, *this);
3987330f729Sjoerg   if (TP.hasError())
3997330f729Sjoerg     return false;
4007330f729Sjoerg   if (!Out.empty())
4017330f729Sjoerg     return Out.constrain(isScalar);
4027330f729Sjoerg 
4037330f729Sjoerg   return Out.assign_if(getLegalTypes(), isScalar);
4047330f729Sjoerg }
4057330f729Sjoerg 
EnforceVector(TypeSetByHwMode & Out)4067330f729Sjoerg bool TypeInfer::EnforceVector(TypeSetByHwMode &Out) {
4077330f729Sjoerg   ValidateOnExit _1(Out, *this);
4087330f729Sjoerg   if (TP.hasError())
4097330f729Sjoerg     return false;
4107330f729Sjoerg   if (!Out.empty())
4117330f729Sjoerg     return Out.constrain(isVector);
4127330f729Sjoerg 
4137330f729Sjoerg   return Out.assign_if(getLegalTypes(), isVector);
4147330f729Sjoerg }
4157330f729Sjoerg 
EnforceAny(TypeSetByHwMode & Out)4167330f729Sjoerg bool TypeInfer::EnforceAny(TypeSetByHwMode &Out) {
4177330f729Sjoerg   ValidateOnExit _1(Out, *this);
4187330f729Sjoerg   if (TP.hasError() || !Out.empty())
4197330f729Sjoerg     return false;
4207330f729Sjoerg 
4217330f729Sjoerg   Out = getLegalTypes();
4227330f729Sjoerg   return true;
4237330f729Sjoerg }
4247330f729Sjoerg 
4257330f729Sjoerg template <typename Iter, typename Pred, typename Less>
min_if(Iter B,Iter E,Pred P,Less L)4267330f729Sjoerg static Iter min_if(Iter B, Iter E, Pred P, Less L) {
4277330f729Sjoerg   if (B == E)
4287330f729Sjoerg     return E;
4297330f729Sjoerg   Iter Min = E;
4307330f729Sjoerg   for (Iter I = B; I != E; ++I) {
4317330f729Sjoerg     if (!P(*I))
4327330f729Sjoerg       continue;
4337330f729Sjoerg     if (Min == E || L(*I, *Min))
4347330f729Sjoerg       Min = I;
4357330f729Sjoerg   }
4367330f729Sjoerg   return Min;
4377330f729Sjoerg }
4387330f729Sjoerg 
4397330f729Sjoerg template <typename Iter, typename Pred, typename Less>
max_if(Iter B,Iter E,Pred P,Less L)4407330f729Sjoerg static Iter max_if(Iter B, Iter E, Pred P, Less L) {
4417330f729Sjoerg   if (B == E)
4427330f729Sjoerg     return E;
4437330f729Sjoerg   Iter Max = E;
4447330f729Sjoerg   for (Iter I = B; I != E; ++I) {
4457330f729Sjoerg     if (!P(*I))
4467330f729Sjoerg       continue;
4477330f729Sjoerg     if (Max == E || L(*Max, *I))
4487330f729Sjoerg       Max = I;
4497330f729Sjoerg   }
4507330f729Sjoerg   return Max;
4517330f729Sjoerg }
4527330f729Sjoerg 
4537330f729Sjoerg /// Make sure that for each type in Small, there exists a larger type in Big.
EnforceSmallerThan(TypeSetByHwMode & Small,TypeSetByHwMode & Big)4547330f729Sjoerg bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small,
4557330f729Sjoerg                                    TypeSetByHwMode &Big) {
4567330f729Sjoerg   ValidateOnExit _1(Small, *this), _2(Big, *this);
4577330f729Sjoerg   if (TP.hasError())
4587330f729Sjoerg     return false;
4597330f729Sjoerg   bool Changed = false;
4607330f729Sjoerg 
4617330f729Sjoerg   if (Small.empty())
4627330f729Sjoerg     Changed |= EnforceAny(Small);
4637330f729Sjoerg   if (Big.empty())
4647330f729Sjoerg     Changed |= EnforceAny(Big);
4657330f729Sjoerg 
4667330f729Sjoerg   assert(Small.hasDefault() && Big.hasDefault());
4677330f729Sjoerg 
468*82d56013Sjoerg   SmallVector<unsigned, 4> Modes;
469*82d56013Sjoerg   union_modes(Small, Big, Modes);
4707330f729Sjoerg 
4717330f729Sjoerg   // 1. Only allow integer or floating point types and make sure that
4727330f729Sjoerg   //    both sides are both integer or both floating point.
4737330f729Sjoerg   // 2. Make sure that either both sides have vector types, or neither
4747330f729Sjoerg   //    of them does.
4757330f729Sjoerg   for (unsigned M : Modes) {
4767330f729Sjoerg     TypeSetByHwMode::SetType &S = Small.get(M);
4777330f729Sjoerg     TypeSetByHwMode::SetType &B = Big.get(M);
4787330f729Sjoerg 
4797330f729Sjoerg     if (any_of(S, isIntegerOrPtr) && any_of(S, isIntegerOrPtr)) {
4807330f729Sjoerg       auto NotInt = [](MVT VT) { return !isIntegerOrPtr(VT); };
481*82d56013Sjoerg       Changed |= berase_if(S, NotInt);
482*82d56013Sjoerg       Changed |= berase_if(B, NotInt);
4837330f729Sjoerg     } else if (any_of(S, isFloatingPoint) && any_of(B, isFloatingPoint)) {
4847330f729Sjoerg       auto NotFP = [](MVT VT) { return !isFloatingPoint(VT); };
485*82d56013Sjoerg       Changed |= berase_if(S, NotFP);
486*82d56013Sjoerg       Changed |= berase_if(B, NotFP);
4877330f729Sjoerg     } else if (S.empty() || B.empty()) {
4887330f729Sjoerg       Changed = !S.empty() || !B.empty();
4897330f729Sjoerg       S.clear();
4907330f729Sjoerg       B.clear();
4917330f729Sjoerg     } else {
4927330f729Sjoerg       TP.error("Incompatible types");
4937330f729Sjoerg       return Changed;
4947330f729Sjoerg     }
4957330f729Sjoerg 
4967330f729Sjoerg     if (none_of(S, isVector) || none_of(B, isVector)) {
497*82d56013Sjoerg       Changed |= berase_if(S, isVector);
498*82d56013Sjoerg       Changed |= berase_if(B, isVector);
4997330f729Sjoerg     }
5007330f729Sjoerg   }
5017330f729Sjoerg 
5027330f729Sjoerg   auto LT = [](MVT A, MVT B) -> bool {
503*82d56013Sjoerg     // Always treat non-scalable MVTs as smaller than scalable MVTs for the
504*82d56013Sjoerg     // purposes of ordering.
505*82d56013Sjoerg     auto ASize = std::make_tuple(A.isScalableVector(), A.getScalarSizeInBits(),
506*82d56013Sjoerg                                  A.getSizeInBits().getKnownMinSize());
507*82d56013Sjoerg     auto BSize = std::make_tuple(B.isScalableVector(), B.getScalarSizeInBits(),
508*82d56013Sjoerg                                  B.getSizeInBits().getKnownMinSize());
509*82d56013Sjoerg     return ASize < BSize;
5107330f729Sjoerg   };
511*82d56013Sjoerg   auto SameKindLE = [](MVT A, MVT B) -> bool {
5127330f729Sjoerg     // This function is used when removing elements: when a vector is compared
513*82d56013Sjoerg     // to a non-vector or a scalable vector to any non-scalable MVT, it should
514*82d56013Sjoerg     // return false (to avoid removal).
515*82d56013Sjoerg     if (std::make_tuple(A.isVector(), A.isScalableVector()) !=
516*82d56013Sjoerg         std::make_tuple(B.isVector(), B.isScalableVector()))
5177330f729Sjoerg       return false;
5187330f729Sjoerg 
519*82d56013Sjoerg     return std::make_tuple(A.getScalarSizeInBits(),
520*82d56013Sjoerg                            A.getSizeInBits().getKnownMinSize()) <=
521*82d56013Sjoerg            std::make_tuple(B.getScalarSizeInBits(),
522*82d56013Sjoerg                            B.getSizeInBits().getKnownMinSize());
5237330f729Sjoerg   };
5247330f729Sjoerg 
5257330f729Sjoerg   for (unsigned M : Modes) {
5267330f729Sjoerg     TypeSetByHwMode::SetType &S = Small.get(M);
5277330f729Sjoerg     TypeSetByHwMode::SetType &B = Big.get(M);
5287330f729Sjoerg     // MinS = min scalar in Small, remove all scalars from Big that are
5297330f729Sjoerg     // smaller-or-equal than MinS.
5307330f729Sjoerg     auto MinS = min_if(S.begin(), S.end(), isScalar, LT);
5317330f729Sjoerg     if (MinS != S.end())
532*82d56013Sjoerg       Changed |= berase_if(B, std::bind(SameKindLE,
533*82d56013Sjoerg                                         std::placeholders::_1, *MinS));
5347330f729Sjoerg 
5357330f729Sjoerg     // MaxS = max scalar in Big, remove all scalars from Small that are
5367330f729Sjoerg     // larger than MaxS.
5377330f729Sjoerg     auto MaxS = max_if(B.begin(), B.end(), isScalar, LT);
5387330f729Sjoerg     if (MaxS != B.end())
539*82d56013Sjoerg       Changed |= berase_if(S, std::bind(SameKindLE,
540*82d56013Sjoerg                                         *MaxS, std::placeholders::_1));
5417330f729Sjoerg 
5427330f729Sjoerg     // MinV = min vector in Small, remove all vectors from Big that are
5437330f729Sjoerg     // smaller-or-equal than MinV.
5447330f729Sjoerg     auto MinV = min_if(S.begin(), S.end(), isVector, LT);
5457330f729Sjoerg     if (MinV != S.end())
546*82d56013Sjoerg       Changed |= berase_if(B, std::bind(SameKindLE,
547*82d56013Sjoerg                                         std::placeholders::_1, *MinV));
5487330f729Sjoerg 
5497330f729Sjoerg     // MaxV = max vector in Big, remove all vectors from Small that are
5507330f729Sjoerg     // larger than MaxV.
5517330f729Sjoerg     auto MaxV = max_if(B.begin(), B.end(), isVector, LT);
5527330f729Sjoerg     if (MaxV != B.end())
553*82d56013Sjoerg       Changed |= berase_if(S, std::bind(SameKindLE,
554*82d56013Sjoerg                                         *MaxV, std::placeholders::_1));
5557330f729Sjoerg   }
5567330f729Sjoerg 
5577330f729Sjoerg   return Changed;
5587330f729Sjoerg }
5597330f729Sjoerg 
5607330f729Sjoerg /// 1. Ensure that for each type T in Vec, T is a vector type, and that
5617330f729Sjoerg ///    for each type U in Elem, U is a scalar type.
5627330f729Sjoerg /// 2. Ensure that for each (scalar) type U in Elem, there exists a (vector)
5637330f729Sjoerg ///    type T in Vec, such that U is the element type of T.
EnforceVectorEltTypeIs(TypeSetByHwMode & Vec,TypeSetByHwMode & Elem)5647330f729Sjoerg bool TypeInfer::EnforceVectorEltTypeIs(TypeSetByHwMode &Vec,
5657330f729Sjoerg                                        TypeSetByHwMode &Elem) {
5667330f729Sjoerg   ValidateOnExit _1(Vec, *this), _2(Elem, *this);
5677330f729Sjoerg   if (TP.hasError())
5687330f729Sjoerg     return false;
5697330f729Sjoerg   bool Changed = false;
5707330f729Sjoerg 
5717330f729Sjoerg   if (Vec.empty())
5727330f729Sjoerg     Changed |= EnforceVector(Vec);
5737330f729Sjoerg   if (Elem.empty())
5747330f729Sjoerg     Changed |= EnforceScalar(Elem);
5757330f729Sjoerg 
576*82d56013Sjoerg   SmallVector<unsigned, 4> Modes;
577*82d56013Sjoerg   union_modes(Vec, Elem, Modes);
578*82d56013Sjoerg   for (unsigned M : Modes) {
5797330f729Sjoerg     TypeSetByHwMode::SetType &V = Vec.get(M);
5807330f729Sjoerg     TypeSetByHwMode::SetType &E = Elem.get(M);
5817330f729Sjoerg 
5827330f729Sjoerg     Changed |= berase_if(V, isScalar);  // Scalar = !vector
5837330f729Sjoerg     Changed |= berase_if(E, isVector);  // Vector = !scalar
5847330f729Sjoerg     assert(!V.empty() && !E.empty());
5857330f729Sjoerg 
586*82d56013Sjoerg     MachineValueTypeSet VT, ST;
5877330f729Sjoerg     // Collect element types from the "vector" set.
5887330f729Sjoerg     for (MVT T : V)
5897330f729Sjoerg       VT.insert(T.getVectorElementType());
5907330f729Sjoerg     // Collect scalar types from the "element" set.
5917330f729Sjoerg     for (MVT T : E)
5927330f729Sjoerg       ST.insert(T);
5937330f729Sjoerg 
5947330f729Sjoerg     // Remove from V all (vector) types whose element type is not in S.
5957330f729Sjoerg     Changed |= berase_if(V, [&ST](MVT T) -> bool {
5967330f729Sjoerg                               return !ST.count(T.getVectorElementType());
5977330f729Sjoerg                             });
5987330f729Sjoerg     // Remove from E all (scalar) types, for which there is no corresponding
5997330f729Sjoerg     // type in V.
6007330f729Sjoerg     Changed |= berase_if(E, [&VT](MVT T) -> bool { return !VT.count(T); });
6017330f729Sjoerg   }
6027330f729Sjoerg 
6037330f729Sjoerg   return Changed;
6047330f729Sjoerg }
6057330f729Sjoerg 
EnforceVectorEltTypeIs(TypeSetByHwMode & Vec,const ValueTypeByHwMode & VVT)6067330f729Sjoerg bool TypeInfer::EnforceVectorEltTypeIs(TypeSetByHwMode &Vec,
6077330f729Sjoerg                                        const ValueTypeByHwMode &VVT) {
6087330f729Sjoerg   TypeSetByHwMode Tmp(VVT);
6097330f729Sjoerg   ValidateOnExit _1(Vec, *this), _2(Tmp, *this);
6107330f729Sjoerg   return EnforceVectorEltTypeIs(Vec, Tmp);
6117330f729Sjoerg }
6127330f729Sjoerg 
6137330f729Sjoerg /// Ensure that for each type T in Sub, T is a vector type, and there
6147330f729Sjoerg /// exists a type U in Vec such that U is a vector type with the same
6157330f729Sjoerg /// element type as T and at least as many elements as T.
EnforceVectorSubVectorTypeIs(TypeSetByHwMode & Vec,TypeSetByHwMode & Sub)6167330f729Sjoerg bool TypeInfer::EnforceVectorSubVectorTypeIs(TypeSetByHwMode &Vec,
6177330f729Sjoerg                                              TypeSetByHwMode &Sub) {
6187330f729Sjoerg   ValidateOnExit _1(Vec, *this), _2(Sub, *this);
6197330f729Sjoerg   if (TP.hasError())
6207330f729Sjoerg     return false;
6217330f729Sjoerg 
6227330f729Sjoerg   /// Return true if B is a suB-vector of P, i.e. P is a suPer-vector of B.
6237330f729Sjoerg   auto IsSubVec = [](MVT B, MVT P) -> bool {
6247330f729Sjoerg     if (!B.isVector() || !P.isVector())
6257330f729Sjoerg       return false;
6267330f729Sjoerg     // Logically a <4 x i32> is a valid subvector of <n x 4 x i32>
6277330f729Sjoerg     // but until there are obvious use-cases for this, keep the
6287330f729Sjoerg     // types separate.
6297330f729Sjoerg     if (B.isScalableVector() != P.isScalableVector())
6307330f729Sjoerg       return false;
6317330f729Sjoerg     if (B.getVectorElementType() != P.getVectorElementType())
6327330f729Sjoerg       return false;
633*82d56013Sjoerg     return B.getVectorMinNumElements() < P.getVectorMinNumElements();
6347330f729Sjoerg   };
6357330f729Sjoerg 
6367330f729Sjoerg   /// Return true if S has no element (vector type) that T is a sub-vector of,
6377330f729Sjoerg   /// i.e. has the same element type as T and more elements.
6387330f729Sjoerg   auto NoSubV = [&IsSubVec](const TypeSetByHwMode::SetType &S, MVT T) -> bool {
639*82d56013Sjoerg     for (auto I : S)
6407330f729Sjoerg       if (IsSubVec(T, I))
6417330f729Sjoerg         return false;
6427330f729Sjoerg     return true;
6437330f729Sjoerg   };
6447330f729Sjoerg 
6457330f729Sjoerg   /// Return true if S has no element (vector type) that T is a super-vector
6467330f729Sjoerg   /// of, i.e. has the same element type as T and fewer elements.
6477330f729Sjoerg   auto NoSupV = [&IsSubVec](const TypeSetByHwMode::SetType &S, MVT T) -> bool {
648*82d56013Sjoerg     for (auto I : S)
6497330f729Sjoerg       if (IsSubVec(I, T))
6507330f729Sjoerg         return false;
6517330f729Sjoerg     return true;
6527330f729Sjoerg   };
6537330f729Sjoerg 
6547330f729Sjoerg   bool Changed = false;
6557330f729Sjoerg 
6567330f729Sjoerg   if (Vec.empty())
6577330f729Sjoerg     Changed |= EnforceVector(Vec);
6587330f729Sjoerg   if (Sub.empty())
6597330f729Sjoerg     Changed |= EnforceVector(Sub);
6607330f729Sjoerg 
661*82d56013Sjoerg   SmallVector<unsigned, 4> Modes;
662*82d56013Sjoerg   union_modes(Vec, Sub, Modes);
663*82d56013Sjoerg   for (unsigned M : Modes) {
6647330f729Sjoerg     TypeSetByHwMode::SetType &S = Sub.get(M);
6657330f729Sjoerg     TypeSetByHwMode::SetType &V = Vec.get(M);
6667330f729Sjoerg 
6677330f729Sjoerg     Changed |= berase_if(S, isScalar);
6687330f729Sjoerg 
6697330f729Sjoerg     // Erase all types from S that are not sub-vectors of a type in V.
6707330f729Sjoerg     Changed |= berase_if(S, std::bind(NoSubV, V, std::placeholders::_1));
6717330f729Sjoerg 
6727330f729Sjoerg     // Erase all types from V that are not super-vectors of a type in S.
6737330f729Sjoerg     Changed |= berase_if(V, std::bind(NoSupV, S, std::placeholders::_1));
6747330f729Sjoerg   }
6757330f729Sjoerg 
6767330f729Sjoerg   return Changed;
6777330f729Sjoerg }
6787330f729Sjoerg 
6797330f729Sjoerg /// 1. Ensure that V has a scalar type iff W has a scalar type.
6807330f729Sjoerg /// 2. Ensure that for each vector type T in V, there exists a vector
6817330f729Sjoerg ///    type U in W, such that T and U have the same number of elements.
6827330f729Sjoerg /// 3. Ensure that for each vector type U in W, there exists a vector
6837330f729Sjoerg ///    type T in V, such that T and U have the same number of elements
6847330f729Sjoerg ///    (reverse of 2).
EnforceSameNumElts(TypeSetByHwMode & V,TypeSetByHwMode & W)6857330f729Sjoerg bool TypeInfer::EnforceSameNumElts(TypeSetByHwMode &V, TypeSetByHwMode &W) {
6867330f729Sjoerg   ValidateOnExit _1(V, *this), _2(W, *this);
6877330f729Sjoerg   if (TP.hasError())
6887330f729Sjoerg     return false;
6897330f729Sjoerg 
6907330f729Sjoerg   bool Changed = false;
6917330f729Sjoerg   if (V.empty())
6927330f729Sjoerg     Changed |= EnforceAny(V);
6937330f729Sjoerg   if (W.empty())
6947330f729Sjoerg     Changed |= EnforceAny(W);
6957330f729Sjoerg 
6967330f729Sjoerg   // An actual vector type cannot have 0 elements, so we can treat scalars
6977330f729Sjoerg   // as zero-length vectors. This way both vectors and scalars can be
6987330f729Sjoerg   // processed identically.
699*82d56013Sjoerg   auto NoLength = [](const SmallDenseSet<ElementCount> &Lengths,
700*82d56013Sjoerg                      MVT T) -> bool {
701*82d56013Sjoerg     return !Lengths.count(T.isVector() ? T.getVectorElementCount()
702*82d56013Sjoerg                                        : ElementCount::getNull());
7037330f729Sjoerg   };
7047330f729Sjoerg 
705*82d56013Sjoerg   SmallVector<unsigned, 4> Modes;
706*82d56013Sjoerg   union_modes(V, W, Modes);
707*82d56013Sjoerg   for (unsigned M : Modes) {
7087330f729Sjoerg     TypeSetByHwMode::SetType &VS = V.get(M);
7097330f729Sjoerg     TypeSetByHwMode::SetType &WS = W.get(M);
7107330f729Sjoerg 
711*82d56013Sjoerg     SmallDenseSet<ElementCount> VN, WN;
7127330f729Sjoerg     for (MVT T : VS)
713*82d56013Sjoerg       VN.insert(T.isVector() ? T.getVectorElementCount()
714*82d56013Sjoerg                              : ElementCount::getNull());
7157330f729Sjoerg     for (MVT T : WS)
716*82d56013Sjoerg       WN.insert(T.isVector() ? T.getVectorElementCount()
717*82d56013Sjoerg                              : ElementCount::getNull());
7187330f729Sjoerg 
7197330f729Sjoerg     Changed |= berase_if(VS, std::bind(NoLength, WN, std::placeholders::_1));
7207330f729Sjoerg     Changed |= berase_if(WS, std::bind(NoLength, VN, std::placeholders::_1));
7217330f729Sjoerg   }
7227330f729Sjoerg   return Changed;
7237330f729Sjoerg }
7247330f729Sjoerg 
725*82d56013Sjoerg namespace {
726*82d56013Sjoerg struct TypeSizeComparator {
operator ()__anon539a54781011::TypeSizeComparator727*82d56013Sjoerg   bool operator()(const TypeSize &LHS, const TypeSize &RHS) const {
728*82d56013Sjoerg     return std::make_tuple(LHS.isScalable(), LHS.getKnownMinValue()) <
729*82d56013Sjoerg            std::make_tuple(RHS.isScalable(), RHS.getKnownMinValue());
730*82d56013Sjoerg   }
731*82d56013Sjoerg };
732*82d56013Sjoerg } // end anonymous namespace
733*82d56013Sjoerg 
7347330f729Sjoerg /// 1. Ensure that for each type T in A, there exists a type U in B,
7357330f729Sjoerg ///    such that T and U have equal size in bits.
7367330f729Sjoerg /// 2. Ensure that for each type U in B, there exists a type T in A
7377330f729Sjoerg ///    such that T and U have equal size in bits (reverse of 1).
EnforceSameSize(TypeSetByHwMode & A,TypeSetByHwMode & B)7387330f729Sjoerg bool TypeInfer::EnforceSameSize(TypeSetByHwMode &A, TypeSetByHwMode &B) {
7397330f729Sjoerg   ValidateOnExit _1(A, *this), _2(B, *this);
7407330f729Sjoerg   if (TP.hasError())
7417330f729Sjoerg     return false;
7427330f729Sjoerg   bool Changed = false;
7437330f729Sjoerg   if (A.empty())
7447330f729Sjoerg     Changed |= EnforceAny(A);
7457330f729Sjoerg   if (B.empty())
7467330f729Sjoerg     Changed |= EnforceAny(B);
7477330f729Sjoerg 
748*82d56013Sjoerg   typedef SmallSet<TypeSize, 2, TypeSizeComparator> TypeSizeSet;
749*82d56013Sjoerg 
750*82d56013Sjoerg   auto NoSize = [](const TypeSizeSet &Sizes, MVT T) -> bool {
7517330f729Sjoerg     return !Sizes.count(T.getSizeInBits());
7527330f729Sjoerg   };
7537330f729Sjoerg 
754*82d56013Sjoerg   SmallVector<unsigned, 4> Modes;
755*82d56013Sjoerg   union_modes(A, B, Modes);
756*82d56013Sjoerg   for (unsigned M : Modes) {
7577330f729Sjoerg     TypeSetByHwMode::SetType &AS = A.get(M);
7587330f729Sjoerg     TypeSetByHwMode::SetType &BS = B.get(M);
759*82d56013Sjoerg     TypeSizeSet AN, BN;
7607330f729Sjoerg 
7617330f729Sjoerg     for (MVT T : AS)
7627330f729Sjoerg       AN.insert(T.getSizeInBits());
7637330f729Sjoerg     for (MVT T : BS)
7647330f729Sjoerg       BN.insert(T.getSizeInBits());
7657330f729Sjoerg 
7667330f729Sjoerg     Changed |= berase_if(AS, std::bind(NoSize, BN, std::placeholders::_1));
7677330f729Sjoerg     Changed |= berase_if(BS, std::bind(NoSize, AN, std::placeholders::_1));
7687330f729Sjoerg   }
7697330f729Sjoerg 
7707330f729Sjoerg   return Changed;
7717330f729Sjoerg }
7727330f729Sjoerg 
expandOverloads(TypeSetByHwMode & VTS)7737330f729Sjoerg void TypeInfer::expandOverloads(TypeSetByHwMode &VTS) {
7747330f729Sjoerg   ValidateOnExit _1(VTS, *this);
7757330f729Sjoerg   const TypeSetByHwMode &Legal = getLegalTypes();
7767330f729Sjoerg   assert(Legal.isDefaultOnly() && "Default-mode only expected");
7777330f729Sjoerg   const TypeSetByHwMode::SetType &LegalTypes = Legal.get(DefaultMode);
7787330f729Sjoerg 
7797330f729Sjoerg   for (auto &I : VTS)
7807330f729Sjoerg     expandOverloads(I.second, LegalTypes);
7817330f729Sjoerg }
7827330f729Sjoerg 
expandOverloads(TypeSetByHwMode::SetType & Out,const TypeSetByHwMode::SetType & Legal)7837330f729Sjoerg void TypeInfer::expandOverloads(TypeSetByHwMode::SetType &Out,
7847330f729Sjoerg                                 const TypeSetByHwMode::SetType &Legal) {
7857330f729Sjoerg   std::set<MVT> Ovs;
7867330f729Sjoerg   for (MVT T : Out) {
7877330f729Sjoerg     if (!T.isOverloaded())
7887330f729Sjoerg       continue;
7897330f729Sjoerg 
7907330f729Sjoerg     Ovs.insert(T);
7917330f729Sjoerg     // MachineValueTypeSet allows iteration and erasing.
7927330f729Sjoerg     Out.erase(T);
7937330f729Sjoerg   }
7947330f729Sjoerg 
7957330f729Sjoerg   for (MVT Ov : Ovs) {
7967330f729Sjoerg     switch (Ov.SimpleTy) {
7977330f729Sjoerg       case MVT::iPTRAny:
7987330f729Sjoerg         Out.insert(MVT::iPTR);
7997330f729Sjoerg         return;
8007330f729Sjoerg       case MVT::iAny:
8017330f729Sjoerg         for (MVT T : MVT::integer_valuetypes())
8027330f729Sjoerg           if (Legal.count(T))
8037330f729Sjoerg             Out.insert(T);
8047330f729Sjoerg         for (MVT T : MVT::integer_fixedlen_vector_valuetypes())
8057330f729Sjoerg           if (Legal.count(T))
8067330f729Sjoerg             Out.insert(T);
8077330f729Sjoerg         for (MVT T : MVT::integer_scalable_vector_valuetypes())
8087330f729Sjoerg           if (Legal.count(T))
8097330f729Sjoerg             Out.insert(T);
8107330f729Sjoerg         return;
8117330f729Sjoerg       case MVT::fAny:
8127330f729Sjoerg         for (MVT T : MVT::fp_valuetypes())
8137330f729Sjoerg           if (Legal.count(T))
8147330f729Sjoerg             Out.insert(T);
8157330f729Sjoerg         for (MVT T : MVT::fp_fixedlen_vector_valuetypes())
8167330f729Sjoerg           if (Legal.count(T))
8177330f729Sjoerg             Out.insert(T);
8187330f729Sjoerg         for (MVT T : MVT::fp_scalable_vector_valuetypes())
8197330f729Sjoerg           if (Legal.count(T))
8207330f729Sjoerg             Out.insert(T);
8217330f729Sjoerg         return;
8227330f729Sjoerg       case MVT::vAny:
8237330f729Sjoerg         for (MVT T : MVT::vector_valuetypes())
8247330f729Sjoerg           if (Legal.count(T))
8257330f729Sjoerg             Out.insert(T);
8267330f729Sjoerg         return;
8277330f729Sjoerg       case MVT::Any:
8287330f729Sjoerg         for (MVT T : MVT::all_valuetypes())
8297330f729Sjoerg           if (Legal.count(T))
8307330f729Sjoerg             Out.insert(T);
8317330f729Sjoerg         return;
8327330f729Sjoerg       default:
8337330f729Sjoerg         break;
8347330f729Sjoerg     }
8357330f729Sjoerg   }
8367330f729Sjoerg }
8377330f729Sjoerg 
getLegalTypes()8387330f729Sjoerg const TypeSetByHwMode &TypeInfer::getLegalTypes() {
8397330f729Sjoerg   if (!LegalTypesCached) {
8407330f729Sjoerg     TypeSetByHwMode::SetType &LegalTypes = LegalCache.getOrCreate(DefaultMode);
8417330f729Sjoerg     // Stuff all types from all modes into the default mode.
8427330f729Sjoerg     const TypeSetByHwMode &LTS = TP.getDAGPatterns().getLegalTypes();
8437330f729Sjoerg     for (const auto &I : LTS)
8447330f729Sjoerg       LegalTypes.insert(I.second);
8457330f729Sjoerg     LegalTypesCached = true;
8467330f729Sjoerg   }
8477330f729Sjoerg   assert(LegalCache.isDefaultOnly() && "Default-mode only expected");
8487330f729Sjoerg   return LegalCache;
8497330f729Sjoerg }
8507330f729Sjoerg 
8517330f729Sjoerg #ifndef NDEBUG
~ValidateOnExit()8527330f729Sjoerg TypeInfer::ValidateOnExit::~ValidateOnExit() {
8537330f729Sjoerg   if (Infer.Validate && !VTS.validate()) {
8547330f729Sjoerg     dbgs() << "Type set is empty for each HW mode:\n"
8557330f729Sjoerg               "possible type contradiction in the pattern below "
8567330f729Sjoerg               "(use -print-records with llvm-tblgen to see all "
8577330f729Sjoerg               "expanded records).\n";
8587330f729Sjoerg     Infer.TP.dump();
859*82d56013Sjoerg     dbgs() << "Generated from record:\n";
860*82d56013Sjoerg     Infer.TP.getRecord()->dump();
861*82d56013Sjoerg     PrintFatalError(Infer.TP.getRecord()->getLoc(),
862*82d56013Sjoerg                     "Type set is empty for each HW mode in '" +
863*82d56013Sjoerg                         Infer.TP.getRecord()->getName() + "'");
8647330f729Sjoerg   }
8657330f729Sjoerg }
8667330f729Sjoerg #endif
8677330f729Sjoerg 
8687330f729Sjoerg 
8697330f729Sjoerg //===----------------------------------------------------------------------===//
8707330f729Sjoerg // ScopedName Implementation
8717330f729Sjoerg //===----------------------------------------------------------------------===//
8727330f729Sjoerg 
operator ==(const ScopedName & o) const8737330f729Sjoerg bool ScopedName::operator==(const ScopedName &o) const {
8747330f729Sjoerg   return Scope == o.Scope && Identifier == o.Identifier;
8757330f729Sjoerg }
8767330f729Sjoerg 
operator !=(const ScopedName & o) const8777330f729Sjoerg bool ScopedName::operator!=(const ScopedName &o) const {
8787330f729Sjoerg   return !(*this == o);
8797330f729Sjoerg }
8807330f729Sjoerg 
8817330f729Sjoerg 
8827330f729Sjoerg //===----------------------------------------------------------------------===//
8837330f729Sjoerg // TreePredicateFn Implementation
8847330f729Sjoerg //===----------------------------------------------------------------------===//
8857330f729Sjoerg 
8867330f729Sjoerg /// TreePredicateFn constructor.  Here 'N' is a subclass of PatFrag.
TreePredicateFn(TreePattern * N)8877330f729Sjoerg TreePredicateFn::TreePredicateFn(TreePattern *N) : PatFragRec(N) {
8887330f729Sjoerg   assert(
8897330f729Sjoerg       (!hasPredCode() || !hasImmCode()) &&
8907330f729Sjoerg       ".td file corrupt: can't have a node predicate *and* an imm predicate");
8917330f729Sjoerg }
8927330f729Sjoerg 
hasPredCode() const8937330f729Sjoerg bool TreePredicateFn::hasPredCode() const {
8947330f729Sjoerg   return isLoad() || isStore() || isAtomic() ||
8957330f729Sjoerg          !PatFragRec->getRecord()->getValueAsString("PredicateCode").empty();
8967330f729Sjoerg }
8977330f729Sjoerg 
getPredCode() const8987330f729Sjoerg std::string TreePredicateFn::getPredCode() const {
899*82d56013Sjoerg   std::string Code;
9007330f729Sjoerg 
9017330f729Sjoerg   if (!isLoad() && !isStore() && !isAtomic()) {
9027330f729Sjoerg     Record *MemoryVT = getMemoryVT();
9037330f729Sjoerg 
9047330f729Sjoerg     if (MemoryVT)
9057330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9067330f729Sjoerg                       "MemoryVT requires IsLoad or IsStore");
9077330f729Sjoerg   }
9087330f729Sjoerg 
9097330f729Sjoerg   if (!isLoad() && !isStore()) {
9107330f729Sjoerg     if (isUnindexed())
9117330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9127330f729Sjoerg                       "IsUnindexed requires IsLoad or IsStore");
9137330f729Sjoerg 
9147330f729Sjoerg     Record *ScalarMemoryVT = getScalarMemoryVT();
9157330f729Sjoerg 
9167330f729Sjoerg     if (ScalarMemoryVT)
9177330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9187330f729Sjoerg                       "ScalarMemoryVT requires IsLoad or IsStore");
9197330f729Sjoerg   }
9207330f729Sjoerg 
9217330f729Sjoerg   if (isLoad() + isStore() + isAtomic() > 1)
9227330f729Sjoerg     PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9237330f729Sjoerg                     "IsLoad, IsStore, and IsAtomic are mutually exclusive");
9247330f729Sjoerg 
9257330f729Sjoerg   if (isLoad()) {
9267330f729Sjoerg     if (!isUnindexed() && !isNonExtLoad() && !isAnyExtLoad() &&
9277330f729Sjoerg         !isSignExtLoad() && !isZeroExtLoad() && getMemoryVT() == nullptr &&
9287330f729Sjoerg         getScalarMemoryVT() == nullptr && getAddressSpaces() == nullptr &&
9297330f729Sjoerg         getMinAlignment() < 1)
9307330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9317330f729Sjoerg                       "IsLoad cannot be used by itself");
9327330f729Sjoerg   } else {
9337330f729Sjoerg     if (isNonExtLoad())
9347330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9357330f729Sjoerg                       "IsNonExtLoad requires IsLoad");
9367330f729Sjoerg     if (isAnyExtLoad())
9377330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9387330f729Sjoerg                       "IsAnyExtLoad requires IsLoad");
9397330f729Sjoerg     if (isSignExtLoad())
9407330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9417330f729Sjoerg                       "IsSignExtLoad requires IsLoad");
9427330f729Sjoerg     if (isZeroExtLoad())
9437330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9447330f729Sjoerg                       "IsZeroExtLoad requires IsLoad");
9457330f729Sjoerg   }
9467330f729Sjoerg 
9477330f729Sjoerg   if (isStore()) {
9487330f729Sjoerg     if (!isUnindexed() && !isTruncStore() && !isNonTruncStore() &&
9497330f729Sjoerg         getMemoryVT() == nullptr && getScalarMemoryVT() == nullptr &&
9507330f729Sjoerg         getAddressSpaces() == nullptr && getMinAlignment() < 1)
9517330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9527330f729Sjoerg                       "IsStore cannot be used by itself");
9537330f729Sjoerg   } else {
9547330f729Sjoerg     if (isNonTruncStore())
9557330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9567330f729Sjoerg                       "IsNonTruncStore requires IsStore");
9577330f729Sjoerg     if (isTruncStore())
9587330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9597330f729Sjoerg                       "IsTruncStore requires IsStore");
9607330f729Sjoerg   }
9617330f729Sjoerg 
9627330f729Sjoerg   if (isAtomic()) {
9637330f729Sjoerg     if (getMemoryVT() == nullptr && !isAtomicOrderingMonotonic() &&
9647330f729Sjoerg         getAddressSpaces() == nullptr &&
9657330f729Sjoerg         !isAtomicOrderingAcquire() && !isAtomicOrderingRelease() &&
9667330f729Sjoerg         !isAtomicOrderingAcquireRelease() &&
9677330f729Sjoerg         !isAtomicOrderingSequentiallyConsistent() &&
9687330f729Sjoerg         !isAtomicOrderingAcquireOrStronger() &&
9697330f729Sjoerg         !isAtomicOrderingReleaseOrStronger() &&
9707330f729Sjoerg         !isAtomicOrderingWeakerThanAcquire() &&
9717330f729Sjoerg         !isAtomicOrderingWeakerThanRelease())
9727330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9737330f729Sjoerg                       "IsAtomic cannot be used by itself");
9747330f729Sjoerg   } else {
9757330f729Sjoerg     if (isAtomicOrderingMonotonic())
9767330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9777330f729Sjoerg                       "IsAtomicOrderingMonotonic requires IsAtomic");
9787330f729Sjoerg     if (isAtomicOrderingAcquire())
9797330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9807330f729Sjoerg                       "IsAtomicOrderingAcquire requires IsAtomic");
9817330f729Sjoerg     if (isAtomicOrderingRelease())
9827330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9837330f729Sjoerg                       "IsAtomicOrderingRelease requires IsAtomic");
9847330f729Sjoerg     if (isAtomicOrderingAcquireRelease())
9857330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9867330f729Sjoerg                       "IsAtomicOrderingAcquireRelease requires IsAtomic");
9877330f729Sjoerg     if (isAtomicOrderingSequentiallyConsistent())
9887330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9897330f729Sjoerg                       "IsAtomicOrderingSequentiallyConsistent requires IsAtomic");
9907330f729Sjoerg     if (isAtomicOrderingAcquireOrStronger())
9917330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9927330f729Sjoerg                       "IsAtomicOrderingAcquireOrStronger requires IsAtomic");
9937330f729Sjoerg     if (isAtomicOrderingReleaseOrStronger())
9947330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9957330f729Sjoerg                       "IsAtomicOrderingReleaseOrStronger requires IsAtomic");
9967330f729Sjoerg     if (isAtomicOrderingWeakerThanAcquire())
9977330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
9987330f729Sjoerg                       "IsAtomicOrderingWeakerThanAcquire requires IsAtomic");
9997330f729Sjoerg   }
10007330f729Sjoerg 
10017330f729Sjoerg   if (isLoad() || isStore() || isAtomic()) {
10027330f729Sjoerg     if (ListInit *AddressSpaces = getAddressSpaces()) {
10037330f729Sjoerg       Code += "unsigned AddrSpace = cast<MemSDNode>(N)->getAddressSpace();\n"
10047330f729Sjoerg         " if (";
10057330f729Sjoerg 
1006*82d56013Sjoerg       ListSeparator LS(" && ");
10077330f729Sjoerg       for (Init *Val : AddressSpaces->getValues()) {
1008*82d56013Sjoerg         Code += LS;
10097330f729Sjoerg 
10107330f729Sjoerg         IntInit *IntVal = dyn_cast<IntInit>(Val);
10117330f729Sjoerg         if (!IntVal) {
10127330f729Sjoerg           PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
10137330f729Sjoerg                           "AddressSpaces element must be integer");
10147330f729Sjoerg         }
10157330f729Sjoerg 
10167330f729Sjoerg         Code += "AddrSpace != " + utostr(IntVal->getValue());
10177330f729Sjoerg       }
10187330f729Sjoerg 
10197330f729Sjoerg       Code += ")\nreturn false;\n";
10207330f729Sjoerg     }
10217330f729Sjoerg 
10227330f729Sjoerg     int64_t MinAlign = getMinAlignment();
10237330f729Sjoerg     if (MinAlign > 0) {
1024*82d56013Sjoerg       Code += "if (cast<MemSDNode>(N)->getAlign() < Align(";
10257330f729Sjoerg       Code += utostr(MinAlign);
1026*82d56013Sjoerg       Code += "))\nreturn false;\n";
10277330f729Sjoerg     }
10287330f729Sjoerg 
10297330f729Sjoerg     Record *MemoryVT = getMemoryVT();
10307330f729Sjoerg 
10317330f729Sjoerg     if (MemoryVT)
10327330f729Sjoerg       Code += ("if (cast<MemSDNode>(N)->getMemoryVT() != MVT::" +
10337330f729Sjoerg                MemoryVT->getName() + ") return false;\n")
10347330f729Sjoerg                   .str();
10357330f729Sjoerg   }
10367330f729Sjoerg 
10377330f729Sjoerg   if (isAtomic() && isAtomicOrderingMonotonic())
10387330f729Sjoerg     Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
10397330f729Sjoerg             "AtomicOrdering::Monotonic) return false;\n";
10407330f729Sjoerg   if (isAtomic() && isAtomicOrderingAcquire())
10417330f729Sjoerg     Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
10427330f729Sjoerg             "AtomicOrdering::Acquire) return false;\n";
10437330f729Sjoerg   if (isAtomic() && isAtomicOrderingRelease())
10447330f729Sjoerg     Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
10457330f729Sjoerg             "AtomicOrdering::Release) return false;\n";
10467330f729Sjoerg   if (isAtomic() && isAtomicOrderingAcquireRelease())
10477330f729Sjoerg     Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
10487330f729Sjoerg             "AtomicOrdering::AcquireRelease) return false;\n";
10497330f729Sjoerg   if (isAtomic() && isAtomicOrderingSequentiallyConsistent())
10507330f729Sjoerg     Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
10517330f729Sjoerg             "AtomicOrdering::SequentiallyConsistent) return false;\n";
10527330f729Sjoerg 
10537330f729Sjoerg   if (isAtomic() && isAtomicOrderingAcquireOrStronger())
10547330f729Sjoerg     Code += "if (!isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
10557330f729Sjoerg             "return false;\n";
10567330f729Sjoerg   if (isAtomic() && isAtomicOrderingWeakerThanAcquire())
10577330f729Sjoerg     Code += "if (isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
10587330f729Sjoerg             "return false;\n";
10597330f729Sjoerg 
10607330f729Sjoerg   if (isAtomic() && isAtomicOrderingReleaseOrStronger())
10617330f729Sjoerg     Code += "if (!isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
10627330f729Sjoerg             "return false;\n";
10637330f729Sjoerg   if (isAtomic() && isAtomicOrderingWeakerThanRelease())
10647330f729Sjoerg     Code += "if (isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
10657330f729Sjoerg             "return false;\n";
10667330f729Sjoerg 
10677330f729Sjoerg   if (isLoad() || isStore()) {
10687330f729Sjoerg     StringRef SDNodeName = isLoad() ? "LoadSDNode" : "StoreSDNode";
10697330f729Sjoerg 
10707330f729Sjoerg     if (isUnindexed())
10717330f729Sjoerg       Code += ("if (cast<" + SDNodeName +
10727330f729Sjoerg                ">(N)->getAddressingMode() != ISD::UNINDEXED) "
10737330f729Sjoerg                "return false;\n")
10747330f729Sjoerg                   .str();
10757330f729Sjoerg 
10767330f729Sjoerg     if (isLoad()) {
10777330f729Sjoerg       if ((isNonExtLoad() + isAnyExtLoad() + isSignExtLoad() +
10787330f729Sjoerg            isZeroExtLoad()) > 1)
10797330f729Sjoerg         PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
10807330f729Sjoerg                         "IsNonExtLoad, IsAnyExtLoad, IsSignExtLoad, and "
10817330f729Sjoerg                         "IsZeroExtLoad are mutually exclusive");
10827330f729Sjoerg       if (isNonExtLoad())
10837330f729Sjoerg         Code += "if (cast<LoadSDNode>(N)->getExtensionType() != "
10847330f729Sjoerg                 "ISD::NON_EXTLOAD) return false;\n";
10857330f729Sjoerg       if (isAnyExtLoad())
10867330f729Sjoerg         Code += "if (cast<LoadSDNode>(N)->getExtensionType() != ISD::EXTLOAD) "
10877330f729Sjoerg                 "return false;\n";
10887330f729Sjoerg       if (isSignExtLoad())
10897330f729Sjoerg         Code += "if (cast<LoadSDNode>(N)->getExtensionType() != ISD::SEXTLOAD) "
10907330f729Sjoerg                 "return false;\n";
10917330f729Sjoerg       if (isZeroExtLoad())
10927330f729Sjoerg         Code += "if (cast<LoadSDNode>(N)->getExtensionType() != ISD::ZEXTLOAD) "
10937330f729Sjoerg                 "return false;\n";
10947330f729Sjoerg     } else {
10957330f729Sjoerg       if ((isNonTruncStore() + isTruncStore()) > 1)
10967330f729Sjoerg         PrintFatalError(
10977330f729Sjoerg             getOrigPatFragRecord()->getRecord()->getLoc(),
10987330f729Sjoerg             "IsNonTruncStore, and IsTruncStore are mutually exclusive");
10997330f729Sjoerg       if (isNonTruncStore())
11007330f729Sjoerg         Code +=
11017330f729Sjoerg             " if (cast<StoreSDNode>(N)->isTruncatingStore()) return false;\n";
11027330f729Sjoerg       if (isTruncStore())
11037330f729Sjoerg         Code +=
11047330f729Sjoerg             " if (!cast<StoreSDNode>(N)->isTruncatingStore()) return false;\n";
11057330f729Sjoerg     }
11067330f729Sjoerg 
11077330f729Sjoerg     Record *ScalarMemoryVT = getScalarMemoryVT();
11087330f729Sjoerg 
11097330f729Sjoerg     if (ScalarMemoryVT)
11107330f729Sjoerg       Code += ("if (cast<" + SDNodeName +
11117330f729Sjoerg                ">(N)->getMemoryVT().getScalarType() != MVT::" +
11127330f729Sjoerg                ScalarMemoryVT->getName() + ") return false;\n")
11137330f729Sjoerg                   .str();
11147330f729Sjoerg   }
11157330f729Sjoerg 
1116*82d56013Sjoerg   std::string PredicateCode =
1117*82d56013Sjoerg       std::string(PatFragRec->getRecord()->getValueAsString("PredicateCode"));
11187330f729Sjoerg 
11197330f729Sjoerg   Code += PredicateCode;
11207330f729Sjoerg 
11217330f729Sjoerg   if (PredicateCode.empty() && !Code.empty())
11227330f729Sjoerg     Code += "return true;\n";
11237330f729Sjoerg 
11247330f729Sjoerg   return Code;
11257330f729Sjoerg }
11267330f729Sjoerg 
hasImmCode() const11277330f729Sjoerg bool TreePredicateFn::hasImmCode() const {
11287330f729Sjoerg   return !PatFragRec->getRecord()->getValueAsString("ImmediateCode").empty();
11297330f729Sjoerg }
11307330f729Sjoerg 
getImmCode() const11317330f729Sjoerg std::string TreePredicateFn::getImmCode() const {
1132*82d56013Sjoerg   return std::string(
1133*82d56013Sjoerg       PatFragRec->getRecord()->getValueAsString("ImmediateCode"));
11347330f729Sjoerg }
11357330f729Sjoerg 
immCodeUsesAPInt() const11367330f729Sjoerg bool TreePredicateFn::immCodeUsesAPInt() const {
11377330f729Sjoerg   return getOrigPatFragRecord()->getRecord()->getValueAsBit("IsAPInt");
11387330f729Sjoerg }
11397330f729Sjoerg 
immCodeUsesAPFloat() const11407330f729Sjoerg bool TreePredicateFn::immCodeUsesAPFloat() const {
11417330f729Sjoerg   bool Unset;
11427330f729Sjoerg   // The return value will be false when IsAPFloat is unset.
11437330f729Sjoerg   return getOrigPatFragRecord()->getRecord()->getValueAsBitOrUnset("IsAPFloat",
11447330f729Sjoerg                                                                    Unset);
11457330f729Sjoerg }
11467330f729Sjoerg 
isPredefinedPredicateEqualTo(StringRef Field,bool Value) const11477330f729Sjoerg bool TreePredicateFn::isPredefinedPredicateEqualTo(StringRef Field,
11487330f729Sjoerg                                                    bool Value) const {
11497330f729Sjoerg   bool Unset;
11507330f729Sjoerg   bool Result =
11517330f729Sjoerg       getOrigPatFragRecord()->getRecord()->getValueAsBitOrUnset(Field, Unset);
11527330f729Sjoerg   if (Unset)
11537330f729Sjoerg     return false;
11547330f729Sjoerg   return Result == Value;
11557330f729Sjoerg }
usesOperands() const11567330f729Sjoerg bool TreePredicateFn::usesOperands() const {
11577330f729Sjoerg   return isPredefinedPredicateEqualTo("PredicateCodeUsesOperands", true);
11587330f729Sjoerg }
isLoad() const11597330f729Sjoerg bool TreePredicateFn::isLoad() const {
11607330f729Sjoerg   return isPredefinedPredicateEqualTo("IsLoad", true);
11617330f729Sjoerg }
isStore() const11627330f729Sjoerg bool TreePredicateFn::isStore() const {
11637330f729Sjoerg   return isPredefinedPredicateEqualTo("IsStore", true);
11647330f729Sjoerg }
isAtomic() const11657330f729Sjoerg bool TreePredicateFn::isAtomic() const {
11667330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAtomic", true);
11677330f729Sjoerg }
isUnindexed() const11687330f729Sjoerg bool TreePredicateFn::isUnindexed() const {
11697330f729Sjoerg   return isPredefinedPredicateEqualTo("IsUnindexed", true);
11707330f729Sjoerg }
isNonExtLoad() const11717330f729Sjoerg bool TreePredicateFn::isNonExtLoad() const {
11727330f729Sjoerg   return isPredefinedPredicateEqualTo("IsNonExtLoad", true);
11737330f729Sjoerg }
isAnyExtLoad() const11747330f729Sjoerg bool TreePredicateFn::isAnyExtLoad() const {
11757330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAnyExtLoad", true);
11767330f729Sjoerg }
isSignExtLoad() const11777330f729Sjoerg bool TreePredicateFn::isSignExtLoad() const {
11787330f729Sjoerg   return isPredefinedPredicateEqualTo("IsSignExtLoad", true);
11797330f729Sjoerg }
isZeroExtLoad() const11807330f729Sjoerg bool TreePredicateFn::isZeroExtLoad() const {
11817330f729Sjoerg   return isPredefinedPredicateEqualTo("IsZeroExtLoad", true);
11827330f729Sjoerg }
isNonTruncStore() const11837330f729Sjoerg bool TreePredicateFn::isNonTruncStore() const {
11847330f729Sjoerg   return isPredefinedPredicateEqualTo("IsTruncStore", false);
11857330f729Sjoerg }
isTruncStore() const11867330f729Sjoerg bool TreePredicateFn::isTruncStore() const {
11877330f729Sjoerg   return isPredefinedPredicateEqualTo("IsTruncStore", true);
11887330f729Sjoerg }
isAtomicOrderingMonotonic() const11897330f729Sjoerg bool TreePredicateFn::isAtomicOrderingMonotonic() const {
11907330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAtomicOrderingMonotonic", true);
11917330f729Sjoerg }
isAtomicOrderingAcquire() const11927330f729Sjoerg bool TreePredicateFn::isAtomicOrderingAcquire() const {
11937330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquire", true);
11947330f729Sjoerg }
isAtomicOrderingRelease() const11957330f729Sjoerg bool TreePredicateFn::isAtomicOrderingRelease() const {
11967330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAtomicOrderingRelease", true);
11977330f729Sjoerg }
isAtomicOrderingAcquireRelease() const11987330f729Sjoerg bool TreePredicateFn::isAtomicOrderingAcquireRelease() const {
11997330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquireRelease", true);
12007330f729Sjoerg }
isAtomicOrderingSequentiallyConsistent() const12017330f729Sjoerg bool TreePredicateFn::isAtomicOrderingSequentiallyConsistent() const {
12027330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAtomicOrderingSequentiallyConsistent",
12037330f729Sjoerg                                       true);
12047330f729Sjoerg }
isAtomicOrderingAcquireOrStronger() const12057330f729Sjoerg bool TreePredicateFn::isAtomicOrderingAcquireOrStronger() const {
12067330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquireOrStronger", true);
12077330f729Sjoerg }
isAtomicOrderingWeakerThanAcquire() const12087330f729Sjoerg bool TreePredicateFn::isAtomicOrderingWeakerThanAcquire() const {
12097330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquireOrStronger", false);
12107330f729Sjoerg }
isAtomicOrderingReleaseOrStronger() const12117330f729Sjoerg bool TreePredicateFn::isAtomicOrderingReleaseOrStronger() const {
12127330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAtomicOrderingReleaseOrStronger", true);
12137330f729Sjoerg }
isAtomicOrderingWeakerThanRelease() const12147330f729Sjoerg bool TreePredicateFn::isAtomicOrderingWeakerThanRelease() const {
12157330f729Sjoerg   return isPredefinedPredicateEqualTo("IsAtomicOrderingReleaseOrStronger", false);
12167330f729Sjoerg }
getMemoryVT() const12177330f729Sjoerg Record *TreePredicateFn::getMemoryVT() const {
12187330f729Sjoerg   Record *R = getOrigPatFragRecord()->getRecord();
12197330f729Sjoerg   if (R->isValueUnset("MemoryVT"))
12207330f729Sjoerg     return nullptr;
12217330f729Sjoerg   return R->getValueAsDef("MemoryVT");
12227330f729Sjoerg }
12237330f729Sjoerg 
getAddressSpaces() const12247330f729Sjoerg ListInit *TreePredicateFn::getAddressSpaces() const {
12257330f729Sjoerg   Record *R = getOrigPatFragRecord()->getRecord();
12267330f729Sjoerg   if (R->isValueUnset("AddressSpaces"))
12277330f729Sjoerg     return nullptr;
12287330f729Sjoerg   return R->getValueAsListInit("AddressSpaces");
12297330f729Sjoerg }
12307330f729Sjoerg 
getMinAlignment() const12317330f729Sjoerg int64_t TreePredicateFn::getMinAlignment() const {
12327330f729Sjoerg   Record *R = getOrigPatFragRecord()->getRecord();
12337330f729Sjoerg   if (R->isValueUnset("MinAlignment"))
12347330f729Sjoerg     return 0;
12357330f729Sjoerg   return R->getValueAsInt("MinAlignment");
12367330f729Sjoerg }
12377330f729Sjoerg 
getScalarMemoryVT() const12387330f729Sjoerg Record *TreePredicateFn::getScalarMemoryVT() const {
12397330f729Sjoerg   Record *R = getOrigPatFragRecord()->getRecord();
12407330f729Sjoerg   if (R->isValueUnset("ScalarMemoryVT"))
12417330f729Sjoerg     return nullptr;
12427330f729Sjoerg   return R->getValueAsDef("ScalarMemoryVT");
12437330f729Sjoerg }
hasGISelPredicateCode() const12447330f729Sjoerg bool TreePredicateFn::hasGISelPredicateCode() const {
12457330f729Sjoerg   return !PatFragRec->getRecord()
12467330f729Sjoerg               ->getValueAsString("GISelPredicateCode")
12477330f729Sjoerg               .empty();
12487330f729Sjoerg }
getGISelPredicateCode() const12497330f729Sjoerg std::string TreePredicateFn::getGISelPredicateCode() const {
1250*82d56013Sjoerg   return std::string(
1251*82d56013Sjoerg       PatFragRec->getRecord()->getValueAsString("GISelPredicateCode"));
12527330f729Sjoerg }
12537330f729Sjoerg 
getImmType() const12547330f729Sjoerg StringRef TreePredicateFn::getImmType() const {
12557330f729Sjoerg   if (immCodeUsesAPInt())
12567330f729Sjoerg     return "const APInt &";
12577330f729Sjoerg   if (immCodeUsesAPFloat())
12587330f729Sjoerg     return "const APFloat &";
12597330f729Sjoerg   return "int64_t";
12607330f729Sjoerg }
12617330f729Sjoerg 
getImmTypeIdentifier() const12627330f729Sjoerg StringRef TreePredicateFn::getImmTypeIdentifier() const {
12637330f729Sjoerg   if (immCodeUsesAPInt())
12647330f729Sjoerg     return "APInt";
1265*82d56013Sjoerg   if (immCodeUsesAPFloat())
12667330f729Sjoerg     return "APFloat";
12677330f729Sjoerg   return "I64";
12687330f729Sjoerg }
12697330f729Sjoerg 
12707330f729Sjoerg /// isAlwaysTrue - Return true if this is a noop predicate.
isAlwaysTrue() const12717330f729Sjoerg bool TreePredicateFn::isAlwaysTrue() const {
12727330f729Sjoerg   return !hasPredCode() && !hasImmCode();
12737330f729Sjoerg }
12747330f729Sjoerg 
12757330f729Sjoerg /// Return the name to use in the generated code to reference this, this is
12767330f729Sjoerg /// "Predicate_foo" if from a pattern fragment "foo".
getFnName() const12777330f729Sjoerg std::string TreePredicateFn::getFnName() const {
12787330f729Sjoerg   return "Predicate_" + PatFragRec->getRecord()->getName().str();
12797330f729Sjoerg }
12807330f729Sjoerg 
12817330f729Sjoerg /// getCodeToRunOnSDNode - Return the code for the function body that
12827330f729Sjoerg /// evaluates this predicate.  The argument is expected to be in "Node",
12837330f729Sjoerg /// not N.  This handles casting and conversion to a concrete node type as
12847330f729Sjoerg /// appropriate.
getCodeToRunOnSDNode() const12857330f729Sjoerg std::string TreePredicateFn::getCodeToRunOnSDNode() const {
12867330f729Sjoerg   // Handle immediate predicates first.
12877330f729Sjoerg   std::string ImmCode = getImmCode();
12887330f729Sjoerg   if (!ImmCode.empty()) {
12897330f729Sjoerg     if (isLoad())
12907330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
12917330f729Sjoerg                       "IsLoad cannot be used with ImmLeaf or its subclasses");
12927330f729Sjoerg     if (isStore())
12937330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
12947330f729Sjoerg                       "IsStore cannot be used with ImmLeaf or its subclasses");
12957330f729Sjoerg     if (isUnindexed())
12967330f729Sjoerg       PrintFatalError(
12977330f729Sjoerg           getOrigPatFragRecord()->getRecord()->getLoc(),
12987330f729Sjoerg           "IsUnindexed cannot be used with ImmLeaf or its subclasses");
12997330f729Sjoerg     if (isNonExtLoad())
13007330f729Sjoerg       PrintFatalError(
13017330f729Sjoerg           getOrigPatFragRecord()->getRecord()->getLoc(),
13027330f729Sjoerg           "IsNonExtLoad cannot be used with ImmLeaf or its subclasses");
13037330f729Sjoerg     if (isAnyExtLoad())
13047330f729Sjoerg       PrintFatalError(
13057330f729Sjoerg           getOrigPatFragRecord()->getRecord()->getLoc(),
13067330f729Sjoerg           "IsAnyExtLoad cannot be used with ImmLeaf or its subclasses");
13077330f729Sjoerg     if (isSignExtLoad())
13087330f729Sjoerg       PrintFatalError(
13097330f729Sjoerg           getOrigPatFragRecord()->getRecord()->getLoc(),
13107330f729Sjoerg           "IsSignExtLoad cannot be used with ImmLeaf or its subclasses");
13117330f729Sjoerg     if (isZeroExtLoad())
13127330f729Sjoerg       PrintFatalError(
13137330f729Sjoerg           getOrigPatFragRecord()->getRecord()->getLoc(),
13147330f729Sjoerg           "IsZeroExtLoad cannot be used with ImmLeaf or its subclasses");
13157330f729Sjoerg     if (isNonTruncStore())
13167330f729Sjoerg       PrintFatalError(
13177330f729Sjoerg           getOrigPatFragRecord()->getRecord()->getLoc(),
13187330f729Sjoerg           "IsNonTruncStore cannot be used with ImmLeaf or its subclasses");
13197330f729Sjoerg     if (isTruncStore())
13207330f729Sjoerg       PrintFatalError(
13217330f729Sjoerg           getOrigPatFragRecord()->getRecord()->getLoc(),
13227330f729Sjoerg           "IsTruncStore cannot be used with ImmLeaf or its subclasses");
13237330f729Sjoerg     if (getMemoryVT())
13247330f729Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
13257330f729Sjoerg                       "MemoryVT cannot be used with ImmLeaf or its subclasses");
13267330f729Sjoerg     if (getScalarMemoryVT())
13277330f729Sjoerg       PrintFatalError(
13287330f729Sjoerg           getOrigPatFragRecord()->getRecord()->getLoc(),
13297330f729Sjoerg           "ScalarMemoryVT cannot be used with ImmLeaf or its subclasses");
13307330f729Sjoerg 
13317330f729Sjoerg     std::string Result = ("    " + getImmType() + " Imm = ").str();
13327330f729Sjoerg     if (immCodeUsesAPFloat())
13337330f729Sjoerg       Result += "cast<ConstantFPSDNode>(Node)->getValueAPF();\n";
13347330f729Sjoerg     else if (immCodeUsesAPInt())
13357330f729Sjoerg       Result += "cast<ConstantSDNode>(Node)->getAPIntValue();\n";
13367330f729Sjoerg     else
13377330f729Sjoerg       Result += "cast<ConstantSDNode>(Node)->getSExtValue();\n";
13387330f729Sjoerg     return Result + ImmCode;
13397330f729Sjoerg   }
13407330f729Sjoerg 
13417330f729Sjoerg   // Handle arbitrary node predicates.
13427330f729Sjoerg   assert(hasPredCode() && "Don't have any predicate code!");
1343*82d56013Sjoerg 
1344*82d56013Sjoerg   // If this is using PatFrags, there are multiple trees to search. They should
1345*82d56013Sjoerg   // all have the same class.  FIXME: Is there a way to find a common
1346*82d56013Sjoerg   // superclass?
13477330f729Sjoerg   StringRef ClassName;
1348*82d56013Sjoerg   for (const auto &Tree : PatFragRec->getTrees()) {
1349*82d56013Sjoerg     StringRef TreeClassName;
1350*82d56013Sjoerg     if (Tree->isLeaf())
1351*82d56013Sjoerg       TreeClassName = "SDNode";
13527330f729Sjoerg     else {
1353*82d56013Sjoerg       Record *Op = Tree->getOperator();
1354*82d56013Sjoerg       const SDNodeInfo &Info = PatFragRec->getDAGPatterns().getSDNodeInfo(Op);
1355*82d56013Sjoerg       TreeClassName = Info.getSDClassName();
13567330f729Sjoerg     }
1357*82d56013Sjoerg 
1358*82d56013Sjoerg     if (ClassName.empty())
1359*82d56013Sjoerg       ClassName = TreeClassName;
1360*82d56013Sjoerg     else if (ClassName != TreeClassName) {
1361*82d56013Sjoerg       PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
1362*82d56013Sjoerg                       "PatFrags trees do not have consistent class");
1363*82d56013Sjoerg     }
1364*82d56013Sjoerg   }
1365*82d56013Sjoerg 
13667330f729Sjoerg   std::string Result;
13677330f729Sjoerg   if (ClassName == "SDNode")
13687330f729Sjoerg     Result = "    SDNode *N = Node;\n";
13697330f729Sjoerg   else
13707330f729Sjoerg     Result = "    auto *N = cast<" + ClassName.str() + ">(Node);\n";
13717330f729Sjoerg 
13727330f729Sjoerg   return (Twine(Result) + "    (void)N;\n" + getPredCode()).str();
13737330f729Sjoerg }
13747330f729Sjoerg 
13757330f729Sjoerg //===----------------------------------------------------------------------===//
13767330f729Sjoerg // PatternToMatch implementation
13777330f729Sjoerg //
13787330f729Sjoerg 
isImmAllOnesAllZerosMatch(const TreePatternNode * P)13797330f729Sjoerg static bool isImmAllOnesAllZerosMatch(const TreePatternNode *P) {
13807330f729Sjoerg   if (!P->isLeaf())
13817330f729Sjoerg     return false;
13827330f729Sjoerg   DefInit *DI = dyn_cast<DefInit>(P->getLeafValue());
13837330f729Sjoerg   if (!DI)
13847330f729Sjoerg     return false;
13857330f729Sjoerg 
13867330f729Sjoerg   Record *R = DI->getDef();
13877330f729Sjoerg   return R->getName() == "immAllOnesV" || R->getName() == "immAllZerosV";
13887330f729Sjoerg }
13897330f729Sjoerg 
13907330f729Sjoerg /// getPatternSize - Return the 'size' of this pattern.  We want to match large
13917330f729Sjoerg /// patterns before small ones.  This is used to determine the size of a
13927330f729Sjoerg /// pattern.
getPatternSize(const TreePatternNode * P,const CodeGenDAGPatterns & CGP)13937330f729Sjoerg static unsigned getPatternSize(const TreePatternNode *P,
13947330f729Sjoerg                                const CodeGenDAGPatterns &CGP) {
13957330f729Sjoerg   unsigned Size = 3;  // The node itself.
13967330f729Sjoerg   // If the root node is a ConstantSDNode, increases its size.
13977330f729Sjoerg   // e.g. (set R32:$dst, 0).
13987330f729Sjoerg   if (P->isLeaf() && isa<IntInit>(P->getLeafValue()))
13997330f729Sjoerg     Size += 2;
14007330f729Sjoerg 
14017330f729Sjoerg   if (const ComplexPattern *AM = P->getComplexPatternInfo(CGP)) {
14027330f729Sjoerg     Size += AM->getComplexity();
14037330f729Sjoerg     // We don't want to count any children twice, so return early.
14047330f729Sjoerg     return Size;
14057330f729Sjoerg   }
14067330f729Sjoerg 
14077330f729Sjoerg   // If this node has some predicate function that must match, it adds to the
14087330f729Sjoerg   // complexity of this node.
14097330f729Sjoerg   if (!P->getPredicateCalls().empty())
14107330f729Sjoerg     ++Size;
14117330f729Sjoerg 
14127330f729Sjoerg   // Count children in the count if they are also nodes.
14137330f729Sjoerg   for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) {
14147330f729Sjoerg     const TreePatternNode *Child = P->getChild(i);
14157330f729Sjoerg     if (!Child->isLeaf() && Child->getNumTypes()) {
14167330f729Sjoerg       const TypeSetByHwMode &T0 = Child->getExtType(0);
14177330f729Sjoerg       // At this point, all variable type sets should be simple, i.e. only
14187330f729Sjoerg       // have a default mode.
14197330f729Sjoerg       if (T0.getMachineValueType() != MVT::Other) {
14207330f729Sjoerg         Size += getPatternSize(Child, CGP);
14217330f729Sjoerg         continue;
14227330f729Sjoerg       }
14237330f729Sjoerg     }
14247330f729Sjoerg     if (Child->isLeaf()) {
14257330f729Sjoerg       if (isa<IntInit>(Child->getLeafValue()))
14267330f729Sjoerg         Size += 5;  // Matches a ConstantSDNode (+3) and a specific value (+2).
14277330f729Sjoerg       else if (Child->getComplexPatternInfo(CGP))
14287330f729Sjoerg         Size += getPatternSize(Child, CGP);
14297330f729Sjoerg       else if (isImmAllOnesAllZerosMatch(Child))
14307330f729Sjoerg         Size += 4; // Matches a build_vector(+3) and a predicate (+1).
14317330f729Sjoerg       else if (!Child->getPredicateCalls().empty())
14327330f729Sjoerg         ++Size;
14337330f729Sjoerg     }
14347330f729Sjoerg   }
14357330f729Sjoerg 
14367330f729Sjoerg   return Size;
14377330f729Sjoerg }
14387330f729Sjoerg 
14397330f729Sjoerg /// Compute the complexity metric for the input pattern.  This roughly
14407330f729Sjoerg /// corresponds to the number of nodes that are covered.
14417330f729Sjoerg int PatternToMatch::
getPatternComplexity(const CodeGenDAGPatterns & CGP) const14427330f729Sjoerg getPatternComplexity(const CodeGenDAGPatterns &CGP) const {
14437330f729Sjoerg   return getPatternSize(getSrcPattern(), CGP) + getAddedComplexity();
14447330f729Sjoerg }
14457330f729Sjoerg 
getPredicateRecords(SmallVectorImpl<Record * > & PredicateRecs) const1446*82d56013Sjoerg void PatternToMatch::getPredicateRecords(
1447*82d56013Sjoerg     SmallVectorImpl<Record *> &PredicateRecs) const {
1448*82d56013Sjoerg   for (Init *I : Predicates->getValues()) {
1449*82d56013Sjoerg     if (DefInit *Pred = dyn_cast<DefInit>(I)) {
1450*82d56013Sjoerg       Record *Def = Pred->getDef();
1451*82d56013Sjoerg       if (!Def->isSubClassOf("Predicate")) {
1452*82d56013Sjoerg #ifndef NDEBUG
1453*82d56013Sjoerg         Def->dump();
1454*82d56013Sjoerg #endif
1455*82d56013Sjoerg         llvm_unreachable("Unknown predicate type!");
1456*82d56013Sjoerg       }
1457*82d56013Sjoerg       PredicateRecs.push_back(Def);
1458*82d56013Sjoerg     }
1459*82d56013Sjoerg   }
1460*82d56013Sjoerg   // Sort so that different orders get canonicalized to the same string.
1461*82d56013Sjoerg   llvm::sort(PredicateRecs, LessRecord());
1462*82d56013Sjoerg }
1463*82d56013Sjoerg 
14647330f729Sjoerg /// getPredicateCheck - Return a single string containing all of this
14657330f729Sjoerg /// pattern's predicates concatenated with "&&" operators.
14667330f729Sjoerg ///
getPredicateCheck() const14677330f729Sjoerg std::string PatternToMatch::getPredicateCheck() const {
1468*82d56013Sjoerg   SmallVector<Record *, 4> PredicateRecs;
1469*82d56013Sjoerg   getPredicateRecords(PredicateRecs);
14707330f729Sjoerg 
1471*82d56013Sjoerg   SmallString<128> PredicateCheck;
1472*82d56013Sjoerg   for (Record *Pred : PredicateRecs) {
1473*82d56013Sjoerg     StringRef CondString = Pred->getValueAsString("CondString");
1474*82d56013Sjoerg     if (CondString.empty())
1475*82d56013Sjoerg       continue;
1476*82d56013Sjoerg     if (!PredicateCheck.empty())
1477*82d56013Sjoerg       PredicateCheck += " && ";
1478*82d56013Sjoerg     PredicateCheck += "(";
1479*82d56013Sjoerg     PredicateCheck += CondString;
1480*82d56013Sjoerg     PredicateCheck += ")";
14817330f729Sjoerg   }
1482*82d56013Sjoerg 
1483*82d56013Sjoerg   if (!HwModeFeatures.empty()) {
1484*82d56013Sjoerg     if (!PredicateCheck.empty())
1485*82d56013Sjoerg       PredicateCheck += " && ";
1486*82d56013Sjoerg     PredicateCheck += HwModeFeatures;
1487*82d56013Sjoerg   }
1488*82d56013Sjoerg 
1489*82d56013Sjoerg   return std::string(PredicateCheck);
14907330f729Sjoerg }
14917330f729Sjoerg 
14927330f729Sjoerg //===----------------------------------------------------------------------===//
14937330f729Sjoerg // SDTypeConstraint implementation
14947330f729Sjoerg //
14957330f729Sjoerg 
SDTypeConstraint(Record * R,const CodeGenHwModes & CGH)14967330f729Sjoerg SDTypeConstraint::SDTypeConstraint(Record *R, const CodeGenHwModes &CGH) {
14977330f729Sjoerg   OperandNo = R->getValueAsInt("OperandNum");
14987330f729Sjoerg 
14997330f729Sjoerg   if (R->isSubClassOf("SDTCisVT")) {
15007330f729Sjoerg     ConstraintType = SDTCisVT;
15017330f729Sjoerg     VVT = getValueTypeByHwMode(R->getValueAsDef("VT"), CGH);
15027330f729Sjoerg     for (const auto &P : VVT)
15037330f729Sjoerg       if (P.second == MVT::isVoid)
15047330f729Sjoerg         PrintFatalError(R->getLoc(), "Cannot use 'Void' as type to SDTCisVT");
15057330f729Sjoerg   } else if (R->isSubClassOf("SDTCisPtrTy")) {
15067330f729Sjoerg     ConstraintType = SDTCisPtrTy;
15077330f729Sjoerg   } else if (R->isSubClassOf("SDTCisInt")) {
15087330f729Sjoerg     ConstraintType = SDTCisInt;
15097330f729Sjoerg   } else if (R->isSubClassOf("SDTCisFP")) {
15107330f729Sjoerg     ConstraintType = SDTCisFP;
15117330f729Sjoerg   } else if (R->isSubClassOf("SDTCisVec")) {
15127330f729Sjoerg     ConstraintType = SDTCisVec;
15137330f729Sjoerg   } else if (R->isSubClassOf("SDTCisSameAs")) {
15147330f729Sjoerg     ConstraintType = SDTCisSameAs;
15157330f729Sjoerg     x.SDTCisSameAs_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum");
15167330f729Sjoerg   } else if (R->isSubClassOf("SDTCisVTSmallerThanOp")) {
15177330f729Sjoerg     ConstraintType = SDTCisVTSmallerThanOp;
15187330f729Sjoerg     x.SDTCisVTSmallerThanOp_Info.OtherOperandNum =
15197330f729Sjoerg       R->getValueAsInt("OtherOperandNum");
15207330f729Sjoerg   } else if (R->isSubClassOf("SDTCisOpSmallerThanOp")) {
15217330f729Sjoerg     ConstraintType = SDTCisOpSmallerThanOp;
15227330f729Sjoerg     x.SDTCisOpSmallerThanOp_Info.BigOperandNum =
15237330f729Sjoerg       R->getValueAsInt("BigOperandNum");
15247330f729Sjoerg   } else if (R->isSubClassOf("SDTCisEltOfVec")) {
15257330f729Sjoerg     ConstraintType = SDTCisEltOfVec;
15267330f729Sjoerg     x.SDTCisEltOfVec_Info.OtherOperandNum = R->getValueAsInt("OtherOpNum");
15277330f729Sjoerg   } else if (R->isSubClassOf("SDTCisSubVecOfVec")) {
15287330f729Sjoerg     ConstraintType = SDTCisSubVecOfVec;
15297330f729Sjoerg     x.SDTCisSubVecOfVec_Info.OtherOperandNum =
15307330f729Sjoerg       R->getValueAsInt("OtherOpNum");
15317330f729Sjoerg   } else if (R->isSubClassOf("SDTCVecEltisVT")) {
15327330f729Sjoerg     ConstraintType = SDTCVecEltisVT;
15337330f729Sjoerg     VVT = getValueTypeByHwMode(R->getValueAsDef("VT"), CGH);
15347330f729Sjoerg     for (const auto &P : VVT) {
15357330f729Sjoerg       MVT T = P.second;
15367330f729Sjoerg       if (T.isVector())
15377330f729Sjoerg         PrintFatalError(R->getLoc(),
15387330f729Sjoerg                         "Cannot use vector type as SDTCVecEltisVT");
15397330f729Sjoerg       if (!T.isInteger() && !T.isFloatingPoint())
15407330f729Sjoerg         PrintFatalError(R->getLoc(), "Must use integer or floating point type "
15417330f729Sjoerg                                      "as SDTCVecEltisVT");
15427330f729Sjoerg     }
15437330f729Sjoerg   } else if (R->isSubClassOf("SDTCisSameNumEltsAs")) {
15447330f729Sjoerg     ConstraintType = SDTCisSameNumEltsAs;
15457330f729Sjoerg     x.SDTCisSameNumEltsAs_Info.OtherOperandNum =
15467330f729Sjoerg       R->getValueAsInt("OtherOperandNum");
15477330f729Sjoerg   } else if (R->isSubClassOf("SDTCisSameSizeAs")) {
15487330f729Sjoerg     ConstraintType = SDTCisSameSizeAs;
15497330f729Sjoerg     x.SDTCisSameSizeAs_Info.OtherOperandNum =
15507330f729Sjoerg       R->getValueAsInt("OtherOperandNum");
15517330f729Sjoerg   } else {
15527330f729Sjoerg     PrintFatalError(R->getLoc(),
15537330f729Sjoerg                     "Unrecognized SDTypeConstraint '" + R->getName() + "'!\n");
15547330f729Sjoerg   }
15557330f729Sjoerg }
15567330f729Sjoerg 
15577330f729Sjoerg /// getOperandNum - Return the node corresponding to operand #OpNo in tree
15587330f729Sjoerg /// N, and the result number in ResNo.
getOperandNum(unsigned OpNo,TreePatternNode * N,const SDNodeInfo & NodeInfo,unsigned & ResNo)15597330f729Sjoerg static TreePatternNode *getOperandNum(unsigned OpNo, TreePatternNode *N,
15607330f729Sjoerg                                       const SDNodeInfo &NodeInfo,
15617330f729Sjoerg                                       unsigned &ResNo) {
15627330f729Sjoerg   unsigned NumResults = NodeInfo.getNumResults();
15637330f729Sjoerg   if (OpNo < NumResults) {
15647330f729Sjoerg     ResNo = OpNo;
15657330f729Sjoerg     return N;
15667330f729Sjoerg   }
15677330f729Sjoerg 
15687330f729Sjoerg   OpNo -= NumResults;
15697330f729Sjoerg 
15707330f729Sjoerg   if (OpNo >= N->getNumChildren()) {
15717330f729Sjoerg     std::string S;
15727330f729Sjoerg     raw_string_ostream OS(S);
15737330f729Sjoerg     OS << "Invalid operand number in type constraint "
15747330f729Sjoerg            << (OpNo+NumResults) << " ";
15757330f729Sjoerg     N->print(OS);
15767330f729Sjoerg     PrintFatalError(OS.str());
15777330f729Sjoerg   }
15787330f729Sjoerg 
15797330f729Sjoerg   return N->getChild(OpNo);
15807330f729Sjoerg }
15817330f729Sjoerg 
15827330f729Sjoerg /// ApplyTypeConstraint - Given a node in a pattern, apply this type
15837330f729Sjoerg /// constraint to the nodes operands.  This returns true if it makes a
15847330f729Sjoerg /// change, false otherwise.  If a type contradiction is found, flag an error.
ApplyTypeConstraint(TreePatternNode * N,const SDNodeInfo & NodeInfo,TreePattern & TP) const15857330f729Sjoerg bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N,
15867330f729Sjoerg                                            const SDNodeInfo &NodeInfo,
15877330f729Sjoerg                                            TreePattern &TP) const {
15887330f729Sjoerg   if (TP.hasError())
15897330f729Sjoerg     return false;
15907330f729Sjoerg 
15917330f729Sjoerg   unsigned ResNo = 0; // The result number being referenced.
15927330f729Sjoerg   TreePatternNode *NodeToApply = getOperandNum(OperandNo, N, NodeInfo, ResNo);
15937330f729Sjoerg   TypeInfer &TI = TP.getInfer();
15947330f729Sjoerg 
15957330f729Sjoerg   switch (ConstraintType) {
15967330f729Sjoerg   case SDTCisVT:
15977330f729Sjoerg     // Operand must be a particular type.
15987330f729Sjoerg     return NodeToApply->UpdateNodeType(ResNo, VVT, TP);
15997330f729Sjoerg   case SDTCisPtrTy:
16007330f729Sjoerg     // Operand must be same as target pointer type.
16017330f729Sjoerg     return NodeToApply->UpdateNodeType(ResNo, MVT::iPTR, TP);
16027330f729Sjoerg   case SDTCisInt:
16037330f729Sjoerg     // Require it to be one of the legal integer VTs.
16047330f729Sjoerg      return TI.EnforceInteger(NodeToApply->getExtType(ResNo));
16057330f729Sjoerg   case SDTCisFP:
16067330f729Sjoerg     // Require it to be one of the legal fp VTs.
16077330f729Sjoerg     return TI.EnforceFloatingPoint(NodeToApply->getExtType(ResNo));
16087330f729Sjoerg   case SDTCisVec:
16097330f729Sjoerg     // Require it to be one of the legal vector VTs.
16107330f729Sjoerg     return TI.EnforceVector(NodeToApply->getExtType(ResNo));
16117330f729Sjoerg   case SDTCisSameAs: {
16127330f729Sjoerg     unsigned OResNo = 0;
16137330f729Sjoerg     TreePatternNode *OtherNode =
16147330f729Sjoerg       getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NodeInfo, OResNo);
16157330f729Sjoerg     return NodeToApply->UpdateNodeType(ResNo, OtherNode->getExtType(OResNo),TP)|
16167330f729Sjoerg            OtherNode->UpdateNodeType(OResNo,NodeToApply->getExtType(ResNo),TP);
16177330f729Sjoerg   }
16187330f729Sjoerg   case SDTCisVTSmallerThanOp: {
16197330f729Sjoerg     // The NodeToApply must be a leaf node that is a VT.  OtherOperandNum must
16207330f729Sjoerg     // have an integer type that is smaller than the VT.
16217330f729Sjoerg     if (!NodeToApply->isLeaf() ||
16227330f729Sjoerg         !isa<DefInit>(NodeToApply->getLeafValue()) ||
16237330f729Sjoerg         !static_cast<DefInit*>(NodeToApply->getLeafValue())->getDef()
16247330f729Sjoerg                ->isSubClassOf("ValueType")) {
16257330f729Sjoerg       TP.error(N->getOperator()->getName() + " expects a VT operand!");
16267330f729Sjoerg       return false;
16277330f729Sjoerg     }
16287330f729Sjoerg     DefInit *DI = static_cast<DefInit*>(NodeToApply->getLeafValue());
16297330f729Sjoerg     const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
16307330f729Sjoerg     auto VVT = getValueTypeByHwMode(DI->getDef(), T.getHwModes());
16317330f729Sjoerg     TypeSetByHwMode TypeListTmp(VVT);
16327330f729Sjoerg 
16337330f729Sjoerg     unsigned OResNo = 0;
16347330f729Sjoerg     TreePatternNode *OtherNode =
16357330f729Sjoerg       getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N, NodeInfo,
16367330f729Sjoerg                     OResNo);
16377330f729Sjoerg 
16387330f729Sjoerg     return TI.EnforceSmallerThan(TypeListTmp, OtherNode->getExtType(OResNo));
16397330f729Sjoerg   }
16407330f729Sjoerg   case SDTCisOpSmallerThanOp: {
16417330f729Sjoerg     unsigned BResNo = 0;
16427330f729Sjoerg     TreePatternNode *BigOperand =
16437330f729Sjoerg       getOperandNum(x.SDTCisOpSmallerThanOp_Info.BigOperandNum, N, NodeInfo,
16447330f729Sjoerg                     BResNo);
16457330f729Sjoerg     return TI.EnforceSmallerThan(NodeToApply->getExtType(ResNo),
16467330f729Sjoerg                                  BigOperand->getExtType(BResNo));
16477330f729Sjoerg   }
16487330f729Sjoerg   case SDTCisEltOfVec: {
16497330f729Sjoerg     unsigned VResNo = 0;
16507330f729Sjoerg     TreePatternNode *VecOperand =
16517330f729Sjoerg       getOperandNum(x.SDTCisEltOfVec_Info.OtherOperandNum, N, NodeInfo,
16527330f729Sjoerg                     VResNo);
16537330f729Sjoerg     // Filter vector types out of VecOperand that don't have the right element
16547330f729Sjoerg     // type.
16557330f729Sjoerg     return TI.EnforceVectorEltTypeIs(VecOperand->getExtType(VResNo),
16567330f729Sjoerg                                      NodeToApply->getExtType(ResNo));
16577330f729Sjoerg   }
16587330f729Sjoerg   case SDTCisSubVecOfVec: {
16597330f729Sjoerg     unsigned VResNo = 0;
16607330f729Sjoerg     TreePatternNode *BigVecOperand =
16617330f729Sjoerg       getOperandNum(x.SDTCisSubVecOfVec_Info.OtherOperandNum, N, NodeInfo,
16627330f729Sjoerg                     VResNo);
16637330f729Sjoerg 
16647330f729Sjoerg     // Filter vector types out of BigVecOperand that don't have the
16657330f729Sjoerg     // right subvector type.
16667330f729Sjoerg     return TI.EnforceVectorSubVectorTypeIs(BigVecOperand->getExtType(VResNo),
16677330f729Sjoerg                                            NodeToApply->getExtType(ResNo));
16687330f729Sjoerg   }
16697330f729Sjoerg   case SDTCVecEltisVT: {
16707330f729Sjoerg     return TI.EnforceVectorEltTypeIs(NodeToApply->getExtType(ResNo), VVT);
16717330f729Sjoerg   }
16727330f729Sjoerg   case SDTCisSameNumEltsAs: {
16737330f729Sjoerg     unsigned OResNo = 0;
16747330f729Sjoerg     TreePatternNode *OtherNode =
16757330f729Sjoerg       getOperandNum(x.SDTCisSameNumEltsAs_Info.OtherOperandNum,
16767330f729Sjoerg                     N, NodeInfo, OResNo);
16777330f729Sjoerg     return TI.EnforceSameNumElts(OtherNode->getExtType(OResNo),
16787330f729Sjoerg                                  NodeToApply->getExtType(ResNo));
16797330f729Sjoerg   }
16807330f729Sjoerg   case SDTCisSameSizeAs: {
16817330f729Sjoerg     unsigned OResNo = 0;
16827330f729Sjoerg     TreePatternNode *OtherNode =
16837330f729Sjoerg       getOperandNum(x.SDTCisSameSizeAs_Info.OtherOperandNum,
16847330f729Sjoerg                     N, NodeInfo, OResNo);
16857330f729Sjoerg     return TI.EnforceSameSize(OtherNode->getExtType(OResNo),
16867330f729Sjoerg                               NodeToApply->getExtType(ResNo));
16877330f729Sjoerg   }
16887330f729Sjoerg   }
16897330f729Sjoerg   llvm_unreachable("Invalid ConstraintType!");
16907330f729Sjoerg }
16917330f729Sjoerg 
16927330f729Sjoerg // Update the node type to match an instruction operand or result as specified
16937330f729Sjoerg // in the ins or outs lists on the instruction definition. Return true if the
16947330f729Sjoerg // type was actually changed.
UpdateNodeTypeFromInst(unsigned ResNo,Record * Operand,TreePattern & TP)16957330f729Sjoerg bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo,
16967330f729Sjoerg                                              Record *Operand,
16977330f729Sjoerg                                              TreePattern &TP) {
16987330f729Sjoerg   // The 'unknown' operand indicates that types should be inferred from the
16997330f729Sjoerg   // context.
17007330f729Sjoerg   if (Operand->isSubClassOf("unknown_class"))
17017330f729Sjoerg     return false;
17027330f729Sjoerg 
17037330f729Sjoerg   // The Operand class specifies a type directly.
17047330f729Sjoerg   if (Operand->isSubClassOf("Operand")) {
17057330f729Sjoerg     Record *R = Operand->getValueAsDef("Type");
17067330f729Sjoerg     const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
17077330f729Sjoerg     return UpdateNodeType(ResNo, getValueTypeByHwMode(R, T.getHwModes()), TP);
17087330f729Sjoerg   }
17097330f729Sjoerg 
17107330f729Sjoerg   // PointerLikeRegClass has a type that is determined at runtime.
17117330f729Sjoerg   if (Operand->isSubClassOf("PointerLikeRegClass"))
17127330f729Sjoerg     return UpdateNodeType(ResNo, MVT::iPTR, TP);
17137330f729Sjoerg 
17147330f729Sjoerg   // Both RegisterClass and RegisterOperand operands derive their types from a
17157330f729Sjoerg   // register class def.
17167330f729Sjoerg   Record *RC = nullptr;
17177330f729Sjoerg   if (Operand->isSubClassOf("RegisterClass"))
17187330f729Sjoerg     RC = Operand;
17197330f729Sjoerg   else if (Operand->isSubClassOf("RegisterOperand"))
17207330f729Sjoerg     RC = Operand->getValueAsDef("RegClass");
17217330f729Sjoerg 
17227330f729Sjoerg   assert(RC && "Unknown operand type");
17237330f729Sjoerg   CodeGenTarget &Tgt = TP.getDAGPatterns().getTargetInfo();
17247330f729Sjoerg   return UpdateNodeType(ResNo, Tgt.getRegisterClass(RC).getValueTypes(), TP);
17257330f729Sjoerg }
17267330f729Sjoerg 
ContainsUnresolvedType(TreePattern & TP) const17277330f729Sjoerg bool TreePatternNode::ContainsUnresolvedType(TreePattern &TP) const {
17287330f729Sjoerg   for (unsigned i = 0, e = Types.size(); i != e; ++i)
17297330f729Sjoerg     if (!TP.getInfer().isConcrete(Types[i], true))
17307330f729Sjoerg       return true;
17317330f729Sjoerg   for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
17327330f729Sjoerg     if (getChild(i)->ContainsUnresolvedType(TP))
17337330f729Sjoerg       return true;
17347330f729Sjoerg   return false;
17357330f729Sjoerg }
17367330f729Sjoerg 
hasProperTypeByHwMode() const17377330f729Sjoerg bool TreePatternNode::hasProperTypeByHwMode() const {
17387330f729Sjoerg   for (const TypeSetByHwMode &S : Types)
17397330f729Sjoerg     if (!S.isDefaultOnly())
17407330f729Sjoerg       return true;
17417330f729Sjoerg   for (const TreePatternNodePtr &C : Children)
17427330f729Sjoerg     if (C->hasProperTypeByHwMode())
17437330f729Sjoerg       return true;
17447330f729Sjoerg   return false;
17457330f729Sjoerg }
17467330f729Sjoerg 
hasPossibleType() const17477330f729Sjoerg bool TreePatternNode::hasPossibleType() const {
17487330f729Sjoerg   for (const TypeSetByHwMode &S : Types)
17497330f729Sjoerg     if (!S.isPossible())
17507330f729Sjoerg       return false;
17517330f729Sjoerg   for (const TreePatternNodePtr &C : Children)
17527330f729Sjoerg     if (!C->hasPossibleType())
17537330f729Sjoerg       return false;
17547330f729Sjoerg   return true;
17557330f729Sjoerg }
17567330f729Sjoerg 
setDefaultMode(unsigned Mode)17577330f729Sjoerg bool TreePatternNode::setDefaultMode(unsigned Mode) {
17587330f729Sjoerg   for (TypeSetByHwMode &S : Types) {
17597330f729Sjoerg     S.makeSimple(Mode);
17607330f729Sjoerg     // Check if the selected mode had a type conflict.
17617330f729Sjoerg     if (S.get(DefaultMode).empty())
17627330f729Sjoerg       return false;
17637330f729Sjoerg   }
17647330f729Sjoerg   for (const TreePatternNodePtr &C : Children)
17657330f729Sjoerg     if (!C->setDefaultMode(Mode))
17667330f729Sjoerg       return false;
17677330f729Sjoerg   return true;
17687330f729Sjoerg }
17697330f729Sjoerg 
17707330f729Sjoerg //===----------------------------------------------------------------------===//
17717330f729Sjoerg // SDNodeInfo implementation
17727330f729Sjoerg //
SDNodeInfo(Record * R,const CodeGenHwModes & CGH)17737330f729Sjoerg SDNodeInfo::SDNodeInfo(Record *R, const CodeGenHwModes &CGH) : Def(R) {
17747330f729Sjoerg   EnumName    = R->getValueAsString("Opcode");
17757330f729Sjoerg   SDClassName = R->getValueAsString("SDClass");
17767330f729Sjoerg   Record *TypeProfile = R->getValueAsDef("TypeProfile");
17777330f729Sjoerg   NumResults = TypeProfile->getValueAsInt("NumResults");
17787330f729Sjoerg   NumOperands = TypeProfile->getValueAsInt("NumOperands");
17797330f729Sjoerg 
17807330f729Sjoerg   // Parse the properties.
17817330f729Sjoerg   Properties = parseSDPatternOperatorProperties(R);
17827330f729Sjoerg 
17837330f729Sjoerg   // Parse the type constraints.
17847330f729Sjoerg   std::vector<Record*> ConstraintList =
17857330f729Sjoerg     TypeProfile->getValueAsListOfDefs("Constraints");
17867330f729Sjoerg   for (Record *R : ConstraintList)
17877330f729Sjoerg     TypeConstraints.emplace_back(R, CGH);
17887330f729Sjoerg }
17897330f729Sjoerg 
17907330f729Sjoerg /// getKnownType - If the type constraints on this node imply a fixed type
17917330f729Sjoerg /// (e.g. all stores return void, etc), then return it as an
17927330f729Sjoerg /// MVT::SimpleValueType.  Otherwise, return EEVT::Other.
getKnownType(unsigned ResNo) const17937330f729Sjoerg MVT::SimpleValueType SDNodeInfo::getKnownType(unsigned ResNo) const {
17947330f729Sjoerg   unsigned NumResults = getNumResults();
17957330f729Sjoerg   assert(NumResults <= 1 &&
17967330f729Sjoerg          "We only work with nodes with zero or one result so far!");
17977330f729Sjoerg   assert(ResNo == 0 && "Only handles single result nodes so far");
17987330f729Sjoerg 
17997330f729Sjoerg   for (const SDTypeConstraint &Constraint : TypeConstraints) {
18007330f729Sjoerg     // Make sure that this applies to the correct node result.
18017330f729Sjoerg     if (Constraint.OperandNo >= NumResults)  // FIXME: need value #
18027330f729Sjoerg       continue;
18037330f729Sjoerg 
18047330f729Sjoerg     switch (Constraint.ConstraintType) {
18057330f729Sjoerg     default: break;
18067330f729Sjoerg     case SDTypeConstraint::SDTCisVT:
18077330f729Sjoerg       if (Constraint.VVT.isSimple())
18087330f729Sjoerg         return Constraint.VVT.getSimple().SimpleTy;
18097330f729Sjoerg       break;
18107330f729Sjoerg     case SDTypeConstraint::SDTCisPtrTy:
18117330f729Sjoerg       return MVT::iPTR;
18127330f729Sjoerg     }
18137330f729Sjoerg   }
18147330f729Sjoerg   return MVT::Other;
18157330f729Sjoerg }
18167330f729Sjoerg 
18177330f729Sjoerg //===----------------------------------------------------------------------===//
18187330f729Sjoerg // TreePatternNode implementation
18197330f729Sjoerg //
18207330f729Sjoerg 
GetNumNodeResults(Record * Operator,CodeGenDAGPatterns & CDP)18217330f729Sjoerg static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
18227330f729Sjoerg   if (Operator->getName() == "set" ||
18237330f729Sjoerg       Operator->getName() == "implicit")
18247330f729Sjoerg     return 0;  // All return nothing.
18257330f729Sjoerg 
18267330f729Sjoerg   if (Operator->isSubClassOf("Intrinsic"))
18277330f729Sjoerg     return CDP.getIntrinsic(Operator).IS.RetVTs.size();
18287330f729Sjoerg 
18297330f729Sjoerg   if (Operator->isSubClassOf("SDNode"))
18307330f729Sjoerg     return CDP.getSDNodeInfo(Operator).getNumResults();
18317330f729Sjoerg 
18327330f729Sjoerg   if (Operator->isSubClassOf("PatFrags")) {
18337330f729Sjoerg     // If we've already parsed this pattern fragment, get it.  Otherwise, handle
18347330f729Sjoerg     // the forward reference case where one pattern fragment references another
18357330f729Sjoerg     // before it is processed.
18367330f729Sjoerg     if (TreePattern *PFRec = CDP.getPatternFragmentIfRead(Operator)) {
18377330f729Sjoerg       // The number of results of a fragment with alternative records is the
18387330f729Sjoerg       // maximum number of results across all alternatives.
18397330f729Sjoerg       unsigned NumResults = 0;
1840*82d56013Sjoerg       for (const auto &T : PFRec->getTrees())
18417330f729Sjoerg         NumResults = std::max(NumResults, T->getNumTypes());
18427330f729Sjoerg       return NumResults;
18437330f729Sjoerg     }
18447330f729Sjoerg 
18457330f729Sjoerg     ListInit *LI = Operator->getValueAsListInit("Fragments");
18467330f729Sjoerg     assert(LI && "Invalid Fragment");
18477330f729Sjoerg     unsigned NumResults = 0;
18487330f729Sjoerg     for (Init *I : LI->getValues()) {
18497330f729Sjoerg       Record *Op = nullptr;
18507330f729Sjoerg       if (DagInit *Dag = dyn_cast<DagInit>(I))
18517330f729Sjoerg         if (DefInit *DI = dyn_cast<DefInit>(Dag->getOperator()))
18527330f729Sjoerg           Op = DI->getDef();
18537330f729Sjoerg       assert(Op && "Invalid Fragment");
18547330f729Sjoerg       NumResults = std::max(NumResults, GetNumNodeResults(Op, CDP));
18557330f729Sjoerg     }
18567330f729Sjoerg     return NumResults;
18577330f729Sjoerg   }
18587330f729Sjoerg 
18597330f729Sjoerg   if (Operator->isSubClassOf("Instruction")) {
18607330f729Sjoerg     CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator);
18617330f729Sjoerg 
18627330f729Sjoerg     unsigned NumDefsToAdd = InstInfo.Operands.NumDefs;
18637330f729Sjoerg 
18647330f729Sjoerg     // Subtract any defaulted outputs.
18657330f729Sjoerg     for (unsigned i = 0; i != InstInfo.Operands.NumDefs; ++i) {
18667330f729Sjoerg       Record *OperandNode = InstInfo.Operands[i].Rec;
18677330f729Sjoerg 
18687330f729Sjoerg       if (OperandNode->isSubClassOf("OperandWithDefaultOps") &&
18697330f729Sjoerg           !CDP.getDefaultOperand(OperandNode).DefaultOps.empty())
18707330f729Sjoerg         --NumDefsToAdd;
18717330f729Sjoerg     }
18727330f729Sjoerg 
18737330f729Sjoerg     // Add on one implicit def if it has a resolvable type.
18747330f729Sjoerg     if (InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()) !=MVT::Other)
18757330f729Sjoerg       ++NumDefsToAdd;
18767330f729Sjoerg     return NumDefsToAdd;
18777330f729Sjoerg   }
18787330f729Sjoerg 
18797330f729Sjoerg   if (Operator->isSubClassOf("SDNodeXForm"))
18807330f729Sjoerg     return 1;  // FIXME: Generalize SDNodeXForm
18817330f729Sjoerg 
18827330f729Sjoerg   if (Operator->isSubClassOf("ValueType"))
18837330f729Sjoerg     return 1;  // A type-cast of one result.
18847330f729Sjoerg 
18857330f729Sjoerg   if (Operator->isSubClassOf("ComplexPattern"))
18867330f729Sjoerg     return 1;
18877330f729Sjoerg 
18887330f729Sjoerg   errs() << *Operator;
18897330f729Sjoerg   PrintFatalError("Unhandled node in GetNumNodeResults");
18907330f729Sjoerg }
18917330f729Sjoerg 
print(raw_ostream & OS) const18927330f729Sjoerg void TreePatternNode::print(raw_ostream &OS) const {
18937330f729Sjoerg   if (isLeaf())
18947330f729Sjoerg     OS << *getLeafValue();
18957330f729Sjoerg   else
18967330f729Sjoerg     OS << '(' << getOperator()->getName();
18977330f729Sjoerg 
18987330f729Sjoerg   for (unsigned i = 0, e = Types.size(); i != e; ++i) {
18997330f729Sjoerg     OS << ':';
19007330f729Sjoerg     getExtType(i).writeToStream(OS);
19017330f729Sjoerg   }
19027330f729Sjoerg 
19037330f729Sjoerg   if (!isLeaf()) {
19047330f729Sjoerg     if (getNumChildren() != 0) {
19057330f729Sjoerg       OS << " ";
1906*82d56013Sjoerg       ListSeparator LS;
1907*82d56013Sjoerg       for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
1908*82d56013Sjoerg         OS << LS;
19097330f729Sjoerg         getChild(i)->print(OS);
19107330f729Sjoerg       }
19117330f729Sjoerg     }
19127330f729Sjoerg     OS << ")";
19137330f729Sjoerg   }
19147330f729Sjoerg 
19157330f729Sjoerg   for (const TreePredicateCall &Pred : PredicateCalls) {
19167330f729Sjoerg     OS << "<<P:";
19177330f729Sjoerg     if (Pred.Scope)
19187330f729Sjoerg       OS << Pred.Scope << ":";
19197330f729Sjoerg     OS << Pred.Fn.getFnName() << ">>";
19207330f729Sjoerg   }
19217330f729Sjoerg   if (TransformFn)
19227330f729Sjoerg     OS << "<<X:" << TransformFn->getName() << ">>";
19237330f729Sjoerg   if (!getName().empty())
19247330f729Sjoerg     OS << ":$" << getName();
19257330f729Sjoerg 
19267330f729Sjoerg   for (const ScopedName &Name : NamesAsPredicateArg)
19277330f729Sjoerg     OS << ":$pred:" << Name.getScope() << ":" << Name.getIdentifier();
19287330f729Sjoerg }
dump() const19297330f729Sjoerg void TreePatternNode::dump() const {
19307330f729Sjoerg   print(errs());
19317330f729Sjoerg }
19327330f729Sjoerg 
19337330f729Sjoerg /// isIsomorphicTo - Return true if this node is recursively
19347330f729Sjoerg /// isomorphic to the specified node.  For this comparison, the node's
19357330f729Sjoerg /// entire state is considered. The assigned name is ignored, since
19367330f729Sjoerg /// nodes with differing names are considered isomorphic. However, if
19377330f729Sjoerg /// the assigned name is present in the dependent variable set, then
19387330f729Sjoerg /// the assigned name is considered significant and the node is
19397330f729Sjoerg /// isomorphic if the names match.
isIsomorphicTo(const TreePatternNode * N,const MultipleUseVarSet & DepVars) const19407330f729Sjoerg bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N,
19417330f729Sjoerg                                      const MultipleUseVarSet &DepVars) const {
19427330f729Sjoerg   if (N == this) return true;
19437330f729Sjoerg   if (N->isLeaf() != isLeaf() || getExtTypes() != N->getExtTypes() ||
19447330f729Sjoerg       getPredicateCalls() != N->getPredicateCalls() ||
19457330f729Sjoerg       getTransformFn() != N->getTransformFn())
19467330f729Sjoerg     return false;
19477330f729Sjoerg 
19487330f729Sjoerg   if (isLeaf()) {
19497330f729Sjoerg     if (DefInit *DI = dyn_cast<DefInit>(getLeafValue())) {
19507330f729Sjoerg       if (DefInit *NDI = dyn_cast<DefInit>(N->getLeafValue())) {
19517330f729Sjoerg         return ((DI->getDef() == NDI->getDef())
19527330f729Sjoerg                 && (DepVars.find(getName()) == DepVars.end()
19537330f729Sjoerg                     || getName() == N->getName()));
19547330f729Sjoerg       }
19557330f729Sjoerg     }
19567330f729Sjoerg     return getLeafValue() == N->getLeafValue();
19577330f729Sjoerg   }
19587330f729Sjoerg 
19597330f729Sjoerg   if (N->getOperator() != getOperator() ||
19607330f729Sjoerg       N->getNumChildren() != getNumChildren()) return false;
19617330f729Sjoerg   for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
19627330f729Sjoerg     if (!getChild(i)->isIsomorphicTo(N->getChild(i), DepVars))
19637330f729Sjoerg       return false;
19647330f729Sjoerg   return true;
19657330f729Sjoerg }
19667330f729Sjoerg 
19677330f729Sjoerg /// clone - Make a copy of this tree and all of its children.
19687330f729Sjoerg ///
clone() const19697330f729Sjoerg TreePatternNodePtr TreePatternNode::clone() const {
19707330f729Sjoerg   TreePatternNodePtr New;
19717330f729Sjoerg   if (isLeaf()) {
19727330f729Sjoerg     New = std::make_shared<TreePatternNode>(getLeafValue(), getNumTypes());
19737330f729Sjoerg   } else {
19747330f729Sjoerg     std::vector<TreePatternNodePtr> CChildren;
19757330f729Sjoerg     CChildren.reserve(Children.size());
19767330f729Sjoerg     for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
19777330f729Sjoerg       CChildren.push_back(getChild(i)->clone());
19787330f729Sjoerg     New = std::make_shared<TreePatternNode>(getOperator(), std::move(CChildren),
19797330f729Sjoerg                                             getNumTypes());
19807330f729Sjoerg   }
19817330f729Sjoerg   New->setName(getName());
19827330f729Sjoerg   New->setNamesAsPredicateArg(getNamesAsPredicateArg());
19837330f729Sjoerg   New->Types = Types;
19847330f729Sjoerg   New->setPredicateCalls(getPredicateCalls());
19857330f729Sjoerg   New->setTransformFn(getTransformFn());
19867330f729Sjoerg   return New;
19877330f729Sjoerg }
19887330f729Sjoerg 
19897330f729Sjoerg /// RemoveAllTypes - Recursively strip all the types of this tree.
RemoveAllTypes()19907330f729Sjoerg void TreePatternNode::RemoveAllTypes() {
19917330f729Sjoerg   // Reset to unknown type.
19927330f729Sjoerg   std::fill(Types.begin(), Types.end(), TypeSetByHwMode());
19937330f729Sjoerg   if (isLeaf()) return;
19947330f729Sjoerg   for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
19957330f729Sjoerg     getChild(i)->RemoveAllTypes();
19967330f729Sjoerg }
19977330f729Sjoerg 
19987330f729Sjoerg 
19997330f729Sjoerg /// SubstituteFormalArguments - Replace the formal arguments in this tree
20007330f729Sjoerg /// with actual values specified by ArgMap.
SubstituteFormalArguments(std::map<std::string,TreePatternNodePtr> & ArgMap)20017330f729Sjoerg void TreePatternNode::SubstituteFormalArguments(
20027330f729Sjoerg     std::map<std::string, TreePatternNodePtr> &ArgMap) {
20037330f729Sjoerg   if (isLeaf()) return;
20047330f729Sjoerg 
20057330f729Sjoerg   for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
20067330f729Sjoerg     TreePatternNode *Child = getChild(i);
20077330f729Sjoerg     if (Child->isLeaf()) {
20087330f729Sjoerg       Init *Val = Child->getLeafValue();
20097330f729Sjoerg       // Note that, when substituting into an output pattern, Val might be an
20107330f729Sjoerg       // UnsetInit.
20117330f729Sjoerg       if (isa<UnsetInit>(Val) || (isa<DefInit>(Val) &&
20127330f729Sjoerg           cast<DefInit>(Val)->getDef()->getName() == "node")) {
20137330f729Sjoerg         // We found a use of a formal argument, replace it with its value.
20147330f729Sjoerg         TreePatternNodePtr NewChild = ArgMap[Child->getName()];
20157330f729Sjoerg         assert(NewChild && "Couldn't find formal argument!");
20167330f729Sjoerg         assert((Child->getPredicateCalls().empty() ||
20177330f729Sjoerg                 NewChild->getPredicateCalls() == Child->getPredicateCalls()) &&
20187330f729Sjoerg                "Non-empty child predicate clobbered!");
20197330f729Sjoerg         setChild(i, std::move(NewChild));
20207330f729Sjoerg       }
20217330f729Sjoerg     } else {
20227330f729Sjoerg       getChild(i)->SubstituteFormalArguments(ArgMap);
20237330f729Sjoerg     }
20247330f729Sjoerg   }
20257330f729Sjoerg }
20267330f729Sjoerg 
20277330f729Sjoerg 
20287330f729Sjoerg /// InlinePatternFragments - If this pattern refers to any pattern
20297330f729Sjoerg /// fragments, return the set of inlined versions (this can be more than
20307330f729Sjoerg /// one if a PatFrags record has multiple alternatives).
InlinePatternFragments(TreePatternNodePtr T,TreePattern & TP,std::vector<TreePatternNodePtr> & OutAlternatives)20317330f729Sjoerg void TreePatternNode::InlinePatternFragments(
20327330f729Sjoerg   TreePatternNodePtr T, TreePattern &TP,
20337330f729Sjoerg   std::vector<TreePatternNodePtr> &OutAlternatives) {
20347330f729Sjoerg 
20357330f729Sjoerg   if (TP.hasError())
20367330f729Sjoerg     return;
20377330f729Sjoerg 
20387330f729Sjoerg   if (isLeaf()) {
20397330f729Sjoerg     OutAlternatives.push_back(T);  // nothing to do.
20407330f729Sjoerg     return;
20417330f729Sjoerg   }
20427330f729Sjoerg 
20437330f729Sjoerg   Record *Op = getOperator();
20447330f729Sjoerg 
20457330f729Sjoerg   if (!Op->isSubClassOf("PatFrags")) {
20467330f729Sjoerg     if (getNumChildren() == 0) {
20477330f729Sjoerg       OutAlternatives.push_back(T);
20487330f729Sjoerg       return;
20497330f729Sjoerg     }
20507330f729Sjoerg 
20517330f729Sjoerg     // Recursively inline children nodes.
20527330f729Sjoerg     std::vector<std::vector<TreePatternNodePtr> > ChildAlternatives;
20537330f729Sjoerg     ChildAlternatives.resize(getNumChildren());
20547330f729Sjoerg     for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
20557330f729Sjoerg       TreePatternNodePtr Child = getChildShared(i);
20567330f729Sjoerg       Child->InlinePatternFragments(Child, TP, ChildAlternatives[i]);
20577330f729Sjoerg       // If there are no alternatives for any child, there are no
20587330f729Sjoerg       // alternatives for this expression as whole.
20597330f729Sjoerg       if (ChildAlternatives[i].empty())
20607330f729Sjoerg         return;
20617330f729Sjoerg 
20627330f729Sjoerg       assert((Child->getPredicateCalls().empty() ||
2063*82d56013Sjoerg               llvm::all_of(ChildAlternatives[i],
2064*82d56013Sjoerg                            [&](const TreePatternNodePtr &NewChild) {
2065*82d56013Sjoerg                              return NewChild->getPredicateCalls() ==
2066*82d56013Sjoerg                                     Child->getPredicateCalls();
2067*82d56013Sjoerg                            })) &&
20687330f729Sjoerg              "Non-empty child predicate clobbered!");
20697330f729Sjoerg     }
20707330f729Sjoerg 
20717330f729Sjoerg     // The end result is an all-pairs construction of the resultant pattern.
20727330f729Sjoerg     std::vector<unsigned> Idxs;
20737330f729Sjoerg     Idxs.resize(ChildAlternatives.size());
20747330f729Sjoerg     bool NotDone;
20757330f729Sjoerg     do {
20767330f729Sjoerg       // Create the variant and add it to the output list.
20777330f729Sjoerg       std::vector<TreePatternNodePtr> NewChildren;
20787330f729Sjoerg       for (unsigned i = 0, e = ChildAlternatives.size(); i != e; ++i)
20797330f729Sjoerg         NewChildren.push_back(ChildAlternatives[i][Idxs[i]]);
20807330f729Sjoerg       TreePatternNodePtr R = std::make_shared<TreePatternNode>(
20817330f729Sjoerg           getOperator(), std::move(NewChildren), getNumTypes());
20827330f729Sjoerg 
20837330f729Sjoerg       // Copy over properties.
20847330f729Sjoerg       R->setName(getName());
20857330f729Sjoerg       R->setNamesAsPredicateArg(getNamesAsPredicateArg());
20867330f729Sjoerg       R->setPredicateCalls(getPredicateCalls());
20877330f729Sjoerg       R->setTransformFn(getTransformFn());
20887330f729Sjoerg       for (unsigned i = 0, e = getNumTypes(); i != e; ++i)
20897330f729Sjoerg         R->setType(i, getExtType(i));
20907330f729Sjoerg       for (unsigned i = 0, e = getNumResults(); i != e; ++i)
20917330f729Sjoerg         R->setResultIndex(i, getResultIndex(i));
20927330f729Sjoerg 
20937330f729Sjoerg       // Register alternative.
20947330f729Sjoerg       OutAlternatives.push_back(R);
20957330f729Sjoerg 
20967330f729Sjoerg       // Increment indices to the next permutation by incrementing the
20977330f729Sjoerg       // indices from last index backward, e.g., generate the sequence
20987330f729Sjoerg       // [0, 0], [0, 1], [1, 0], [1, 1].
20997330f729Sjoerg       int IdxsIdx;
21007330f729Sjoerg       for (IdxsIdx = Idxs.size() - 1; IdxsIdx >= 0; --IdxsIdx) {
21017330f729Sjoerg         if (++Idxs[IdxsIdx] == ChildAlternatives[IdxsIdx].size())
21027330f729Sjoerg           Idxs[IdxsIdx] = 0;
21037330f729Sjoerg         else
21047330f729Sjoerg           break;
21057330f729Sjoerg       }
21067330f729Sjoerg       NotDone = (IdxsIdx >= 0);
21077330f729Sjoerg     } while (NotDone);
21087330f729Sjoerg 
21097330f729Sjoerg     return;
21107330f729Sjoerg   }
21117330f729Sjoerg 
21127330f729Sjoerg   // Otherwise, we found a reference to a fragment.  First, look up its
21137330f729Sjoerg   // TreePattern record.
21147330f729Sjoerg   TreePattern *Frag = TP.getDAGPatterns().getPatternFragment(Op);
21157330f729Sjoerg 
21167330f729Sjoerg   // Verify that we are passing the right number of operands.
21177330f729Sjoerg   if (Frag->getNumArgs() != Children.size()) {
21187330f729Sjoerg     TP.error("'" + Op->getName() + "' fragment requires " +
21197330f729Sjoerg              Twine(Frag->getNumArgs()) + " operands!");
21207330f729Sjoerg     return;
21217330f729Sjoerg   }
21227330f729Sjoerg 
21237330f729Sjoerg   TreePredicateFn PredFn(Frag);
21247330f729Sjoerg   unsigned Scope = 0;
21257330f729Sjoerg   if (TreePredicateFn(Frag).usesOperands())
21267330f729Sjoerg     Scope = TP.getDAGPatterns().allocateScope();
21277330f729Sjoerg 
21287330f729Sjoerg   // Compute the map of formal to actual arguments.
21297330f729Sjoerg   std::map<std::string, TreePatternNodePtr> ArgMap;
21307330f729Sjoerg   for (unsigned i = 0, e = Frag->getNumArgs(); i != e; ++i) {
21317330f729Sjoerg     TreePatternNodePtr Child = getChildShared(i);
21327330f729Sjoerg     if (Scope != 0) {
21337330f729Sjoerg       Child = Child->clone();
21347330f729Sjoerg       Child->addNameAsPredicateArg(ScopedName(Scope, Frag->getArgName(i)));
21357330f729Sjoerg     }
21367330f729Sjoerg     ArgMap[Frag->getArgName(i)] = Child;
21377330f729Sjoerg   }
21387330f729Sjoerg 
21397330f729Sjoerg   // Loop over all fragment alternatives.
2140*82d56013Sjoerg   for (const auto &Alternative : Frag->getTrees()) {
21417330f729Sjoerg     TreePatternNodePtr FragTree = Alternative->clone();
21427330f729Sjoerg 
21437330f729Sjoerg     if (!PredFn.isAlwaysTrue())
21447330f729Sjoerg       FragTree->addPredicateCall(PredFn, Scope);
21457330f729Sjoerg 
21467330f729Sjoerg     // Resolve formal arguments to their actual value.
21477330f729Sjoerg     if (Frag->getNumArgs())
21487330f729Sjoerg       FragTree->SubstituteFormalArguments(ArgMap);
21497330f729Sjoerg 
21507330f729Sjoerg     // Transfer types.  Note that the resolved alternative may have fewer
21517330f729Sjoerg     // (but not more) results than the PatFrags node.
21527330f729Sjoerg     FragTree->setName(getName());
21537330f729Sjoerg     for (unsigned i = 0, e = FragTree->getNumTypes(); i != e; ++i)
21547330f729Sjoerg       FragTree->UpdateNodeType(i, getExtType(i), TP);
21557330f729Sjoerg 
21567330f729Sjoerg     // Transfer in the old predicates.
21577330f729Sjoerg     for (const TreePredicateCall &Pred : getPredicateCalls())
21587330f729Sjoerg       FragTree->addPredicateCall(Pred);
21597330f729Sjoerg 
21607330f729Sjoerg     // The fragment we inlined could have recursive inlining that is needed.  See
21617330f729Sjoerg     // if there are any pattern fragments in it and inline them as needed.
21627330f729Sjoerg     FragTree->InlinePatternFragments(FragTree, TP, OutAlternatives);
21637330f729Sjoerg   }
21647330f729Sjoerg }
21657330f729Sjoerg 
21667330f729Sjoerg /// getImplicitType - Check to see if the specified record has an implicit
21677330f729Sjoerg /// type which should be applied to it.  This will infer the type of register
21687330f729Sjoerg /// references from the register file information, for example.
21697330f729Sjoerg ///
21707330f729Sjoerg /// When Unnamed is set, return the type of a DAG operand with no name, such as
21717330f729Sjoerg /// the F8RC register class argument in:
21727330f729Sjoerg ///
21737330f729Sjoerg ///   (COPY_TO_REGCLASS GPR:$src, F8RC)
21747330f729Sjoerg ///
21757330f729Sjoerg /// When Unnamed is false, return the type of a named DAG operand such as the
21767330f729Sjoerg /// GPR:$src operand above.
21777330f729Sjoerg ///
getImplicitType(Record * R,unsigned ResNo,bool NotRegisters,bool Unnamed,TreePattern & TP)21787330f729Sjoerg static TypeSetByHwMode getImplicitType(Record *R, unsigned ResNo,
21797330f729Sjoerg                                        bool NotRegisters,
21807330f729Sjoerg                                        bool Unnamed,
21817330f729Sjoerg                                        TreePattern &TP) {
21827330f729Sjoerg   CodeGenDAGPatterns &CDP = TP.getDAGPatterns();
21837330f729Sjoerg 
21847330f729Sjoerg   // Check to see if this is a register operand.
21857330f729Sjoerg   if (R->isSubClassOf("RegisterOperand")) {
21867330f729Sjoerg     assert(ResNo == 0 && "Regoperand ref only has one result!");
21877330f729Sjoerg     if (NotRegisters)
21887330f729Sjoerg       return TypeSetByHwMode(); // Unknown.
21897330f729Sjoerg     Record *RegClass = R->getValueAsDef("RegClass");
21907330f729Sjoerg     const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
21917330f729Sjoerg     return TypeSetByHwMode(T.getRegisterClass(RegClass).getValueTypes());
21927330f729Sjoerg   }
21937330f729Sjoerg 
21947330f729Sjoerg   // Check to see if this is a register or a register class.
21957330f729Sjoerg   if (R->isSubClassOf("RegisterClass")) {
21967330f729Sjoerg     assert(ResNo == 0 && "Regclass ref only has one result!");
21977330f729Sjoerg     // An unnamed register class represents itself as an i32 immediate, for
21987330f729Sjoerg     // example on a COPY_TO_REGCLASS instruction.
21997330f729Sjoerg     if (Unnamed)
22007330f729Sjoerg       return TypeSetByHwMode(MVT::i32);
22017330f729Sjoerg 
22027330f729Sjoerg     // In a named operand, the register class provides the possible set of
22037330f729Sjoerg     // types.
22047330f729Sjoerg     if (NotRegisters)
22057330f729Sjoerg       return TypeSetByHwMode(); // Unknown.
22067330f729Sjoerg     const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
22077330f729Sjoerg     return TypeSetByHwMode(T.getRegisterClass(R).getValueTypes());
22087330f729Sjoerg   }
22097330f729Sjoerg 
22107330f729Sjoerg   if (R->isSubClassOf("PatFrags")) {
22117330f729Sjoerg     assert(ResNo == 0 && "FIXME: PatFrag with multiple results?");
22127330f729Sjoerg     // Pattern fragment types will be resolved when they are inlined.
22137330f729Sjoerg     return TypeSetByHwMode(); // Unknown.
22147330f729Sjoerg   }
22157330f729Sjoerg 
22167330f729Sjoerg   if (R->isSubClassOf("Register")) {
22177330f729Sjoerg     assert(ResNo == 0 && "Registers only produce one result!");
22187330f729Sjoerg     if (NotRegisters)
22197330f729Sjoerg       return TypeSetByHwMode(); // Unknown.
22207330f729Sjoerg     const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
22217330f729Sjoerg     return TypeSetByHwMode(T.getRegisterVTs(R));
22227330f729Sjoerg   }
22237330f729Sjoerg 
22247330f729Sjoerg   if (R->isSubClassOf("SubRegIndex")) {
22257330f729Sjoerg     assert(ResNo == 0 && "SubRegisterIndices only produce one result!");
22267330f729Sjoerg     return TypeSetByHwMode(MVT::i32);
22277330f729Sjoerg   }
22287330f729Sjoerg 
22297330f729Sjoerg   if (R->isSubClassOf("ValueType")) {
22307330f729Sjoerg     assert(ResNo == 0 && "This node only has one result!");
22317330f729Sjoerg     // An unnamed VTSDNode represents itself as an MVT::Other immediate.
22327330f729Sjoerg     //
22337330f729Sjoerg     //   (sext_inreg GPR:$src, i16)
22347330f729Sjoerg     //                         ~~~
22357330f729Sjoerg     if (Unnamed)
22367330f729Sjoerg       return TypeSetByHwMode(MVT::Other);
22377330f729Sjoerg     // With a name, the ValueType simply provides the type of the named
22387330f729Sjoerg     // variable.
22397330f729Sjoerg     //
22407330f729Sjoerg     //   (sext_inreg i32:$src, i16)
22417330f729Sjoerg     //               ~~~~~~~~
22427330f729Sjoerg     if (NotRegisters)
22437330f729Sjoerg       return TypeSetByHwMode(); // Unknown.
22447330f729Sjoerg     const CodeGenHwModes &CGH = CDP.getTargetInfo().getHwModes();
22457330f729Sjoerg     return TypeSetByHwMode(getValueTypeByHwMode(R, CGH));
22467330f729Sjoerg   }
22477330f729Sjoerg 
22487330f729Sjoerg   if (R->isSubClassOf("CondCode")) {
22497330f729Sjoerg     assert(ResNo == 0 && "This node only has one result!");
22507330f729Sjoerg     // Using a CondCodeSDNode.
22517330f729Sjoerg     return TypeSetByHwMode(MVT::Other);
22527330f729Sjoerg   }
22537330f729Sjoerg 
22547330f729Sjoerg   if (R->isSubClassOf("ComplexPattern")) {
22557330f729Sjoerg     assert(ResNo == 0 && "FIXME: ComplexPattern with multiple results?");
22567330f729Sjoerg     if (NotRegisters)
22577330f729Sjoerg       return TypeSetByHwMode(); // Unknown.
22587330f729Sjoerg     return TypeSetByHwMode(CDP.getComplexPattern(R).getValueType());
22597330f729Sjoerg   }
22607330f729Sjoerg   if (R->isSubClassOf("PointerLikeRegClass")) {
22617330f729Sjoerg     assert(ResNo == 0 && "Regclass can only have one result!");
22627330f729Sjoerg     TypeSetByHwMode VTS(MVT::iPTR);
22637330f729Sjoerg     TP.getInfer().expandOverloads(VTS);
22647330f729Sjoerg     return VTS;
22657330f729Sjoerg   }
22667330f729Sjoerg 
22677330f729Sjoerg   if (R->getName() == "node" || R->getName() == "srcvalue" ||
22687330f729Sjoerg       R->getName() == "zero_reg" || R->getName() == "immAllOnesV" ||
22697330f729Sjoerg       R->getName() == "immAllZerosV" || R->getName() == "undef_tied_input") {
22707330f729Sjoerg     // Placeholder.
22717330f729Sjoerg     return TypeSetByHwMode(); // Unknown.
22727330f729Sjoerg   }
22737330f729Sjoerg 
22747330f729Sjoerg   if (R->isSubClassOf("Operand")) {
22757330f729Sjoerg     const CodeGenHwModes &CGH = CDP.getTargetInfo().getHwModes();
22767330f729Sjoerg     Record *T = R->getValueAsDef("Type");
22777330f729Sjoerg     return TypeSetByHwMode(getValueTypeByHwMode(T, CGH));
22787330f729Sjoerg   }
22797330f729Sjoerg 
22807330f729Sjoerg   TP.error("Unknown node flavor used in pattern: " + R->getName());
22817330f729Sjoerg   return TypeSetByHwMode(MVT::Other);
22827330f729Sjoerg }
22837330f729Sjoerg 
22847330f729Sjoerg 
22857330f729Sjoerg /// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
22867330f729Sjoerg /// CodeGenIntrinsic information for it, otherwise return a null pointer.
22877330f729Sjoerg const CodeGenIntrinsic *TreePatternNode::
getIntrinsicInfo(const CodeGenDAGPatterns & CDP) const22887330f729Sjoerg getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const {
22897330f729Sjoerg   if (getOperator() != CDP.get_intrinsic_void_sdnode() &&
22907330f729Sjoerg       getOperator() != CDP.get_intrinsic_w_chain_sdnode() &&
22917330f729Sjoerg       getOperator() != CDP.get_intrinsic_wo_chain_sdnode())
22927330f729Sjoerg     return nullptr;
22937330f729Sjoerg 
22947330f729Sjoerg   unsigned IID = cast<IntInit>(getChild(0)->getLeafValue())->getValue();
22957330f729Sjoerg   return &CDP.getIntrinsicInfo(IID);
22967330f729Sjoerg }
22977330f729Sjoerg 
22987330f729Sjoerg /// getComplexPatternInfo - If this node corresponds to a ComplexPattern,
22997330f729Sjoerg /// return the ComplexPattern information, otherwise return null.
23007330f729Sjoerg const ComplexPattern *
getComplexPatternInfo(const CodeGenDAGPatterns & CGP) const23017330f729Sjoerg TreePatternNode::getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const {
23027330f729Sjoerg   Record *Rec;
23037330f729Sjoerg   if (isLeaf()) {
23047330f729Sjoerg     DefInit *DI = dyn_cast<DefInit>(getLeafValue());
23057330f729Sjoerg     if (!DI)
23067330f729Sjoerg       return nullptr;
23077330f729Sjoerg     Rec = DI->getDef();
23087330f729Sjoerg   } else
23097330f729Sjoerg     Rec = getOperator();
23107330f729Sjoerg 
23117330f729Sjoerg   if (!Rec->isSubClassOf("ComplexPattern"))
23127330f729Sjoerg     return nullptr;
23137330f729Sjoerg   return &CGP.getComplexPattern(Rec);
23147330f729Sjoerg }
23157330f729Sjoerg 
getNumMIResults(const CodeGenDAGPatterns & CGP) const23167330f729Sjoerg unsigned TreePatternNode::getNumMIResults(const CodeGenDAGPatterns &CGP) const {
23177330f729Sjoerg   // A ComplexPattern specifically declares how many results it fills in.
23187330f729Sjoerg   if (const ComplexPattern *CP = getComplexPatternInfo(CGP))
23197330f729Sjoerg     return CP->getNumOperands();
23207330f729Sjoerg 
23217330f729Sjoerg   // If MIOperandInfo is specified, that gives the count.
23227330f729Sjoerg   if (isLeaf()) {
23237330f729Sjoerg     DefInit *DI = dyn_cast<DefInit>(getLeafValue());
23247330f729Sjoerg     if (DI && DI->getDef()->isSubClassOf("Operand")) {
23257330f729Sjoerg       DagInit *MIOps = DI->getDef()->getValueAsDag("MIOperandInfo");
23267330f729Sjoerg       if (MIOps->getNumArgs())
23277330f729Sjoerg         return MIOps->getNumArgs();
23287330f729Sjoerg     }
23297330f729Sjoerg   }
23307330f729Sjoerg 
23317330f729Sjoerg   // Otherwise there is just one result.
23327330f729Sjoerg   return 1;
23337330f729Sjoerg }
23347330f729Sjoerg 
23357330f729Sjoerg /// NodeHasProperty - Return true if this node has the specified property.
NodeHasProperty(SDNP Property,const CodeGenDAGPatterns & CGP) const23367330f729Sjoerg bool TreePatternNode::NodeHasProperty(SDNP Property,
23377330f729Sjoerg                                       const CodeGenDAGPatterns &CGP) const {
23387330f729Sjoerg   if (isLeaf()) {
23397330f729Sjoerg     if (const ComplexPattern *CP = getComplexPatternInfo(CGP))
23407330f729Sjoerg       return CP->hasProperty(Property);
23417330f729Sjoerg 
23427330f729Sjoerg     return false;
23437330f729Sjoerg   }
23447330f729Sjoerg 
23457330f729Sjoerg   if (Property != SDNPHasChain) {
23467330f729Sjoerg     // The chain proprety is already present on the different intrinsic node
23477330f729Sjoerg     // types (intrinsic_w_chain, intrinsic_void), and is not explicitly listed
23487330f729Sjoerg     // on the intrinsic. Anything else is specific to the individual intrinsic.
23497330f729Sjoerg     if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CGP))
23507330f729Sjoerg       return Int->hasProperty(Property);
23517330f729Sjoerg   }
23527330f729Sjoerg 
23537330f729Sjoerg   if (!Operator->isSubClassOf("SDPatternOperator"))
23547330f729Sjoerg     return false;
23557330f729Sjoerg 
23567330f729Sjoerg   return CGP.getSDNodeInfo(Operator).hasProperty(Property);
23577330f729Sjoerg }
23587330f729Sjoerg 
23597330f729Sjoerg 
23607330f729Sjoerg 
23617330f729Sjoerg 
23627330f729Sjoerg /// TreeHasProperty - Return true if any node in this tree has the specified
23637330f729Sjoerg /// property.
TreeHasProperty(SDNP Property,const CodeGenDAGPatterns & CGP) const23647330f729Sjoerg bool TreePatternNode::TreeHasProperty(SDNP Property,
23657330f729Sjoerg                                       const CodeGenDAGPatterns &CGP) const {
23667330f729Sjoerg   if (NodeHasProperty(Property, CGP))
23677330f729Sjoerg     return true;
23687330f729Sjoerg   for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
23697330f729Sjoerg     if (getChild(i)->TreeHasProperty(Property, CGP))
23707330f729Sjoerg       return true;
23717330f729Sjoerg   return false;
23727330f729Sjoerg }
23737330f729Sjoerg 
23747330f729Sjoerg /// isCommutativeIntrinsic - Return true if the node corresponds to a
23757330f729Sjoerg /// commutative intrinsic.
23767330f729Sjoerg bool
isCommutativeIntrinsic(const CodeGenDAGPatterns & CDP) const23777330f729Sjoerg TreePatternNode::isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const {
23787330f729Sjoerg   if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP))
23797330f729Sjoerg     return Int->isCommutative;
23807330f729Sjoerg   return false;
23817330f729Sjoerg }
23827330f729Sjoerg 
isOperandClass(const TreePatternNode * N,StringRef Class)23837330f729Sjoerg static bool isOperandClass(const TreePatternNode *N, StringRef Class) {
23847330f729Sjoerg   if (!N->isLeaf())
23857330f729Sjoerg     return N->getOperator()->isSubClassOf(Class);
23867330f729Sjoerg 
23877330f729Sjoerg   DefInit *DI = dyn_cast<DefInit>(N->getLeafValue());
23887330f729Sjoerg   if (DI && DI->getDef()->isSubClassOf(Class))
23897330f729Sjoerg     return true;
23907330f729Sjoerg 
23917330f729Sjoerg   return false;
23927330f729Sjoerg }
23937330f729Sjoerg 
emitTooManyOperandsError(TreePattern & TP,StringRef InstName,unsigned Expected,unsigned Actual)23947330f729Sjoerg static void emitTooManyOperandsError(TreePattern &TP,
23957330f729Sjoerg                                      StringRef InstName,
23967330f729Sjoerg                                      unsigned Expected,
23977330f729Sjoerg                                      unsigned Actual) {
23987330f729Sjoerg   TP.error("Instruction '" + InstName + "' was provided " + Twine(Actual) +
23997330f729Sjoerg            " operands but expected only " + Twine(Expected) + "!");
24007330f729Sjoerg }
24017330f729Sjoerg 
emitTooFewOperandsError(TreePattern & TP,StringRef InstName,unsigned Actual)24027330f729Sjoerg static void emitTooFewOperandsError(TreePattern &TP,
24037330f729Sjoerg                                     StringRef InstName,
24047330f729Sjoerg                                     unsigned Actual) {
24057330f729Sjoerg   TP.error("Instruction '" + InstName +
24067330f729Sjoerg            "' expects more than the provided " + Twine(Actual) + " operands!");
24077330f729Sjoerg }
24087330f729Sjoerg 
24097330f729Sjoerg /// ApplyTypeConstraints - Apply all of the type constraints relevant to
24107330f729Sjoerg /// this node and its children in the tree.  This returns true if it makes a
24117330f729Sjoerg /// change, false otherwise.  If a type contradiction is found, flag an error.
ApplyTypeConstraints(TreePattern & TP,bool NotRegisters)24127330f729Sjoerg bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
24137330f729Sjoerg   if (TP.hasError())
24147330f729Sjoerg     return false;
24157330f729Sjoerg 
24167330f729Sjoerg   CodeGenDAGPatterns &CDP = TP.getDAGPatterns();
24177330f729Sjoerg   if (isLeaf()) {
24187330f729Sjoerg     if (DefInit *DI = dyn_cast<DefInit>(getLeafValue())) {
24197330f729Sjoerg       // If it's a regclass or something else known, include the type.
24207330f729Sjoerg       bool MadeChange = false;
24217330f729Sjoerg       for (unsigned i = 0, e = Types.size(); i != e; ++i)
24227330f729Sjoerg         MadeChange |= UpdateNodeType(i, getImplicitType(DI->getDef(), i,
24237330f729Sjoerg                                                         NotRegisters,
24247330f729Sjoerg                                                         !hasName(), TP), TP);
24257330f729Sjoerg       return MadeChange;
24267330f729Sjoerg     }
24277330f729Sjoerg 
24287330f729Sjoerg     if (IntInit *II = dyn_cast<IntInit>(getLeafValue())) {
24297330f729Sjoerg       assert(Types.size() == 1 && "Invalid IntInit");
24307330f729Sjoerg 
24317330f729Sjoerg       // Int inits are always integers. :)
24327330f729Sjoerg       bool MadeChange = TP.getInfer().EnforceInteger(Types[0]);
24337330f729Sjoerg 
24347330f729Sjoerg       if (!TP.getInfer().isConcrete(Types[0], false))
24357330f729Sjoerg         return MadeChange;
24367330f729Sjoerg 
24377330f729Sjoerg       ValueTypeByHwMode VVT = TP.getInfer().getConcrete(Types[0], false);
24387330f729Sjoerg       for (auto &P : VVT) {
24397330f729Sjoerg         MVT::SimpleValueType VT = P.second.SimpleTy;
24407330f729Sjoerg         if (VT == MVT::iPTR || VT == MVT::iPTRAny)
24417330f729Sjoerg           continue;
2442*82d56013Sjoerg         unsigned Size = MVT(VT).getFixedSizeInBits();
24437330f729Sjoerg         // Make sure that the value is representable for this type.
24447330f729Sjoerg         if (Size >= 32)
24457330f729Sjoerg           continue;
24467330f729Sjoerg         // Check that the value doesn't use more bits than we have. It must
24477330f729Sjoerg         // either be a sign- or zero-extended equivalent of the original.
24487330f729Sjoerg         int64_t SignBitAndAbove = II->getValue() >> (Size - 1);
24497330f729Sjoerg         if (SignBitAndAbove == -1 || SignBitAndAbove == 0 ||
24507330f729Sjoerg             SignBitAndAbove == 1)
24517330f729Sjoerg           continue;
24527330f729Sjoerg 
24537330f729Sjoerg         TP.error("Integer value '" + Twine(II->getValue()) +
24547330f729Sjoerg                  "' is out of range for type '" + getEnumName(VT) + "'!");
24557330f729Sjoerg         break;
24567330f729Sjoerg       }
24577330f729Sjoerg       return MadeChange;
24587330f729Sjoerg     }
24597330f729Sjoerg 
24607330f729Sjoerg     return false;
24617330f729Sjoerg   }
24627330f729Sjoerg 
24637330f729Sjoerg   if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) {
24647330f729Sjoerg     bool MadeChange = false;
24657330f729Sjoerg 
24667330f729Sjoerg     // Apply the result type to the node.
24677330f729Sjoerg     unsigned NumRetVTs = Int->IS.RetVTs.size();
24687330f729Sjoerg     unsigned NumParamVTs = Int->IS.ParamVTs.size();
24697330f729Sjoerg 
24707330f729Sjoerg     for (unsigned i = 0, e = NumRetVTs; i != e; ++i)
24717330f729Sjoerg       MadeChange |= UpdateNodeType(i, Int->IS.RetVTs[i], TP);
24727330f729Sjoerg 
24737330f729Sjoerg     if (getNumChildren() != NumParamVTs + 1) {
24747330f729Sjoerg       TP.error("Intrinsic '" + Int->Name + "' expects " + Twine(NumParamVTs) +
24757330f729Sjoerg                " operands, not " + Twine(getNumChildren() - 1) + " operands!");
24767330f729Sjoerg       return false;
24777330f729Sjoerg     }
24787330f729Sjoerg 
24797330f729Sjoerg     // Apply type info to the intrinsic ID.
24807330f729Sjoerg     MadeChange |= getChild(0)->UpdateNodeType(0, MVT::iPTR, TP);
24817330f729Sjoerg 
24827330f729Sjoerg     for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i) {
24837330f729Sjoerg       MadeChange |= getChild(i+1)->ApplyTypeConstraints(TP, NotRegisters);
24847330f729Sjoerg 
24857330f729Sjoerg       MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i];
24867330f729Sjoerg       assert(getChild(i+1)->getNumTypes() == 1 && "Unhandled case");
24877330f729Sjoerg       MadeChange |= getChild(i+1)->UpdateNodeType(0, OpVT, TP);
24887330f729Sjoerg     }
24897330f729Sjoerg     return MadeChange;
24907330f729Sjoerg   }
24917330f729Sjoerg 
24927330f729Sjoerg   if (getOperator()->isSubClassOf("SDNode")) {
24937330f729Sjoerg     const SDNodeInfo &NI = CDP.getSDNodeInfo(getOperator());
24947330f729Sjoerg 
24957330f729Sjoerg     // Check that the number of operands is sane.  Negative operands -> varargs.
24967330f729Sjoerg     if (NI.getNumOperands() >= 0 &&
24977330f729Sjoerg         getNumChildren() != (unsigned)NI.getNumOperands()) {
24987330f729Sjoerg       TP.error(getOperator()->getName() + " node requires exactly " +
24997330f729Sjoerg                Twine(NI.getNumOperands()) + " operands!");
25007330f729Sjoerg       return false;
25017330f729Sjoerg     }
25027330f729Sjoerg 
25037330f729Sjoerg     bool MadeChange = false;
25047330f729Sjoerg     for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
25057330f729Sjoerg       MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
25067330f729Sjoerg     MadeChange |= NI.ApplyTypeConstraints(this, TP);
25077330f729Sjoerg     return MadeChange;
25087330f729Sjoerg   }
25097330f729Sjoerg 
25107330f729Sjoerg   if (getOperator()->isSubClassOf("Instruction")) {
25117330f729Sjoerg     const DAGInstruction &Inst = CDP.getInstruction(getOperator());
25127330f729Sjoerg     CodeGenInstruction &InstInfo =
25137330f729Sjoerg       CDP.getTargetInfo().getInstruction(getOperator());
25147330f729Sjoerg 
25157330f729Sjoerg     bool MadeChange = false;
25167330f729Sjoerg 
25177330f729Sjoerg     // Apply the result types to the node, these come from the things in the
25187330f729Sjoerg     // (outs) list of the instruction.
25197330f729Sjoerg     unsigned NumResultsToAdd = std::min(InstInfo.Operands.NumDefs,
25207330f729Sjoerg                                         Inst.getNumResults());
25217330f729Sjoerg     for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo)
25227330f729Sjoerg       MadeChange |= UpdateNodeTypeFromInst(ResNo, Inst.getResult(ResNo), TP);
25237330f729Sjoerg 
25247330f729Sjoerg     // If the instruction has implicit defs, we apply the first one as a result.
25257330f729Sjoerg     // FIXME: This sucks, it should apply all implicit defs.
25267330f729Sjoerg     if (!InstInfo.ImplicitDefs.empty()) {
25277330f729Sjoerg       unsigned ResNo = NumResultsToAdd;
25287330f729Sjoerg 
25297330f729Sjoerg       // FIXME: Generalize to multiple possible types and multiple possible
25307330f729Sjoerg       // ImplicitDefs.
25317330f729Sjoerg       MVT::SimpleValueType VT =
25327330f729Sjoerg         InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo());
25337330f729Sjoerg 
25347330f729Sjoerg       if (VT != MVT::Other)
25357330f729Sjoerg         MadeChange |= UpdateNodeType(ResNo, VT, TP);
25367330f729Sjoerg     }
25377330f729Sjoerg 
25387330f729Sjoerg     // If this is an INSERT_SUBREG, constrain the source and destination VTs to
25397330f729Sjoerg     // be the same.
25407330f729Sjoerg     if (getOperator()->getName() == "INSERT_SUBREG") {
25417330f729Sjoerg       assert(getChild(0)->getNumTypes() == 1 && "FIXME: Unhandled");
25427330f729Sjoerg       MadeChange |= UpdateNodeType(0, getChild(0)->getExtType(0), TP);
25437330f729Sjoerg       MadeChange |= getChild(0)->UpdateNodeType(0, getExtType(0), TP);
25447330f729Sjoerg     } else if (getOperator()->getName() == "REG_SEQUENCE") {
25457330f729Sjoerg       // We need to do extra, custom typechecking for REG_SEQUENCE since it is
25467330f729Sjoerg       // variadic.
25477330f729Sjoerg 
25487330f729Sjoerg       unsigned NChild = getNumChildren();
25497330f729Sjoerg       if (NChild < 3) {
25507330f729Sjoerg         TP.error("REG_SEQUENCE requires at least 3 operands!");
25517330f729Sjoerg         return false;
25527330f729Sjoerg       }
25537330f729Sjoerg 
25547330f729Sjoerg       if (NChild % 2 == 0) {
25557330f729Sjoerg         TP.error("REG_SEQUENCE requires an odd number of operands!");
25567330f729Sjoerg         return false;
25577330f729Sjoerg       }
25587330f729Sjoerg 
25597330f729Sjoerg       if (!isOperandClass(getChild(0), "RegisterClass")) {
25607330f729Sjoerg         TP.error("REG_SEQUENCE requires a RegisterClass for first operand!");
25617330f729Sjoerg         return false;
25627330f729Sjoerg       }
25637330f729Sjoerg 
25647330f729Sjoerg       for (unsigned I = 1; I < NChild; I += 2) {
25657330f729Sjoerg         TreePatternNode *SubIdxChild = getChild(I + 1);
25667330f729Sjoerg         if (!isOperandClass(SubIdxChild, "SubRegIndex")) {
25677330f729Sjoerg           TP.error("REG_SEQUENCE requires a SubRegIndex for operand " +
25687330f729Sjoerg                    Twine(I + 1) + "!");
25697330f729Sjoerg           return false;
25707330f729Sjoerg         }
25717330f729Sjoerg       }
25727330f729Sjoerg     }
25737330f729Sjoerg 
2574*82d56013Sjoerg     unsigned NumResults = Inst.getNumResults();
2575*82d56013Sjoerg     unsigned NumFixedOperands = InstInfo.Operands.size();
2576*82d56013Sjoerg 
25777330f729Sjoerg     // If one or more operands with a default value appear at the end of the
25787330f729Sjoerg     // formal operand list for an instruction, we allow them to be overridden
25797330f729Sjoerg     // by optional operands provided in the pattern.
25807330f729Sjoerg     //
25817330f729Sjoerg     // But if an operand B without a default appears at any point after an
25827330f729Sjoerg     // operand A with a default, then we don't allow A to be overridden,
25837330f729Sjoerg     // because there would be no way to specify whether the next operand in
25847330f729Sjoerg     // the pattern was intended to override A or skip it.
2585*82d56013Sjoerg     unsigned NonOverridableOperands = NumFixedOperands;
2586*82d56013Sjoerg     while (NonOverridableOperands > NumResults &&
2587*82d56013Sjoerg            CDP.operandHasDefault(InstInfo.Operands[NonOverridableOperands-1].Rec))
25887330f729Sjoerg       --NonOverridableOperands;
25897330f729Sjoerg 
25907330f729Sjoerg     unsigned ChildNo = 0;
2591*82d56013Sjoerg     assert(NumResults <= NumFixedOperands);
2592*82d56013Sjoerg     for (unsigned i = NumResults, e = NumFixedOperands; i != e; ++i) {
2593*82d56013Sjoerg       Record *OperandNode = InstInfo.Operands[i].Rec;
25947330f729Sjoerg 
25957330f729Sjoerg       // If the operand has a default value, do we use it? We must use the
25967330f729Sjoerg       // default if we've run out of children of the pattern DAG to consume,
25977330f729Sjoerg       // or if the operand is followed by a non-defaulted one.
25987330f729Sjoerg       if (CDP.operandHasDefault(OperandNode) &&
25997330f729Sjoerg           (i < NonOverridableOperands || ChildNo >= getNumChildren()))
26007330f729Sjoerg         continue;
26017330f729Sjoerg 
26027330f729Sjoerg       // If we have run out of child nodes and there _isn't_ a default
26037330f729Sjoerg       // value we can use for the next operand, give an error.
26047330f729Sjoerg       if (ChildNo >= getNumChildren()) {
26057330f729Sjoerg         emitTooFewOperandsError(TP, getOperator()->getName(), getNumChildren());
26067330f729Sjoerg         return false;
26077330f729Sjoerg       }
26087330f729Sjoerg 
26097330f729Sjoerg       TreePatternNode *Child = getChild(ChildNo++);
26107330f729Sjoerg       unsigned ChildResNo = 0;  // Instructions always use res #0 of their op.
26117330f729Sjoerg 
26127330f729Sjoerg       // If the operand has sub-operands, they may be provided by distinct
26137330f729Sjoerg       // child patterns, so attempt to match each sub-operand separately.
26147330f729Sjoerg       if (OperandNode->isSubClassOf("Operand")) {
26157330f729Sjoerg         DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo");
26167330f729Sjoerg         if (unsigned NumArgs = MIOpInfo->getNumArgs()) {
26177330f729Sjoerg           // But don't do that if the whole operand is being provided by
26187330f729Sjoerg           // a single ComplexPattern-related Operand.
26197330f729Sjoerg 
26207330f729Sjoerg           if (Child->getNumMIResults(CDP) < NumArgs) {
26217330f729Sjoerg             // Match first sub-operand against the child we already have.
26227330f729Sjoerg             Record *SubRec = cast<DefInit>(MIOpInfo->getArg(0))->getDef();
26237330f729Sjoerg             MadeChange |=
26247330f729Sjoerg               Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP);
26257330f729Sjoerg 
26267330f729Sjoerg             // And the remaining sub-operands against subsequent children.
26277330f729Sjoerg             for (unsigned Arg = 1; Arg < NumArgs; ++Arg) {
26287330f729Sjoerg               if (ChildNo >= getNumChildren()) {
26297330f729Sjoerg                 emitTooFewOperandsError(TP, getOperator()->getName(),
26307330f729Sjoerg                                         getNumChildren());
26317330f729Sjoerg                 return false;
26327330f729Sjoerg               }
26337330f729Sjoerg               Child = getChild(ChildNo++);
26347330f729Sjoerg 
26357330f729Sjoerg               SubRec = cast<DefInit>(MIOpInfo->getArg(Arg))->getDef();
26367330f729Sjoerg               MadeChange |=
26377330f729Sjoerg                 Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP);
26387330f729Sjoerg             }
26397330f729Sjoerg             continue;
26407330f729Sjoerg           }
26417330f729Sjoerg         }
26427330f729Sjoerg       }
26437330f729Sjoerg 
26447330f729Sjoerg       // If we didn't match by pieces above, attempt to match the whole
26457330f729Sjoerg       // operand now.
26467330f729Sjoerg       MadeChange |= Child->UpdateNodeTypeFromInst(ChildResNo, OperandNode, TP);
26477330f729Sjoerg     }
26487330f729Sjoerg 
26497330f729Sjoerg     if (!InstInfo.Operands.isVariadic && ChildNo != getNumChildren()) {
26507330f729Sjoerg       emitTooManyOperandsError(TP, getOperator()->getName(),
26517330f729Sjoerg                                ChildNo, getNumChildren());
26527330f729Sjoerg       return false;
26537330f729Sjoerg     }
26547330f729Sjoerg 
26557330f729Sjoerg     for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
26567330f729Sjoerg       MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
26577330f729Sjoerg     return MadeChange;
26587330f729Sjoerg   }
26597330f729Sjoerg 
26607330f729Sjoerg   if (getOperator()->isSubClassOf("ComplexPattern")) {
26617330f729Sjoerg     bool MadeChange = false;
26627330f729Sjoerg 
26637330f729Sjoerg     for (unsigned i = 0; i < getNumChildren(); ++i)
26647330f729Sjoerg       MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
26657330f729Sjoerg 
26667330f729Sjoerg     return MadeChange;
26677330f729Sjoerg   }
26687330f729Sjoerg 
26697330f729Sjoerg   assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
26707330f729Sjoerg 
26717330f729Sjoerg   // Node transforms always take one operand.
26727330f729Sjoerg   if (getNumChildren() != 1) {
26737330f729Sjoerg     TP.error("Node transform '" + getOperator()->getName() +
26747330f729Sjoerg              "' requires one operand!");
26757330f729Sjoerg     return false;
26767330f729Sjoerg   }
26777330f729Sjoerg 
26787330f729Sjoerg   bool MadeChange = getChild(0)->ApplyTypeConstraints(TP, NotRegisters);
26797330f729Sjoerg   return MadeChange;
26807330f729Sjoerg }
26817330f729Sjoerg 
26827330f729Sjoerg /// OnlyOnRHSOfCommutative - Return true if this value is only allowed on the
26837330f729Sjoerg /// RHS of a commutative operation, not the on LHS.
OnlyOnRHSOfCommutative(TreePatternNode * N)26847330f729Sjoerg static bool OnlyOnRHSOfCommutative(TreePatternNode *N) {
26857330f729Sjoerg   if (!N->isLeaf() && N->getOperator()->getName() == "imm")
26867330f729Sjoerg     return true;
26877330f729Sjoerg   if (N->isLeaf() && isa<IntInit>(N->getLeafValue()))
26887330f729Sjoerg     return true;
2689*82d56013Sjoerg   if (isImmAllOnesAllZerosMatch(N))
2690*82d56013Sjoerg     return true;
26917330f729Sjoerg   return false;
26927330f729Sjoerg }
26937330f729Sjoerg 
26947330f729Sjoerg 
26957330f729Sjoerg /// canPatternMatch - If it is impossible for this pattern to match on this
26967330f729Sjoerg /// target, fill in Reason and return false.  Otherwise, return true.  This is
26977330f729Sjoerg /// used as a sanity check for .td files (to prevent people from writing stuff
26987330f729Sjoerg /// that can never possibly work), and to prevent the pattern permuter from
26997330f729Sjoerg /// generating stuff that is useless.
canPatternMatch(std::string & Reason,const CodeGenDAGPatterns & CDP)27007330f729Sjoerg bool TreePatternNode::canPatternMatch(std::string &Reason,
27017330f729Sjoerg                                       const CodeGenDAGPatterns &CDP) {
27027330f729Sjoerg   if (isLeaf()) return true;
27037330f729Sjoerg 
27047330f729Sjoerg   for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
27057330f729Sjoerg     if (!getChild(i)->canPatternMatch(Reason, CDP))
27067330f729Sjoerg       return false;
27077330f729Sjoerg 
27087330f729Sjoerg   // If this is an intrinsic, handle cases that would make it not match.  For
27097330f729Sjoerg   // example, if an operand is required to be an immediate.
27107330f729Sjoerg   if (getOperator()->isSubClassOf("Intrinsic")) {
27117330f729Sjoerg     // TODO:
27127330f729Sjoerg     return true;
27137330f729Sjoerg   }
27147330f729Sjoerg 
27157330f729Sjoerg   if (getOperator()->isSubClassOf("ComplexPattern"))
27167330f729Sjoerg     return true;
27177330f729Sjoerg 
27187330f729Sjoerg   // If this node is a commutative operator, check that the LHS isn't an
27197330f729Sjoerg   // immediate.
27207330f729Sjoerg   const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(getOperator());
27217330f729Sjoerg   bool isCommIntrinsic = isCommutativeIntrinsic(CDP);
27227330f729Sjoerg   if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) {
27237330f729Sjoerg     // Scan all of the operands of the node and make sure that only the last one
27247330f729Sjoerg     // is a constant node, unless the RHS also is.
27257330f729Sjoerg     if (!OnlyOnRHSOfCommutative(getChild(getNumChildren()-1))) {
27267330f729Sjoerg       unsigned Skip = isCommIntrinsic ? 1 : 0; // First operand is intrinsic id.
27277330f729Sjoerg       for (unsigned i = Skip, e = getNumChildren()-1; i != e; ++i)
27287330f729Sjoerg         if (OnlyOnRHSOfCommutative(getChild(i))) {
27297330f729Sjoerg           Reason="Immediate value must be on the RHS of commutative operators!";
27307330f729Sjoerg           return false;
27317330f729Sjoerg         }
27327330f729Sjoerg     }
27337330f729Sjoerg   }
27347330f729Sjoerg 
27357330f729Sjoerg   return true;
27367330f729Sjoerg }
27377330f729Sjoerg 
27387330f729Sjoerg //===----------------------------------------------------------------------===//
27397330f729Sjoerg // TreePattern implementation
27407330f729Sjoerg //
27417330f729Sjoerg 
TreePattern(Record * TheRec,ListInit * RawPat,bool isInput,CodeGenDAGPatterns & cdp)27427330f729Sjoerg TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
27437330f729Sjoerg                          CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp),
27447330f729Sjoerg                          isInputPattern(isInput), HasError(false),
27457330f729Sjoerg                          Infer(*this) {
27467330f729Sjoerg   for (Init *I : RawPat->getValues())
27477330f729Sjoerg     Trees.push_back(ParseTreePattern(I, ""));
27487330f729Sjoerg }
27497330f729Sjoerg 
TreePattern(Record * TheRec,DagInit * Pat,bool isInput,CodeGenDAGPatterns & cdp)27507330f729Sjoerg TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
27517330f729Sjoerg                          CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp),
27527330f729Sjoerg                          isInputPattern(isInput), HasError(false),
27537330f729Sjoerg                          Infer(*this) {
27547330f729Sjoerg   Trees.push_back(ParseTreePattern(Pat, ""));
27557330f729Sjoerg }
27567330f729Sjoerg 
TreePattern(Record * TheRec,TreePatternNodePtr Pat,bool isInput,CodeGenDAGPatterns & cdp)27577330f729Sjoerg TreePattern::TreePattern(Record *TheRec, TreePatternNodePtr Pat, bool isInput,
27587330f729Sjoerg                          CodeGenDAGPatterns &cdp)
27597330f729Sjoerg     : TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false),
27607330f729Sjoerg       Infer(*this) {
27617330f729Sjoerg   Trees.push_back(Pat);
27627330f729Sjoerg }
27637330f729Sjoerg 
error(const Twine & Msg)27647330f729Sjoerg void TreePattern::error(const Twine &Msg) {
27657330f729Sjoerg   if (HasError)
27667330f729Sjoerg     return;
27677330f729Sjoerg   dump();
27687330f729Sjoerg   PrintError(TheRecord->getLoc(), "In " + TheRecord->getName() + ": " + Msg);
27697330f729Sjoerg   HasError = true;
27707330f729Sjoerg }
27717330f729Sjoerg 
ComputeNamedNodes()27727330f729Sjoerg void TreePattern::ComputeNamedNodes() {
27737330f729Sjoerg   for (TreePatternNodePtr &Tree : Trees)
27747330f729Sjoerg     ComputeNamedNodes(Tree.get());
27757330f729Sjoerg }
27767330f729Sjoerg 
ComputeNamedNodes(TreePatternNode * N)27777330f729Sjoerg void TreePattern::ComputeNamedNodes(TreePatternNode *N) {
27787330f729Sjoerg   if (!N->getName().empty())
27797330f729Sjoerg     NamedNodes[N->getName()].push_back(N);
27807330f729Sjoerg 
27817330f729Sjoerg   for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
27827330f729Sjoerg     ComputeNamedNodes(N->getChild(i));
27837330f729Sjoerg }
27847330f729Sjoerg 
ParseTreePattern(Init * TheInit,StringRef OpName)27857330f729Sjoerg TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
27867330f729Sjoerg                                                  StringRef OpName) {
27877330f729Sjoerg   if (DefInit *DI = dyn_cast<DefInit>(TheInit)) {
27887330f729Sjoerg     Record *R = DI->getDef();
27897330f729Sjoerg 
27907330f729Sjoerg     // Direct reference to a leaf DagNode or PatFrag?  Turn it into a
27917330f729Sjoerg     // TreePatternNode of its own.  For example:
27927330f729Sjoerg     ///   (foo GPR, imm) -> (foo GPR, (imm))
27937330f729Sjoerg     if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrags"))
27947330f729Sjoerg       return ParseTreePattern(
27957330f729Sjoerg         DagInit::get(DI, nullptr,
27967330f729Sjoerg                      std::vector<std::pair<Init*, StringInit*> >()),
27977330f729Sjoerg         OpName);
27987330f729Sjoerg 
27997330f729Sjoerg     // Input argument?
28007330f729Sjoerg     TreePatternNodePtr Res = std::make_shared<TreePatternNode>(DI, 1);
28017330f729Sjoerg     if (R->getName() == "node" && !OpName.empty()) {
28027330f729Sjoerg       if (OpName.empty())
28037330f729Sjoerg         error("'node' argument requires a name to match with operand list");
2804*82d56013Sjoerg       Args.push_back(std::string(OpName));
28057330f729Sjoerg     }
28067330f729Sjoerg 
28077330f729Sjoerg     Res->setName(OpName);
28087330f729Sjoerg     return Res;
28097330f729Sjoerg   }
28107330f729Sjoerg 
28117330f729Sjoerg   // ?:$name or just $name.
28127330f729Sjoerg   if (isa<UnsetInit>(TheInit)) {
28137330f729Sjoerg     if (OpName.empty())
28147330f729Sjoerg       error("'?' argument requires a name to match with operand list");
28157330f729Sjoerg     TreePatternNodePtr Res = std::make_shared<TreePatternNode>(TheInit, 1);
2816*82d56013Sjoerg     Args.push_back(std::string(OpName));
28177330f729Sjoerg     Res->setName(OpName);
28187330f729Sjoerg     return Res;
28197330f729Sjoerg   }
28207330f729Sjoerg 
28217330f729Sjoerg   if (isa<IntInit>(TheInit) || isa<BitInit>(TheInit)) {
28227330f729Sjoerg     if (!OpName.empty())
28237330f729Sjoerg       error("Constant int or bit argument should not have a name!");
28247330f729Sjoerg     if (isa<BitInit>(TheInit))
28257330f729Sjoerg       TheInit = TheInit->convertInitializerTo(IntRecTy::get());
28267330f729Sjoerg     return std::make_shared<TreePatternNode>(TheInit, 1);
28277330f729Sjoerg   }
28287330f729Sjoerg 
28297330f729Sjoerg   if (BitsInit *BI = dyn_cast<BitsInit>(TheInit)) {
28307330f729Sjoerg     // Turn this into an IntInit.
28317330f729Sjoerg     Init *II = BI->convertInitializerTo(IntRecTy::get());
28327330f729Sjoerg     if (!II || !isa<IntInit>(II))
28337330f729Sjoerg       error("Bits value must be constants!");
28347330f729Sjoerg     return ParseTreePattern(II, OpName);
28357330f729Sjoerg   }
28367330f729Sjoerg 
28377330f729Sjoerg   DagInit *Dag = dyn_cast<DagInit>(TheInit);
28387330f729Sjoerg   if (!Dag) {
28397330f729Sjoerg     TheInit->print(errs());
28407330f729Sjoerg     error("Pattern has unexpected init kind!");
28417330f729Sjoerg   }
28427330f729Sjoerg   DefInit *OpDef = dyn_cast<DefInit>(Dag->getOperator());
28437330f729Sjoerg   if (!OpDef) error("Pattern has unexpected operator type!");
28447330f729Sjoerg   Record *Operator = OpDef->getDef();
28457330f729Sjoerg 
28467330f729Sjoerg   if (Operator->isSubClassOf("ValueType")) {
28477330f729Sjoerg     // If the operator is a ValueType, then this must be "type cast" of a leaf
28487330f729Sjoerg     // node.
28497330f729Sjoerg     if (Dag->getNumArgs() != 1)
28507330f729Sjoerg       error("Type cast only takes one operand!");
28517330f729Sjoerg 
28527330f729Sjoerg     TreePatternNodePtr New =
28537330f729Sjoerg         ParseTreePattern(Dag->getArg(0), Dag->getArgNameStr(0));
28547330f729Sjoerg 
28557330f729Sjoerg     // Apply the type cast.
28567330f729Sjoerg     assert(New->getNumTypes() == 1 && "FIXME: Unhandled");
28577330f729Sjoerg     const CodeGenHwModes &CGH = getDAGPatterns().getTargetInfo().getHwModes();
28587330f729Sjoerg     New->UpdateNodeType(0, getValueTypeByHwMode(Operator, CGH), *this);
28597330f729Sjoerg 
28607330f729Sjoerg     if (!OpName.empty())
28617330f729Sjoerg       error("ValueType cast should not have a name!");
28627330f729Sjoerg     return New;
28637330f729Sjoerg   }
28647330f729Sjoerg 
28657330f729Sjoerg   // Verify that this is something that makes sense for an operator.
28667330f729Sjoerg   if (!Operator->isSubClassOf("PatFrags") &&
28677330f729Sjoerg       !Operator->isSubClassOf("SDNode") &&
28687330f729Sjoerg       !Operator->isSubClassOf("Instruction") &&
28697330f729Sjoerg       !Operator->isSubClassOf("SDNodeXForm") &&
28707330f729Sjoerg       !Operator->isSubClassOf("Intrinsic") &&
28717330f729Sjoerg       !Operator->isSubClassOf("ComplexPattern") &&
28727330f729Sjoerg       Operator->getName() != "set" &&
28737330f729Sjoerg       Operator->getName() != "implicit")
28747330f729Sjoerg     error("Unrecognized node '" + Operator->getName() + "'!");
28757330f729Sjoerg 
28767330f729Sjoerg   //  Check to see if this is something that is illegal in an input pattern.
28777330f729Sjoerg   if (isInputPattern) {
28787330f729Sjoerg     if (Operator->isSubClassOf("Instruction") ||
28797330f729Sjoerg         Operator->isSubClassOf("SDNodeXForm"))
28807330f729Sjoerg       error("Cannot use '" + Operator->getName() + "' in an input pattern!");
28817330f729Sjoerg   } else {
28827330f729Sjoerg     if (Operator->isSubClassOf("Intrinsic"))
28837330f729Sjoerg       error("Cannot use '" + Operator->getName() + "' in an output pattern!");
28847330f729Sjoerg 
28857330f729Sjoerg     if (Operator->isSubClassOf("SDNode") &&
28867330f729Sjoerg         Operator->getName() != "imm" &&
28877330f729Sjoerg         Operator->getName() != "timm" &&
28887330f729Sjoerg         Operator->getName() != "fpimm" &&
28897330f729Sjoerg         Operator->getName() != "tglobaltlsaddr" &&
28907330f729Sjoerg         Operator->getName() != "tconstpool" &&
28917330f729Sjoerg         Operator->getName() != "tjumptable" &&
28927330f729Sjoerg         Operator->getName() != "tframeindex" &&
28937330f729Sjoerg         Operator->getName() != "texternalsym" &&
28947330f729Sjoerg         Operator->getName() != "tblockaddress" &&
28957330f729Sjoerg         Operator->getName() != "tglobaladdr" &&
28967330f729Sjoerg         Operator->getName() != "bb" &&
28977330f729Sjoerg         Operator->getName() != "vt" &&
28987330f729Sjoerg         Operator->getName() != "mcsym")
28997330f729Sjoerg       error("Cannot use '" + Operator->getName() + "' in an output pattern!");
29007330f729Sjoerg   }
29017330f729Sjoerg 
29027330f729Sjoerg   std::vector<TreePatternNodePtr> Children;
29037330f729Sjoerg 
29047330f729Sjoerg   // Parse all the operands.
29057330f729Sjoerg   for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i)
29067330f729Sjoerg     Children.push_back(ParseTreePattern(Dag->getArg(i), Dag->getArgNameStr(i)));
29077330f729Sjoerg 
29087330f729Sjoerg   // Get the actual number of results before Operator is converted to an intrinsic
29097330f729Sjoerg   // node (which is hard-coded to have either zero or one result).
29107330f729Sjoerg   unsigned NumResults = GetNumNodeResults(Operator, CDP);
29117330f729Sjoerg 
29127330f729Sjoerg   // If the operator is an intrinsic, then this is just syntactic sugar for
29137330f729Sjoerg   // (intrinsic_* <number>, ..children..).  Pick the right intrinsic node, and
29147330f729Sjoerg   // convert the intrinsic name to a number.
29157330f729Sjoerg   if (Operator->isSubClassOf("Intrinsic")) {
29167330f729Sjoerg     const CodeGenIntrinsic &Int = getDAGPatterns().getIntrinsic(Operator);
29177330f729Sjoerg     unsigned IID = getDAGPatterns().getIntrinsicID(Operator)+1;
29187330f729Sjoerg 
29197330f729Sjoerg     // If this intrinsic returns void, it must have side-effects and thus a
29207330f729Sjoerg     // chain.
29217330f729Sjoerg     if (Int.IS.RetVTs.empty())
29227330f729Sjoerg       Operator = getDAGPatterns().get_intrinsic_void_sdnode();
29237330f729Sjoerg     else if (Int.ModRef != CodeGenIntrinsic::NoMem || Int.hasSideEffects)
29247330f729Sjoerg       // Has side-effects, requires chain.
29257330f729Sjoerg       Operator = getDAGPatterns().get_intrinsic_w_chain_sdnode();
29267330f729Sjoerg     else // Otherwise, no chain.
29277330f729Sjoerg       Operator = getDAGPatterns().get_intrinsic_wo_chain_sdnode();
29287330f729Sjoerg 
29297330f729Sjoerg     Children.insert(Children.begin(),
29307330f729Sjoerg                     std::make_shared<TreePatternNode>(IntInit::get(IID), 1));
29317330f729Sjoerg   }
29327330f729Sjoerg 
29337330f729Sjoerg   if (Operator->isSubClassOf("ComplexPattern")) {
29347330f729Sjoerg     for (unsigned i = 0; i < Children.size(); ++i) {
29357330f729Sjoerg       TreePatternNodePtr Child = Children[i];
29367330f729Sjoerg 
29377330f729Sjoerg       if (Child->getName().empty())
29387330f729Sjoerg         error("All arguments to a ComplexPattern must be named");
29397330f729Sjoerg 
29407330f729Sjoerg       // Check that the ComplexPattern uses are consistent: "(MY_PAT $a, $b)"
29417330f729Sjoerg       // and "(MY_PAT $b, $a)" should not be allowed in the same pattern;
29427330f729Sjoerg       // neither should "(MY_PAT_1 $a, $b)" and "(MY_PAT_2 $a, $b)".
29437330f729Sjoerg       auto OperandId = std::make_pair(Operator, i);
29447330f729Sjoerg       auto PrevOp = ComplexPatternOperands.find(Child->getName());
29457330f729Sjoerg       if (PrevOp != ComplexPatternOperands.end()) {
29467330f729Sjoerg         if (PrevOp->getValue() != OperandId)
29477330f729Sjoerg           error("All ComplexPattern operands must appear consistently: "
29487330f729Sjoerg                 "in the same order in just one ComplexPattern instance.");
29497330f729Sjoerg       } else
29507330f729Sjoerg         ComplexPatternOperands[Child->getName()] = OperandId;
29517330f729Sjoerg     }
29527330f729Sjoerg   }
29537330f729Sjoerg 
29547330f729Sjoerg   TreePatternNodePtr Result =
29557330f729Sjoerg       std::make_shared<TreePatternNode>(Operator, std::move(Children),
29567330f729Sjoerg                                         NumResults);
29577330f729Sjoerg   Result->setName(OpName);
29587330f729Sjoerg 
29597330f729Sjoerg   if (Dag->getName()) {
29607330f729Sjoerg     assert(Result->getName().empty());
29617330f729Sjoerg     Result->setName(Dag->getNameStr());
29627330f729Sjoerg   }
29637330f729Sjoerg   return Result;
29647330f729Sjoerg }
29657330f729Sjoerg 
29667330f729Sjoerg /// SimplifyTree - See if we can simplify this tree to eliminate something that
29677330f729Sjoerg /// will never match in favor of something obvious that will.  This is here
29687330f729Sjoerg /// strictly as a convenience to target authors because it allows them to write
29697330f729Sjoerg /// more type generic things and have useless type casts fold away.
29707330f729Sjoerg ///
29717330f729Sjoerg /// This returns true if any change is made.
SimplifyTree(TreePatternNodePtr & N)29727330f729Sjoerg static bool SimplifyTree(TreePatternNodePtr &N) {
29737330f729Sjoerg   if (N->isLeaf())
29747330f729Sjoerg     return false;
29757330f729Sjoerg 
29767330f729Sjoerg   // If we have a bitconvert with a resolved type and if the source and
29777330f729Sjoerg   // destination types are the same, then the bitconvert is useless, remove it.
2978*82d56013Sjoerg   //
2979*82d56013Sjoerg   // We make an exception if the types are completely empty. This can come up
2980*82d56013Sjoerg   // when the pattern being simplified is in the Fragments list of a PatFrags,
2981*82d56013Sjoerg   // so that the operand is just an untyped "node". In that situation we leave
2982*82d56013Sjoerg   // bitconverts unsimplified, and simplify them later once the fragment is
2983*82d56013Sjoerg   // expanded into its true context.
29847330f729Sjoerg   if (N->getOperator()->getName() == "bitconvert" &&
29857330f729Sjoerg       N->getExtType(0).isValueTypeByHwMode(false) &&
2986*82d56013Sjoerg       !N->getExtType(0).empty() &&
29877330f729Sjoerg       N->getExtType(0) == N->getChild(0)->getExtType(0) &&
29887330f729Sjoerg       N->getName().empty()) {
29897330f729Sjoerg     N = N->getChildShared(0);
29907330f729Sjoerg     SimplifyTree(N);
29917330f729Sjoerg     return true;
29927330f729Sjoerg   }
29937330f729Sjoerg 
29947330f729Sjoerg   // Walk all children.
29957330f729Sjoerg   bool MadeChange = false;
29967330f729Sjoerg   for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
29977330f729Sjoerg     TreePatternNodePtr Child = N->getChildShared(i);
29987330f729Sjoerg     MadeChange |= SimplifyTree(Child);
29997330f729Sjoerg     N->setChild(i, std::move(Child));
30007330f729Sjoerg   }
30017330f729Sjoerg   return MadeChange;
30027330f729Sjoerg }
30037330f729Sjoerg 
30047330f729Sjoerg 
30057330f729Sjoerg 
30067330f729Sjoerg /// InferAllTypes - Infer/propagate as many types throughout the expression
30077330f729Sjoerg /// patterns as possible.  Return true if all types are inferred, false
30087330f729Sjoerg /// otherwise.  Flags an error if a type contradiction is found.
30097330f729Sjoerg bool TreePattern::
InferAllTypes(const StringMap<SmallVector<TreePatternNode *,1>> * InNamedTypes)30107330f729Sjoerg InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) {
30117330f729Sjoerg   if (NamedNodes.empty())
30127330f729Sjoerg     ComputeNamedNodes();
30137330f729Sjoerg 
30147330f729Sjoerg   bool MadeChange = true;
30157330f729Sjoerg   while (MadeChange) {
30167330f729Sjoerg     MadeChange = false;
30177330f729Sjoerg     for (TreePatternNodePtr &Tree : Trees) {
30187330f729Sjoerg       MadeChange |= Tree->ApplyTypeConstraints(*this, false);
30197330f729Sjoerg       MadeChange |= SimplifyTree(Tree);
30207330f729Sjoerg     }
30217330f729Sjoerg 
30227330f729Sjoerg     // If there are constraints on our named nodes, apply them.
30237330f729Sjoerg     for (auto &Entry : NamedNodes) {
30247330f729Sjoerg       SmallVectorImpl<TreePatternNode*> &Nodes = Entry.second;
30257330f729Sjoerg 
30267330f729Sjoerg       // If we have input named node types, propagate their types to the named
30277330f729Sjoerg       // values here.
30287330f729Sjoerg       if (InNamedTypes) {
30297330f729Sjoerg         if (!InNamedTypes->count(Entry.getKey())) {
30307330f729Sjoerg           error("Node '" + std::string(Entry.getKey()) +
30317330f729Sjoerg                 "' in output pattern but not input pattern");
30327330f729Sjoerg           return true;
30337330f729Sjoerg         }
30347330f729Sjoerg 
30357330f729Sjoerg         const SmallVectorImpl<TreePatternNode*> &InNodes =
30367330f729Sjoerg           InNamedTypes->find(Entry.getKey())->second;
30377330f729Sjoerg 
30387330f729Sjoerg         // The input types should be fully resolved by now.
30397330f729Sjoerg         for (TreePatternNode *Node : Nodes) {
30407330f729Sjoerg           // If this node is a register class, and it is the root of the pattern
30417330f729Sjoerg           // then we're mapping something onto an input register.  We allow
30427330f729Sjoerg           // changing the type of the input register in this case.  This allows
30437330f729Sjoerg           // us to match things like:
30447330f729Sjoerg           //  def : Pat<(v1i64 (bitconvert(v2i32 DPR:$src))), (v1i64 DPR:$src)>;
30457330f729Sjoerg           if (Node == Trees[0].get() && Node->isLeaf()) {
30467330f729Sjoerg             DefInit *DI = dyn_cast<DefInit>(Node->getLeafValue());
30477330f729Sjoerg             if (DI && (DI->getDef()->isSubClassOf("RegisterClass") ||
30487330f729Sjoerg                        DI->getDef()->isSubClassOf("RegisterOperand")))
30497330f729Sjoerg               continue;
30507330f729Sjoerg           }
30517330f729Sjoerg 
30527330f729Sjoerg           assert(Node->getNumTypes() == 1 &&
30537330f729Sjoerg                  InNodes[0]->getNumTypes() == 1 &&
30547330f729Sjoerg                  "FIXME: cannot name multiple result nodes yet");
30557330f729Sjoerg           MadeChange |= Node->UpdateNodeType(0, InNodes[0]->getExtType(0),
30567330f729Sjoerg                                              *this);
30577330f729Sjoerg         }
30587330f729Sjoerg       }
30597330f729Sjoerg 
30607330f729Sjoerg       // If there are multiple nodes with the same name, they must all have the
30617330f729Sjoerg       // same type.
30627330f729Sjoerg       if (Entry.second.size() > 1) {
30637330f729Sjoerg         for (unsigned i = 0, e = Nodes.size()-1; i != e; ++i) {
30647330f729Sjoerg           TreePatternNode *N1 = Nodes[i], *N2 = Nodes[i+1];
30657330f729Sjoerg           assert(N1->getNumTypes() == 1 && N2->getNumTypes() == 1 &&
30667330f729Sjoerg                  "FIXME: cannot name multiple result nodes yet");
30677330f729Sjoerg 
30687330f729Sjoerg           MadeChange |= N1->UpdateNodeType(0, N2->getExtType(0), *this);
30697330f729Sjoerg           MadeChange |= N2->UpdateNodeType(0, N1->getExtType(0), *this);
30707330f729Sjoerg         }
30717330f729Sjoerg       }
30727330f729Sjoerg     }
30737330f729Sjoerg   }
30747330f729Sjoerg 
30757330f729Sjoerg   bool HasUnresolvedTypes = false;
30767330f729Sjoerg   for (const TreePatternNodePtr &Tree : Trees)
30777330f729Sjoerg     HasUnresolvedTypes |= Tree->ContainsUnresolvedType(*this);
30787330f729Sjoerg   return !HasUnresolvedTypes;
30797330f729Sjoerg }
30807330f729Sjoerg 
print(raw_ostream & OS) const30817330f729Sjoerg void TreePattern::print(raw_ostream &OS) const {
30827330f729Sjoerg   OS << getRecord()->getName();
30837330f729Sjoerg   if (!Args.empty()) {
3084*82d56013Sjoerg     OS << "(";
3085*82d56013Sjoerg     ListSeparator LS;
3086*82d56013Sjoerg     for (const std::string &Arg : Args)
3087*82d56013Sjoerg       OS << LS << Arg;
30887330f729Sjoerg     OS << ")";
30897330f729Sjoerg   }
30907330f729Sjoerg   OS << ": ";
30917330f729Sjoerg 
30927330f729Sjoerg   if (Trees.size() > 1)
30937330f729Sjoerg     OS << "[\n";
30947330f729Sjoerg   for (const TreePatternNodePtr &Tree : Trees) {
30957330f729Sjoerg     OS << "\t";
30967330f729Sjoerg     Tree->print(OS);
30977330f729Sjoerg     OS << "\n";
30987330f729Sjoerg   }
30997330f729Sjoerg 
31007330f729Sjoerg   if (Trees.size() > 1)
31017330f729Sjoerg     OS << "]\n";
31027330f729Sjoerg }
31037330f729Sjoerg 
dump() const31047330f729Sjoerg void TreePattern::dump() const { print(errs()); }
31057330f729Sjoerg 
31067330f729Sjoerg //===----------------------------------------------------------------------===//
31077330f729Sjoerg // CodeGenDAGPatterns implementation
31087330f729Sjoerg //
31097330f729Sjoerg 
CodeGenDAGPatterns(RecordKeeper & R,PatternRewriterFn PatternRewriter)31107330f729Sjoerg CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R,
31117330f729Sjoerg                                        PatternRewriterFn PatternRewriter)
31127330f729Sjoerg     : Records(R), Target(R), LegalVTS(Target.getLegalValueTypes()),
31137330f729Sjoerg       PatternRewriter(PatternRewriter) {
31147330f729Sjoerg 
3115*82d56013Sjoerg   Intrinsics = CodeGenIntrinsicTable(Records);
31167330f729Sjoerg   ParseNodeInfo();
31177330f729Sjoerg   ParseNodeTransforms();
31187330f729Sjoerg   ParseComplexPatterns();
31197330f729Sjoerg   ParsePatternFragments();
31207330f729Sjoerg   ParseDefaultOperands();
31217330f729Sjoerg   ParseInstructions();
31227330f729Sjoerg   ParsePatternFragments(/*OutFrags*/true);
31237330f729Sjoerg   ParsePatterns();
31247330f729Sjoerg 
3125*82d56013Sjoerg   // Generate variants.  For example, commutative patterns can match
3126*82d56013Sjoerg   // multiple ways.  Add them to PatternsToMatch as well.
3127*82d56013Sjoerg   GenerateVariants();
3128*82d56013Sjoerg 
31297330f729Sjoerg   // Break patterns with parameterized types into a series of patterns,
31307330f729Sjoerg   // where each one has a fixed type and is predicated on the conditions
31317330f729Sjoerg   // of the associated HW mode.
31327330f729Sjoerg   ExpandHwModeBasedTypes();
31337330f729Sjoerg 
31347330f729Sjoerg   // Infer instruction flags.  For example, we can detect loads,
31357330f729Sjoerg   // stores, and side effects in many cases by examining an
31367330f729Sjoerg   // instruction's pattern.
31377330f729Sjoerg   InferInstructionFlags();
31387330f729Sjoerg 
31397330f729Sjoerg   // Verify that instruction flags match the patterns.
31407330f729Sjoerg   VerifyInstructionFlags();
31417330f729Sjoerg }
31427330f729Sjoerg 
getSDNodeNamed(StringRef Name) const3143*82d56013Sjoerg Record *CodeGenDAGPatterns::getSDNodeNamed(StringRef Name) const {
31447330f729Sjoerg   Record *N = Records.getDef(Name);
31457330f729Sjoerg   if (!N || !N->isSubClassOf("SDNode"))
31467330f729Sjoerg     PrintFatalError("Error getting SDNode '" + Name + "'!");
31477330f729Sjoerg 
31487330f729Sjoerg   return N;
31497330f729Sjoerg }
31507330f729Sjoerg 
31517330f729Sjoerg // Parse all of the SDNode definitions for the target, populating SDNodes.
ParseNodeInfo()31527330f729Sjoerg void CodeGenDAGPatterns::ParseNodeInfo() {
31537330f729Sjoerg   std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("SDNode");
31547330f729Sjoerg   const CodeGenHwModes &CGH = getTargetInfo().getHwModes();
31557330f729Sjoerg 
31567330f729Sjoerg   while (!Nodes.empty()) {
31577330f729Sjoerg     Record *R = Nodes.back();
31587330f729Sjoerg     SDNodes.insert(std::make_pair(R, SDNodeInfo(R, CGH)));
31597330f729Sjoerg     Nodes.pop_back();
31607330f729Sjoerg   }
31617330f729Sjoerg 
31627330f729Sjoerg   // Get the builtin intrinsic nodes.
31637330f729Sjoerg   intrinsic_void_sdnode     = getSDNodeNamed("intrinsic_void");
31647330f729Sjoerg   intrinsic_w_chain_sdnode  = getSDNodeNamed("intrinsic_w_chain");
31657330f729Sjoerg   intrinsic_wo_chain_sdnode = getSDNodeNamed("intrinsic_wo_chain");
31667330f729Sjoerg }
31677330f729Sjoerg 
31687330f729Sjoerg /// ParseNodeTransforms - Parse all SDNodeXForm instances into the SDNodeXForms
31697330f729Sjoerg /// map, and emit them to the file as functions.
ParseNodeTransforms()31707330f729Sjoerg void CodeGenDAGPatterns::ParseNodeTransforms() {
31717330f729Sjoerg   std::vector<Record*> Xforms = Records.getAllDerivedDefinitions("SDNodeXForm");
31727330f729Sjoerg   while (!Xforms.empty()) {
31737330f729Sjoerg     Record *XFormNode = Xforms.back();
31747330f729Sjoerg     Record *SDNode = XFormNode->getValueAsDef("Opcode");
31757330f729Sjoerg     StringRef Code = XFormNode->getValueAsString("XFormFunction");
3176*82d56013Sjoerg     SDNodeXForms.insert(
3177*82d56013Sjoerg         std::make_pair(XFormNode, NodeXForm(SDNode, std::string(Code))));
31787330f729Sjoerg 
31797330f729Sjoerg     Xforms.pop_back();
31807330f729Sjoerg   }
31817330f729Sjoerg }
31827330f729Sjoerg 
ParseComplexPatterns()31837330f729Sjoerg void CodeGenDAGPatterns::ParseComplexPatterns() {
31847330f729Sjoerg   std::vector<Record*> AMs = Records.getAllDerivedDefinitions("ComplexPattern");
31857330f729Sjoerg   while (!AMs.empty()) {
31867330f729Sjoerg     ComplexPatterns.insert(std::make_pair(AMs.back(), AMs.back()));
31877330f729Sjoerg     AMs.pop_back();
31887330f729Sjoerg   }
31897330f729Sjoerg }
31907330f729Sjoerg 
31917330f729Sjoerg 
31927330f729Sjoerg /// ParsePatternFragments - Parse all of the PatFrag definitions in the .td
31937330f729Sjoerg /// file, building up the PatternFragments map.  After we've collected them all,
31947330f729Sjoerg /// inline fragments together as necessary, so that there are no references left
31957330f729Sjoerg /// inside a pattern fragment to a pattern fragment.
31967330f729Sjoerg ///
ParsePatternFragments(bool OutFrags)31977330f729Sjoerg void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) {
31987330f729Sjoerg   std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrags");
31997330f729Sjoerg 
32007330f729Sjoerg   // First step, parse all of the fragments.
32017330f729Sjoerg   for (Record *Frag : Fragments) {
32027330f729Sjoerg     if (OutFrags != Frag->isSubClassOf("OutPatFrag"))
32037330f729Sjoerg       continue;
32047330f729Sjoerg 
32057330f729Sjoerg     ListInit *LI = Frag->getValueAsListInit("Fragments");
32067330f729Sjoerg     TreePattern *P =
32077330f729Sjoerg         (PatternFragments[Frag] = std::make_unique<TreePattern>(
32087330f729Sjoerg              Frag, LI, !Frag->isSubClassOf("OutPatFrag"),
32097330f729Sjoerg              *this)).get();
32107330f729Sjoerg 
32117330f729Sjoerg     // Validate the argument list, converting it to set, to discard duplicates.
32127330f729Sjoerg     std::vector<std::string> &Args = P->getArgList();
32137330f729Sjoerg     // Copy the args so we can take StringRefs to them.
32147330f729Sjoerg     auto ArgsCopy = Args;
32157330f729Sjoerg     SmallDenseSet<StringRef, 4> OperandsSet;
32167330f729Sjoerg     OperandsSet.insert(ArgsCopy.begin(), ArgsCopy.end());
32177330f729Sjoerg 
32187330f729Sjoerg     if (OperandsSet.count(""))
32197330f729Sjoerg       P->error("Cannot have unnamed 'node' values in pattern fragment!");
32207330f729Sjoerg 
32217330f729Sjoerg     // Parse the operands list.
32227330f729Sjoerg     DagInit *OpsList = Frag->getValueAsDag("Operands");
32237330f729Sjoerg     DefInit *OpsOp = dyn_cast<DefInit>(OpsList->getOperator());
32247330f729Sjoerg     // Special cases: ops == outs == ins. Different names are used to
32257330f729Sjoerg     // improve readability.
32267330f729Sjoerg     if (!OpsOp ||
32277330f729Sjoerg         (OpsOp->getDef()->getName() != "ops" &&
32287330f729Sjoerg          OpsOp->getDef()->getName() != "outs" &&
32297330f729Sjoerg          OpsOp->getDef()->getName() != "ins"))
32307330f729Sjoerg       P->error("Operands list should start with '(ops ... '!");
32317330f729Sjoerg 
32327330f729Sjoerg     // Copy over the arguments.
32337330f729Sjoerg     Args.clear();
32347330f729Sjoerg     for (unsigned j = 0, e = OpsList->getNumArgs(); j != e; ++j) {
32357330f729Sjoerg       if (!isa<DefInit>(OpsList->getArg(j)) ||
32367330f729Sjoerg           cast<DefInit>(OpsList->getArg(j))->getDef()->getName() != "node")
32377330f729Sjoerg         P->error("Operands list should all be 'node' values.");
32387330f729Sjoerg       if (!OpsList->getArgName(j))
32397330f729Sjoerg         P->error("Operands list should have names for each operand!");
32407330f729Sjoerg       StringRef ArgNameStr = OpsList->getArgNameStr(j);
32417330f729Sjoerg       if (!OperandsSet.count(ArgNameStr))
32427330f729Sjoerg         P->error("'" + ArgNameStr +
32437330f729Sjoerg                  "' does not occur in pattern or was multiply specified!");
32447330f729Sjoerg       OperandsSet.erase(ArgNameStr);
3245*82d56013Sjoerg       Args.push_back(std::string(ArgNameStr));
32467330f729Sjoerg     }
32477330f729Sjoerg 
32487330f729Sjoerg     if (!OperandsSet.empty())
32497330f729Sjoerg       P->error("Operands list does not contain an entry for operand '" +
32507330f729Sjoerg                *OperandsSet.begin() + "'!");
32517330f729Sjoerg 
32527330f729Sjoerg     // If there is a node transformation corresponding to this, keep track of
32537330f729Sjoerg     // it.
32547330f729Sjoerg     Record *Transform = Frag->getValueAsDef("OperandTransform");
32557330f729Sjoerg     if (!getSDNodeTransform(Transform).second.empty())    // not noop xform?
3256*82d56013Sjoerg       for (const auto &T : P->getTrees())
32577330f729Sjoerg         T->setTransformFn(Transform);
32587330f729Sjoerg   }
32597330f729Sjoerg 
32607330f729Sjoerg   // Now that we've parsed all of the tree fragments, do a closure on them so
32617330f729Sjoerg   // that there are not references to PatFrags left inside of them.
32627330f729Sjoerg   for (Record *Frag : Fragments) {
32637330f729Sjoerg     if (OutFrags != Frag->isSubClassOf("OutPatFrag"))
32647330f729Sjoerg       continue;
32657330f729Sjoerg 
32667330f729Sjoerg     TreePattern &ThePat = *PatternFragments[Frag];
32677330f729Sjoerg     ThePat.InlinePatternFragments();
32687330f729Sjoerg 
32697330f729Sjoerg     // Infer as many types as possible.  Don't worry about it if we don't infer
32707330f729Sjoerg     // all of them, some may depend on the inputs of the pattern.  Also, don't
32717330f729Sjoerg     // validate type sets; validation may cause spurious failures e.g. if a
32727330f729Sjoerg     // fragment needs floating-point types but the current target does not have
32737330f729Sjoerg     // any (this is only an error if that fragment is ever used!).
32747330f729Sjoerg     {
32757330f729Sjoerg       TypeInfer::SuppressValidation SV(ThePat.getInfer());
32767330f729Sjoerg       ThePat.InferAllTypes();
32777330f729Sjoerg       ThePat.resetError();
32787330f729Sjoerg     }
32797330f729Sjoerg 
32807330f729Sjoerg     // If debugging, print out the pattern fragment result.
32817330f729Sjoerg     LLVM_DEBUG(ThePat.dump());
32827330f729Sjoerg   }
32837330f729Sjoerg }
32847330f729Sjoerg 
ParseDefaultOperands()32857330f729Sjoerg void CodeGenDAGPatterns::ParseDefaultOperands() {
32867330f729Sjoerg   std::vector<Record*> DefaultOps;
32877330f729Sjoerg   DefaultOps = Records.getAllDerivedDefinitions("OperandWithDefaultOps");
32887330f729Sjoerg 
32897330f729Sjoerg   // Find some SDNode.
32907330f729Sjoerg   assert(!SDNodes.empty() && "No SDNodes parsed?");
32917330f729Sjoerg   Init *SomeSDNode = DefInit::get(SDNodes.begin()->first);
32927330f729Sjoerg 
32937330f729Sjoerg   for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) {
32947330f729Sjoerg     DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps");
32957330f729Sjoerg 
32967330f729Sjoerg     // Clone the DefaultInfo dag node, changing the operator from 'ops' to
32977330f729Sjoerg     // SomeSDnode so that we can parse this.
32987330f729Sjoerg     std::vector<std::pair<Init*, StringInit*> > Ops;
32997330f729Sjoerg     for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)
33007330f729Sjoerg       Ops.push_back(std::make_pair(DefaultInfo->getArg(op),
33017330f729Sjoerg                                    DefaultInfo->getArgName(op)));
33027330f729Sjoerg     DagInit *DI = DagInit::get(SomeSDNode, nullptr, Ops);
33037330f729Sjoerg 
33047330f729Sjoerg     // Create a TreePattern to parse this.
33057330f729Sjoerg     TreePattern P(DefaultOps[i], DI, false, *this);
33067330f729Sjoerg     assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
33077330f729Sjoerg 
33087330f729Sjoerg     // Copy the operands over into a DAGDefaultOperand.
33097330f729Sjoerg     DAGDefaultOperand DefaultOpInfo;
33107330f729Sjoerg 
33117330f729Sjoerg     const TreePatternNodePtr &T = P.getTree(0);
33127330f729Sjoerg     for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) {
33137330f729Sjoerg       TreePatternNodePtr TPN = T->getChildShared(op);
33147330f729Sjoerg       while (TPN->ApplyTypeConstraints(P, false))
33157330f729Sjoerg         /* Resolve all types */;
33167330f729Sjoerg 
33177330f729Sjoerg       if (TPN->ContainsUnresolvedType(P)) {
33187330f729Sjoerg         PrintFatalError("Value #" + Twine(i) + " of OperandWithDefaultOps '" +
33197330f729Sjoerg                         DefaultOps[i]->getName() +
33207330f729Sjoerg                         "' doesn't have a concrete type!");
33217330f729Sjoerg       }
33227330f729Sjoerg       DefaultOpInfo.DefaultOps.push_back(std::move(TPN));
33237330f729Sjoerg     }
33247330f729Sjoerg 
33257330f729Sjoerg     // Insert it into the DefaultOperands map so we can find it later.
33267330f729Sjoerg     DefaultOperands[DefaultOps[i]] = DefaultOpInfo;
33277330f729Sjoerg   }
33287330f729Sjoerg }
33297330f729Sjoerg 
33307330f729Sjoerg /// HandleUse - Given "Pat" a leaf in the pattern, check to see if it is an
33317330f729Sjoerg /// instruction input.  Return true if this is a real use.
HandleUse(TreePattern & I,TreePatternNodePtr Pat,std::map<std::string,TreePatternNodePtr> & InstInputs)33327330f729Sjoerg static bool HandleUse(TreePattern &I, TreePatternNodePtr Pat,
33337330f729Sjoerg                       std::map<std::string, TreePatternNodePtr> &InstInputs) {
33347330f729Sjoerg   // No name -> not interesting.
33357330f729Sjoerg   if (Pat->getName().empty()) {
33367330f729Sjoerg     if (Pat->isLeaf()) {
33377330f729Sjoerg       DefInit *DI = dyn_cast<DefInit>(Pat->getLeafValue());
33387330f729Sjoerg       if (DI && (DI->getDef()->isSubClassOf("RegisterClass") ||
33397330f729Sjoerg                  DI->getDef()->isSubClassOf("RegisterOperand")))
33407330f729Sjoerg         I.error("Input " + DI->getDef()->getName() + " must be named!");
33417330f729Sjoerg     }
33427330f729Sjoerg     return false;
33437330f729Sjoerg   }
33447330f729Sjoerg 
33457330f729Sjoerg   Record *Rec;
33467330f729Sjoerg   if (Pat->isLeaf()) {
33477330f729Sjoerg     DefInit *DI = dyn_cast<DefInit>(Pat->getLeafValue());
33487330f729Sjoerg     if (!DI)
33497330f729Sjoerg       I.error("Input $" + Pat->getName() + " must be an identifier!");
33507330f729Sjoerg     Rec = DI->getDef();
33517330f729Sjoerg   } else {
33527330f729Sjoerg     Rec = Pat->getOperator();
33537330f729Sjoerg   }
33547330f729Sjoerg 
33557330f729Sjoerg   // SRCVALUE nodes are ignored.
33567330f729Sjoerg   if (Rec->getName() == "srcvalue")
33577330f729Sjoerg     return false;
33587330f729Sjoerg 
33597330f729Sjoerg   TreePatternNodePtr &Slot = InstInputs[Pat->getName()];
33607330f729Sjoerg   if (!Slot) {
33617330f729Sjoerg     Slot = Pat;
33627330f729Sjoerg     return true;
33637330f729Sjoerg   }
33647330f729Sjoerg   Record *SlotRec;
33657330f729Sjoerg   if (Slot->isLeaf()) {
33667330f729Sjoerg     SlotRec = cast<DefInit>(Slot->getLeafValue())->getDef();
33677330f729Sjoerg   } else {
33687330f729Sjoerg     assert(Slot->getNumChildren() == 0 && "can't be a use with children!");
33697330f729Sjoerg     SlotRec = Slot->getOperator();
33707330f729Sjoerg   }
33717330f729Sjoerg 
33727330f729Sjoerg   // Ensure that the inputs agree if we've already seen this input.
33737330f729Sjoerg   if (Rec != SlotRec)
33747330f729Sjoerg     I.error("All $" + Pat->getName() + " inputs must agree with each other");
33757330f729Sjoerg   // Ensure that the types can agree as well.
33767330f729Sjoerg   Slot->UpdateNodeType(0, Pat->getExtType(0), I);
33777330f729Sjoerg   Pat->UpdateNodeType(0, Slot->getExtType(0), I);
33787330f729Sjoerg   if (Slot->getExtTypes() != Pat->getExtTypes())
33797330f729Sjoerg     I.error("All $" + Pat->getName() + " inputs must agree with each other");
33807330f729Sjoerg   return true;
33817330f729Sjoerg }
33827330f729Sjoerg 
33837330f729Sjoerg /// FindPatternInputsAndOutputs - Scan the specified TreePatternNode (which is
33847330f729Sjoerg /// part of "I", the instruction), computing the set of inputs and outputs of
33857330f729Sjoerg /// the pattern.  Report errors if we see anything naughty.
FindPatternInputsAndOutputs(TreePattern & I,TreePatternNodePtr Pat,std::map<std::string,TreePatternNodePtr> & InstInputs,MapVector<std::string,TreePatternNodePtr,std::map<std::string,unsigned>> & InstResults,std::vector<Record * > & InstImpResults)33867330f729Sjoerg void CodeGenDAGPatterns::FindPatternInputsAndOutputs(
33877330f729Sjoerg     TreePattern &I, TreePatternNodePtr Pat,
33887330f729Sjoerg     std::map<std::string, TreePatternNodePtr> &InstInputs,
33897330f729Sjoerg     MapVector<std::string, TreePatternNodePtr, std::map<std::string, unsigned>>
33907330f729Sjoerg         &InstResults,
33917330f729Sjoerg     std::vector<Record *> &InstImpResults) {
33927330f729Sjoerg 
33937330f729Sjoerg   // The instruction pattern still has unresolved fragments.  For *named*
33947330f729Sjoerg   // nodes we must resolve those here.  This may not result in multiple
33957330f729Sjoerg   // alternatives.
33967330f729Sjoerg   if (!Pat->getName().empty()) {
33977330f729Sjoerg     TreePattern SrcPattern(I.getRecord(), Pat, true, *this);
33987330f729Sjoerg     SrcPattern.InlinePatternFragments();
33997330f729Sjoerg     SrcPattern.InferAllTypes();
34007330f729Sjoerg     Pat = SrcPattern.getOnlyTree();
34017330f729Sjoerg   }
34027330f729Sjoerg 
34037330f729Sjoerg   if (Pat->isLeaf()) {
34047330f729Sjoerg     bool isUse = HandleUse(I, Pat, InstInputs);
34057330f729Sjoerg     if (!isUse && Pat->getTransformFn())
34067330f729Sjoerg       I.error("Cannot specify a transform function for a non-input value!");
34077330f729Sjoerg     return;
34087330f729Sjoerg   }
34097330f729Sjoerg 
34107330f729Sjoerg   if (Pat->getOperator()->getName() == "implicit") {
34117330f729Sjoerg     for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
34127330f729Sjoerg       TreePatternNode *Dest = Pat->getChild(i);
34137330f729Sjoerg       if (!Dest->isLeaf())
34147330f729Sjoerg         I.error("implicitly defined value should be a register!");
34157330f729Sjoerg 
34167330f729Sjoerg       DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue());
34177330f729Sjoerg       if (!Val || !Val->getDef()->isSubClassOf("Register"))
34187330f729Sjoerg         I.error("implicitly defined value should be a register!");
34197330f729Sjoerg       InstImpResults.push_back(Val->getDef());
34207330f729Sjoerg     }
34217330f729Sjoerg     return;
34227330f729Sjoerg   }
34237330f729Sjoerg 
34247330f729Sjoerg   if (Pat->getOperator()->getName() != "set") {
34257330f729Sjoerg     // If this is not a set, verify that the children nodes are not void typed,
34267330f729Sjoerg     // and recurse.
34277330f729Sjoerg     for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
34287330f729Sjoerg       if (Pat->getChild(i)->getNumTypes() == 0)
34297330f729Sjoerg         I.error("Cannot have void nodes inside of patterns!");
34307330f729Sjoerg       FindPatternInputsAndOutputs(I, Pat->getChildShared(i), InstInputs,
34317330f729Sjoerg                                   InstResults, InstImpResults);
34327330f729Sjoerg     }
34337330f729Sjoerg 
34347330f729Sjoerg     // If this is a non-leaf node with no children, treat it basically as if
34357330f729Sjoerg     // it were a leaf.  This handles nodes like (imm).
34367330f729Sjoerg     bool isUse = HandleUse(I, Pat, InstInputs);
34377330f729Sjoerg 
34387330f729Sjoerg     if (!isUse && Pat->getTransformFn())
34397330f729Sjoerg       I.error("Cannot specify a transform function for a non-input value!");
34407330f729Sjoerg     return;
34417330f729Sjoerg   }
34427330f729Sjoerg 
34437330f729Sjoerg   // Otherwise, this is a set, validate and collect instruction results.
34447330f729Sjoerg   if (Pat->getNumChildren() == 0)
34457330f729Sjoerg     I.error("set requires operands!");
34467330f729Sjoerg 
34477330f729Sjoerg   if (Pat->getTransformFn())
34487330f729Sjoerg     I.error("Cannot specify a transform function on a set node!");
34497330f729Sjoerg 
34507330f729Sjoerg   // Check the set destinations.
34517330f729Sjoerg   unsigned NumDests = Pat->getNumChildren()-1;
34527330f729Sjoerg   for (unsigned i = 0; i != NumDests; ++i) {
34537330f729Sjoerg     TreePatternNodePtr Dest = Pat->getChildShared(i);
34547330f729Sjoerg     // For set destinations we also must resolve fragments here.
34557330f729Sjoerg     TreePattern DestPattern(I.getRecord(), Dest, false, *this);
34567330f729Sjoerg     DestPattern.InlinePatternFragments();
34577330f729Sjoerg     DestPattern.InferAllTypes();
34587330f729Sjoerg     Dest = DestPattern.getOnlyTree();
34597330f729Sjoerg 
34607330f729Sjoerg     if (!Dest->isLeaf())
34617330f729Sjoerg       I.error("set destination should be a register!");
34627330f729Sjoerg 
34637330f729Sjoerg     DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue());
34647330f729Sjoerg     if (!Val) {
34657330f729Sjoerg       I.error("set destination should be a register!");
34667330f729Sjoerg       continue;
34677330f729Sjoerg     }
34687330f729Sjoerg 
34697330f729Sjoerg     if (Val->getDef()->isSubClassOf("RegisterClass") ||
34707330f729Sjoerg         Val->getDef()->isSubClassOf("ValueType") ||
34717330f729Sjoerg         Val->getDef()->isSubClassOf("RegisterOperand") ||
34727330f729Sjoerg         Val->getDef()->isSubClassOf("PointerLikeRegClass")) {
34737330f729Sjoerg       if (Dest->getName().empty())
34747330f729Sjoerg         I.error("set destination must have a name!");
34757330f729Sjoerg       if (InstResults.count(Dest->getName()))
34767330f729Sjoerg         I.error("cannot set '" + Dest->getName() + "' multiple times");
34777330f729Sjoerg       InstResults[Dest->getName()] = Dest;
34787330f729Sjoerg     } else if (Val->getDef()->isSubClassOf("Register")) {
34797330f729Sjoerg       InstImpResults.push_back(Val->getDef());
34807330f729Sjoerg     } else {
34817330f729Sjoerg       I.error("set destination should be a register!");
34827330f729Sjoerg     }
34837330f729Sjoerg   }
34847330f729Sjoerg 
34857330f729Sjoerg   // Verify and collect info from the computation.
34867330f729Sjoerg   FindPatternInputsAndOutputs(I, Pat->getChildShared(NumDests), InstInputs,
34877330f729Sjoerg                               InstResults, InstImpResults);
34887330f729Sjoerg }
34897330f729Sjoerg 
34907330f729Sjoerg //===----------------------------------------------------------------------===//
34917330f729Sjoerg // Instruction Analysis
34927330f729Sjoerg //===----------------------------------------------------------------------===//
34937330f729Sjoerg 
34947330f729Sjoerg class InstAnalyzer {
34957330f729Sjoerg   const CodeGenDAGPatterns &CDP;
34967330f729Sjoerg public:
34977330f729Sjoerg   bool hasSideEffects;
34987330f729Sjoerg   bool mayStore;
34997330f729Sjoerg   bool mayLoad;
35007330f729Sjoerg   bool isBitcast;
35017330f729Sjoerg   bool isVariadic;
35027330f729Sjoerg   bool hasChain;
35037330f729Sjoerg 
InstAnalyzer(const CodeGenDAGPatterns & cdp)35047330f729Sjoerg   InstAnalyzer(const CodeGenDAGPatterns &cdp)
35057330f729Sjoerg     : CDP(cdp), hasSideEffects(false), mayStore(false), mayLoad(false),
35067330f729Sjoerg       isBitcast(false), isVariadic(false), hasChain(false) {}
35077330f729Sjoerg 
Analyze(const PatternToMatch & Pat)35087330f729Sjoerg   void Analyze(const PatternToMatch &Pat) {
35097330f729Sjoerg     const TreePatternNode *N = Pat.getSrcPattern();
35107330f729Sjoerg     AnalyzeNode(N);
35117330f729Sjoerg     // These properties are detected only on the root node.
35127330f729Sjoerg     isBitcast = IsNodeBitcast(N);
35137330f729Sjoerg   }
35147330f729Sjoerg 
35157330f729Sjoerg private:
IsNodeBitcast(const TreePatternNode * N) const35167330f729Sjoerg   bool IsNodeBitcast(const TreePatternNode *N) const {
35177330f729Sjoerg     if (hasSideEffects || mayLoad || mayStore || isVariadic)
35187330f729Sjoerg       return false;
35197330f729Sjoerg 
35207330f729Sjoerg     if (N->isLeaf())
35217330f729Sjoerg       return false;
35227330f729Sjoerg     if (N->getNumChildren() != 1 || !N->getChild(0)->isLeaf())
35237330f729Sjoerg       return false;
35247330f729Sjoerg 
3525*82d56013Sjoerg     if (N->getOperator()->isSubClassOf("ComplexPattern"))
3526*82d56013Sjoerg       return false;
3527*82d56013Sjoerg 
35287330f729Sjoerg     const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
35297330f729Sjoerg     if (OpInfo.getNumResults() != 1 || OpInfo.getNumOperands() != 1)
35307330f729Sjoerg       return false;
35317330f729Sjoerg     return OpInfo.getEnumName() == "ISD::BITCAST";
35327330f729Sjoerg   }
35337330f729Sjoerg 
35347330f729Sjoerg public:
AnalyzeNode(const TreePatternNode * N)35357330f729Sjoerg   void AnalyzeNode(const TreePatternNode *N) {
35367330f729Sjoerg     if (N->isLeaf()) {
35377330f729Sjoerg       if (DefInit *DI = dyn_cast<DefInit>(N->getLeafValue())) {
35387330f729Sjoerg         Record *LeafRec = DI->getDef();
35397330f729Sjoerg         // Handle ComplexPattern leaves.
35407330f729Sjoerg         if (LeafRec->isSubClassOf("ComplexPattern")) {
35417330f729Sjoerg           const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
35427330f729Sjoerg           if (CP.hasProperty(SDNPMayStore)) mayStore = true;
35437330f729Sjoerg           if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
35447330f729Sjoerg           if (CP.hasProperty(SDNPSideEffect)) hasSideEffects = true;
35457330f729Sjoerg         }
35467330f729Sjoerg       }
35477330f729Sjoerg       return;
35487330f729Sjoerg     }
35497330f729Sjoerg 
35507330f729Sjoerg     // Analyze children.
35517330f729Sjoerg     for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
35527330f729Sjoerg       AnalyzeNode(N->getChild(i));
35537330f729Sjoerg 
35547330f729Sjoerg     // Notice properties of the node.
35557330f729Sjoerg     if (N->NodeHasProperty(SDNPMayStore, CDP)) mayStore = true;
35567330f729Sjoerg     if (N->NodeHasProperty(SDNPMayLoad, CDP)) mayLoad = true;
35577330f729Sjoerg     if (N->NodeHasProperty(SDNPSideEffect, CDP)) hasSideEffects = true;
35587330f729Sjoerg     if (N->NodeHasProperty(SDNPVariadic, CDP)) isVariadic = true;
35597330f729Sjoerg     if (N->NodeHasProperty(SDNPHasChain, CDP)) hasChain = true;
35607330f729Sjoerg 
35617330f729Sjoerg     if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
35627330f729Sjoerg       // If this is an intrinsic, analyze it.
35637330f729Sjoerg       if (IntInfo->ModRef & CodeGenIntrinsic::MR_Ref)
35647330f729Sjoerg         mayLoad = true;// These may load memory.
35657330f729Sjoerg 
35667330f729Sjoerg       if (IntInfo->ModRef & CodeGenIntrinsic::MR_Mod)
35677330f729Sjoerg         mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
35687330f729Sjoerg 
35697330f729Sjoerg       if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem ||
35707330f729Sjoerg           IntInfo->hasSideEffects)
35717330f729Sjoerg         // ReadWriteMem intrinsics can have other strange effects.
35727330f729Sjoerg         hasSideEffects = true;
35737330f729Sjoerg     }
35747330f729Sjoerg   }
35757330f729Sjoerg 
35767330f729Sjoerg };
35777330f729Sjoerg 
InferFromPattern(CodeGenInstruction & InstInfo,const InstAnalyzer & PatInfo,Record * PatDef)35787330f729Sjoerg static bool InferFromPattern(CodeGenInstruction &InstInfo,
35797330f729Sjoerg                              const InstAnalyzer &PatInfo,
35807330f729Sjoerg                              Record *PatDef) {
35817330f729Sjoerg   bool Error = false;
35827330f729Sjoerg 
35837330f729Sjoerg   // Remember where InstInfo got its flags.
35847330f729Sjoerg   if (InstInfo.hasUndefFlags())
35857330f729Sjoerg       InstInfo.InferredFrom = PatDef;
35867330f729Sjoerg 
35877330f729Sjoerg   // Check explicitly set flags for consistency.
35887330f729Sjoerg   if (InstInfo.hasSideEffects != PatInfo.hasSideEffects &&
35897330f729Sjoerg       !InstInfo.hasSideEffects_Unset) {
35907330f729Sjoerg     // Allow explicitly setting hasSideEffects = 1 on instructions, even when
35917330f729Sjoerg     // the pattern has no side effects. That could be useful for div/rem
35927330f729Sjoerg     // instructions that may trap.
35937330f729Sjoerg     if (!InstInfo.hasSideEffects) {
35947330f729Sjoerg       Error = true;
35957330f729Sjoerg       PrintError(PatDef->getLoc(), "Pattern doesn't match hasSideEffects = " +
35967330f729Sjoerg                  Twine(InstInfo.hasSideEffects));
35977330f729Sjoerg     }
35987330f729Sjoerg   }
35997330f729Sjoerg 
36007330f729Sjoerg   if (InstInfo.mayStore != PatInfo.mayStore && !InstInfo.mayStore_Unset) {
36017330f729Sjoerg     Error = true;
36027330f729Sjoerg     PrintError(PatDef->getLoc(), "Pattern doesn't match mayStore = " +
36037330f729Sjoerg                Twine(InstInfo.mayStore));
36047330f729Sjoerg   }
36057330f729Sjoerg 
36067330f729Sjoerg   if (InstInfo.mayLoad != PatInfo.mayLoad && !InstInfo.mayLoad_Unset) {
36077330f729Sjoerg     // Allow explicitly setting mayLoad = 1, even when the pattern has no loads.
36087330f729Sjoerg     // Some targets translate immediates to loads.
36097330f729Sjoerg     if (!InstInfo.mayLoad) {
36107330f729Sjoerg       Error = true;
36117330f729Sjoerg       PrintError(PatDef->getLoc(), "Pattern doesn't match mayLoad = " +
36127330f729Sjoerg                  Twine(InstInfo.mayLoad));
36137330f729Sjoerg     }
36147330f729Sjoerg   }
36157330f729Sjoerg 
36167330f729Sjoerg   // Transfer inferred flags.
36177330f729Sjoerg   InstInfo.hasSideEffects |= PatInfo.hasSideEffects;
36187330f729Sjoerg   InstInfo.mayStore |= PatInfo.mayStore;
36197330f729Sjoerg   InstInfo.mayLoad |= PatInfo.mayLoad;
36207330f729Sjoerg 
36217330f729Sjoerg   // These flags are silently added without any verification.
36227330f729Sjoerg   // FIXME: To match historical behavior of TableGen, for now add those flags
36237330f729Sjoerg   // only when we're inferring from the primary instruction pattern.
36247330f729Sjoerg   if (PatDef->isSubClassOf("Instruction")) {
36257330f729Sjoerg     InstInfo.isBitcast |= PatInfo.isBitcast;
36267330f729Sjoerg     InstInfo.hasChain |= PatInfo.hasChain;
36277330f729Sjoerg     InstInfo.hasChain_Inferred = true;
36287330f729Sjoerg   }
36297330f729Sjoerg 
36307330f729Sjoerg   // Don't infer isVariadic. This flag means something different on SDNodes and
36317330f729Sjoerg   // instructions. For example, a CALL SDNode is variadic because it has the
36327330f729Sjoerg   // call arguments as operands, but a CALL instruction is not variadic - it
36337330f729Sjoerg   // has argument registers as implicit, not explicit uses.
36347330f729Sjoerg 
36357330f729Sjoerg   return Error;
36367330f729Sjoerg }
36377330f729Sjoerg 
36387330f729Sjoerg /// hasNullFragReference - Return true if the DAG has any reference to the
36397330f729Sjoerg /// null_frag operator.
hasNullFragReference(DagInit * DI)36407330f729Sjoerg static bool hasNullFragReference(DagInit *DI) {
36417330f729Sjoerg   DefInit *OpDef = dyn_cast<DefInit>(DI->getOperator());
36427330f729Sjoerg   if (!OpDef) return false;
36437330f729Sjoerg   Record *Operator = OpDef->getDef();
36447330f729Sjoerg 
36457330f729Sjoerg   // If this is the null fragment, return true.
36467330f729Sjoerg   if (Operator->getName() == "null_frag") return true;
36477330f729Sjoerg   // If any of the arguments reference the null fragment, return true.
36487330f729Sjoerg   for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) {
3649*82d56013Sjoerg     if (auto Arg = dyn_cast<DefInit>(DI->getArg(i)))
3650*82d56013Sjoerg       if (Arg->getDef()->getName() == "null_frag")
3651*82d56013Sjoerg         return true;
36527330f729Sjoerg     DagInit *Arg = dyn_cast<DagInit>(DI->getArg(i));
36537330f729Sjoerg     if (Arg && hasNullFragReference(Arg))
36547330f729Sjoerg       return true;
36557330f729Sjoerg   }
36567330f729Sjoerg 
36577330f729Sjoerg   return false;
36587330f729Sjoerg }
36597330f729Sjoerg 
36607330f729Sjoerg /// hasNullFragReference - Return true if any DAG in the list references
36617330f729Sjoerg /// the null_frag operator.
hasNullFragReference(ListInit * LI)36627330f729Sjoerg static bool hasNullFragReference(ListInit *LI) {
36637330f729Sjoerg   for (Init *I : LI->getValues()) {
36647330f729Sjoerg     DagInit *DI = dyn_cast<DagInit>(I);
36657330f729Sjoerg     assert(DI && "non-dag in an instruction Pattern list?!");
36667330f729Sjoerg     if (hasNullFragReference(DI))
36677330f729Sjoerg       return true;
36687330f729Sjoerg   }
36697330f729Sjoerg   return false;
36707330f729Sjoerg }
36717330f729Sjoerg 
36727330f729Sjoerg /// Get all the instructions in a tree.
36737330f729Sjoerg static void
getInstructionsInTree(TreePatternNode * Tree,SmallVectorImpl<Record * > & Instrs)36747330f729Sjoerg getInstructionsInTree(TreePatternNode *Tree, SmallVectorImpl<Record*> &Instrs) {
36757330f729Sjoerg   if (Tree->isLeaf())
36767330f729Sjoerg     return;
36777330f729Sjoerg   if (Tree->getOperator()->isSubClassOf("Instruction"))
36787330f729Sjoerg     Instrs.push_back(Tree->getOperator());
36797330f729Sjoerg   for (unsigned i = 0, e = Tree->getNumChildren(); i != e; ++i)
36807330f729Sjoerg     getInstructionsInTree(Tree->getChild(i), Instrs);
36817330f729Sjoerg }
36827330f729Sjoerg 
36837330f729Sjoerg /// Check the class of a pattern leaf node against the instruction operand it
36847330f729Sjoerg /// represents.
checkOperandClass(CGIOperandList::OperandInfo & OI,Record * Leaf)36857330f729Sjoerg static bool checkOperandClass(CGIOperandList::OperandInfo &OI,
36867330f729Sjoerg                               Record *Leaf) {
36877330f729Sjoerg   if (OI.Rec == Leaf)
36887330f729Sjoerg     return true;
36897330f729Sjoerg 
36907330f729Sjoerg   // Allow direct value types to be used in instruction set patterns.
36917330f729Sjoerg   // The type will be checked later.
36927330f729Sjoerg   if (Leaf->isSubClassOf("ValueType"))
36937330f729Sjoerg     return true;
36947330f729Sjoerg 
36957330f729Sjoerg   // Patterns can also be ComplexPattern instances.
36967330f729Sjoerg   if (Leaf->isSubClassOf("ComplexPattern"))
36977330f729Sjoerg     return true;
36987330f729Sjoerg 
36997330f729Sjoerg   return false;
37007330f729Sjoerg }
37017330f729Sjoerg 
parseInstructionPattern(CodeGenInstruction & CGI,ListInit * Pat,DAGInstMap & DAGInsts)37027330f729Sjoerg void CodeGenDAGPatterns::parseInstructionPattern(
37037330f729Sjoerg     CodeGenInstruction &CGI, ListInit *Pat, DAGInstMap &DAGInsts) {
37047330f729Sjoerg 
37057330f729Sjoerg   assert(!DAGInsts.count(CGI.TheDef) && "Instruction already parsed!");
37067330f729Sjoerg 
37077330f729Sjoerg   // Parse the instruction.
37087330f729Sjoerg   TreePattern I(CGI.TheDef, Pat, true, *this);
37097330f729Sjoerg 
37107330f729Sjoerg   // InstInputs - Keep track of all of the inputs of the instruction, along
37117330f729Sjoerg   // with the record they are declared as.
37127330f729Sjoerg   std::map<std::string, TreePatternNodePtr> InstInputs;
37137330f729Sjoerg 
37147330f729Sjoerg   // InstResults - Keep track of all the virtual registers that are 'set'
37157330f729Sjoerg   // in the instruction, including what reg class they are.
37167330f729Sjoerg   MapVector<std::string, TreePatternNodePtr, std::map<std::string, unsigned>>
37177330f729Sjoerg       InstResults;
37187330f729Sjoerg 
37197330f729Sjoerg   std::vector<Record*> InstImpResults;
37207330f729Sjoerg 
37217330f729Sjoerg   // Verify that the top-level forms in the instruction are of void type, and
37227330f729Sjoerg   // fill in the InstResults map.
37237330f729Sjoerg   SmallString<32> TypesString;
37247330f729Sjoerg   for (unsigned j = 0, e = I.getNumTrees(); j != e; ++j) {
37257330f729Sjoerg     TypesString.clear();
37267330f729Sjoerg     TreePatternNodePtr Pat = I.getTree(j);
37277330f729Sjoerg     if (Pat->getNumTypes() != 0) {
37287330f729Sjoerg       raw_svector_ostream OS(TypesString);
3729*82d56013Sjoerg       ListSeparator LS;
37307330f729Sjoerg       for (unsigned k = 0, ke = Pat->getNumTypes(); k != ke; ++k) {
3731*82d56013Sjoerg         OS << LS;
37327330f729Sjoerg         Pat->getExtType(k).writeToStream(OS);
37337330f729Sjoerg       }
37347330f729Sjoerg       I.error("Top-level forms in instruction pattern should have"
37357330f729Sjoerg                " void types, has types " +
37367330f729Sjoerg                OS.str());
37377330f729Sjoerg     }
37387330f729Sjoerg 
37397330f729Sjoerg     // Find inputs and outputs, and verify the structure of the uses/defs.
37407330f729Sjoerg     FindPatternInputsAndOutputs(I, Pat, InstInputs, InstResults,
37417330f729Sjoerg                                 InstImpResults);
37427330f729Sjoerg   }
37437330f729Sjoerg 
37447330f729Sjoerg   // Now that we have inputs and outputs of the pattern, inspect the operands
37457330f729Sjoerg   // list for the instruction.  This determines the order that operands are
37467330f729Sjoerg   // added to the machine instruction the node corresponds to.
37477330f729Sjoerg   unsigned NumResults = InstResults.size();
37487330f729Sjoerg 
37497330f729Sjoerg   // Parse the operands list from the (ops) list, validating it.
37507330f729Sjoerg   assert(I.getArgList().empty() && "Args list should still be empty here!");
37517330f729Sjoerg 
37527330f729Sjoerg   // Check that all of the results occur first in the list.
37537330f729Sjoerg   std::vector<Record*> Results;
37547330f729Sjoerg   std::vector<unsigned> ResultIndices;
37557330f729Sjoerg   SmallVector<TreePatternNodePtr, 2> ResNodes;
37567330f729Sjoerg   for (unsigned i = 0; i != NumResults; ++i) {
37577330f729Sjoerg     if (i == CGI.Operands.size()) {
37587330f729Sjoerg       const std::string &OpName =
3759*82d56013Sjoerg           llvm::find_if(
3760*82d56013Sjoerg               InstResults,
37617330f729Sjoerg               [](const std::pair<std::string, TreePatternNodePtr> &P) {
37627330f729Sjoerg                 return P.second;
37637330f729Sjoerg               })
37647330f729Sjoerg               ->first;
37657330f729Sjoerg 
37667330f729Sjoerg       I.error("'" + OpName + "' set but does not appear in operand list!");
37677330f729Sjoerg     }
37687330f729Sjoerg 
37697330f729Sjoerg     const std::string &OpName = CGI.Operands[i].Name;
37707330f729Sjoerg 
37717330f729Sjoerg     // Check that it exists in InstResults.
37727330f729Sjoerg     auto InstResultIter = InstResults.find(OpName);
37737330f729Sjoerg     if (InstResultIter == InstResults.end() || !InstResultIter->second)
37747330f729Sjoerg       I.error("Operand $" + OpName + " does not exist in operand list!");
37757330f729Sjoerg 
37767330f729Sjoerg     TreePatternNodePtr RNode = InstResultIter->second;
37777330f729Sjoerg     Record *R = cast<DefInit>(RNode->getLeafValue())->getDef();
37787330f729Sjoerg     ResNodes.push_back(std::move(RNode));
37797330f729Sjoerg     if (!R)
37807330f729Sjoerg       I.error("Operand $" + OpName + " should be a set destination: all "
37817330f729Sjoerg                "outputs must occur before inputs in operand list!");
37827330f729Sjoerg 
37837330f729Sjoerg     if (!checkOperandClass(CGI.Operands[i], R))
37847330f729Sjoerg       I.error("Operand $" + OpName + " class mismatch!");
37857330f729Sjoerg 
37867330f729Sjoerg     // Remember the return type.
37877330f729Sjoerg     Results.push_back(CGI.Operands[i].Rec);
37887330f729Sjoerg 
37897330f729Sjoerg     // Remember the result index.
37907330f729Sjoerg     ResultIndices.push_back(std::distance(InstResults.begin(), InstResultIter));
37917330f729Sjoerg 
37927330f729Sjoerg     // Okay, this one checks out.
37937330f729Sjoerg     InstResultIter->second = nullptr;
37947330f729Sjoerg   }
37957330f729Sjoerg 
37967330f729Sjoerg   // Loop over the inputs next.
37977330f729Sjoerg   std::vector<TreePatternNodePtr> ResultNodeOperands;
37987330f729Sjoerg   std::vector<Record*> Operands;
37997330f729Sjoerg   for (unsigned i = NumResults, e = CGI.Operands.size(); i != e; ++i) {
38007330f729Sjoerg     CGIOperandList::OperandInfo &Op = CGI.Operands[i];
38017330f729Sjoerg     const std::string &OpName = Op.Name;
38027330f729Sjoerg     if (OpName.empty())
38037330f729Sjoerg       I.error("Operand #" + Twine(i) + " in operands list has no name!");
38047330f729Sjoerg 
38057330f729Sjoerg     if (!InstInputs.count(OpName)) {
38067330f729Sjoerg       // If this is an operand with a DefaultOps set filled in, we can ignore
38077330f729Sjoerg       // this.  When we codegen it, we will do so as always executed.
38087330f729Sjoerg       if (Op.Rec->isSubClassOf("OperandWithDefaultOps")) {
38097330f729Sjoerg         // Does it have a non-empty DefaultOps field?  If so, ignore this
38107330f729Sjoerg         // operand.
38117330f729Sjoerg         if (!getDefaultOperand(Op.Rec).DefaultOps.empty())
38127330f729Sjoerg           continue;
38137330f729Sjoerg       }
38147330f729Sjoerg       I.error("Operand $" + OpName +
38157330f729Sjoerg                " does not appear in the instruction pattern");
38167330f729Sjoerg     }
38177330f729Sjoerg     TreePatternNodePtr InVal = InstInputs[OpName];
38187330f729Sjoerg     InstInputs.erase(OpName);   // It occurred, remove from map.
38197330f729Sjoerg 
38207330f729Sjoerg     if (InVal->isLeaf() && isa<DefInit>(InVal->getLeafValue())) {
38217330f729Sjoerg       Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef();
38227330f729Sjoerg       if (!checkOperandClass(Op, InRec))
38237330f729Sjoerg         I.error("Operand $" + OpName + "'s register class disagrees"
38247330f729Sjoerg                  " between the operand and pattern");
38257330f729Sjoerg     }
38267330f729Sjoerg     Operands.push_back(Op.Rec);
38277330f729Sjoerg 
38287330f729Sjoerg     // Construct the result for the dest-pattern operand list.
38297330f729Sjoerg     TreePatternNodePtr OpNode = InVal->clone();
38307330f729Sjoerg 
38317330f729Sjoerg     // No predicate is useful on the result.
38327330f729Sjoerg     OpNode->clearPredicateCalls();
38337330f729Sjoerg 
38347330f729Sjoerg     // Promote the xform function to be an explicit node if set.
38357330f729Sjoerg     if (Record *Xform = OpNode->getTransformFn()) {
38367330f729Sjoerg       OpNode->setTransformFn(nullptr);
38377330f729Sjoerg       std::vector<TreePatternNodePtr> Children;
38387330f729Sjoerg       Children.push_back(OpNode);
38397330f729Sjoerg       OpNode = std::make_shared<TreePatternNode>(Xform, std::move(Children),
38407330f729Sjoerg                                                  OpNode->getNumTypes());
38417330f729Sjoerg     }
38427330f729Sjoerg 
38437330f729Sjoerg     ResultNodeOperands.push_back(std::move(OpNode));
38447330f729Sjoerg   }
38457330f729Sjoerg 
38467330f729Sjoerg   if (!InstInputs.empty())
38477330f729Sjoerg     I.error("Input operand $" + InstInputs.begin()->first +
38487330f729Sjoerg             " occurs in pattern but not in operands list!");
38497330f729Sjoerg 
38507330f729Sjoerg   TreePatternNodePtr ResultPattern = std::make_shared<TreePatternNode>(
38517330f729Sjoerg       I.getRecord(), std::move(ResultNodeOperands),
38527330f729Sjoerg       GetNumNodeResults(I.getRecord(), *this));
38537330f729Sjoerg   // Copy fully inferred output node types to instruction result pattern.
38547330f729Sjoerg   for (unsigned i = 0; i != NumResults; ++i) {
38557330f729Sjoerg     assert(ResNodes[i]->getNumTypes() == 1 && "FIXME: Unhandled");
38567330f729Sjoerg     ResultPattern->setType(i, ResNodes[i]->getExtType(0));
38577330f729Sjoerg     ResultPattern->setResultIndex(i, ResultIndices[i]);
38587330f729Sjoerg   }
38597330f729Sjoerg 
38607330f729Sjoerg   // FIXME: Assume only the first tree is the pattern. The others are clobber
38617330f729Sjoerg   // nodes.
38627330f729Sjoerg   TreePatternNodePtr Pattern = I.getTree(0);
38637330f729Sjoerg   TreePatternNodePtr SrcPattern;
38647330f729Sjoerg   if (Pattern->getOperator()->getName() == "set") {
38657330f729Sjoerg     SrcPattern = Pattern->getChild(Pattern->getNumChildren()-1)->clone();
38667330f729Sjoerg   } else{
38677330f729Sjoerg     // Not a set (store or something?)
38687330f729Sjoerg     SrcPattern = Pattern;
38697330f729Sjoerg   }
38707330f729Sjoerg 
38717330f729Sjoerg   // Create and insert the instruction.
38727330f729Sjoerg   // FIXME: InstImpResults should not be part of DAGInstruction.
38737330f729Sjoerg   Record *R = I.getRecord();
38747330f729Sjoerg   DAGInsts.emplace(std::piecewise_construct, std::forward_as_tuple(R),
38757330f729Sjoerg                    std::forward_as_tuple(Results, Operands, InstImpResults,
38767330f729Sjoerg                                          SrcPattern, ResultPattern));
38777330f729Sjoerg 
38787330f729Sjoerg   LLVM_DEBUG(I.dump());
38797330f729Sjoerg }
38807330f729Sjoerg 
38817330f729Sjoerg /// ParseInstructions - Parse all of the instructions, inlining and resolving
38827330f729Sjoerg /// any fragments involved.  This populates the Instructions list with fully
38837330f729Sjoerg /// resolved instructions.
ParseInstructions()38847330f729Sjoerg void CodeGenDAGPatterns::ParseInstructions() {
38857330f729Sjoerg   std::vector<Record*> Instrs = Records.getAllDerivedDefinitions("Instruction");
38867330f729Sjoerg 
38877330f729Sjoerg   for (Record *Instr : Instrs) {
38887330f729Sjoerg     ListInit *LI = nullptr;
38897330f729Sjoerg 
38907330f729Sjoerg     if (isa<ListInit>(Instr->getValueInit("Pattern")))
38917330f729Sjoerg       LI = Instr->getValueAsListInit("Pattern");
38927330f729Sjoerg 
38937330f729Sjoerg     // If there is no pattern, only collect minimal information about the
38947330f729Sjoerg     // instruction for its operand list.  We have to assume that there is one
38957330f729Sjoerg     // result, as we have no detailed info. A pattern which references the
38967330f729Sjoerg     // null_frag operator is as-if no pattern were specified. Normally this
38977330f729Sjoerg     // is from a multiclass expansion w/ a SDPatternOperator passed in as
38987330f729Sjoerg     // null_frag.
38997330f729Sjoerg     if (!LI || LI->empty() || hasNullFragReference(LI)) {
39007330f729Sjoerg       std::vector<Record*> Results;
39017330f729Sjoerg       std::vector<Record*> Operands;
39027330f729Sjoerg 
39037330f729Sjoerg       CodeGenInstruction &InstInfo = Target.getInstruction(Instr);
39047330f729Sjoerg 
39057330f729Sjoerg       if (InstInfo.Operands.size() != 0) {
39067330f729Sjoerg         for (unsigned j = 0, e = InstInfo.Operands.NumDefs; j < e; ++j)
39077330f729Sjoerg           Results.push_back(InstInfo.Operands[j].Rec);
39087330f729Sjoerg 
39097330f729Sjoerg         // The rest are inputs.
39107330f729Sjoerg         for (unsigned j = InstInfo.Operands.NumDefs,
39117330f729Sjoerg                e = InstInfo.Operands.size(); j < e; ++j)
39127330f729Sjoerg           Operands.push_back(InstInfo.Operands[j].Rec);
39137330f729Sjoerg       }
39147330f729Sjoerg 
39157330f729Sjoerg       // Create and insert the instruction.
39167330f729Sjoerg       std::vector<Record*> ImpResults;
39177330f729Sjoerg       Instructions.insert(std::make_pair(Instr,
39187330f729Sjoerg                             DAGInstruction(Results, Operands, ImpResults)));
39197330f729Sjoerg       continue;  // no pattern.
39207330f729Sjoerg     }
39217330f729Sjoerg 
39227330f729Sjoerg     CodeGenInstruction &CGI = Target.getInstruction(Instr);
39237330f729Sjoerg     parseInstructionPattern(CGI, LI, Instructions);
39247330f729Sjoerg   }
39257330f729Sjoerg 
39267330f729Sjoerg   // If we can, convert the instructions to be patterns that are matched!
39277330f729Sjoerg   for (auto &Entry : Instructions) {
39287330f729Sjoerg     Record *Instr = Entry.first;
39297330f729Sjoerg     DAGInstruction &TheInst = Entry.second;
39307330f729Sjoerg     TreePatternNodePtr SrcPattern = TheInst.getSrcPattern();
39317330f729Sjoerg     TreePatternNodePtr ResultPattern = TheInst.getResultPattern();
39327330f729Sjoerg 
39337330f729Sjoerg     if (SrcPattern && ResultPattern) {
39347330f729Sjoerg       TreePattern Pattern(Instr, SrcPattern, true, *this);
39357330f729Sjoerg       TreePattern Result(Instr, ResultPattern, false, *this);
39367330f729Sjoerg       ParseOnePattern(Instr, Pattern, Result, TheInst.getImpResults());
39377330f729Sjoerg     }
39387330f729Sjoerg   }
39397330f729Sjoerg }
39407330f729Sjoerg 
39417330f729Sjoerg typedef std::pair<TreePatternNode *, unsigned> NameRecord;
39427330f729Sjoerg 
FindNames(TreePatternNode * P,std::map<std::string,NameRecord> & Names,TreePattern * PatternTop)39437330f729Sjoerg static void FindNames(TreePatternNode *P,
39447330f729Sjoerg                       std::map<std::string, NameRecord> &Names,
39457330f729Sjoerg                       TreePattern *PatternTop) {
39467330f729Sjoerg   if (!P->getName().empty()) {
39477330f729Sjoerg     NameRecord &Rec = Names[P->getName()];
39487330f729Sjoerg     // If this is the first instance of the name, remember the node.
39497330f729Sjoerg     if (Rec.second++ == 0)
39507330f729Sjoerg       Rec.first = P;
39517330f729Sjoerg     else if (Rec.first->getExtTypes() != P->getExtTypes())
39527330f729Sjoerg       PatternTop->error("repetition of value: $" + P->getName() +
39537330f729Sjoerg                         " where different uses have different types!");
39547330f729Sjoerg   }
39557330f729Sjoerg 
39567330f729Sjoerg   if (!P->isLeaf()) {
39577330f729Sjoerg     for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i)
39587330f729Sjoerg       FindNames(P->getChild(i), Names, PatternTop);
39597330f729Sjoerg   }
39607330f729Sjoerg }
39617330f729Sjoerg 
AddPatternToMatch(TreePattern * Pattern,PatternToMatch && PTM)39627330f729Sjoerg void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern,
39637330f729Sjoerg                                            PatternToMatch &&PTM) {
39647330f729Sjoerg   // Do some sanity checking on the pattern we're about to match.
39657330f729Sjoerg   std::string Reason;
39667330f729Sjoerg   if (!PTM.getSrcPattern()->canPatternMatch(Reason, *this)) {
39677330f729Sjoerg     PrintWarning(Pattern->getRecord()->getLoc(),
39687330f729Sjoerg       Twine("Pattern can never match: ") + Reason);
39697330f729Sjoerg     return;
39707330f729Sjoerg   }
39717330f729Sjoerg 
39727330f729Sjoerg   // If the source pattern's root is a complex pattern, that complex pattern
39737330f729Sjoerg   // must specify the nodes it can potentially match.
39747330f729Sjoerg   if (const ComplexPattern *CP =
39757330f729Sjoerg         PTM.getSrcPattern()->getComplexPatternInfo(*this))
39767330f729Sjoerg     if (CP->getRootNodes().empty())
39777330f729Sjoerg       Pattern->error("ComplexPattern at root must specify list of opcodes it"
39787330f729Sjoerg                      " could match");
39797330f729Sjoerg 
39807330f729Sjoerg 
39817330f729Sjoerg   // Find all of the named values in the input and output, ensure they have the
39827330f729Sjoerg   // same type.
39837330f729Sjoerg   std::map<std::string, NameRecord> SrcNames, DstNames;
39847330f729Sjoerg   FindNames(PTM.getSrcPattern(), SrcNames, Pattern);
39857330f729Sjoerg   FindNames(PTM.getDstPattern(), DstNames, Pattern);
39867330f729Sjoerg 
39877330f729Sjoerg   // Scan all of the named values in the destination pattern, rejecting them if
39887330f729Sjoerg   // they don't exist in the input pattern.
39897330f729Sjoerg   for (const auto &Entry : DstNames) {
39907330f729Sjoerg     if (SrcNames[Entry.first].first == nullptr)
39917330f729Sjoerg       Pattern->error("Pattern has input without matching name in output: $" +
39927330f729Sjoerg                      Entry.first);
39937330f729Sjoerg   }
39947330f729Sjoerg 
39957330f729Sjoerg   // Scan all of the named values in the source pattern, rejecting them if the
39967330f729Sjoerg   // name isn't used in the dest, and isn't used to tie two values together.
39977330f729Sjoerg   for (const auto &Entry : SrcNames)
39987330f729Sjoerg     if (DstNames[Entry.first].first == nullptr &&
39997330f729Sjoerg         SrcNames[Entry.first].second == 1)
40007330f729Sjoerg       Pattern->error("Pattern has dead named input: $" + Entry.first);
40017330f729Sjoerg 
4002*82d56013Sjoerg   PatternsToMatch.push_back(std::move(PTM));
40037330f729Sjoerg }
40047330f729Sjoerg 
InferInstructionFlags()40057330f729Sjoerg void CodeGenDAGPatterns::InferInstructionFlags() {
40067330f729Sjoerg   ArrayRef<const CodeGenInstruction*> Instructions =
40077330f729Sjoerg     Target.getInstructionsByEnumValue();
40087330f729Sjoerg 
40097330f729Sjoerg   unsigned Errors = 0;
40107330f729Sjoerg 
40117330f729Sjoerg   // Try to infer flags from all patterns in PatternToMatch.  These include
40127330f729Sjoerg   // both the primary instruction patterns (which always come first) and
40137330f729Sjoerg   // patterns defined outside the instruction.
40147330f729Sjoerg   for (const PatternToMatch &PTM : ptms()) {
40157330f729Sjoerg     // We can only infer from single-instruction patterns, otherwise we won't
40167330f729Sjoerg     // know which instruction should get the flags.
40177330f729Sjoerg     SmallVector<Record*, 8> PatInstrs;
40187330f729Sjoerg     getInstructionsInTree(PTM.getDstPattern(), PatInstrs);
40197330f729Sjoerg     if (PatInstrs.size() != 1)
40207330f729Sjoerg       continue;
40217330f729Sjoerg 
40227330f729Sjoerg     // Get the single instruction.
40237330f729Sjoerg     CodeGenInstruction &InstInfo = Target.getInstruction(PatInstrs.front());
40247330f729Sjoerg 
40257330f729Sjoerg     // Only infer properties from the first pattern. We'll verify the others.
40267330f729Sjoerg     if (InstInfo.InferredFrom)
40277330f729Sjoerg       continue;
40287330f729Sjoerg 
40297330f729Sjoerg     InstAnalyzer PatInfo(*this);
40307330f729Sjoerg     PatInfo.Analyze(PTM);
40317330f729Sjoerg     Errors += InferFromPattern(InstInfo, PatInfo, PTM.getSrcRecord());
40327330f729Sjoerg   }
40337330f729Sjoerg 
40347330f729Sjoerg   if (Errors)
40357330f729Sjoerg     PrintFatalError("pattern conflicts");
40367330f729Sjoerg 
40377330f729Sjoerg   // If requested by the target, guess any undefined properties.
40387330f729Sjoerg   if (Target.guessInstructionProperties()) {
40397330f729Sjoerg     for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
40407330f729Sjoerg       CodeGenInstruction *InstInfo =
40417330f729Sjoerg         const_cast<CodeGenInstruction *>(Instructions[i]);
40427330f729Sjoerg       if (InstInfo->InferredFrom)
40437330f729Sjoerg         continue;
40447330f729Sjoerg       // The mayLoad and mayStore flags default to false.
40457330f729Sjoerg       // Conservatively assume hasSideEffects if it wasn't explicit.
40467330f729Sjoerg       if (InstInfo->hasSideEffects_Unset)
40477330f729Sjoerg         InstInfo->hasSideEffects = true;
40487330f729Sjoerg     }
40497330f729Sjoerg     return;
40507330f729Sjoerg   }
40517330f729Sjoerg 
40527330f729Sjoerg   // Complain about any flags that are still undefined.
40537330f729Sjoerg   for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
40547330f729Sjoerg     CodeGenInstruction *InstInfo =
40557330f729Sjoerg       const_cast<CodeGenInstruction *>(Instructions[i]);
40567330f729Sjoerg     if (InstInfo->InferredFrom)
40577330f729Sjoerg       continue;
40587330f729Sjoerg     if (InstInfo->hasSideEffects_Unset)
40597330f729Sjoerg       PrintError(InstInfo->TheDef->getLoc(),
40607330f729Sjoerg                  "Can't infer hasSideEffects from patterns");
40617330f729Sjoerg     if (InstInfo->mayStore_Unset)
40627330f729Sjoerg       PrintError(InstInfo->TheDef->getLoc(),
40637330f729Sjoerg                  "Can't infer mayStore from patterns");
40647330f729Sjoerg     if (InstInfo->mayLoad_Unset)
40657330f729Sjoerg       PrintError(InstInfo->TheDef->getLoc(),
40667330f729Sjoerg                  "Can't infer mayLoad from patterns");
40677330f729Sjoerg   }
40687330f729Sjoerg }
40697330f729Sjoerg 
40707330f729Sjoerg 
40717330f729Sjoerg /// Verify instruction flags against pattern node properties.
VerifyInstructionFlags()40727330f729Sjoerg void CodeGenDAGPatterns::VerifyInstructionFlags() {
40737330f729Sjoerg   unsigned Errors = 0;
4074*82d56013Sjoerg   for (const PatternToMatch &PTM : ptms()) {
40757330f729Sjoerg     SmallVector<Record*, 8> Instrs;
40767330f729Sjoerg     getInstructionsInTree(PTM.getDstPattern(), Instrs);
40777330f729Sjoerg     if (Instrs.empty())
40787330f729Sjoerg       continue;
40797330f729Sjoerg 
40807330f729Sjoerg     // Count the number of instructions with each flag set.
40817330f729Sjoerg     unsigned NumSideEffects = 0;
40827330f729Sjoerg     unsigned NumStores = 0;
40837330f729Sjoerg     unsigned NumLoads = 0;
40847330f729Sjoerg     for (const Record *Instr : Instrs) {
40857330f729Sjoerg       const CodeGenInstruction &InstInfo = Target.getInstruction(Instr);
40867330f729Sjoerg       NumSideEffects += InstInfo.hasSideEffects;
40877330f729Sjoerg       NumStores += InstInfo.mayStore;
40887330f729Sjoerg       NumLoads += InstInfo.mayLoad;
40897330f729Sjoerg     }
40907330f729Sjoerg 
40917330f729Sjoerg     // Analyze the source pattern.
40927330f729Sjoerg     InstAnalyzer PatInfo(*this);
40937330f729Sjoerg     PatInfo.Analyze(PTM);
40947330f729Sjoerg 
40957330f729Sjoerg     // Collect error messages.
40967330f729Sjoerg     SmallVector<std::string, 4> Msgs;
40977330f729Sjoerg 
40987330f729Sjoerg     // Check for missing flags in the output.
40997330f729Sjoerg     // Permit extra flags for now at least.
41007330f729Sjoerg     if (PatInfo.hasSideEffects && !NumSideEffects)
41017330f729Sjoerg       Msgs.push_back("pattern has side effects, but hasSideEffects isn't set");
41027330f729Sjoerg 
41037330f729Sjoerg     // Don't verify store flags on instructions with side effects. At least for
41047330f729Sjoerg     // intrinsics, side effects implies mayStore.
41057330f729Sjoerg     if (!PatInfo.hasSideEffects && PatInfo.mayStore && !NumStores)
41067330f729Sjoerg       Msgs.push_back("pattern may store, but mayStore isn't set");
41077330f729Sjoerg 
41087330f729Sjoerg     // Similarly, mayStore implies mayLoad on intrinsics.
41097330f729Sjoerg     if (!PatInfo.mayStore && PatInfo.mayLoad && !NumLoads)
41107330f729Sjoerg       Msgs.push_back("pattern may load, but mayLoad isn't set");
41117330f729Sjoerg 
41127330f729Sjoerg     // Print error messages.
41137330f729Sjoerg     if (Msgs.empty())
41147330f729Sjoerg       continue;
41157330f729Sjoerg     ++Errors;
41167330f729Sjoerg 
41177330f729Sjoerg     for (const std::string &Msg : Msgs)
41187330f729Sjoerg       PrintError(PTM.getSrcRecord()->getLoc(), Twine(Msg) + " on the " +
41197330f729Sjoerg                  (Instrs.size() == 1 ?
41207330f729Sjoerg                   "instruction" : "output instructions"));
41217330f729Sjoerg     // Provide the location of the relevant instruction definitions.
41227330f729Sjoerg     for (const Record *Instr : Instrs) {
41237330f729Sjoerg       if (Instr != PTM.getSrcRecord())
41247330f729Sjoerg         PrintError(Instr->getLoc(), "defined here");
41257330f729Sjoerg       const CodeGenInstruction &InstInfo = Target.getInstruction(Instr);
41267330f729Sjoerg       if (InstInfo.InferredFrom &&
41277330f729Sjoerg           InstInfo.InferredFrom != InstInfo.TheDef &&
41287330f729Sjoerg           InstInfo.InferredFrom != PTM.getSrcRecord())
41297330f729Sjoerg         PrintError(InstInfo.InferredFrom->getLoc(), "inferred from pattern");
41307330f729Sjoerg     }
41317330f729Sjoerg   }
41327330f729Sjoerg   if (Errors)
41337330f729Sjoerg     PrintFatalError("Errors in DAG patterns");
41347330f729Sjoerg }
41357330f729Sjoerg 
41367330f729Sjoerg /// Given a pattern result with an unresolved type, see if we can find one
41377330f729Sjoerg /// instruction with an unresolved result type.  Force this result type to an
41387330f729Sjoerg /// arbitrary element if it's possible types to converge results.
ForceArbitraryInstResultType(TreePatternNode * N,TreePattern & TP)41397330f729Sjoerg static bool ForceArbitraryInstResultType(TreePatternNode *N, TreePattern &TP) {
41407330f729Sjoerg   if (N->isLeaf())
41417330f729Sjoerg     return false;
41427330f729Sjoerg 
41437330f729Sjoerg   // Analyze children.
41447330f729Sjoerg   for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
41457330f729Sjoerg     if (ForceArbitraryInstResultType(N->getChild(i), TP))
41467330f729Sjoerg       return true;
41477330f729Sjoerg 
41487330f729Sjoerg   if (!N->getOperator()->isSubClassOf("Instruction"))
41497330f729Sjoerg     return false;
41507330f729Sjoerg 
41517330f729Sjoerg   // If this type is already concrete or completely unknown we can't do
41527330f729Sjoerg   // anything.
41537330f729Sjoerg   TypeInfer &TI = TP.getInfer();
41547330f729Sjoerg   for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i) {
41557330f729Sjoerg     if (N->getExtType(i).empty() || TI.isConcrete(N->getExtType(i), false))
41567330f729Sjoerg       continue;
41577330f729Sjoerg 
41587330f729Sjoerg     // Otherwise, force its type to an arbitrary choice.
41597330f729Sjoerg     if (TI.forceArbitrary(N->getExtType(i)))
41607330f729Sjoerg       return true;
41617330f729Sjoerg   }
41627330f729Sjoerg 
41637330f729Sjoerg   return false;
41647330f729Sjoerg }
41657330f729Sjoerg 
41667330f729Sjoerg // Promote xform function to be an explicit node wherever set.
PromoteXForms(TreePatternNodePtr N)41677330f729Sjoerg static TreePatternNodePtr PromoteXForms(TreePatternNodePtr N) {
41687330f729Sjoerg   if (Record *Xform = N->getTransformFn()) {
41697330f729Sjoerg       N->setTransformFn(nullptr);
41707330f729Sjoerg       std::vector<TreePatternNodePtr> Children;
41717330f729Sjoerg       Children.push_back(PromoteXForms(N));
41727330f729Sjoerg       return std::make_shared<TreePatternNode>(Xform, std::move(Children),
41737330f729Sjoerg                                                N->getNumTypes());
41747330f729Sjoerg   }
41757330f729Sjoerg 
41767330f729Sjoerg   if (!N->isLeaf())
41777330f729Sjoerg     for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
41787330f729Sjoerg       TreePatternNodePtr Child = N->getChildShared(i);
41797330f729Sjoerg       N->setChild(i, PromoteXForms(Child));
41807330f729Sjoerg     }
41817330f729Sjoerg   return N;
41827330f729Sjoerg }
41837330f729Sjoerg 
ParseOnePattern(Record * TheDef,TreePattern & Pattern,TreePattern & Result,const std::vector<Record * > & InstImpResults)41847330f729Sjoerg void CodeGenDAGPatterns::ParseOnePattern(Record *TheDef,
41857330f729Sjoerg        TreePattern &Pattern, TreePattern &Result,
41867330f729Sjoerg        const std::vector<Record *> &InstImpResults) {
41877330f729Sjoerg 
41887330f729Sjoerg   // Inline pattern fragments and expand multiple alternatives.
41897330f729Sjoerg   Pattern.InlinePatternFragments();
41907330f729Sjoerg   Result.InlinePatternFragments();
41917330f729Sjoerg 
41927330f729Sjoerg   if (Result.getNumTrees() != 1)
41937330f729Sjoerg     Result.error("Cannot use multi-alternative fragments in result pattern!");
41947330f729Sjoerg 
41957330f729Sjoerg   // Infer types.
41967330f729Sjoerg   bool IterateInference;
41977330f729Sjoerg   bool InferredAllPatternTypes, InferredAllResultTypes;
41987330f729Sjoerg   do {
41997330f729Sjoerg     // Infer as many types as possible.  If we cannot infer all of them, we
42007330f729Sjoerg     // can never do anything with this pattern: report it to the user.
42017330f729Sjoerg     InferredAllPatternTypes =
42027330f729Sjoerg         Pattern.InferAllTypes(&Pattern.getNamedNodesMap());
42037330f729Sjoerg 
42047330f729Sjoerg     // Infer as many types as possible.  If we cannot infer all of them, we
42057330f729Sjoerg     // can never do anything with this pattern: report it to the user.
42067330f729Sjoerg     InferredAllResultTypes =
42077330f729Sjoerg         Result.InferAllTypes(&Pattern.getNamedNodesMap());
42087330f729Sjoerg 
42097330f729Sjoerg     IterateInference = false;
42107330f729Sjoerg 
42117330f729Sjoerg     // Apply the type of the result to the source pattern.  This helps us
42127330f729Sjoerg     // resolve cases where the input type is known to be a pointer type (which
42137330f729Sjoerg     // is considered resolved), but the result knows it needs to be 32- or
42147330f729Sjoerg     // 64-bits.  Infer the other way for good measure.
4215*82d56013Sjoerg     for (const auto &T : Pattern.getTrees())
42167330f729Sjoerg       for (unsigned i = 0, e = std::min(Result.getOnlyTree()->getNumTypes(),
42177330f729Sjoerg                                         T->getNumTypes());
42187330f729Sjoerg          i != e; ++i) {
42197330f729Sjoerg         IterateInference |= T->UpdateNodeType(
42207330f729Sjoerg             i, Result.getOnlyTree()->getExtType(i), Result);
42217330f729Sjoerg         IterateInference |= Result.getOnlyTree()->UpdateNodeType(
42227330f729Sjoerg             i, T->getExtType(i), Result);
42237330f729Sjoerg       }
42247330f729Sjoerg 
42257330f729Sjoerg     // If our iteration has converged and the input pattern's types are fully
42267330f729Sjoerg     // resolved but the result pattern is not fully resolved, we may have a
42277330f729Sjoerg     // situation where we have two instructions in the result pattern and
42287330f729Sjoerg     // the instructions require a common register class, but don't care about
42297330f729Sjoerg     // what actual MVT is used.  This is actually a bug in our modelling:
42307330f729Sjoerg     // output patterns should have register classes, not MVTs.
42317330f729Sjoerg     //
42327330f729Sjoerg     // In any case, to handle this, we just go through and disambiguate some
42337330f729Sjoerg     // arbitrary types to the result pattern's nodes.
42347330f729Sjoerg     if (!IterateInference && InferredAllPatternTypes &&
42357330f729Sjoerg         !InferredAllResultTypes)
42367330f729Sjoerg       IterateInference =
42377330f729Sjoerg           ForceArbitraryInstResultType(Result.getTree(0).get(), Result);
42387330f729Sjoerg   } while (IterateInference);
42397330f729Sjoerg 
42407330f729Sjoerg   // Verify that we inferred enough types that we can do something with the
42417330f729Sjoerg   // pattern and result.  If these fire the user has to add type casts.
42427330f729Sjoerg   if (!InferredAllPatternTypes)
42437330f729Sjoerg     Pattern.error("Could not infer all types in pattern!");
42447330f729Sjoerg   if (!InferredAllResultTypes) {
42457330f729Sjoerg     Pattern.dump();
42467330f729Sjoerg     Result.error("Could not infer all types in pattern result!");
42477330f729Sjoerg   }
42487330f729Sjoerg 
42497330f729Sjoerg   // Promote xform function to be an explicit node wherever set.
42507330f729Sjoerg   TreePatternNodePtr DstShared = PromoteXForms(Result.getOnlyTree());
42517330f729Sjoerg 
42527330f729Sjoerg   TreePattern Temp(Result.getRecord(), DstShared, false, *this);
42537330f729Sjoerg   Temp.InferAllTypes();
42547330f729Sjoerg 
42557330f729Sjoerg   ListInit *Preds = TheDef->getValueAsListInit("Predicates");
42567330f729Sjoerg   int Complexity = TheDef->getValueAsInt("AddedComplexity");
42577330f729Sjoerg 
42587330f729Sjoerg   if (PatternRewriter)
42597330f729Sjoerg     PatternRewriter(&Pattern);
42607330f729Sjoerg 
42617330f729Sjoerg   // A pattern may end up with an "impossible" type, i.e. a situation
42627330f729Sjoerg   // where all types have been eliminated for some node in this pattern.
42637330f729Sjoerg   // This could occur for intrinsics that only make sense for a specific
42647330f729Sjoerg   // value type, and use a specific register class. If, for some mode,
42657330f729Sjoerg   // that register class does not accept that type, the type inference
42667330f729Sjoerg   // will lead to a contradiction, which is not an error however, but
42677330f729Sjoerg   // a sign that this pattern will simply never match.
42687330f729Sjoerg   if (Temp.getOnlyTree()->hasPossibleType())
4269*82d56013Sjoerg     for (const auto &T : Pattern.getTrees())
42707330f729Sjoerg       if (T->hasPossibleType())
42717330f729Sjoerg         AddPatternToMatch(&Pattern,
4272*82d56013Sjoerg                           PatternToMatch(TheDef, Preds, T, Temp.getOnlyTree(),
42737330f729Sjoerg                                          InstImpResults, Complexity,
42747330f729Sjoerg                                          TheDef->getID()));
42757330f729Sjoerg }
42767330f729Sjoerg 
ParsePatterns()42777330f729Sjoerg void CodeGenDAGPatterns::ParsePatterns() {
42787330f729Sjoerg   std::vector<Record*> Patterns = Records.getAllDerivedDefinitions("Pattern");
42797330f729Sjoerg 
42807330f729Sjoerg   for (Record *CurPattern : Patterns) {
42817330f729Sjoerg     DagInit *Tree = CurPattern->getValueAsDag("PatternToMatch");
42827330f729Sjoerg 
42837330f729Sjoerg     // If the pattern references the null_frag, there's nothing to do.
42847330f729Sjoerg     if (hasNullFragReference(Tree))
42857330f729Sjoerg       continue;
42867330f729Sjoerg 
42877330f729Sjoerg     TreePattern Pattern(CurPattern, Tree, true, *this);
42887330f729Sjoerg 
42897330f729Sjoerg     ListInit *LI = CurPattern->getValueAsListInit("ResultInstrs");
42907330f729Sjoerg     if (LI->empty()) continue;  // no pattern.
42917330f729Sjoerg 
42927330f729Sjoerg     // Parse the instruction.
42937330f729Sjoerg     TreePattern Result(CurPattern, LI, false, *this);
42947330f729Sjoerg 
42957330f729Sjoerg     if (Result.getNumTrees() != 1)
42967330f729Sjoerg       Result.error("Cannot handle instructions producing instructions "
42977330f729Sjoerg                    "with temporaries yet!");
42987330f729Sjoerg 
42997330f729Sjoerg     // Validate that the input pattern is correct.
43007330f729Sjoerg     std::map<std::string, TreePatternNodePtr> InstInputs;
43017330f729Sjoerg     MapVector<std::string, TreePatternNodePtr, std::map<std::string, unsigned>>
43027330f729Sjoerg         InstResults;
43037330f729Sjoerg     std::vector<Record*> InstImpResults;
43047330f729Sjoerg     for (unsigned j = 0, ee = Pattern.getNumTrees(); j != ee; ++j)
43057330f729Sjoerg       FindPatternInputsAndOutputs(Pattern, Pattern.getTree(j), InstInputs,
43067330f729Sjoerg                                   InstResults, InstImpResults);
43077330f729Sjoerg 
43087330f729Sjoerg     ParseOnePattern(CurPattern, Pattern, Result, InstImpResults);
43097330f729Sjoerg   }
43107330f729Sjoerg }
43117330f729Sjoerg 
collectModes(std::set<unsigned> & Modes,const TreePatternNode * N)43127330f729Sjoerg static void collectModes(std::set<unsigned> &Modes, const TreePatternNode *N) {
43137330f729Sjoerg   for (const TypeSetByHwMode &VTS : N->getExtTypes())
43147330f729Sjoerg     for (const auto &I : VTS)
43157330f729Sjoerg       Modes.insert(I.first);
43167330f729Sjoerg 
43177330f729Sjoerg   for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
43187330f729Sjoerg     collectModes(Modes, N->getChild(i));
43197330f729Sjoerg }
43207330f729Sjoerg 
ExpandHwModeBasedTypes()43217330f729Sjoerg void CodeGenDAGPatterns::ExpandHwModeBasedTypes() {
43227330f729Sjoerg   const CodeGenHwModes &CGH = getTargetInfo().getHwModes();
4323*82d56013Sjoerg   std::vector<PatternToMatch> Copy;
4324*82d56013Sjoerg   PatternsToMatch.swap(Copy);
43257330f729Sjoerg 
4326*82d56013Sjoerg   auto AppendPattern = [this](PatternToMatch &P, unsigned Mode,
4327*82d56013Sjoerg                               StringRef Check) {
4328*82d56013Sjoerg     TreePatternNodePtr NewSrc = P.getSrcPattern()->clone();
4329*82d56013Sjoerg     TreePatternNodePtr NewDst = P.getDstPattern()->clone();
43307330f729Sjoerg     if (!NewSrc->setDefaultMode(Mode) || !NewDst->setDefaultMode(Mode)) {
43317330f729Sjoerg       return;
43327330f729Sjoerg     }
43337330f729Sjoerg 
4334*82d56013Sjoerg     PatternsToMatch.emplace_back(P.getSrcRecord(), P.getPredicates(),
4335*82d56013Sjoerg                                  std::move(NewSrc), std::move(NewDst),
4336*82d56013Sjoerg                                  P.getDstRegs(), P.getAddedComplexity(),
4337*82d56013Sjoerg                                  Record::getNewUID(), Mode, Check);
43387330f729Sjoerg   };
43397330f729Sjoerg 
43407330f729Sjoerg   for (PatternToMatch &P : Copy) {
43417330f729Sjoerg     TreePatternNodePtr SrcP = nullptr, DstP = nullptr;
4342*82d56013Sjoerg     if (P.getSrcPattern()->hasProperTypeByHwMode())
4343*82d56013Sjoerg       SrcP = P.getSrcPatternShared();
4344*82d56013Sjoerg     if (P.getDstPattern()->hasProperTypeByHwMode())
4345*82d56013Sjoerg       DstP = P.getDstPatternShared();
43467330f729Sjoerg     if (!SrcP && !DstP) {
43477330f729Sjoerg       PatternsToMatch.push_back(P);
43487330f729Sjoerg       continue;
43497330f729Sjoerg     }
43507330f729Sjoerg 
43517330f729Sjoerg     std::set<unsigned> Modes;
43527330f729Sjoerg     if (SrcP)
43537330f729Sjoerg       collectModes(Modes, SrcP.get());
43547330f729Sjoerg     if (DstP)
43557330f729Sjoerg       collectModes(Modes, DstP.get());
43567330f729Sjoerg 
43577330f729Sjoerg     // The predicate for the default mode needs to be constructed for each
43587330f729Sjoerg     // pattern separately.
43597330f729Sjoerg     // Since not all modes must be present in each pattern, if a mode m is
43607330f729Sjoerg     // absent, then there is no point in constructing a check for m. If such
43617330f729Sjoerg     // a check was created, it would be equivalent to checking the default
43627330f729Sjoerg     // mode, except not all modes' predicates would be a part of the checking
43637330f729Sjoerg     // code. The subsequently generated check for the default mode would then
43647330f729Sjoerg     // have the exact same patterns, but a different predicate code. To avoid
43657330f729Sjoerg     // duplicated patterns with different predicate checks, construct the
43667330f729Sjoerg     // default check as a negation of all predicates that are actually present
43677330f729Sjoerg     // in the source/destination patterns.
4368*82d56013Sjoerg     SmallString<128> DefaultCheck;
43697330f729Sjoerg 
43707330f729Sjoerg     for (unsigned M : Modes) {
43717330f729Sjoerg       if (M == DefaultMode)
43727330f729Sjoerg         continue;
43737330f729Sjoerg 
43747330f729Sjoerg       // Fill the map entry for this mode.
43757330f729Sjoerg       const HwMode &HM = CGH.getMode(M);
4376*82d56013Sjoerg       AppendPattern(P, M, "(MF->getSubtarget().checkFeatures(\"" + HM.Features + "\"))");
43777330f729Sjoerg 
43787330f729Sjoerg       // Add negations of the HM's predicates to the default predicate.
4379*82d56013Sjoerg       if (!DefaultCheck.empty())
4380*82d56013Sjoerg         DefaultCheck += " && ";
4381*82d56013Sjoerg       DefaultCheck += "(!(MF->getSubtarget().checkFeatures(\"";
4382*82d56013Sjoerg       DefaultCheck += HM.Features;
4383*82d56013Sjoerg       DefaultCheck += "\")))";
43847330f729Sjoerg     }
43857330f729Sjoerg 
43867330f729Sjoerg     bool HasDefault = Modes.count(DefaultMode);
43877330f729Sjoerg     if (HasDefault)
4388*82d56013Sjoerg       AppendPattern(P, DefaultMode, DefaultCheck);
43897330f729Sjoerg   }
43907330f729Sjoerg }
43917330f729Sjoerg 
43927330f729Sjoerg /// Dependent variable map for CodeGenDAGPattern variant generation
43937330f729Sjoerg typedef StringMap<int> DepVarMap;
43947330f729Sjoerg 
FindDepVarsOf(TreePatternNode * N,DepVarMap & DepMap)43957330f729Sjoerg static void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) {
43967330f729Sjoerg   if (N->isLeaf()) {
43977330f729Sjoerg     if (N->hasName() && isa<DefInit>(N->getLeafValue()))
43987330f729Sjoerg       DepMap[N->getName()]++;
43997330f729Sjoerg   } else {
44007330f729Sjoerg     for (size_t i = 0, e = N->getNumChildren(); i != e; ++i)
44017330f729Sjoerg       FindDepVarsOf(N->getChild(i), DepMap);
44027330f729Sjoerg   }
44037330f729Sjoerg }
44047330f729Sjoerg 
44057330f729Sjoerg /// Find dependent variables within child patterns
FindDepVars(TreePatternNode * N,MultipleUseVarSet & DepVars)44067330f729Sjoerg static void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) {
44077330f729Sjoerg   DepVarMap depcounts;
44087330f729Sjoerg   FindDepVarsOf(N, depcounts);
44097330f729Sjoerg   for (const auto &Pair : depcounts) {
44107330f729Sjoerg     if (Pair.getValue() > 1)
44117330f729Sjoerg       DepVars.insert(Pair.getKey());
44127330f729Sjoerg   }
44137330f729Sjoerg }
44147330f729Sjoerg 
44157330f729Sjoerg #ifndef NDEBUG
44167330f729Sjoerg /// Dump the dependent variable set:
DumpDepVars(MultipleUseVarSet & DepVars)44177330f729Sjoerg static void DumpDepVars(MultipleUseVarSet &DepVars) {
44187330f729Sjoerg   if (DepVars.empty()) {
44197330f729Sjoerg     LLVM_DEBUG(errs() << "<empty set>");
44207330f729Sjoerg   } else {
44217330f729Sjoerg     LLVM_DEBUG(errs() << "[ ");
44227330f729Sjoerg     for (const auto &DepVar : DepVars) {
44237330f729Sjoerg       LLVM_DEBUG(errs() << DepVar.getKey() << " ");
44247330f729Sjoerg     }
44257330f729Sjoerg     LLVM_DEBUG(errs() << "]");
44267330f729Sjoerg   }
44277330f729Sjoerg }
44287330f729Sjoerg #endif
44297330f729Sjoerg 
44307330f729Sjoerg 
44317330f729Sjoerg /// CombineChildVariants - Given a bunch of permutations of each child of the
44327330f729Sjoerg /// 'operator' node, put them together in all possible ways.
CombineChildVariants(TreePatternNodePtr Orig,const std::vector<std::vector<TreePatternNodePtr>> & ChildVariants,std::vector<TreePatternNodePtr> & OutVariants,CodeGenDAGPatterns & CDP,const MultipleUseVarSet & DepVars)44337330f729Sjoerg static void CombineChildVariants(
44347330f729Sjoerg     TreePatternNodePtr Orig,
44357330f729Sjoerg     const std::vector<std::vector<TreePatternNodePtr>> &ChildVariants,
44367330f729Sjoerg     std::vector<TreePatternNodePtr> &OutVariants, CodeGenDAGPatterns &CDP,
44377330f729Sjoerg     const MultipleUseVarSet &DepVars) {
44387330f729Sjoerg   // Make sure that each operand has at least one variant to choose from.
44397330f729Sjoerg   for (const auto &Variants : ChildVariants)
44407330f729Sjoerg     if (Variants.empty())
44417330f729Sjoerg       return;
44427330f729Sjoerg 
44437330f729Sjoerg   // The end result is an all-pairs construction of the resultant pattern.
44447330f729Sjoerg   std::vector<unsigned> Idxs;
44457330f729Sjoerg   Idxs.resize(ChildVariants.size());
44467330f729Sjoerg   bool NotDone;
44477330f729Sjoerg   do {
44487330f729Sjoerg #ifndef NDEBUG
44497330f729Sjoerg     LLVM_DEBUG(if (!Idxs.empty()) {
44507330f729Sjoerg       errs() << Orig->getOperator()->getName() << ": Idxs = [ ";
44517330f729Sjoerg       for (unsigned Idx : Idxs) {
44527330f729Sjoerg         errs() << Idx << " ";
44537330f729Sjoerg       }
44547330f729Sjoerg       errs() << "]\n";
44557330f729Sjoerg     });
44567330f729Sjoerg #endif
44577330f729Sjoerg     // Create the variant and add it to the output list.
44587330f729Sjoerg     std::vector<TreePatternNodePtr> NewChildren;
44597330f729Sjoerg     for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i)
44607330f729Sjoerg       NewChildren.push_back(ChildVariants[i][Idxs[i]]);
44617330f729Sjoerg     TreePatternNodePtr R = std::make_shared<TreePatternNode>(
44627330f729Sjoerg         Orig->getOperator(), std::move(NewChildren), Orig->getNumTypes());
44637330f729Sjoerg 
44647330f729Sjoerg     // Copy over properties.
44657330f729Sjoerg     R->setName(Orig->getName());
44667330f729Sjoerg     R->setNamesAsPredicateArg(Orig->getNamesAsPredicateArg());
44677330f729Sjoerg     R->setPredicateCalls(Orig->getPredicateCalls());
44687330f729Sjoerg     R->setTransformFn(Orig->getTransformFn());
44697330f729Sjoerg     for (unsigned i = 0, e = Orig->getNumTypes(); i != e; ++i)
44707330f729Sjoerg       R->setType(i, Orig->getExtType(i));
44717330f729Sjoerg 
44727330f729Sjoerg     // If this pattern cannot match, do not include it as a variant.
44737330f729Sjoerg     std::string ErrString;
44747330f729Sjoerg     // Scan to see if this pattern has already been emitted.  We can get
44757330f729Sjoerg     // duplication due to things like commuting:
44767330f729Sjoerg     //   (and GPRC:$a, GPRC:$b) -> (and GPRC:$b, GPRC:$a)
44777330f729Sjoerg     // which are the same pattern.  Ignore the dups.
44787330f729Sjoerg     if (R->canPatternMatch(ErrString, CDP) &&
44797330f729Sjoerg         none_of(OutVariants, [&](TreePatternNodePtr Variant) {
44807330f729Sjoerg           return R->isIsomorphicTo(Variant.get(), DepVars);
44817330f729Sjoerg         }))
44827330f729Sjoerg       OutVariants.push_back(R);
44837330f729Sjoerg 
44847330f729Sjoerg     // Increment indices to the next permutation by incrementing the
44857330f729Sjoerg     // indices from last index backward, e.g., generate the sequence
44867330f729Sjoerg     // [0, 0], [0, 1], [1, 0], [1, 1].
44877330f729Sjoerg     int IdxsIdx;
44887330f729Sjoerg     for (IdxsIdx = Idxs.size() - 1; IdxsIdx >= 0; --IdxsIdx) {
44897330f729Sjoerg       if (++Idxs[IdxsIdx] == ChildVariants[IdxsIdx].size())
44907330f729Sjoerg         Idxs[IdxsIdx] = 0;
44917330f729Sjoerg       else
44927330f729Sjoerg         break;
44937330f729Sjoerg     }
44947330f729Sjoerg     NotDone = (IdxsIdx >= 0);
44957330f729Sjoerg   } while (NotDone);
44967330f729Sjoerg }
44977330f729Sjoerg 
44987330f729Sjoerg /// CombineChildVariants - A helper function for binary operators.
44997330f729Sjoerg ///
CombineChildVariants(TreePatternNodePtr Orig,const std::vector<TreePatternNodePtr> & LHS,const std::vector<TreePatternNodePtr> & RHS,std::vector<TreePatternNodePtr> & OutVariants,CodeGenDAGPatterns & CDP,const MultipleUseVarSet & DepVars)45007330f729Sjoerg static void CombineChildVariants(TreePatternNodePtr Orig,
45017330f729Sjoerg                                  const std::vector<TreePatternNodePtr> &LHS,
45027330f729Sjoerg                                  const std::vector<TreePatternNodePtr> &RHS,
45037330f729Sjoerg                                  std::vector<TreePatternNodePtr> &OutVariants,
45047330f729Sjoerg                                  CodeGenDAGPatterns &CDP,
45057330f729Sjoerg                                  const MultipleUseVarSet &DepVars) {
45067330f729Sjoerg   std::vector<std::vector<TreePatternNodePtr>> ChildVariants;
45077330f729Sjoerg   ChildVariants.push_back(LHS);
45087330f729Sjoerg   ChildVariants.push_back(RHS);
45097330f729Sjoerg   CombineChildVariants(Orig, ChildVariants, OutVariants, CDP, DepVars);
45107330f729Sjoerg }
45117330f729Sjoerg 
45127330f729Sjoerg static void
GatherChildrenOfAssociativeOpcode(TreePatternNodePtr N,std::vector<TreePatternNodePtr> & Children)45137330f729Sjoerg GatherChildrenOfAssociativeOpcode(TreePatternNodePtr N,
45147330f729Sjoerg                                   std::vector<TreePatternNodePtr> &Children) {
45157330f729Sjoerg   assert(N->getNumChildren()==2 &&"Associative but doesn't have 2 children!");
45167330f729Sjoerg   Record *Operator = N->getOperator();
45177330f729Sjoerg 
45187330f729Sjoerg   // Only permit raw nodes.
45197330f729Sjoerg   if (!N->getName().empty() || !N->getPredicateCalls().empty() ||
45207330f729Sjoerg       N->getTransformFn()) {
45217330f729Sjoerg     Children.push_back(N);
45227330f729Sjoerg     return;
45237330f729Sjoerg   }
45247330f729Sjoerg 
45257330f729Sjoerg   if (N->getChild(0)->isLeaf() || N->getChild(0)->getOperator() != Operator)
45267330f729Sjoerg     Children.push_back(N->getChildShared(0));
45277330f729Sjoerg   else
45287330f729Sjoerg     GatherChildrenOfAssociativeOpcode(N->getChildShared(0), Children);
45297330f729Sjoerg 
45307330f729Sjoerg   if (N->getChild(1)->isLeaf() || N->getChild(1)->getOperator() != Operator)
45317330f729Sjoerg     Children.push_back(N->getChildShared(1));
45327330f729Sjoerg   else
45337330f729Sjoerg     GatherChildrenOfAssociativeOpcode(N->getChildShared(1), Children);
45347330f729Sjoerg }
45357330f729Sjoerg 
45367330f729Sjoerg /// GenerateVariantsOf - Given a pattern N, generate all permutations we can of
45377330f729Sjoerg /// the (potentially recursive) pattern by using algebraic laws.
45387330f729Sjoerg ///
GenerateVariantsOf(TreePatternNodePtr N,std::vector<TreePatternNodePtr> & OutVariants,CodeGenDAGPatterns & CDP,const MultipleUseVarSet & DepVars)45397330f729Sjoerg static void GenerateVariantsOf(TreePatternNodePtr N,
45407330f729Sjoerg                                std::vector<TreePatternNodePtr> &OutVariants,
45417330f729Sjoerg                                CodeGenDAGPatterns &CDP,
45427330f729Sjoerg                                const MultipleUseVarSet &DepVars) {
45437330f729Sjoerg   // We cannot permute leaves or ComplexPattern uses.
45447330f729Sjoerg   if (N->isLeaf() || N->getOperator()->isSubClassOf("ComplexPattern")) {
45457330f729Sjoerg     OutVariants.push_back(N);
45467330f729Sjoerg     return;
45477330f729Sjoerg   }
45487330f729Sjoerg 
45497330f729Sjoerg   // Look up interesting info about the node.
45507330f729Sjoerg   const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(N->getOperator());
45517330f729Sjoerg 
45527330f729Sjoerg   // If this node is associative, re-associate.
45537330f729Sjoerg   if (NodeInfo.hasProperty(SDNPAssociative)) {
45547330f729Sjoerg     // Re-associate by pulling together all of the linked operators
45557330f729Sjoerg     std::vector<TreePatternNodePtr> MaximalChildren;
45567330f729Sjoerg     GatherChildrenOfAssociativeOpcode(N, MaximalChildren);
45577330f729Sjoerg 
45587330f729Sjoerg     // Only handle child sizes of 3.  Otherwise we'll end up trying too many
45597330f729Sjoerg     // permutations.
45607330f729Sjoerg     if (MaximalChildren.size() == 3) {
45617330f729Sjoerg       // Find the variants of all of our maximal children.
45627330f729Sjoerg       std::vector<TreePatternNodePtr> AVariants, BVariants, CVariants;
45637330f729Sjoerg       GenerateVariantsOf(MaximalChildren[0], AVariants, CDP, DepVars);
45647330f729Sjoerg       GenerateVariantsOf(MaximalChildren[1], BVariants, CDP, DepVars);
45657330f729Sjoerg       GenerateVariantsOf(MaximalChildren[2], CVariants, CDP, DepVars);
45667330f729Sjoerg 
45677330f729Sjoerg       // There are only two ways we can permute the tree:
45687330f729Sjoerg       //   (A op B) op C    and    A op (B op C)
45697330f729Sjoerg       // Within these forms, we can also permute A/B/C.
45707330f729Sjoerg 
45717330f729Sjoerg       // Generate legal pair permutations of A/B/C.
45727330f729Sjoerg       std::vector<TreePatternNodePtr> ABVariants;
45737330f729Sjoerg       std::vector<TreePatternNodePtr> BAVariants;
45747330f729Sjoerg       std::vector<TreePatternNodePtr> ACVariants;
45757330f729Sjoerg       std::vector<TreePatternNodePtr> CAVariants;
45767330f729Sjoerg       std::vector<TreePatternNodePtr> BCVariants;
45777330f729Sjoerg       std::vector<TreePatternNodePtr> CBVariants;
45787330f729Sjoerg       CombineChildVariants(N, AVariants, BVariants, ABVariants, CDP, DepVars);
45797330f729Sjoerg       CombineChildVariants(N, BVariants, AVariants, BAVariants, CDP, DepVars);
45807330f729Sjoerg       CombineChildVariants(N, AVariants, CVariants, ACVariants, CDP, DepVars);
45817330f729Sjoerg       CombineChildVariants(N, CVariants, AVariants, CAVariants, CDP, DepVars);
45827330f729Sjoerg       CombineChildVariants(N, BVariants, CVariants, BCVariants, CDP, DepVars);
45837330f729Sjoerg       CombineChildVariants(N, CVariants, BVariants, CBVariants, CDP, DepVars);
45847330f729Sjoerg 
45857330f729Sjoerg       // Combine those into the result: (x op x) op x
45867330f729Sjoerg       CombineChildVariants(N, ABVariants, CVariants, OutVariants, CDP, DepVars);
45877330f729Sjoerg       CombineChildVariants(N, BAVariants, CVariants, OutVariants, CDP, DepVars);
45887330f729Sjoerg       CombineChildVariants(N, ACVariants, BVariants, OutVariants, CDP, DepVars);
45897330f729Sjoerg       CombineChildVariants(N, CAVariants, BVariants, OutVariants, CDP, DepVars);
45907330f729Sjoerg       CombineChildVariants(N, BCVariants, AVariants, OutVariants, CDP, DepVars);
45917330f729Sjoerg       CombineChildVariants(N, CBVariants, AVariants, OutVariants, CDP, DepVars);
45927330f729Sjoerg 
45937330f729Sjoerg       // Combine those into the result: x op (x op x)
45947330f729Sjoerg       CombineChildVariants(N, CVariants, ABVariants, OutVariants, CDP, DepVars);
45957330f729Sjoerg       CombineChildVariants(N, CVariants, BAVariants, OutVariants, CDP, DepVars);
45967330f729Sjoerg       CombineChildVariants(N, BVariants, ACVariants, OutVariants, CDP, DepVars);
45977330f729Sjoerg       CombineChildVariants(N, BVariants, CAVariants, OutVariants, CDP, DepVars);
45987330f729Sjoerg       CombineChildVariants(N, AVariants, BCVariants, OutVariants, CDP, DepVars);
45997330f729Sjoerg       CombineChildVariants(N, AVariants, CBVariants, OutVariants, CDP, DepVars);
46007330f729Sjoerg       return;
46017330f729Sjoerg     }
46027330f729Sjoerg   }
46037330f729Sjoerg 
46047330f729Sjoerg   // Compute permutations of all children.
46057330f729Sjoerg   std::vector<std::vector<TreePatternNodePtr>> ChildVariants;
46067330f729Sjoerg   ChildVariants.resize(N->getNumChildren());
46077330f729Sjoerg   for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
46087330f729Sjoerg     GenerateVariantsOf(N->getChildShared(i), ChildVariants[i], CDP, DepVars);
46097330f729Sjoerg 
46107330f729Sjoerg   // Build all permutations based on how the children were formed.
46117330f729Sjoerg   CombineChildVariants(N, ChildVariants, OutVariants, CDP, DepVars);
46127330f729Sjoerg 
46137330f729Sjoerg   // If this node is commutative, consider the commuted order.
46147330f729Sjoerg   bool isCommIntrinsic = N->isCommutativeIntrinsic(CDP);
46157330f729Sjoerg   if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) {
46167330f729Sjoerg     assert((N->getNumChildren()>=2 || isCommIntrinsic) &&
46177330f729Sjoerg            "Commutative but doesn't have 2 children!");
46187330f729Sjoerg     // Don't count children which are actually register references.
46197330f729Sjoerg     unsigned NC = 0;
46207330f729Sjoerg     for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
46217330f729Sjoerg       TreePatternNode *Child = N->getChild(i);
46227330f729Sjoerg       if (Child->isLeaf())
46237330f729Sjoerg         if (DefInit *DI = dyn_cast<DefInit>(Child->getLeafValue())) {
46247330f729Sjoerg           Record *RR = DI->getDef();
46257330f729Sjoerg           if (RR->isSubClassOf("Register"))
46267330f729Sjoerg             continue;
46277330f729Sjoerg         }
46287330f729Sjoerg       NC++;
46297330f729Sjoerg     }
46307330f729Sjoerg     // Consider the commuted order.
46317330f729Sjoerg     if (isCommIntrinsic) {
46327330f729Sjoerg       // Commutative intrinsic. First operand is the intrinsic id, 2nd and 3rd
46337330f729Sjoerg       // operands are the commutative operands, and there might be more operands
46347330f729Sjoerg       // after those.
46357330f729Sjoerg       assert(NC >= 3 &&
46367330f729Sjoerg              "Commutative intrinsic should have at least 3 children!");
46377330f729Sjoerg       std::vector<std::vector<TreePatternNodePtr>> Variants;
46387330f729Sjoerg       Variants.push_back(std::move(ChildVariants[0])); // Intrinsic id.
46397330f729Sjoerg       Variants.push_back(std::move(ChildVariants[2]));
46407330f729Sjoerg       Variants.push_back(std::move(ChildVariants[1]));
46417330f729Sjoerg       for (unsigned i = 3; i != NC; ++i)
46427330f729Sjoerg         Variants.push_back(std::move(ChildVariants[i]));
46437330f729Sjoerg       CombineChildVariants(N, Variants, OutVariants, CDP, DepVars);
46447330f729Sjoerg     } else if (NC == N->getNumChildren()) {
46457330f729Sjoerg       std::vector<std::vector<TreePatternNodePtr>> Variants;
46467330f729Sjoerg       Variants.push_back(std::move(ChildVariants[1]));
46477330f729Sjoerg       Variants.push_back(std::move(ChildVariants[0]));
46487330f729Sjoerg       for (unsigned i = 2; i != NC; ++i)
46497330f729Sjoerg         Variants.push_back(std::move(ChildVariants[i]));
46507330f729Sjoerg       CombineChildVariants(N, Variants, OutVariants, CDP, DepVars);
46517330f729Sjoerg     }
46527330f729Sjoerg   }
46537330f729Sjoerg }
46547330f729Sjoerg 
46557330f729Sjoerg 
46567330f729Sjoerg // GenerateVariants - Generate variants.  For example, commutative patterns can
46577330f729Sjoerg // match multiple ways.  Add them to PatternsToMatch as well.
GenerateVariants()46587330f729Sjoerg void CodeGenDAGPatterns::GenerateVariants() {
46597330f729Sjoerg   LLVM_DEBUG(errs() << "Generating instruction variants.\n");
46607330f729Sjoerg 
46617330f729Sjoerg   // Loop over all of the patterns we've collected, checking to see if we can
46627330f729Sjoerg   // generate variants of the instruction, through the exploitation of
46637330f729Sjoerg   // identities.  This permits the target to provide aggressive matching without
46647330f729Sjoerg   // the .td file having to contain tons of variants of instructions.
46657330f729Sjoerg   //
46667330f729Sjoerg   // Note that this loop adds new patterns to the PatternsToMatch list, but we
46677330f729Sjoerg   // intentionally do not reconsider these.  Any variants of added patterns have
46687330f729Sjoerg   // already been added.
46697330f729Sjoerg   //
4670*82d56013Sjoerg   for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
46717330f729Sjoerg     MultipleUseVarSet DepVars;
46727330f729Sjoerg     std::vector<TreePatternNodePtr> Variants;
46737330f729Sjoerg     FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars);
46747330f729Sjoerg     LLVM_DEBUG(errs() << "Dependent/multiply used variables: ");
46757330f729Sjoerg     LLVM_DEBUG(DumpDepVars(DepVars));
46767330f729Sjoerg     LLVM_DEBUG(errs() << "\n");
46777330f729Sjoerg     GenerateVariantsOf(PatternsToMatch[i].getSrcPatternShared(), Variants,
46787330f729Sjoerg                        *this, DepVars);
46797330f729Sjoerg 
4680*82d56013Sjoerg     assert(PatternsToMatch[i].getHwModeFeatures().empty() &&
4681*82d56013Sjoerg            "HwModes should not have been expanded yet!");
4682*82d56013Sjoerg 
46837330f729Sjoerg     assert(!Variants.empty() && "Must create at least original variant!");
46847330f729Sjoerg     if (Variants.size() == 1) // No additional variants for this pattern.
46857330f729Sjoerg       continue;
46867330f729Sjoerg 
46877330f729Sjoerg     LLVM_DEBUG(errs() << "FOUND VARIANTS OF: ";
46887330f729Sjoerg                PatternsToMatch[i].getSrcPattern()->dump(); errs() << "\n");
46897330f729Sjoerg 
46907330f729Sjoerg     for (unsigned v = 0, e = Variants.size(); v != e; ++v) {
46917330f729Sjoerg       TreePatternNodePtr Variant = Variants[v];
46927330f729Sjoerg 
46937330f729Sjoerg       LLVM_DEBUG(errs() << "  VAR#" << v << ": "; Variant->dump();
46947330f729Sjoerg                  errs() << "\n");
46957330f729Sjoerg 
46967330f729Sjoerg       // Scan to see if an instruction or explicit pattern already matches this.
46977330f729Sjoerg       bool AlreadyExists = false;
46987330f729Sjoerg       for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) {
46997330f729Sjoerg         // Skip if the top level predicates do not match.
4700*82d56013Sjoerg         if ((i != p) && (PatternsToMatch[i].getPredicates() !=
4701*82d56013Sjoerg                          PatternsToMatch[p].getPredicates()))
47027330f729Sjoerg           continue;
47037330f729Sjoerg         // Check to see if this variant already exists.
47047330f729Sjoerg         if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern(),
47057330f729Sjoerg                                     DepVars)) {
47067330f729Sjoerg           LLVM_DEBUG(errs() << "  *** ALREADY EXISTS, ignoring variant.\n");
47077330f729Sjoerg           AlreadyExists = true;
47087330f729Sjoerg           break;
47097330f729Sjoerg         }
47107330f729Sjoerg       }
47117330f729Sjoerg       // If we already have it, ignore the variant.
47127330f729Sjoerg       if (AlreadyExists) continue;
47137330f729Sjoerg 
47147330f729Sjoerg       // Otherwise, add it to the list of patterns we have.
4715*82d56013Sjoerg       PatternsToMatch.emplace_back(
47167330f729Sjoerg           PatternsToMatch[i].getSrcRecord(), PatternsToMatch[i].getPredicates(),
47177330f729Sjoerg           Variant, PatternsToMatch[i].getDstPatternShared(),
47187330f729Sjoerg           PatternsToMatch[i].getDstRegs(),
4719*82d56013Sjoerg           PatternsToMatch[i].getAddedComplexity(), Record::getNewUID(),
4720*82d56013Sjoerg           PatternsToMatch[i].getForceMode(),
4721*82d56013Sjoerg           PatternsToMatch[i].getHwModeFeatures());
47227330f729Sjoerg     }
47237330f729Sjoerg 
47247330f729Sjoerg     LLVM_DEBUG(errs() << "\n");
47257330f729Sjoerg   }
47267330f729Sjoerg }
4727