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