Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Common/DAGISelMatcher.h
35290 views
//===- DAGISelMatcher.h - Representation of DAG pattern matcher -*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLVM_UTILS_TABLEGEN_DAGISELMATCHER_H9#define LLVM_UTILS_TABLEGEN_DAGISELMATCHER_H1011#include "llvm/ADT/ArrayRef.h"12#include "llvm/ADT/SmallVector.h"13#include "llvm/ADT/StringRef.h"14#include "llvm/CodeGenTypes/MachineValueType.h"15#include "llvm/Support/Casting.h"16#include <cassert>17#include <cstddef>18#include <memory>19#include <string>20#include <utility>2122namespace llvm {23class CodeGenRegister;24class CodeGenDAGPatterns;25class CodeGenInstruction;26class Matcher;27class PatternToMatch;28class raw_ostream;29class ComplexPattern;30class Record;31class SDNodeInfo;32class TreePredicateFn;33class TreePattern;3435Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,36unsigned Variant,37const CodeGenDAGPatterns &CGP);38void OptimizeMatcher(std::unique_ptr<Matcher> &Matcher,39const CodeGenDAGPatterns &CGP);40void EmitMatcherTable(Matcher *Matcher, const CodeGenDAGPatterns &CGP,41raw_ostream &OS);4243/// Matcher - Base class for all the DAG ISel Matcher representation44/// nodes.45class Matcher {46// The next matcher node that is executed after this one. Null if this is47// the last stage of a match.48std::unique_ptr<Matcher> Next;49size_t Size = 0; // Size in bytes of matcher and all its children (if any).50virtual void anchor();5152public:53enum KindTy {54// Matcher state manipulation.55Scope, // Push a checking scope.56RecordNode, // Record the current node.57RecordChild, // Record a child of the current node.58RecordMemRef, // Record the memref in the current node.59CaptureGlueInput, // If the current node has an input glue, save it.60MoveChild, // Move current node to specified child.61MoveSibling, // Move current node to specified sibling.62MoveParent, // Move current node to parent.6364// Predicate checking.65CheckSame, // Fail if not same as prev match.66CheckChildSame, // Fail if child not same as prev match.67CheckPatternPredicate,68CheckPredicate, // Fail if node predicate fails.69CheckOpcode, // Fail if not opcode.70SwitchOpcode, // Dispatch based on opcode.71CheckType, // Fail if not correct type.72SwitchType, // Dispatch based on type.73CheckChildType, // Fail if child has wrong type.74CheckInteger, // Fail if wrong val.75CheckChildInteger, // Fail if child is wrong val.76CheckCondCode, // Fail if not condcode.77CheckChild2CondCode, // Fail if child is wrong condcode.78CheckValueType,79CheckComplexPat,80CheckAndImm,81CheckOrImm,82CheckImmAllOnesV,83CheckImmAllZerosV,84CheckFoldableChainNode,8586// Node creation/emisssion.87EmitInteger, // Create a TargetConstant88EmitStringInteger, // Create a TargetConstant from a string.89EmitRegister, // Create a register.90EmitConvertToTarget, // Convert a imm/fpimm to target imm/fpimm91EmitMergeInputChains, // Merge together a chains for an input.92EmitCopyToReg, // Emit a copytoreg into a physreg.93EmitNode, // Create a DAG node94EmitNodeXForm, // Run a SDNodeXForm95CompleteMatch, // Finish a match and update the results.96MorphNodeTo, // Build a node, finish a match and update results.9798// Highest enum value; watch out when adding more.99HighestKind = MorphNodeTo100};101const KindTy Kind;102103protected:104Matcher(KindTy K) : Kind(K) {}105106public:107virtual ~Matcher() {}108109unsigned getSize() const { return Size; }110void setSize(unsigned sz) { Size = sz; }111KindTy getKind() const { return Kind; }112113Matcher *getNext() { return Next.get(); }114const Matcher *getNext() const { return Next.get(); }115void setNext(Matcher *C) { Next.reset(C); }116Matcher *takeNext() { return Next.release(); }117118std::unique_ptr<Matcher> &getNextPtr() { return Next; }119120bool isEqual(const Matcher *M) const {121if (getKind() != M->getKind())122return false;123return isEqualImpl(M);124}125126/// isSimplePredicateNode - Return true if this is a simple predicate that127/// operates on the node or its children without potential side effects or a128/// change of the current node.129bool isSimplePredicateNode() const {130switch (getKind()) {131default:132return false;133case CheckSame:134case CheckChildSame:135case CheckPatternPredicate:136case CheckPredicate:137case CheckOpcode:138case CheckType:139case CheckChildType:140case CheckInteger:141case CheckChildInteger:142case CheckCondCode:143case CheckChild2CondCode:144case CheckValueType:145case CheckAndImm:146case CheckOrImm:147case CheckImmAllOnesV:148case CheckImmAllZerosV:149case CheckFoldableChainNode:150return true;151}152}153154/// isSimplePredicateOrRecordNode - Return true if this is a record node or155/// a simple predicate.156bool isSimplePredicateOrRecordNode() const {157return isSimplePredicateNode() || getKind() == RecordNode ||158getKind() == RecordChild;159}160161/// unlinkNode - Unlink the specified node from this chain. If Other ==162/// this, we unlink the next pointer and return it. Otherwise we unlink163/// Other from the list and return this.164Matcher *unlinkNode(Matcher *Other);165166/// canMoveBefore - Return true if this matcher is the same as Other, or if167/// we can move this matcher past all of the nodes in-between Other and this168/// node. Other must be equal to or before this.169bool canMoveBefore(const Matcher *Other) const;170171/// canMoveBeforeNode - Return true if it is safe to move the current172/// matcher across the specified one.173bool canMoveBeforeNode(const Matcher *Other) const;174175/// isContradictory - Return true of these two matchers could never match on176/// the same node.177bool isContradictory(const Matcher *Other) const {178// Since this predicate is reflexive, we canonicalize the ordering so that179// we always match a node against nodes with kinds that are greater or180// equal to them. For example, we'll pass in a CheckType node as an181// argument to the CheckOpcode method, not the other way around.182if (getKind() < Other->getKind())183return isContradictoryImpl(Other);184return Other->isContradictoryImpl(this);185}186187void print(raw_ostream &OS, unsigned indent = 0) const;188void printOne(raw_ostream &OS) const;189void dump() const;190191protected:192virtual void printImpl(raw_ostream &OS, unsigned indent) const = 0;193virtual bool isEqualImpl(const Matcher *M) const = 0;194virtual bool isContradictoryImpl(const Matcher *M) const { return false; }195};196197/// ScopeMatcher - This attempts to match each of its children to find the first198/// one that successfully matches. If one child fails, it tries the next child.199/// If none of the children match then this check fails. It never has a 'next'.200class ScopeMatcher : public Matcher {201SmallVector<Matcher *, 4> Children;202203public:204ScopeMatcher(SmallVectorImpl<Matcher *> &&children)205: Matcher(Scope), Children(std::move(children)) {}206~ScopeMatcher() override;207208unsigned getNumChildren() const { return Children.size(); }209210Matcher *getChild(unsigned i) { return Children[i]; }211const Matcher *getChild(unsigned i) const { return Children[i]; }212213void resetChild(unsigned i, Matcher *N) {214delete Children[i];215Children[i] = N;216}217218Matcher *takeChild(unsigned i) {219Matcher *Res = Children[i];220Children[i] = nullptr;221return Res;222}223224void setNumChildren(unsigned NC) {225if (NC < Children.size()) {226// delete any children we're about to lose pointers to.227for (unsigned i = NC, e = Children.size(); i != e; ++i)228delete Children[i];229}230Children.resize(NC);231}232233static bool classof(const Matcher *N) { return N->getKind() == Scope; }234235private:236void printImpl(raw_ostream &OS, unsigned indent) const override;237bool isEqualImpl(const Matcher *M) const override { return false; }238};239240/// RecordMatcher - Save the current node in the operand list.241class RecordMatcher : public Matcher {242/// WhatFor - This is a string indicating why we're recording this. This243/// should only be used for comment generation not anything semantic.244std::string WhatFor;245246/// ResultNo - The slot number in the RecordedNodes vector that this will be,247/// just printed as a comment.248unsigned ResultNo;249250public:251RecordMatcher(const std::string &whatfor, unsigned resultNo)252: Matcher(RecordNode), WhatFor(whatfor), ResultNo(resultNo) {}253254const std::string &getWhatFor() const { return WhatFor; }255unsigned getResultNo() const { return ResultNo; }256257static bool classof(const Matcher *N) { return N->getKind() == RecordNode; }258259private:260void printImpl(raw_ostream &OS, unsigned indent) const override;261bool isEqualImpl(const Matcher *M) const override { return true; }262};263264/// RecordChildMatcher - Save a numbered child of the current node, or fail265/// the match if it doesn't exist. This is logically equivalent to:266/// MoveChild N + RecordNode + MoveParent.267class RecordChildMatcher : public Matcher {268unsigned ChildNo;269270/// WhatFor - This is a string indicating why we're recording this. This271/// should only be used for comment generation not anything semantic.272std::string WhatFor;273274/// ResultNo - The slot number in the RecordedNodes vector that this will be,275/// just printed as a comment.276unsigned ResultNo;277278public:279RecordChildMatcher(unsigned childno, const std::string &whatfor,280unsigned resultNo)281: Matcher(RecordChild), ChildNo(childno), WhatFor(whatfor),282ResultNo(resultNo) {}283284unsigned getChildNo() const { return ChildNo; }285const std::string &getWhatFor() const { return WhatFor; }286unsigned getResultNo() const { return ResultNo; }287288static bool classof(const Matcher *N) { return N->getKind() == RecordChild; }289290private:291void printImpl(raw_ostream &OS, unsigned indent) const override;292bool isEqualImpl(const Matcher *M) const override {293return cast<RecordChildMatcher>(M)->getChildNo() == getChildNo();294}295};296297/// RecordMemRefMatcher - Save the current node's memref.298class RecordMemRefMatcher : public Matcher {299public:300RecordMemRefMatcher() : Matcher(RecordMemRef) {}301302static bool classof(const Matcher *N) { return N->getKind() == RecordMemRef; }303304private:305void printImpl(raw_ostream &OS, unsigned indent) const override;306bool isEqualImpl(const Matcher *M) const override { return true; }307};308309/// CaptureGlueInputMatcher - If the current record has a glue input, record310/// it so that it is used as an input to the generated code.311class CaptureGlueInputMatcher : public Matcher {312public:313CaptureGlueInputMatcher() : Matcher(CaptureGlueInput) {}314315static bool classof(const Matcher *N) {316return N->getKind() == CaptureGlueInput;317}318319private:320void printImpl(raw_ostream &OS, unsigned indent) const override;321bool isEqualImpl(const Matcher *M) const override { return true; }322};323324/// MoveChildMatcher - This tells the interpreter to move into the325/// specified child node.326class MoveChildMatcher : public Matcher {327unsigned ChildNo;328329public:330MoveChildMatcher(unsigned childNo) : Matcher(MoveChild), ChildNo(childNo) {}331332unsigned getChildNo() const { return ChildNo; }333334static bool classof(const Matcher *N) { return N->getKind() == MoveChild; }335336private:337void printImpl(raw_ostream &OS, unsigned indent) const override;338bool isEqualImpl(const Matcher *M) const override {339return cast<MoveChildMatcher>(M)->getChildNo() == getChildNo();340}341};342343/// MoveSiblingMatcher - This tells the interpreter to move into the344/// specified sibling node.345class MoveSiblingMatcher : public Matcher {346unsigned SiblingNo;347348public:349MoveSiblingMatcher(unsigned SiblingNo)350: Matcher(MoveSibling), SiblingNo(SiblingNo) {}351352unsigned getSiblingNo() const { return SiblingNo; }353354static bool classof(const Matcher *N) { return N->getKind() == MoveSibling; }355356private:357void printImpl(raw_ostream &OS, unsigned Indent) const override;358bool isEqualImpl(const Matcher *M) const override {359return cast<MoveSiblingMatcher>(M)->getSiblingNo() == getSiblingNo();360}361};362363/// MoveParentMatcher - This tells the interpreter to move to the parent364/// of the current node.365class MoveParentMatcher : public Matcher {366public:367MoveParentMatcher() : Matcher(MoveParent) {}368369static bool classof(const Matcher *N) { return N->getKind() == MoveParent; }370371private:372void printImpl(raw_ostream &OS, unsigned indent) const override;373bool isEqualImpl(const Matcher *M) const override { return true; }374};375376/// CheckSameMatcher - This checks to see if this node is exactly the same377/// node as the specified match that was recorded with 'Record'. This is used378/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.379class CheckSameMatcher : public Matcher {380unsigned MatchNumber;381382public:383CheckSameMatcher(unsigned matchnumber)384: Matcher(CheckSame), MatchNumber(matchnumber) {}385386unsigned getMatchNumber() const { return MatchNumber; }387388static bool classof(const Matcher *N) { return N->getKind() == CheckSame; }389390private:391void printImpl(raw_ostream &OS, unsigned indent) const override;392bool isEqualImpl(const Matcher *M) const override {393return cast<CheckSameMatcher>(M)->getMatchNumber() == getMatchNumber();394}395};396397/// CheckChildSameMatcher - This checks to see if child node is exactly the same398/// node as the specified match that was recorded with 'Record'. This is used399/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.400class CheckChildSameMatcher : public Matcher {401unsigned ChildNo;402unsigned MatchNumber;403404public:405CheckChildSameMatcher(unsigned childno, unsigned matchnumber)406: Matcher(CheckChildSame), ChildNo(childno), MatchNumber(matchnumber) {}407408unsigned getChildNo() const { return ChildNo; }409unsigned getMatchNumber() const { return MatchNumber; }410411static bool classof(const Matcher *N) {412return N->getKind() == CheckChildSame;413}414415private:416void printImpl(raw_ostream &OS, unsigned indent) const override;417bool isEqualImpl(const Matcher *M) const override {418return cast<CheckChildSameMatcher>(M)->ChildNo == ChildNo &&419cast<CheckChildSameMatcher>(M)->MatchNumber == MatchNumber;420}421};422423/// CheckPatternPredicateMatcher - This checks the target-specific predicate424/// to see if the entire pattern is capable of matching. This predicate does425/// not take a node as input. This is used for subtarget feature checks etc.426class CheckPatternPredicateMatcher : public Matcher {427std::string Predicate;428429public:430CheckPatternPredicateMatcher(StringRef predicate)431: Matcher(CheckPatternPredicate), Predicate(predicate) {}432433StringRef getPredicate() const { return Predicate; }434435static bool classof(const Matcher *N) {436return N->getKind() == CheckPatternPredicate;437}438439private:440void printImpl(raw_ostream &OS, unsigned indent) const override;441bool isEqualImpl(const Matcher *M) const override {442return cast<CheckPatternPredicateMatcher>(M)->getPredicate() == Predicate;443}444};445446/// CheckPredicateMatcher - This checks the target-specific predicate to447/// see if the node is acceptable.448class CheckPredicateMatcher : public Matcher {449TreePattern *Pred;450const SmallVector<unsigned, 4> Operands;451452public:453CheckPredicateMatcher(const TreePredicateFn &pred,454const SmallVectorImpl<unsigned> &Operands);455456TreePredicateFn getPredicate() const;457unsigned getNumOperands() const;458unsigned getOperandNo(unsigned i) const;459460static bool classof(const Matcher *N) {461return N->getKind() == CheckPredicate;462}463464private:465void printImpl(raw_ostream &OS, unsigned indent) const override;466bool isEqualImpl(const Matcher *M) const override {467return cast<CheckPredicateMatcher>(M)->Pred == Pred;468}469};470471/// CheckOpcodeMatcher - This checks to see if the current node has the472/// specified opcode, if not it fails to match.473class CheckOpcodeMatcher : public Matcher {474const SDNodeInfo &Opcode;475476public:477CheckOpcodeMatcher(const SDNodeInfo &opcode)478: Matcher(CheckOpcode), Opcode(opcode) {}479480const SDNodeInfo &getOpcode() const { return Opcode; }481482static bool classof(const Matcher *N) { return N->getKind() == CheckOpcode; }483484private:485void printImpl(raw_ostream &OS, unsigned indent) const override;486bool isEqualImpl(const Matcher *M) const override;487bool isContradictoryImpl(const Matcher *M) const override;488};489490/// SwitchOpcodeMatcher - Switch based on the current node's opcode, dispatching491/// to one matcher per opcode. If the opcode doesn't match any of the cases,492/// then the match fails. This is semantically equivalent to a Scope node where493/// every child does a CheckOpcode, but is much faster.494class SwitchOpcodeMatcher : public Matcher {495SmallVector<std::pair<const SDNodeInfo *, Matcher *>, 8> Cases;496497public:498SwitchOpcodeMatcher(499SmallVectorImpl<std::pair<const SDNodeInfo *, Matcher *>> &&cases)500: Matcher(SwitchOpcode), Cases(std::move(cases)) {}501~SwitchOpcodeMatcher() override;502503static bool classof(const Matcher *N) { return N->getKind() == SwitchOpcode; }504505unsigned getNumCases() const { return Cases.size(); }506507const SDNodeInfo &getCaseOpcode(unsigned i) const { return *Cases[i].first; }508Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; }509const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }510511private:512void printImpl(raw_ostream &OS, unsigned indent) const override;513bool isEqualImpl(const Matcher *M) const override { return false; }514};515516/// CheckTypeMatcher - This checks to see if the current node has the517/// specified type at the specified result, if not it fails to match.518class CheckTypeMatcher : public Matcher {519MVT::SimpleValueType Type;520unsigned ResNo;521522public:523CheckTypeMatcher(MVT::SimpleValueType type, unsigned resno)524: Matcher(CheckType), Type(type), ResNo(resno) {}525526MVT::SimpleValueType getType() const { return Type; }527unsigned getResNo() const { return ResNo; }528529static bool classof(const Matcher *N) { return N->getKind() == CheckType; }530531private:532void printImpl(raw_ostream &OS, unsigned indent) const override;533bool isEqualImpl(const Matcher *M) const override {534return cast<CheckTypeMatcher>(M)->Type == Type;535}536bool isContradictoryImpl(const Matcher *M) const override;537};538539/// SwitchTypeMatcher - Switch based on the current node's type, dispatching540/// to one matcher per case. If the type doesn't match any of the cases,541/// then the match fails. This is semantically equivalent to a Scope node where542/// every child does a CheckType, but is much faster.543class SwitchTypeMatcher : public Matcher {544SmallVector<std::pair<MVT::SimpleValueType, Matcher *>, 8> Cases;545546public:547SwitchTypeMatcher(548SmallVectorImpl<std::pair<MVT::SimpleValueType, Matcher *>> &&cases)549: Matcher(SwitchType), Cases(std::move(cases)) {}550~SwitchTypeMatcher() override;551552static bool classof(const Matcher *N) { return N->getKind() == SwitchType; }553554unsigned getNumCases() const { return Cases.size(); }555556MVT::SimpleValueType getCaseType(unsigned i) const { return Cases[i].first; }557Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; }558const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }559560private:561void printImpl(raw_ostream &OS, unsigned indent) const override;562bool isEqualImpl(const Matcher *M) const override { return false; }563};564565/// CheckChildTypeMatcher - This checks to see if a child node has the566/// specified type, if not it fails to match.567class CheckChildTypeMatcher : public Matcher {568unsigned ChildNo;569MVT::SimpleValueType Type;570571public:572CheckChildTypeMatcher(unsigned childno, MVT::SimpleValueType type)573: Matcher(CheckChildType), ChildNo(childno), Type(type) {}574575unsigned getChildNo() const { return ChildNo; }576MVT::SimpleValueType getType() const { return Type; }577578static bool classof(const Matcher *N) {579return N->getKind() == CheckChildType;580}581582private:583void printImpl(raw_ostream &OS, unsigned indent) const override;584bool isEqualImpl(const Matcher *M) const override {585return cast<CheckChildTypeMatcher>(M)->ChildNo == ChildNo &&586cast<CheckChildTypeMatcher>(M)->Type == Type;587}588bool isContradictoryImpl(const Matcher *M) const override;589};590591/// CheckIntegerMatcher - This checks to see if the current node is a592/// ConstantSDNode with the specified integer value, if not it fails to match.593class CheckIntegerMatcher : public Matcher {594int64_t Value;595596public:597CheckIntegerMatcher(int64_t value) : Matcher(CheckInteger), Value(value) {}598599int64_t getValue() const { return Value; }600601static bool classof(const Matcher *N) { return N->getKind() == CheckInteger; }602603private:604void printImpl(raw_ostream &OS, unsigned indent) const override;605bool isEqualImpl(const Matcher *M) const override {606return cast<CheckIntegerMatcher>(M)->Value == Value;607}608bool isContradictoryImpl(const Matcher *M) const override;609};610611/// CheckChildIntegerMatcher - This checks to see if the child node is a612/// ConstantSDNode with a specified integer value, if not it fails to match.613class CheckChildIntegerMatcher : public Matcher {614unsigned ChildNo;615int64_t Value;616617public:618CheckChildIntegerMatcher(unsigned childno, int64_t value)619: Matcher(CheckChildInteger), ChildNo(childno), Value(value) {}620621unsigned getChildNo() const { return ChildNo; }622int64_t getValue() const { return Value; }623624static bool classof(const Matcher *N) {625return N->getKind() == CheckChildInteger;626}627628private:629void printImpl(raw_ostream &OS, unsigned indent) const override;630bool isEqualImpl(const Matcher *M) const override {631return cast<CheckChildIntegerMatcher>(M)->ChildNo == ChildNo &&632cast<CheckChildIntegerMatcher>(M)->Value == Value;633}634bool isContradictoryImpl(const Matcher *M) const override;635};636637/// CheckCondCodeMatcher - This checks to see if the current node is a638/// CondCodeSDNode with the specified condition, if not it fails to match.639class CheckCondCodeMatcher : public Matcher {640StringRef CondCodeName;641642public:643CheckCondCodeMatcher(StringRef condcodename)644: Matcher(CheckCondCode), CondCodeName(condcodename) {}645646StringRef getCondCodeName() const { return CondCodeName; }647648static bool classof(const Matcher *N) {649return N->getKind() == CheckCondCode;650}651652private:653void printImpl(raw_ostream &OS, unsigned indent) const override;654bool isEqualImpl(const Matcher *M) const override {655return cast<CheckCondCodeMatcher>(M)->CondCodeName == CondCodeName;656}657bool isContradictoryImpl(const Matcher *M) const override;658};659660/// CheckChild2CondCodeMatcher - This checks to see if child 2 node is a661/// CondCodeSDNode with the specified condition, if not it fails to match.662class CheckChild2CondCodeMatcher : public Matcher {663StringRef CondCodeName;664665public:666CheckChild2CondCodeMatcher(StringRef condcodename)667: Matcher(CheckChild2CondCode), CondCodeName(condcodename) {}668669StringRef getCondCodeName() const { return CondCodeName; }670671static bool classof(const Matcher *N) {672return N->getKind() == CheckChild2CondCode;673}674675private:676void printImpl(raw_ostream &OS, unsigned indent) const override;677bool isEqualImpl(const Matcher *M) const override {678return cast<CheckChild2CondCodeMatcher>(M)->CondCodeName == CondCodeName;679}680bool isContradictoryImpl(const Matcher *M) const override;681};682683/// CheckValueTypeMatcher - This checks to see if the current node is a684/// VTSDNode with the specified type, if not it fails to match.685class CheckValueTypeMatcher : public Matcher {686MVT::SimpleValueType VT;687688public:689CheckValueTypeMatcher(MVT::SimpleValueType SimpleVT)690: Matcher(CheckValueType), VT(SimpleVT) {}691692MVT::SimpleValueType getVT() const { return VT; }693694static bool classof(const Matcher *N) {695return N->getKind() == CheckValueType;696}697698private:699void printImpl(raw_ostream &OS, unsigned indent) const override;700bool isEqualImpl(const Matcher *M) const override {701return cast<CheckValueTypeMatcher>(M)->VT == VT;702}703bool isContradictoryImpl(const Matcher *M) const override;704};705706/// CheckComplexPatMatcher - This node runs the specified ComplexPattern on707/// the current node.708class CheckComplexPatMatcher : public Matcher {709const ComplexPattern &Pattern;710711/// MatchNumber - This is the recorded nodes slot that contains the node we712/// want to match against.713unsigned MatchNumber;714715/// Name - The name of the node we're matching, for comment emission.716std::string Name;717718/// FirstResult - This is the first slot in the RecordedNodes list that the719/// result of the match populates.720unsigned FirstResult;721722public:723CheckComplexPatMatcher(const ComplexPattern &pattern, unsigned matchnumber,724const std::string &name, unsigned firstresult)725: Matcher(CheckComplexPat), Pattern(pattern), MatchNumber(matchnumber),726Name(name), FirstResult(firstresult) {}727728const ComplexPattern &getPattern() const { return Pattern; }729unsigned getMatchNumber() const { return MatchNumber; }730731std::string getName() const { return Name; }732unsigned getFirstResult() const { return FirstResult; }733734static bool classof(const Matcher *N) {735return N->getKind() == CheckComplexPat;736}737738private:739void printImpl(raw_ostream &OS, unsigned indent) const override;740bool isEqualImpl(const Matcher *M) const override {741return &cast<CheckComplexPatMatcher>(M)->Pattern == &Pattern &&742cast<CheckComplexPatMatcher>(M)->MatchNumber == MatchNumber;743}744};745746/// CheckAndImmMatcher - This checks to see if the current node is an 'and'747/// with something equivalent to the specified immediate.748class CheckAndImmMatcher : public Matcher {749int64_t Value;750751public:752CheckAndImmMatcher(int64_t value) : Matcher(CheckAndImm), Value(value) {}753754int64_t getValue() const { return Value; }755756static bool classof(const Matcher *N) { return N->getKind() == CheckAndImm; }757758private:759void printImpl(raw_ostream &OS, unsigned indent) const override;760bool isEqualImpl(const Matcher *M) const override {761return cast<CheckAndImmMatcher>(M)->Value == Value;762}763};764765/// CheckOrImmMatcher - This checks to see if the current node is an 'and'766/// with something equivalent to the specified immediate.767class CheckOrImmMatcher : public Matcher {768int64_t Value;769770public:771CheckOrImmMatcher(int64_t value) : Matcher(CheckOrImm), Value(value) {}772773int64_t getValue() const { return Value; }774775static bool classof(const Matcher *N) { return N->getKind() == CheckOrImm; }776777private:778void printImpl(raw_ostream &OS, unsigned indent) const override;779bool isEqualImpl(const Matcher *M) const override {780return cast<CheckOrImmMatcher>(M)->Value == Value;781}782};783784/// CheckImmAllOnesVMatcher - This checks if the current node is a build_vector785/// or splat_vector of all ones.786class CheckImmAllOnesVMatcher : public Matcher {787public:788CheckImmAllOnesVMatcher() : Matcher(CheckImmAllOnesV) {}789790static bool classof(const Matcher *N) {791return N->getKind() == CheckImmAllOnesV;792}793794private:795void printImpl(raw_ostream &OS, unsigned indent) const override;796bool isEqualImpl(const Matcher *M) const override { return true; }797bool isContradictoryImpl(const Matcher *M) const override;798};799800/// CheckImmAllZerosVMatcher - This checks if the current node is a801/// build_vector or splat_vector of all zeros.802class CheckImmAllZerosVMatcher : public Matcher {803public:804CheckImmAllZerosVMatcher() : Matcher(CheckImmAllZerosV) {}805806static bool classof(const Matcher *N) {807return N->getKind() == CheckImmAllZerosV;808}809810private:811void printImpl(raw_ostream &OS, unsigned indent) const override;812bool isEqualImpl(const Matcher *M) const override { return true; }813bool isContradictoryImpl(const Matcher *M) const override;814};815816/// CheckFoldableChainNodeMatcher - This checks to see if the current node817/// (which defines a chain operand) is safe to fold into a larger pattern.818class CheckFoldableChainNodeMatcher : public Matcher {819public:820CheckFoldableChainNodeMatcher() : Matcher(CheckFoldableChainNode) {}821822static bool classof(const Matcher *N) {823return N->getKind() == CheckFoldableChainNode;824}825826private:827void printImpl(raw_ostream &OS, unsigned indent) const override;828bool isEqualImpl(const Matcher *M) const override { return true; }829};830831/// EmitIntegerMatcher - This creates a new TargetConstant.832class EmitIntegerMatcher : public Matcher {833int64_t Val;834MVT::SimpleValueType VT;835836public:837EmitIntegerMatcher(int64_t val, MVT::SimpleValueType vt)838: Matcher(EmitInteger), Val(val), VT(vt) {}839840int64_t getValue() const { return Val; }841MVT::SimpleValueType getVT() const { return VT; }842843static bool classof(const Matcher *N) { return N->getKind() == EmitInteger; }844845private:846void printImpl(raw_ostream &OS, unsigned indent) const override;847bool isEqualImpl(const Matcher *M) const override {848return cast<EmitIntegerMatcher>(M)->Val == Val &&849cast<EmitIntegerMatcher>(M)->VT == VT;850}851};852853/// EmitStringIntegerMatcher - A target constant whose value is represented854/// by a string.855class EmitStringIntegerMatcher : public Matcher {856std::string Val;857MVT::SimpleValueType VT;858859public:860EmitStringIntegerMatcher(const std::string &val, MVT::SimpleValueType vt)861: Matcher(EmitStringInteger), Val(val), VT(vt) {}862863const std::string &getValue() const { return Val; }864MVT::SimpleValueType getVT() const { return VT; }865866static bool classof(const Matcher *N) {867return N->getKind() == EmitStringInteger;868}869870private:871void printImpl(raw_ostream &OS, unsigned indent) const override;872bool isEqualImpl(const Matcher *M) const override {873return cast<EmitStringIntegerMatcher>(M)->Val == Val &&874cast<EmitStringIntegerMatcher>(M)->VT == VT;875}876};877878/// EmitRegisterMatcher - This creates a new TargetConstant.879class EmitRegisterMatcher : public Matcher {880/// Reg - The def for the register that we're emitting. If this is null, then881/// this is a reference to zero_reg.882const CodeGenRegister *Reg;883MVT::SimpleValueType VT;884885public:886EmitRegisterMatcher(const CodeGenRegister *reg, MVT::SimpleValueType vt)887: Matcher(EmitRegister), Reg(reg), VT(vt) {}888889const CodeGenRegister *getReg() const { return Reg; }890MVT::SimpleValueType getVT() const { return VT; }891892static bool classof(const Matcher *N) { return N->getKind() == EmitRegister; }893894private:895void printImpl(raw_ostream &OS, unsigned indent) const override;896bool isEqualImpl(const Matcher *M) const override {897return cast<EmitRegisterMatcher>(M)->Reg == Reg &&898cast<EmitRegisterMatcher>(M)->VT == VT;899}900};901902/// EmitConvertToTargetMatcher - Emit an operation that reads a specified903/// recorded node and converts it from being a ISD::Constant to904/// ISD::TargetConstant, likewise for ConstantFP.905class EmitConvertToTargetMatcher : public Matcher {906unsigned Slot;907908public:909EmitConvertToTargetMatcher(unsigned slot)910: Matcher(EmitConvertToTarget), Slot(slot) {}911912unsigned getSlot() const { return Slot; }913914static bool classof(const Matcher *N) {915return N->getKind() == EmitConvertToTarget;916}917918private:919void printImpl(raw_ostream &OS, unsigned indent) const override;920bool isEqualImpl(const Matcher *M) const override {921return cast<EmitConvertToTargetMatcher>(M)->Slot == Slot;922}923};924925/// EmitMergeInputChainsMatcher - Emit a node that merges a list of input926/// chains together with a token factor. The list of nodes are the nodes in the927/// matched pattern that have chain input/outputs. This node adds all input928/// chains of these nodes if they are not themselves a node in the pattern.929class EmitMergeInputChainsMatcher : public Matcher {930SmallVector<unsigned, 3> ChainNodes;931932public:933EmitMergeInputChainsMatcher(ArrayRef<unsigned> nodes)934: Matcher(EmitMergeInputChains), ChainNodes(nodes.begin(), nodes.end()) {}935936unsigned getNumNodes() const { return ChainNodes.size(); }937938unsigned getNode(unsigned i) const {939assert(i < ChainNodes.size());940return ChainNodes[i];941}942943static bool classof(const Matcher *N) {944return N->getKind() == EmitMergeInputChains;945}946947private:948void printImpl(raw_ostream &OS, unsigned indent) const override;949bool isEqualImpl(const Matcher *M) const override {950return cast<EmitMergeInputChainsMatcher>(M)->ChainNodes == ChainNodes;951}952};953954/// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg,955/// pushing the chain and glue results.956///957class EmitCopyToRegMatcher : public Matcher {958unsigned SrcSlot; // Value to copy into the physreg.959const CodeGenRegister *DestPhysReg;960961public:962EmitCopyToRegMatcher(unsigned srcSlot, const CodeGenRegister *destPhysReg)963: Matcher(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {}964965unsigned getSrcSlot() const { return SrcSlot; }966const CodeGenRegister *getDestPhysReg() const { return DestPhysReg; }967968static bool classof(const Matcher *N) {969return N->getKind() == EmitCopyToReg;970}971972private:973void printImpl(raw_ostream &OS, unsigned indent) const override;974bool isEqualImpl(const Matcher *M) const override {975return cast<EmitCopyToRegMatcher>(M)->SrcSlot == SrcSlot &&976cast<EmitCopyToRegMatcher>(M)->DestPhysReg == DestPhysReg;977}978};979980/// EmitNodeXFormMatcher - Emit an operation that runs an SDNodeXForm on a981/// recorded node and records the result.982class EmitNodeXFormMatcher : public Matcher {983unsigned Slot;984Record *NodeXForm;985986public:987EmitNodeXFormMatcher(unsigned slot, Record *nodeXForm)988: Matcher(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm) {}989990unsigned getSlot() const { return Slot; }991Record *getNodeXForm() const { return NodeXForm; }992993static bool classof(const Matcher *N) {994return N->getKind() == EmitNodeXForm;995}996997private:998void printImpl(raw_ostream &OS, unsigned indent) const override;999bool isEqualImpl(const Matcher *M) const override {1000return cast<EmitNodeXFormMatcher>(M)->Slot == Slot &&1001cast<EmitNodeXFormMatcher>(M)->NodeXForm == NodeXForm;1002}1003};10041005/// EmitNodeMatcherCommon - Common class shared between EmitNode and1006/// MorphNodeTo.1007class EmitNodeMatcherCommon : public Matcher {1008const CodeGenInstruction &CGI;1009const SmallVector<MVT::SimpleValueType, 3> VTs;1010const SmallVector<unsigned, 6> Operands;1011bool HasChain, HasInGlue, HasOutGlue, HasMemRefs;10121013/// NumFixedArityOperands - If this is a fixed arity node, this is set to -1.1014/// If this is a varidic node, this is set to the number of fixed arity1015/// operands in the root of the pattern. The rest are appended to this node.1016int NumFixedArityOperands;10171018public:1019EmitNodeMatcherCommon(const CodeGenInstruction &cgi,1020ArrayRef<MVT::SimpleValueType> vts,1021ArrayRef<unsigned> operands, bool hasChain,1022bool hasInGlue, bool hasOutGlue, bool hasmemrefs,1023int numfixedarityoperands, bool isMorphNodeTo)1024: Matcher(isMorphNodeTo ? MorphNodeTo : EmitNode), CGI(cgi),1025VTs(vts.begin(), vts.end()), Operands(operands.begin(), operands.end()),1026HasChain(hasChain), HasInGlue(hasInGlue), HasOutGlue(hasOutGlue),1027HasMemRefs(hasmemrefs), NumFixedArityOperands(numfixedarityoperands) {}10281029const CodeGenInstruction &getInstruction() const { return CGI; }10301031unsigned getNumVTs() const { return VTs.size(); }1032MVT::SimpleValueType getVT(unsigned i) const {1033assert(i < VTs.size());1034return VTs[i];1035}10361037unsigned getNumOperands() const { return Operands.size(); }1038unsigned getOperand(unsigned i) const {1039assert(i < Operands.size());1040return Operands[i];1041}10421043const SmallVectorImpl<MVT::SimpleValueType> &getVTList() const { return VTs; }1044const SmallVectorImpl<unsigned> &getOperandList() const { return Operands; }10451046bool hasChain() const { return HasChain; }1047bool hasInGlue() const { return HasInGlue; }1048bool hasOutGlue() const { return HasOutGlue; }1049bool hasMemRefs() const { return HasMemRefs; }1050int getNumFixedArityOperands() const { return NumFixedArityOperands; }10511052static bool classof(const Matcher *N) {1053return N->getKind() == EmitNode || N->getKind() == MorphNodeTo;1054}10551056private:1057void printImpl(raw_ostream &OS, unsigned indent) const override;1058bool isEqualImpl(const Matcher *M) const override;1059};10601061/// EmitNodeMatcher - This signals a successful match and generates a node.1062class EmitNodeMatcher : public EmitNodeMatcherCommon {1063void anchor() override;1064unsigned FirstResultSlot;10651066public:1067EmitNodeMatcher(const CodeGenInstruction &cgi,1068ArrayRef<MVT::SimpleValueType> vts,1069ArrayRef<unsigned> operands, bool hasChain, bool hasInGlue,1070bool hasOutGlue, bool hasmemrefs, int numfixedarityoperands,1071unsigned firstresultslot)1072: EmitNodeMatcherCommon(cgi, vts, operands, hasChain, hasInGlue,1073hasOutGlue, hasmemrefs, numfixedarityoperands,1074false),1075FirstResultSlot(firstresultslot) {}10761077unsigned getFirstResultSlot() const { return FirstResultSlot; }10781079static bool classof(const Matcher *N) { return N->getKind() == EmitNode; }1080};10811082class MorphNodeToMatcher : public EmitNodeMatcherCommon {1083void anchor() override;1084const PatternToMatch &Pattern;10851086public:1087MorphNodeToMatcher(const CodeGenInstruction &cgi,1088ArrayRef<MVT::SimpleValueType> vts,1089ArrayRef<unsigned> operands, bool hasChain, bool hasInGlue,1090bool hasOutGlue, bool hasmemrefs,1091int numfixedarityoperands, const PatternToMatch &pattern)1092: EmitNodeMatcherCommon(cgi, vts, operands, hasChain, hasInGlue,1093hasOutGlue, hasmemrefs, numfixedarityoperands,1094true),1095Pattern(pattern) {}10961097const PatternToMatch &getPattern() const { return Pattern; }10981099static bool classof(const Matcher *N) { return N->getKind() == MorphNodeTo; }1100};11011102/// CompleteMatchMatcher - Complete a match by replacing the results of the1103/// pattern with the newly generated nodes. This also prints a comment1104/// indicating the source and dest patterns.1105class CompleteMatchMatcher : public Matcher {1106SmallVector<unsigned, 2> Results;1107const PatternToMatch &Pattern;11081109public:1110CompleteMatchMatcher(ArrayRef<unsigned> results,1111const PatternToMatch &pattern)1112: Matcher(CompleteMatch), Results(results.begin(), results.end()),1113Pattern(pattern) {}11141115unsigned getNumResults() const { return Results.size(); }1116unsigned getResult(unsigned R) const { return Results[R]; }1117const PatternToMatch &getPattern() const { return Pattern; }11181119static bool classof(const Matcher *N) {1120return N->getKind() == CompleteMatch;1121}11221123private:1124void printImpl(raw_ostream &OS, unsigned indent) const override;1125bool isEqualImpl(const Matcher *M) const override {1126return cast<CompleteMatchMatcher>(M)->Results == Results &&1127&cast<CompleteMatchMatcher>(M)->Pattern == &Pattern;1128}1129};11301131} // end namespace llvm11321133#endif113411351136