1fa3d789dSPierre van Houtryve //===- DAGISelMatcher.cpp - Representation of DAG pattern matcher ---------===// 2fa3d789dSPierre van Houtryve // 3fa3d789dSPierre van Houtryve // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fa3d789dSPierre van Houtryve // See https://llvm.org/LICENSE.txt for license information. 5fa3d789dSPierre van Houtryve // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fa3d789dSPierre van Houtryve // 7fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 8fa3d789dSPierre van Houtryve 9fa3d789dSPierre van Houtryve #include "DAGISelMatcher.h" 10fa3d789dSPierre van Houtryve #include "CodeGenDAGPatterns.h" 11fa3d789dSPierre van Houtryve #include "CodeGenInstruction.h" 12fa3d789dSPierre van Houtryve #include "CodeGenRegisters.h" 13fa3d789dSPierre van Houtryve #include "CodeGenTarget.h" 14fa3d789dSPierre van Houtryve #include "llvm/Support/raw_ostream.h" 15fa3d789dSPierre van Houtryve #include "llvm/TableGen/Record.h" 16fa3d789dSPierre van Houtryve using namespace llvm; 17fa3d789dSPierre van Houtryve 18fa3d789dSPierre van Houtryve void Matcher::anchor() {} 19fa3d789dSPierre van Houtryve 203e24dd42SRahul Joshi void Matcher::dump() const { print(errs()); } 21fa3d789dSPierre van Houtryve 22*708567abSRahul Joshi void Matcher::print(raw_ostream &OS, indent Indent) const { 233e24dd42SRahul Joshi printImpl(OS, Indent); 24fa3d789dSPierre van Houtryve if (Next) 253e24dd42SRahul Joshi return Next->print(OS, Indent); 26fa3d789dSPierre van Houtryve } 27fa3d789dSPierre van Houtryve 28*708567abSRahul Joshi void Matcher::printOne(raw_ostream &OS) const { printImpl(OS, indent(0)); } 29fa3d789dSPierre van Houtryve 30fa3d789dSPierre van Houtryve /// unlinkNode - Unlink the specified node from this chain. If Other == this, 31fa3d789dSPierre van Houtryve /// we unlink the next pointer and return it. Otherwise we unlink Other from 32fa3d789dSPierre van Houtryve /// the list and return this. 33fa3d789dSPierre van Houtryve Matcher *Matcher::unlinkNode(Matcher *Other) { 34fa3d789dSPierre van Houtryve if (this == Other) 35fa3d789dSPierre van Houtryve return takeNext(); 36fa3d789dSPierre van Houtryve 37fa3d789dSPierre van Houtryve // Scan until we find the predecessor of Other. 38fa3d789dSPierre van Houtryve Matcher *Cur = this; 39fa3d789dSPierre van Houtryve for (; Cur && Cur->getNext() != Other; Cur = Cur->getNext()) 40fa3d789dSPierre van Houtryve /*empty*/; 41fa3d789dSPierre van Houtryve 42fa3d789dSPierre van Houtryve if (!Cur) 43fa3d789dSPierre van Houtryve return nullptr; 44fa3d789dSPierre van Houtryve Cur->takeNext(); 45fa3d789dSPierre van Houtryve Cur->setNext(Other->takeNext()); 46fa3d789dSPierre van Houtryve return this; 47fa3d789dSPierre van Houtryve } 48fa3d789dSPierre van Houtryve 49fa3d789dSPierre van Houtryve /// canMoveBefore - Return true if this matcher is the same as Other, or if 50fa3d789dSPierre van Houtryve /// we can move this matcher past all of the nodes in-between Other and this 51fa3d789dSPierre van Houtryve /// node. Other must be equal to or before this. 52fa3d789dSPierre van Houtryve bool Matcher::canMoveBefore(const Matcher *Other) const { 53fa3d789dSPierre van Houtryve for (;; Other = Other->getNext()) { 54fa3d789dSPierre van Houtryve assert(Other && "Other didn't come before 'this'?"); 55fa3d789dSPierre van Houtryve if (this == Other) 56fa3d789dSPierre van Houtryve return true; 57fa3d789dSPierre van Houtryve 58fa3d789dSPierre van Houtryve // We have to be able to move this node across the Other node. 59fa3d789dSPierre van Houtryve if (!canMoveBeforeNode(Other)) 60fa3d789dSPierre van Houtryve return false; 61fa3d789dSPierre van Houtryve } 62fa3d789dSPierre van Houtryve } 63fa3d789dSPierre van Houtryve 64fa3d789dSPierre van Houtryve /// canMoveBeforeNode - Return true if it is safe to move the current matcher 65fa3d789dSPierre van Houtryve /// across the specified one. 66fa3d789dSPierre van Houtryve bool Matcher::canMoveBeforeNode(const Matcher *Other) const { 67fa3d789dSPierre van Houtryve // We can move simple predicates before record nodes. 68fa3d789dSPierre van Houtryve if (isSimplePredicateNode()) 69fa3d789dSPierre van Houtryve return Other->isSimplePredicateOrRecordNode(); 70fa3d789dSPierre van Houtryve 71fa3d789dSPierre van Houtryve // We can move record nodes across simple predicates. 72fa3d789dSPierre van Houtryve if (isSimplePredicateOrRecordNode()) 73fa3d789dSPierre van Houtryve return isSimplePredicateNode(); 74fa3d789dSPierre van Houtryve 75fa3d789dSPierre van Houtryve // We can't move record nodes across each other etc. 76fa3d789dSPierre van Houtryve return false; 77fa3d789dSPierre van Houtryve } 78fa3d789dSPierre van Houtryve 79fa3d789dSPierre van Houtryve ScopeMatcher::~ScopeMatcher() { 80fa3d789dSPierre van Houtryve for (Matcher *C : Children) 81fa3d789dSPierre van Houtryve delete C; 82fa3d789dSPierre van Houtryve } 83fa3d789dSPierre van Houtryve 84fa3d789dSPierre van Houtryve SwitchOpcodeMatcher::~SwitchOpcodeMatcher() { 85fa3d789dSPierre van Houtryve for (auto &C : Cases) 86fa3d789dSPierre van Houtryve delete C.second; 87fa3d789dSPierre van Houtryve } 88fa3d789dSPierre van Houtryve 89fa3d789dSPierre van Houtryve SwitchTypeMatcher::~SwitchTypeMatcher() { 90fa3d789dSPierre van Houtryve for (auto &C : Cases) 91fa3d789dSPierre van Houtryve delete C.second; 92fa3d789dSPierre van Houtryve } 93fa3d789dSPierre van Houtryve 94e9a47a66SKazu Hirata CheckPredicateMatcher::CheckPredicateMatcher(const TreePredicateFn &pred, 95e9a47a66SKazu Hirata ArrayRef<unsigned> Ops) 96fa3d789dSPierre van Houtryve : Matcher(CheckPredicate), Pred(pred.getOrigPatFragRecord()), 97e9a47a66SKazu Hirata Operands(Ops) {} 98fa3d789dSPierre van Houtryve 99fa3d789dSPierre van Houtryve TreePredicateFn CheckPredicateMatcher::getPredicate() const { 100fa3d789dSPierre van Houtryve return TreePredicateFn(Pred); 101fa3d789dSPierre van Houtryve } 102fa3d789dSPierre van Houtryve 103fa3d789dSPierre van Houtryve unsigned CheckPredicateMatcher::getNumOperands() const { 104fa3d789dSPierre van Houtryve return Operands.size(); 105fa3d789dSPierre van Houtryve } 106fa3d789dSPierre van Houtryve 107fa3d789dSPierre van Houtryve unsigned CheckPredicateMatcher::getOperandNo(unsigned i) const { 108fa3d789dSPierre van Houtryve assert(i < Operands.size()); 109fa3d789dSPierre van Houtryve return Operands[i]; 110fa3d789dSPierre van Houtryve } 111fa3d789dSPierre van Houtryve 112fa3d789dSPierre van Houtryve // printImpl methods. 113fa3d789dSPierre van Houtryve 114*708567abSRahul Joshi void ScopeMatcher::printImpl(raw_ostream &OS, indent Indent) const { 115*708567abSRahul Joshi OS << Indent << "Scope\n"; 116fa3d789dSPierre van Houtryve for (const Matcher *C : Children) { 117fa3d789dSPierre van Houtryve if (!C) 118*708567abSRahul Joshi OS << Indent + 1 << "NULL POINTER\n"; 119fa3d789dSPierre van Houtryve else 1203e24dd42SRahul Joshi C->print(OS, Indent + 2); 121fa3d789dSPierre van Houtryve } 122fa3d789dSPierre van Houtryve } 123fa3d789dSPierre van Houtryve 124*708567abSRahul Joshi void RecordMatcher::printImpl(raw_ostream &OS, indent Indent) const { 125*708567abSRahul Joshi OS << Indent << "Record\n"; 126fa3d789dSPierre van Houtryve } 127fa3d789dSPierre van Houtryve 128*708567abSRahul Joshi void RecordChildMatcher::printImpl(raw_ostream &OS, indent Indent) const { 129*708567abSRahul Joshi OS << Indent << "RecordChild: " << ChildNo << '\n'; 130fa3d789dSPierre van Houtryve } 131fa3d789dSPierre van Houtryve 132*708567abSRahul Joshi void RecordMemRefMatcher::printImpl(raw_ostream &OS, indent Indent) const { 133*708567abSRahul Joshi OS << Indent << "RecordMemRef\n"; 134fa3d789dSPierre van Houtryve } 135fa3d789dSPierre van Houtryve 136*708567abSRahul Joshi void CaptureGlueInputMatcher::printImpl(raw_ostream &OS, indent Indent) const { 137*708567abSRahul Joshi OS << Indent << "CaptureGlueInput\n"; 138fa3d789dSPierre van Houtryve } 139fa3d789dSPierre van Houtryve 140*708567abSRahul Joshi void MoveChildMatcher::printImpl(raw_ostream &OS, indent Indent) const { 141*708567abSRahul Joshi OS << Indent << "MoveChild " << ChildNo << '\n'; 142fa3d789dSPierre van Houtryve } 143fa3d789dSPierre van Houtryve 144*708567abSRahul Joshi void MoveSiblingMatcher::printImpl(raw_ostream &OS, indent Indent) const { 145*708567abSRahul Joshi OS << Indent << "MoveSibling " << SiblingNo << '\n'; 146fa3d789dSPierre van Houtryve } 147fa3d789dSPierre van Houtryve 148*708567abSRahul Joshi void MoveParentMatcher::printImpl(raw_ostream &OS, indent Indent) const { 149*708567abSRahul Joshi OS << Indent << "MoveParent\n"; 150fa3d789dSPierre van Houtryve } 151fa3d789dSPierre van Houtryve 152*708567abSRahul Joshi void CheckSameMatcher::printImpl(raw_ostream &OS, indent Indent) const { 153*708567abSRahul Joshi OS << Indent << "CheckSame " << MatchNumber << '\n'; 154fa3d789dSPierre van Houtryve } 155fa3d789dSPierre van Houtryve 156*708567abSRahul Joshi void CheckChildSameMatcher::printImpl(raw_ostream &OS, indent Indent) const { 157*708567abSRahul Joshi OS << Indent << "CheckChild" << ChildNo << "Same\n"; 158fa3d789dSPierre van Houtryve } 159fa3d789dSPierre van Houtryve 160fa3d789dSPierre van Houtryve void CheckPatternPredicateMatcher::printImpl(raw_ostream &OS, 161*708567abSRahul Joshi indent Indent) const { 162*708567abSRahul Joshi OS << Indent << "CheckPatternPredicate " << Predicate << '\n'; 163fa3d789dSPierre van Houtryve } 164fa3d789dSPierre van Houtryve 165*708567abSRahul Joshi void CheckPredicateMatcher::printImpl(raw_ostream &OS, indent Indent) const { 166*708567abSRahul Joshi OS << Indent << "CheckPredicate " << getPredicate().getFnName() << '\n'; 167fa3d789dSPierre van Houtryve } 168fa3d789dSPierre van Houtryve 169*708567abSRahul Joshi void CheckOpcodeMatcher::printImpl(raw_ostream &OS, indent Indent) const { 170*708567abSRahul Joshi OS << Indent << "CheckOpcode " << Opcode.getEnumName() << '\n'; 171fa3d789dSPierre van Houtryve } 172fa3d789dSPierre van Houtryve 173*708567abSRahul Joshi void SwitchOpcodeMatcher::printImpl(raw_ostream &OS, indent Indent) const { 174*708567abSRahul Joshi OS << Indent << "SwitchOpcode: {\n"; 175fa3d789dSPierre van Houtryve for (const auto &C : Cases) { 176*708567abSRahul Joshi OS << Indent << "case " << C.first->getEnumName() << ":\n"; 1773e24dd42SRahul Joshi C.second->print(OS, Indent + 2); 178fa3d789dSPierre van Houtryve } 179*708567abSRahul Joshi OS << Indent << "}\n"; 180fa3d789dSPierre van Houtryve } 181fa3d789dSPierre van Houtryve 182*708567abSRahul Joshi void CheckTypeMatcher::printImpl(raw_ostream &OS, indent Indent) const { 183*708567abSRahul Joshi OS << Indent << "CheckType " << getEnumName(Type) << ", ResNo=" << ResNo 184fa3d789dSPierre van Houtryve << '\n'; 185fa3d789dSPierre van Houtryve } 186fa3d789dSPierre van Houtryve 187*708567abSRahul Joshi void SwitchTypeMatcher::printImpl(raw_ostream &OS, indent Indent) const { 188*708567abSRahul Joshi OS << Indent << "SwitchType: {\n"; 189fa3d789dSPierre van Houtryve for (const auto &C : Cases) { 190*708567abSRahul Joshi OS << Indent << "case " << getEnumName(C.first) << ":\n"; 1913e24dd42SRahul Joshi C.second->print(OS, Indent + 2); 192fa3d789dSPierre van Houtryve } 193*708567abSRahul Joshi OS << Indent << "}\n"; 194fa3d789dSPierre van Houtryve } 195fa3d789dSPierre van Houtryve 196*708567abSRahul Joshi void CheckChildTypeMatcher::printImpl(raw_ostream &OS, indent Indent) const { 197*708567abSRahul Joshi OS << Indent << "CheckChildType " << ChildNo << " " << getEnumName(Type) 198fa3d789dSPierre van Houtryve << '\n'; 199fa3d789dSPierre van Houtryve } 200fa3d789dSPierre van Houtryve 201*708567abSRahul Joshi void CheckIntegerMatcher::printImpl(raw_ostream &OS, indent Indent) const { 202*708567abSRahul Joshi OS << Indent << "CheckInteger " << Value << '\n'; 203fa3d789dSPierre van Houtryve } 204fa3d789dSPierre van Houtryve 205*708567abSRahul Joshi void CheckChildIntegerMatcher::printImpl(raw_ostream &OS, indent Indent) const { 206*708567abSRahul Joshi OS << Indent << "CheckChildInteger " << ChildNo << " " << Value << '\n'; 207fa3d789dSPierre van Houtryve } 208fa3d789dSPierre van Houtryve 209*708567abSRahul Joshi void CheckCondCodeMatcher::printImpl(raw_ostream &OS, indent Indent) const { 210*708567abSRahul Joshi OS << Indent << "CheckCondCode ISD::" << CondCodeName << '\n'; 211fa3d789dSPierre van Houtryve } 212fa3d789dSPierre van Houtryve 213fa3d789dSPierre van Houtryve void CheckChild2CondCodeMatcher::printImpl(raw_ostream &OS, 214*708567abSRahul Joshi indent Indent) const { 215*708567abSRahul Joshi OS << Indent << "CheckChild2CondCode ISD::" << CondCodeName << '\n'; 216fa3d789dSPierre van Houtryve } 217fa3d789dSPierre van Houtryve 218*708567abSRahul Joshi void CheckValueTypeMatcher::printImpl(raw_ostream &OS, indent Indent) const { 219*708567abSRahul Joshi OS << Indent << "CheckValueType " << getEnumName(VT) << '\n'; 220fa3d789dSPierre van Houtryve } 221fa3d789dSPierre van Houtryve 222*708567abSRahul Joshi void CheckComplexPatMatcher::printImpl(raw_ostream &OS, indent Indent) const { 223*708567abSRahul Joshi OS << Indent << "CheckComplexPat " << Pattern.getSelectFunc() << '\n'; 224fa3d789dSPierre van Houtryve } 225fa3d789dSPierre van Houtryve 226*708567abSRahul Joshi void CheckAndImmMatcher::printImpl(raw_ostream &OS, indent Indent) const { 227*708567abSRahul Joshi OS << Indent << "CheckAndImm " << Value << '\n'; 228fa3d789dSPierre van Houtryve } 229fa3d789dSPierre van Houtryve 230*708567abSRahul Joshi void CheckOrImmMatcher::printImpl(raw_ostream &OS, indent Indent) const { 231*708567abSRahul Joshi OS << Indent << "CheckOrImm " << Value << '\n'; 232fa3d789dSPierre van Houtryve } 233fa3d789dSPierre van Houtryve 234fa3d789dSPierre van Houtryve void CheckFoldableChainNodeMatcher::printImpl(raw_ostream &OS, 235*708567abSRahul Joshi indent Indent) const { 236*708567abSRahul Joshi OS << Indent << "CheckFoldableChainNode\n"; 237fa3d789dSPierre van Houtryve } 238fa3d789dSPierre van Houtryve 239*708567abSRahul Joshi void CheckImmAllOnesVMatcher::printImpl(raw_ostream &OS, indent Indent) const { 240*708567abSRahul Joshi OS << Indent << "CheckAllOnesV\n"; 241fa3d789dSPierre van Houtryve } 242fa3d789dSPierre van Houtryve 243*708567abSRahul Joshi void CheckImmAllZerosVMatcher::printImpl(raw_ostream &OS, indent Indent) const { 244*708567abSRahul Joshi OS << Indent << "CheckAllZerosV\n"; 245fa3d789dSPierre van Houtryve } 246fa3d789dSPierre van Houtryve 247*708567abSRahul Joshi void EmitIntegerMatcher::printImpl(raw_ostream &OS, indent Indent) const { 248*708567abSRahul Joshi OS << Indent << "EmitInteger " << Val << " VT=" << getEnumName(VT) << '\n'; 249*708567abSRahul Joshi } 250*708567abSRahul Joshi 251*708567abSRahul Joshi void EmitStringIntegerMatcher::printImpl(raw_ostream &OS, indent Indent) const { 252*708567abSRahul Joshi OS << Indent << "EmitStringInteger " << Val << " VT=" << getEnumName(VT) 253fa3d789dSPierre van Houtryve << '\n'; 254fa3d789dSPierre van Houtryve } 255fa3d789dSPierre van Houtryve 256*708567abSRahul Joshi void EmitRegisterMatcher::printImpl(raw_ostream &OS, indent Indent) const { 257*708567abSRahul Joshi OS << Indent << "EmitRegister "; 258fa3d789dSPierre van Houtryve if (Reg) 259fa3d789dSPierre van Houtryve OS << Reg->getName(); 260fa3d789dSPierre van Houtryve else 261fa3d789dSPierre van Houtryve OS << "zero_reg"; 262fa3d789dSPierre van Houtryve OS << " VT=" << getEnumName(VT) << '\n'; 263fa3d789dSPierre van Houtryve } 264fa3d789dSPierre van Houtryve 265fa3d789dSPierre van Houtryve void EmitConvertToTargetMatcher::printImpl(raw_ostream &OS, 266*708567abSRahul Joshi indent Indent) const { 267*708567abSRahul Joshi OS << Indent << "EmitConvertToTarget " << Slot << '\n'; 268fa3d789dSPierre van Houtryve } 269fa3d789dSPierre van Houtryve 270fa3d789dSPierre van Houtryve void EmitMergeInputChainsMatcher::printImpl(raw_ostream &OS, 271*708567abSRahul Joshi indent Indent) const { 272*708567abSRahul Joshi OS << Indent << "EmitMergeInputChains <todo: args>\n"; 273fa3d789dSPierre van Houtryve } 274fa3d789dSPierre van Houtryve 275*708567abSRahul Joshi void EmitCopyToRegMatcher::printImpl(raw_ostream &OS, indent Indent) const { 276*708567abSRahul Joshi OS << Indent << "EmitCopyToReg <todo: args>\n"; 277fa3d789dSPierre van Houtryve } 278fa3d789dSPierre van Houtryve 279*708567abSRahul Joshi void EmitNodeXFormMatcher::printImpl(raw_ostream &OS, indent Indent) const { 280*708567abSRahul Joshi OS << Indent << "EmitNodeXForm " << NodeXForm->getName() << " Slot=" << Slot 281*708567abSRahul Joshi << '\n'; 282fa3d789dSPierre van Houtryve } 283fa3d789dSPierre van Houtryve 284*708567abSRahul Joshi void EmitNodeMatcherCommon::printImpl(raw_ostream &OS, indent Indent) const { 285*708567abSRahul Joshi OS << Indent; 286fa3d789dSPierre van Houtryve OS << (isa<MorphNodeToMatcher>(this) ? "MorphNodeTo: " : "EmitNode: ") 287fa3d789dSPierre van Houtryve << CGI.Namespace << "::" << CGI.TheDef->getName() << ": <todo flags> "; 288fa3d789dSPierre van Houtryve 289fa3d789dSPierre van Houtryve for (unsigned i = 0, e = VTs.size(); i != e; ++i) 290fa3d789dSPierre van Houtryve OS << ' ' << getEnumName(VTs[i]); 291fa3d789dSPierre van Houtryve OS << '('; 292fa3d789dSPierre van Houtryve for (unsigned i = 0, e = Operands.size(); i != e; ++i) 293fa3d789dSPierre van Houtryve OS << Operands[i] << ' '; 294fa3d789dSPierre van Houtryve OS << ")\n"; 295fa3d789dSPierre van Houtryve } 296fa3d789dSPierre van Houtryve 297*708567abSRahul Joshi void CompleteMatchMatcher::printImpl(raw_ostream &OS, indent Indent) const { 298*708567abSRahul Joshi OS << Indent << "CompleteMatch <todo args>\n"; 299*708567abSRahul Joshi OS << Indent << "Src = " << Pattern.getSrcPattern() << "\n"; 300*708567abSRahul Joshi OS << Indent << "Dst = " << Pattern.getDstPattern() << "\n"; 301fa3d789dSPierre van Houtryve } 302fa3d789dSPierre van Houtryve 303fa3d789dSPierre van Houtryve bool CheckOpcodeMatcher::isEqualImpl(const Matcher *M) const { 304fa3d789dSPierre van Houtryve // Note: pointer equality isn't enough here, we have to check the enum names 305fa3d789dSPierre van Houtryve // to ensure that the nodes are for the same opcode. 306fa3d789dSPierre van Houtryve return cast<CheckOpcodeMatcher>(M)->Opcode.getEnumName() == 307fa3d789dSPierre van Houtryve Opcode.getEnumName(); 308fa3d789dSPierre van Houtryve } 309fa3d789dSPierre van Houtryve 310fa3d789dSPierre van Houtryve bool EmitNodeMatcherCommon::isEqualImpl(const Matcher *m) const { 311fa3d789dSPierre van Houtryve const EmitNodeMatcherCommon *M = cast<EmitNodeMatcherCommon>(m); 312fa3d789dSPierre van Houtryve return &M->CGI == &CGI && M->VTs == VTs && M->Operands == Operands && 313fa3d789dSPierre van Houtryve M->HasChain == HasChain && M->HasInGlue == HasInGlue && 314fa3d789dSPierre van Houtryve M->HasOutGlue == HasOutGlue && M->HasMemRefs == HasMemRefs && 315fa3d789dSPierre van Houtryve M->NumFixedArityOperands == NumFixedArityOperands; 316fa3d789dSPierre van Houtryve } 317fa3d789dSPierre van Houtryve 318fa3d789dSPierre van Houtryve void EmitNodeMatcher::anchor() {} 319fa3d789dSPierre van Houtryve 320fa3d789dSPierre van Houtryve void MorphNodeToMatcher::anchor() {} 321fa3d789dSPierre van Houtryve 322fa3d789dSPierre van Houtryve // isContradictoryImpl Implementations. 323fa3d789dSPierre van Houtryve 324fa3d789dSPierre van Houtryve static bool TypesAreContradictory(MVT::SimpleValueType T1, 325fa3d789dSPierre van Houtryve MVT::SimpleValueType T2) { 326fa3d789dSPierre van Houtryve // If the two types are the same, then they are the same, so they don't 327fa3d789dSPierre van Houtryve // contradict. 328fa3d789dSPierre van Houtryve if (T1 == T2) 329fa3d789dSPierre van Houtryve return false; 330fa3d789dSPierre van Houtryve 331fa3d789dSPierre van Houtryve // If either type is about iPtr, then they don't conflict unless the other 332fa3d789dSPierre van Houtryve // one is not a scalar integer type. 333fa3d789dSPierre van Houtryve if (T1 == MVT::iPTR) 334fa3d789dSPierre van Houtryve return !MVT(T2).isInteger() || MVT(T2).isVector(); 335fa3d789dSPierre van Houtryve 336fa3d789dSPierre van Houtryve if (T2 == MVT::iPTR) 337fa3d789dSPierre van Houtryve return !MVT(T1).isInteger() || MVT(T1).isVector(); 338fa3d789dSPierre van Houtryve 339fa3d789dSPierre van Houtryve // Otherwise, they are two different non-iPTR types, they conflict. 340fa3d789dSPierre van Houtryve return true; 341fa3d789dSPierre van Houtryve } 342fa3d789dSPierre van Houtryve 343fa3d789dSPierre van Houtryve bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const { 344fa3d789dSPierre van Houtryve if (const CheckOpcodeMatcher *COM = dyn_cast<CheckOpcodeMatcher>(M)) { 345fa3d789dSPierre van Houtryve // One node can't have two different opcodes! 346fa3d789dSPierre van Houtryve // Note: pointer equality isn't enough here, we have to check the enum names 347fa3d789dSPierre van Houtryve // to ensure that the nodes are for the same opcode. 348fa3d789dSPierre van Houtryve return COM->getOpcode().getEnumName() != getOpcode().getEnumName(); 349fa3d789dSPierre van Houtryve } 350fa3d789dSPierre van Houtryve 351fa3d789dSPierre van Houtryve // If the node has a known type, and if the type we're checking for is 352fa3d789dSPierre van Houtryve // different, then we know they contradict. For example, a check for 353fa3d789dSPierre van Houtryve // ISD::STORE will never be true at the same time a check for Type i32 is. 354fa3d789dSPierre van Houtryve if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M)) { 355fa3d789dSPierre van Houtryve // If checking for a result the opcode doesn't have, it can't match. 356fa3d789dSPierre van Houtryve if (CT->getResNo() >= getOpcode().getNumResults()) 357fa3d789dSPierre van Houtryve return true; 358fa3d789dSPierre van Houtryve 359fa3d789dSPierre van Houtryve MVT::SimpleValueType NodeType = getOpcode().getKnownType(CT->getResNo()); 360fa3d789dSPierre van Houtryve if (NodeType != MVT::Other) 361fa3d789dSPierre van Houtryve return TypesAreContradictory(NodeType, CT->getType()); 362fa3d789dSPierre van Houtryve } 363fa3d789dSPierre van Houtryve 364fa3d789dSPierre van Houtryve return false; 365fa3d789dSPierre van Houtryve } 366fa3d789dSPierre van Houtryve 367fa3d789dSPierre van Houtryve bool CheckTypeMatcher::isContradictoryImpl(const Matcher *M) const { 368fa3d789dSPierre van Houtryve if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M)) 369fa3d789dSPierre van Houtryve return TypesAreContradictory(getType(), CT->getType()); 370fa3d789dSPierre van Houtryve return false; 371fa3d789dSPierre van Houtryve } 372fa3d789dSPierre van Houtryve 373fa3d789dSPierre van Houtryve bool CheckChildTypeMatcher::isContradictoryImpl(const Matcher *M) const { 374fa3d789dSPierre van Houtryve if (const CheckChildTypeMatcher *CC = dyn_cast<CheckChildTypeMatcher>(M)) { 375fa3d789dSPierre van Houtryve // If the two checks are about different nodes, we don't know if they 376fa3d789dSPierre van Houtryve // conflict! 377fa3d789dSPierre van Houtryve if (CC->getChildNo() != getChildNo()) 378fa3d789dSPierre van Houtryve return false; 379fa3d789dSPierre van Houtryve 380fa3d789dSPierre van Houtryve return TypesAreContradictory(getType(), CC->getType()); 381fa3d789dSPierre van Houtryve } 382fa3d789dSPierre van Houtryve return false; 383fa3d789dSPierre van Houtryve } 384fa3d789dSPierre van Houtryve 385fa3d789dSPierre van Houtryve bool CheckIntegerMatcher::isContradictoryImpl(const Matcher *M) const { 386fa3d789dSPierre van Houtryve if (const CheckIntegerMatcher *CIM = dyn_cast<CheckIntegerMatcher>(M)) 387fa3d789dSPierre van Houtryve return CIM->getValue() != getValue(); 388fa3d789dSPierre van Houtryve return false; 389fa3d789dSPierre van Houtryve } 390fa3d789dSPierre van Houtryve 391fa3d789dSPierre van Houtryve bool CheckChildIntegerMatcher::isContradictoryImpl(const Matcher *M) const { 392fa3d789dSPierre van Houtryve if (const CheckChildIntegerMatcher *CCIM = 393fa3d789dSPierre van Houtryve dyn_cast<CheckChildIntegerMatcher>(M)) { 394fa3d789dSPierre van Houtryve // If the two checks are about different nodes, we don't know if they 395fa3d789dSPierre van Houtryve // conflict! 396fa3d789dSPierre van Houtryve if (CCIM->getChildNo() != getChildNo()) 397fa3d789dSPierre van Houtryve return false; 398fa3d789dSPierre van Houtryve 399fa3d789dSPierre van Houtryve return CCIM->getValue() != getValue(); 400fa3d789dSPierre van Houtryve } 401fa3d789dSPierre van Houtryve return false; 402fa3d789dSPierre van Houtryve } 403fa3d789dSPierre van Houtryve 404fa3d789dSPierre van Houtryve bool CheckValueTypeMatcher::isContradictoryImpl(const Matcher *M) const { 405fa3d789dSPierre van Houtryve if (const CheckValueTypeMatcher *CVT = dyn_cast<CheckValueTypeMatcher>(M)) 406592233a9SBrandon Wu return CVT->getVT() != getVT(); 407fa3d789dSPierre van Houtryve return false; 408fa3d789dSPierre van Houtryve } 409fa3d789dSPierre van Houtryve 410fa3d789dSPierre van Houtryve bool CheckImmAllOnesVMatcher::isContradictoryImpl(const Matcher *M) const { 411fa3d789dSPierre van Houtryve // AllZeros is contradictory. 412fa3d789dSPierre van Houtryve return isa<CheckImmAllZerosVMatcher>(M); 413fa3d789dSPierre van Houtryve } 414fa3d789dSPierre van Houtryve 415fa3d789dSPierre van Houtryve bool CheckImmAllZerosVMatcher::isContradictoryImpl(const Matcher *M) const { 416fa3d789dSPierre van Houtryve // AllOnes is contradictory. 417fa3d789dSPierre van Houtryve return isa<CheckImmAllOnesVMatcher>(M); 418fa3d789dSPierre van Houtryve } 419fa3d789dSPierre van Houtryve 420fa3d789dSPierre van Houtryve bool CheckCondCodeMatcher::isContradictoryImpl(const Matcher *M) const { 421fa3d789dSPierre van Houtryve if (const auto *CCCM = dyn_cast<CheckCondCodeMatcher>(M)) 422fa3d789dSPierre van Houtryve return CCCM->getCondCodeName() != getCondCodeName(); 423fa3d789dSPierre van Houtryve return false; 424fa3d789dSPierre van Houtryve } 425fa3d789dSPierre van Houtryve 426fa3d789dSPierre van Houtryve bool CheckChild2CondCodeMatcher::isContradictoryImpl(const Matcher *M) const { 427fa3d789dSPierre van Houtryve if (const auto *CCCCM = dyn_cast<CheckChild2CondCodeMatcher>(M)) 428fa3d789dSPierre van Houtryve return CCCCM->getCondCodeName() != getCondCodeName(); 429fa3d789dSPierre van Houtryve return false; 430fa3d789dSPierre van Houtryve } 431