Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
35258 views
//===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//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//===----------------------------------------------------------------------===//7//8// This file contains code to generate C++ code for a matcher.9//10//===----------------------------------------------------------------------===//1112#include "Basic/SDNodeProperties.h"13#include "Common/CodeGenDAGPatterns.h"14#include "Common/CodeGenInstruction.h"15#include "Common/CodeGenRegisters.h"16#include "Common/CodeGenTarget.h"17#include "Common/DAGISelMatcher.h"18#include "llvm/ADT/DenseMap.h"19#include "llvm/ADT/MapVector.h"20#include "llvm/ADT/StringMap.h"21#include "llvm/ADT/TinyPtrVector.h"22#include "llvm/Support/CommandLine.h"23#include "llvm/Support/Format.h"24#include "llvm/Support/SourceMgr.h"25#include "llvm/TableGen/Error.h"26#include "llvm/TableGen/Record.h"2728using namespace llvm;2930enum {31IndexWidth = 6,32FullIndexWidth = IndexWidth + 4,33HistOpcWidth = 40,34};3536cl::OptionCategory DAGISelCat("Options for -gen-dag-isel");3738// To reduce generated source code size.39static cl::opt<bool> OmitComments("omit-comments",40cl::desc("Do not generate comments"),41cl::init(false), cl::cat(DAGISelCat));4243static cl::opt<bool> InstrumentCoverage(44"instrument-coverage",45cl::desc("Generates tables to help identify patterns matched"),46cl::init(false), cl::cat(DAGISelCat));4748namespace {49class MatcherTableEmitter {50const CodeGenDAGPatterns &CGP;5152SmallVector<unsigned, Matcher::HighestKind + 1> OpcodeCounts;5354std::vector<TreePattern *> NodePredicates;55std::vector<TreePattern *> NodePredicatesWithOperands;5657// We de-duplicate the predicates by code string, and use this map to track58// all the patterns with "identical" predicates.59MapVector<std::string, TinyPtrVector<TreePattern *>, StringMap<unsigned>>60NodePredicatesByCodeToRun;6162std::vector<std::string> PatternPredicates;6364std::vector<const ComplexPattern *> ComplexPatterns;6566DenseMap<Record *, unsigned> NodeXFormMap;67std::vector<Record *> NodeXForms;6869std::vector<std::string> VecIncludeStrings;70MapVector<std::string, unsigned, StringMap<unsigned>> VecPatterns;7172unsigned getPatternIdxFromTable(std::string &&P, std::string &&include_loc) {73const auto It = VecPatterns.find(P);74if (It == VecPatterns.end()) {75VecPatterns.insert(std::pair(std::move(P), VecPatterns.size()));76VecIncludeStrings.push_back(std::move(include_loc));77return VecIncludeStrings.size() - 1;78}79return It->second;80}8182public:83MatcherTableEmitter(const Matcher *TheMatcher, const CodeGenDAGPatterns &cgp)84: CGP(cgp), OpcodeCounts(Matcher::HighestKind + 1, 0) {85// Record the usage of ComplexPattern.86MapVector<const ComplexPattern *, unsigned> ComplexPatternUsage;87// Record the usage of PatternPredicate.88MapVector<StringRef, unsigned> PatternPredicateUsage;89// Record the usage of Predicate.90MapVector<TreePattern *, unsigned> PredicateUsage;9192// Iterate the whole MatcherTable once and do some statistics.93std::function<void(const Matcher *)> Statistic = [&](const Matcher *N) {94while (N) {95if (auto *SM = dyn_cast<ScopeMatcher>(N))96for (unsigned I = 0; I < SM->getNumChildren(); I++)97Statistic(SM->getChild(I));98else if (auto *SOM = dyn_cast<SwitchOpcodeMatcher>(N))99for (unsigned I = 0; I < SOM->getNumCases(); I++)100Statistic(SOM->getCaseMatcher(I));101else if (auto *STM = dyn_cast<SwitchTypeMatcher>(N))102for (unsigned I = 0; I < STM->getNumCases(); I++)103Statistic(STM->getCaseMatcher(I));104else if (auto *CPM = dyn_cast<CheckComplexPatMatcher>(N))105++ComplexPatternUsage[&CPM->getPattern()];106else if (auto *CPPM = dyn_cast<CheckPatternPredicateMatcher>(N))107++PatternPredicateUsage[CPPM->getPredicate()];108else if (auto *PM = dyn_cast<CheckPredicateMatcher>(N))109++PredicateUsage[PM->getPredicate().getOrigPatFragRecord()];110N = N->getNext();111}112};113Statistic(TheMatcher);114115// Sort ComplexPatterns by usage.116std::vector<std::pair<const ComplexPattern *, unsigned>> ComplexPatternList(117ComplexPatternUsage.begin(), ComplexPatternUsage.end());118stable_sort(ComplexPatternList, [](const auto &A, const auto &B) {119return A.second > B.second;120});121for (const auto &ComplexPattern : ComplexPatternList)122ComplexPatterns.push_back(ComplexPattern.first);123124// Sort PatternPredicates by usage.125std::vector<std::pair<std::string, unsigned>> PatternPredicateList(126PatternPredicateUsage.begin(), PatternPredicateUsage.end());127stable_sort(PatternPredicateList, [](const auto &A, const auto &B) {128return A.second > B.second;129});130for (const auto &PatternPredicate : PatternPredicateList)131PatternPredicates.push_back(PatternPredicate.first);132133// Sort Predicates by usage.134// Merge predicates with same code.135for (const auto &Usage : PredicateUsage) {136TreePattern *TP = Usage.first;137TreePredicateFn Pred(TP);138NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()].push_back(TP);139}140141std::vector<std::pair<TreePattern *, unsigned>> PredicateList;142// Sum the usage.143for (auto &Predicate : NodePredicatesByCodeToRun) {144TinyPtrVector<TreePattern *> &TPs = Predicate.second;145stable_sort(TPs, [](const auto *A, const auto *B) {146return A->getRecord()->getName() < B->getRecord()->getName();147});148unsigned Uses = 0;149for (TreePattern *TP : TPs)150Uses += PredicateUsage[TP];151152// We only add the first predicate here since they are with the same code.153PredicateList.push_back({TPs[0], Uses});154}155156stable_sort(PredicateList, [](const auto &A, const auto &B) {157return A.second > B.second;158});159for (const auto &Predicate : PredicateList) {160TreePattern *TP = Predicate.first;161if (TreePredicateFn(TP).usesOperands())162NodePredicatesWithOperands.push_back(TP);163else164NodePredicates.push_back(TP);165}166}167168unsigned EmitMatcherList(const Matcher *N, const unsigned Indent,169unsigned StartIdx, raw_ostream &OS);170171unsigned SizeMatcherList(Matcher *N, raw_ostream &OS);172173void EmitPredicateFunctions(raw_ostream &OS);174175void EmitHistogram(const Matcher *N, raw_ostream &OS);176177void EmitPatternMatchTable(raw_ostream &OS);178179private:180void EmitNodePredicatesFunction(const std::vector<TreePattern *> &Preds,181StringRef Decl, raw_ostream &OS);182183unsigned SizeMatcher(Matcher *N, raw_ostream &OS);184185unsigned EmitMatcher(const Matcher *N, const unsigned Indent,186unsigned CurrentIdx, raw_ostream &OS);187188unsigned getNodePredicate(TreePredicateFn Pred) {189// We use the first predicate.190TreePattern *PredPat =191NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()][0];192return Pred.usesOperands()193? llvm::find(NodePredicatesWithOperands, PredPat) -194NodePredicatesWithOperands.begin()195: llvm::find(NodePredicates, PredPat) - NodePredicates.begin();196}197198unsigned getPatternPredicate(StringRef PredName) {199return llvm::find(PatternPredicates, PredName) - PatternPredicates.begin();200}201unsigned getComplexPat(const ComplexPattern &P) {202return llvm::find(ComplexPatterns, &P) - ComplexPatterns.begin();203}204205unsigned getNodeXFormID(Record *Rec) {206unsigned &Entry = NodeXFormMap[Rec];207if (Entry == 0) {208NodeXForms.push_back(Rec);209Entry = NodeXForms.size();210}211return Entry - 1;212}213};214} // end anonymous namespace.215216static std::string GetPatFromTreePatternNode(const TreePatternNode &N) {217std::string str;218raw_string_ostream Stream(str);219Stream << N;220return str;221}222223static unsigned GetVBRSize(unsigned Val) {224if (Val <= 127)225return 1;226227unsigned NumBytes = 0;228while (Val >= 128) {229Val >>= 7;230++NumBytes;231}232return NumBytes + 1;233}234235/// EmitVBRValue - Emit the specified value as a VBR, returning the number of236/// bytes emitted.237static unsigned EmitVBRValue(uint64_t Val, raw_ostream &OS) {238if (Val <= 127) {239OS << Val << ", ";240return 1;241}242243uint64_t InVal = Val;244unsigned NumBytes = 0;245while (Val >= 128) {246OS << (Val & 127) << "|128,";247Val >>= 7;248++NumBytes;249}250OS << Val;251if (!OmitComments)252OS << "/*" << InVal << "*/";253OS << ", ";254return NumBytes + 1;255}256257/// Emit the specified signed value as a VBR. To improve compression we encode258/// positive numbers shifted left by 1 and negative numbers negated and shifted259/// left by 1 with bit 0 set.260static unsigned EmitSignedVBRValue(uint64_t Val, raw_ostream &OS) {261if ((int64_t)Val >= 0)262Val = Val << 1;263else264Val = (-Val << 1) | 1;265266return EmitVBRValue(Val, OS);267}268269// This is expensive and slow.270static std::string getIncludePath(const Record *R) {271std::string str;272raw_string_ostream Stream(str);273auto Locs = R->getLoc();274SMLoc L;275if (Locs.size() > 1) {276// Get where the pattern prototype was instantiated277L = Locs[1];278} else if (Locs.size() == 1) {279L = Locs[0];280}281unsigned CurBuf = SrcMgr.FindBufferContainingLoc(L);282assert(CurBuf && "Invalid or unspecified location!");283284Stream << SrcMgr.getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":"285<< SrcMgr.FindLineNumber(L, CurBuf);286return str;287}288289/// This function traverses the matcher tree and sizes all the nodes290/// that are children of the three kinds of nodes that have them.291unsigned MatcherTableEmitter::SizeMatcherList(Matcher *N, raw_ostream &OS) {292unsigned Size = 0;293while (N) {294Size += SizeMatcher(N, OS);295N = N->getNext();296}297return Size;298}299300/// This function sizes the children of the three kinds of nodes that301/// have them. It does so by using special cases for those three302/// nodes, but sharing the code in EmitMatcher() for the other kinds.303unsigned MatcherTableEmitter::SizeMatcher(Matcher *N, raw_ostream &OS) {304unsigned Idx = 0;305306++OpcodeCounts[N->getKind()];307switch (N->getKind()) {308// The Scope matcher has its kind, a series of child size + child,309// and a trailing zero.310case Matcher::Scope: {311ScopeMatcher *SM = cast<ScopeMatcher>(N);312assert(SM->getNext() == nullptr && "Scope matcher should not have next");313unsigned Size = 1; // Count the kind.314for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {315const unsigned ChildSize = SizeMatcherList(SM->getChild(i), OS);316assert(ChildSize != 0 && "Matcher cannot have child of size 0");317SM->getChild(i)->setSize(ChildSize);318Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.319}320++Size; // Count the zero sentinel.321return Size;322}323324// SwitchOpcode and SwitchType have their kind, a series of child size +325// opcode/type + child, and a trailing zero.326case Matcher::SwitchOpcode:327case Matcher::SwitchType: {328unsigned Size = 1; // Count the kind.329unsigned NumCases;330if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))331NumCases = SOM->getNumCases();332else333NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();334for (unsigned i = 0, e = NumCases; i != e; ++i) {335Matcher *Child;336if (SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {337Child = SOM->getCaseMatcher(i);338Size += 2; // Count the child's opcode.339} else {340Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);341++Size; // Count the child's type.342}343const unsigned ChildSize = SizeMatcherList(Child, OS);344assert(ChildSize != 0 && "Matcher cannot have child of size 0");345Child->setSize(ChildSize);346Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.347}348++Size; // Count the zero sentinel.349return Size;350}351352default:353// Employ the matcher emitter to size other matchers.354return EmitMatcher(N, 0, Idx, OS);355}356llvm_unreachable("Unreachable");357}358359static void BeginEmitFunction(raw_ostream &OS, StringRef RetType,360StringRef Decl, bool AddOverride) {361OS << "#ifdef GET_DAGISEL_DECL\n";362OS << RetType << ' ' << Decl;363if (AddOverride)364OS << " override";365OS << ";\n"366"#endif\n"367"#if defined(GET_DAGISEL_BODY) || DAGISEL_INLINE\n";368OS << RetType << " DAGISEL_CLASS_COLONCOLON " << Decl << "\n";369if (AddOverride) {370OS << "#if DAGISEL_INLINE\n"371" override\n"372"#endif\n";373}374}375376static void EndEmitFunction(raw_ostream &OS) {377OS << "#endif // GET_DAGISEL_BODY\n\n";378}379380void MatcherTableEmitter::EmitPatternMatchTable(raw_ostream &OS) {381382assert(isUInt<16>(VecPatterns.size()) &&383"Using only 16 bits to encode offset into Pattern Table");384assert(VecPatterns.size() == VecIncludeStrings.size() &&385"The sizes of Pattern and include vectors should be the same");386387BeginEmitFunction(OS, "StringRef", "getPatternForIndex(unsigned Index)",388true /*AddOverride*/);389OS << "{\n";390OS << "static const char *PATTERN_MATCH_TABLE[] = {\n";391392for (const auto &It : VecPatterns) {393OS << "\"" << It.first << "\",\n";394}395396OS << "\n};";397OS << "\nreturn StringRef(PATTERN_MATCH_TABLE[Index]);";398OS << "\n}\n";399EndEmitFunction(OS);400401BeginEmitFunction(OS, "StringRef", "getIncludePathForIndex(unsigned Index)",402true /*AddOverride*/);403OS << "{\n";404OS << "static const char *INCLUDE_PATH_TABLE[] = {\n";405406for (const auto &It : VecIncludeStrings) {407OS << "\"" << It << "\",\n";408}409410OS << "\n};";411OS << "\nreturn StringRef(INCLUDE_PATH_TABLE[Index]);";412OS << "\n}\n";413EndEmitFunction(OS);414}415416/// EmitMatcher - Emit bytes for the specified matcher and return417/// the number of bytes emitted.418unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,419const unsigned Indent,420unsigned CurrentIdx,421raw_ostream &OS) {422OS.indent(Indent);423424switch (N->getKind()) {425case Matcher::Scope: {426const ScopeMatcher *SM = cast<ScopeMatcher>(N);427unsigned StartIdx = CurrentIdx;428429// Emit all of the children.430for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {431if (i == 0) {432OS << "OPC_Scope, ";433++CurrentIdx;434} else {435if (!OmitComments) {436OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";437OS.indent(Indent) << "/*Scope*/ ";438} else439OS.indent(Indent);440}441442unsigned ChildSize = SM->getChild(i)->getSize();443unsigned VBRSize = EmitVBRValue(ChildSize, OS);444if (!OmitComments) {445OS << "/*->" << CurrentIdx + VBRSize + ChildSize << "*/";446if (i == 0)447OS << " // " << SM->getNumChildren() << " children in Scope";448}449OS << '\n';450451ChildSize = EmitMatcherList(SM->getChild(i), Indent + 1,452CurrentIdx + VBRSize, OS);453assert(ChildSize == SM->getChild(i)->getSize() &&454"Emitted child size does not match calculated size");455CurrentIdx += VBRSize + ChildSize;456}457458// Emit a zero as a sentinel indicating end of 'Scope'.459if (!OmitComments)460OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";461OS.indent(Indent) << "0, ";462if (!OmitComments)463OS << "/*End of Scope*/";464OS << '\n';465return CurrentIdx - StartIdx + 1;466}467468case Matcher::RecordNode:469OS << "OPC_RecordNode,";470if (!OmitComments)471OS << " // #" << cast<RecordMatcher>(N)->getResultNo() << " = "472<< cast<RecordMatcher>(N)->getWhatFor();473OS << '\n';474return 1;475476case Matcher::RecordChild:477OS << "OPC_RecordChild" << cast<RecordChildMatcher>(N)->getChildNo() << ',';478if (!OmitComments)479OS << " // #" << cast<RecordChildMatcher>(N)->getResultNo() << " = "480<< cast<RecordChildMatcher>(N)->getWhatFor();481OS << '\n';482return 1;483484case Matcher::RecordMemRef:485OS << "OPC_RecordMemRef,\n";486return 1;487488case Matcher::CaptureGlueInput:489OS << "OPC_CaptureGlueInput,\n";490return 1;491492case Matcher::MoveChild: {493const auto *MCM = cast<MoveChildMatcher>(N);494495OS << "OPC_MoveChild";496// Handle the specialized forms.497if (MCM->getChildNo() >= 8)498OS << ", ";499OS << MCM->getChildNo() << ",\n";500return (MCM->getChildNo() >= 8) ? 2 : 1;501}502503case Matcher::MoveSibling: {504const auto *MSM = cast<MoveSiblingMatcher>(N);505506OS << "OPC_MoveSibling";507// Handle the specialized forms.508if (MSM->getSiblingNo() >= 8)509OS << ", ";510OS << MSM->getSiblingNo() << ",\n";511return (MSM->getSiblingNo() >= 8) ? 2 : 1;512}513514case Matcher::MoveParent:515OS << "OPC_MoveParent,\n";516return 1;517518case Matcher::CheckSame:519OS << "OPC_CheckSame, " << cast<CheckSameMatcher>(N)->getMatchNumber()520<< ",\n";521return 2;522523case Matcher::CheckChildSame:524OS << "OPC_CheckChild" << cast<CheckChildSameMatcher>(N)->getChildNo()525<< "Same, " << cast<CheckChildSameMatcher>(N)->getMatchNumber() << ",\n";526return 2;527528case Matcher::CheckPatternPredicate: {529StringRef Pred = cast<CheckPatternPredicateMatcher>(N)->getPredicate();530unsigned PredNo = getPatternPredicate(Pred);531if (PredNo > 255)532OS << "OPC_CheckPatternPredicateTwoByte, TARGET_VAL(" << PredNo << "),";533else if (PredNo < 8)534OS << "OPC_CheckPatternPredicate" << PredNo << ',';535else536OS << "OPC_CheckPatternPredicate, " << PredNo << ',';537if (!OmitComments)538OS << " // " << Pred;539OS << '\n';540return 2 + (PredNo > 255) - (PredNo < 8);541}542case Matcher::CheckPredicate: {543TreePredicateFn Pred = cast<CheckPredicateMatcher>(N)->getPredicate();544unsigned OperandBytes = 0;545unsigned PredNo = getNodePredicate(Pred);546547if (Pred.usesOperands()) {548unsigned NumOps = cast<CheckPredicateMatcher>(N)->getNumOperands();549OS << "OPC_CheckPredicateWithOperands, " << NumOps << "/*#Ops*/, ";550for (unsigned i = 0; i < NumOps; ++i)551OS << cast<CheckPredicateMatcher>(N)->getOperandNo(i) << ", ";552OperandBytes = 1 + NumOps;553} else {554if (PredNo < 8) {555OperandBytes = -1;556OS << "OPC_CheckPredicate" << PredNo << ", ";557} else558OS << "OPC_CheckPredicate, ";559}560561if (PredNo >= 8 || Pred.usesOperands())562OS << PredNo << ',';563if (!OmitComments)564OS << " // " << Pred.getFnName();565OS << '\n';566return 2 + OperandBytes;567}568569case Matcher::CheckOpcode:570OS << "OPC_CheckOpcode, TARGET_VAL("571<< cast<CheckOpcodeMatcher>(N)->getOpcode().getEnumName() << "),\n";572return 3;573574case Matcher::SwitchOpcode:575case Matcher::SwitchType: {576unsigned StartIdx = CurrentIdx;577578unsigned NumCases;579if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {580OS << "OPC_SwitchOpcode ";581NumCases = SOM->getNumCases();582} else {583OS << "OPC_SwitchType ";584NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();585}586587if (!OmitComments)588OS << "/*" << NumCases << " cases */";589OS << ", ";590++CurrentIdx;591592// For each case we emit the size, then the opcode, then the matcher.593for (unsigned i = 0, e = NumCases; i != e; ++i) {594const Matcher *Child;595unsigned IdxSize;596if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {597Child = SOM->getCaseMatcher(i);598IdxSize = 2; // size of opcode in table is 2 bytes.599} else {600Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);601IdxSize = 1; // size of type in table is 1 byte.602}603604if (i != 0) {605if (!OmitComments)606OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";607OS.indent(Indent);608if (!OmitComments)609OS << (isa<SwitchOpcodeMatcher>(N) ? "/*SwitchOpcode*/ "610: "/*SwitchType*/ ");611}612613unsigned ChildSize = Child->getSize();614CurrentIdx += EmitVBRValue(ChildSize, OS) + IdxSize;615if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))616OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),";617else618OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << ',';619if (!OmitComments)620OS << "// ->" << CurrentIdx + ChildSize;621OS << '\n';622623ChildSize = EmitMatcherList(Child, Indent + 1, CurrentIdx, OS);624assert(ChildSize == Child->getSize() &&625"Emitted child size does not match calculated size");626CurrentIdx += ChildSize;627}628629// Emit the final zero to terminate the switch.630if (!OmitComments)631OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";632OS.indent(Indent) << "0,";633if (!OmitComments)634OS << (isa<SwitchOpcodeMatcher>(N) ? " // EndSwitchOpcode"635: " // EndSwitchType");636637OS << '\n';638return CurrentIdx - StartIdx + 1;639}640641case Matcher::CheckType:642if (cast<CheckTypeMatcher>(N)->getResNo() == 0) {643MVT::SimpleValueType VT = cast<CheckTypeMatcher>(N)->getType();644switch (VT) {645case MVT::i32:646case MVT::i64:647OS << "OPC_CheckTypeI" << MVT(VT).getSizeInBits() << ",\n";648return 1;649default:650OS << "OPC_CheckType, " << getEnumName(VT) << ",\n";651return 2;652}653}654OS << "OPC_CheckTypeRes, " << cast<CheckTypeMatcher>(N)->getResNo() << ", "655<< getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";656return 3;657658case Matcher::CheckChildType: {659MVT::SimpleValueType VT = cast<CheckChildTypeMatcher>(N)->getType();660switch (VT) {661case MVT::i32:662case MVT::i64:663OS << "OPC_CheckChild" << cast<CheckChildTypeMatcher>(N)->getChildNo()664<< "TypeI" << MVT(VT).getSizeInBits() << ",\n";665return 1;666default:667OS << "OPC_CheckChild" << cast<CheckChildTypeMatcher>(N)->getChildNo()668<< "Type, " << getEnumName(VT) << ",\n";669return 2;670}671}672673case Matcher::CheckInteger: {674OS << "OPC_CheckInteger, ";675unsigned Bytes =6761 + EmitSignedVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS);677OS << '\n';678return Bytes;679}680case Matcher::CheckChildInteger: {681OS << "OPC_CheckChild" << cast<CheckChildIntegerMatcher>(N)->getChildNo()682<< "Integer, ";683unsigned Bytes = 1 + EmitSignedVBRValue(684cast<CheckChildIntegerMatcher>(N)->getValue(), OS);685OS << '\n';686return Bytes;687}688case Matcher::CheckCondCode:689OS << "OPC_CheckCondCode, ISD::"690<< cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n";691return 2;692693case Matcher::CheckChild2CondCode:694OS << "OPC_CheckChild2CondCode, ISD::"695<< cast<CheckChild2CondCodeMatcher>(N)->getCondCodeName() << ",\n";696return 2;697698case Matcher::CheckValueType:699OS << "OPC_CheckValueType, "700<< getEnumName(cast<CheckValueTypeMatcher>(N)->getVT()) << ",\n";701return 2;702703case Matcher::CheckComplexPat: {704const CheckComplexPatMatcher *CCPM = cast<CheckComplexPatMatcher>(N);705const ComplexPattern &Pattern = CCPM->getPattern();706unsigned PatternNo = getComplexPat(Pattern);707if (PatternNo < 8)708OS << "OPC_CheckComplexPat" << PatternNo << ", /*#*/"709<< CCPM->getMatchNumber() << ',';710else711OS << "OPC_CheckComplexPat, /*CP*/" << PatternNo << ", /*#*/"712<< CCPM->getMatchNumber() << ',';713714if (!OmitComments) {715OS << " // " << Pattern.getSelectFunc();716OS << ":$" << CCPM->getName();717for (unsigned i = 0, e = Pattern.getNumOperands(); i != e; ++i)718OS << " #" << CCPM->getFirstResult() + i;719720if (Pattern.hasProperty(SDNPHasChain))721OS << " + chain result";722}723OS << '\n';724return PatternNo < 8 ? 2 : 3;725}726727case Matcher::CheckAndImm: {728OS << "OPC_CheckAndImm, ";729unsigned Bytes =7301 + EmitVBRValue(cast<CheckAndImmMatcher>(N)->getValue(), OS);731OS << '\n';732return Bytes;733}734735case Matcher::CheckOrImm: {736OS << "OPC_CheckOrImm, ";737unsigned Bytes =7381 + EmitVBRValue(cast<CheckOrImmMatcher>(N)->getValue(), OS);739OS << '\n';740return Bytes;741}742743case Matcher::CheckFoldableChainNode:744OS << "OPC_CheckFoldableChainNode,\n";745return 1;746747case Matcher::CheckImmAllOnesV:748OS << "OPC_CheckImmAllOnesV,\n";749return 1;750751case Matcher::CheckImmAllZerosV:752OS << "OPC_CheckImmAllZerosV,\n";753return 1;754755case Matcher::EmitInteger: {756int64_t Val = cast<EmitIntegerMatcher>(N)->getValue();757MVT::SimpleValueType VT = cast<EmitIntegerMatcher>(N)->getVT();758unsigned OpBytes;759switch (VT) {760case MVT::i8:761case MVT::i16:762case MVT::i32:763case MVT::i64:764OpBytes = 1;765OS << "OPC_EmitInteger" << MVT(VT).getSizeInBits() << ", ";766break;767default:768OpBytes = 2;769OS << "OPC_EmitInteger, " << getEnumName(VT) << ", ";770break;771}772unsigned Bytes = OpBytes + EmitSignedVBRValue(Val, OS);773OS << '\n';774return Bytes;775}776case Matcher::EmitStringInteger: {777const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();778MVT::SimpleValueType VT = cast<EmitStringIntegerMatcher>(N)->getVT();779// These should always fit into 7 bits.780unsigned OpBytes;781switch (VT) {782case MVT::i32:783OpBytes = 1;784OS << "OPC_EmitStringInteger" << MVT(VT).getSizeInBits() << ", ";785break;786default:787OpBytes = 2;788OS << "OPC_EmitStringInteger, " << getEnumName(VT) << ", ";789break;790}791OS << Val << ",\n";792return OpBytes + 1;793}794795case Matcher::EmitRegister: {796const EmitRegisterMatcher *Matcher = cast<EmitRegisterMatcher>(N);797const CodeGenRegister *Reg = Matcher->getReg();798MVT::SimpleValueType VT = Matcher->getVT();799// If the enum value of the register is larger than one byte can handle,800// use EmitRegister2.801if (Reg && Reg->EnumValue > 255) {802OS << "OPC_EmitRegister2, " << getEnumName(VT) << ", ";803OS << "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n";804return 4;805}806unsigned OpBytes;807switch (VT) {808case MVT::i32:809case MVT::i64:810OpBytes = 1;811OS << "OPC_EmitRegisterI" << MVT(VT).getSizeInBits() << ", ";812break;813default:814OpBytes = 2;815OS << "OPC_EmitRegister, " << getEnumName(VT) << ", ";816break;817}818if (Reg) {819OS << getQualifiedName(Reg->TheDef) << ",\n";820} else {821OS << "0 ";822if (!OmitComments)823OS << "/*zero_reg*/";824OS << ",\n";825}826return OpBytes + 1;827}828829case Matcher::EmitConvertToTarget: {830unsigned Slot = cast<EmitConvertToTargetMatcher>(N)->getSlot();831if (Slot < 8) {832OS << "OPC_EmitConvertToTarget" << Slot << ",\n";833return 1;834}835OS << "OPC_EmitConvertToTarget, " << Slot << ",\n";836return 2;837}838839case Matcher::EmitMergeInputChains: {840const EmitMergeInputChainsMatcher *MN =841cast<EmitMergeInputChainsMatcher>(N);842843// Handle the specialized forms OPC_EmitMergeInputChains1_0, 1_1, and 1_2.844if (MN->getNumNodes() == 1 && MN->getNode(0) < 3) {845OS << "OPC_EmitMergeInputChains1_" << MN->getNode(0) << ",\n";846return 1;847}848849OS << "OPC_EmitMergeInputChains, " << MN->getNumNodes() << ", ";850for (unsigned i = 0, e = MN->getNumNodes(); i != e; ++i)851OS << MN->getNode(i) << ", ";852OS << '\n';853return 2 + MN->getNumNodes();854}855case Matcher::EmitCopyToReg: {856const auto *C2RMatcher = cast<EmitCopyToRegMatcher>(N);857int Bytes = 3;858const CodeGenRegister *Reg = C2RMatcher->getDestPhysReg();859unsigned Slot = C2RMatcher->getSrcSlot();860if (Reg->EnumValue > 255) {861assert(isUInt<16>(Reg->EnumValue) && "not handled");862OS << "OPC_EmitCopyToRegTwoByte, " << Slot << ", "863<< "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n";864++Bytes;865} else {866if (Slot < 8) {867OS << "OPC_EmitCopyToReg" << Slot << ", "868<< getQualifiedName(Reg->TheDef) << ",\n";869--Bytes;870} else871OS << "OPC_EmitCopyToReg, " << Slot << ", "872<< getQualifiedName(Reg->TheDef) << ",\n";873}874875return Bytes;876}877case Matcher::EmitNodeXForm: {878const EmitNodeXFormMatcher *XF = cast<EmitNodeXFormMatcher>(N);879OS << "OPC_EmitNodeXForm, " << getNodeXFormID(XF->getNodeXForm()) << ", "880<< XF->getSlot() << ',';881if (!OmitComments)882OS << " // " << XF->getNodeXForm()->getName();883OS << '\n';884return 3;885}886887case Matcher::EmitNode:888case Matcher::MorphNodeTo: {889auto NumCoveredBytes = 0;890if (InstrumentCoverage) {891if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {892NumCoveredBytes = 3;893OS << "OPC_Coverage, ";894std::string src =895GetPatFromTreePatternNode(SNT->getPattern().getSrcPattern());896std::string dst =897GetPatFromTreePatternNode(SNT->getPattern().getDstPattern());898Record *PatRecord = SNT->getPattern().getSrcRecord();899std::string include_src = getIncludePath(PatRecord);900unsigned Offset =901getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));902OS << "TARGET_VAL(" << Offset << "),\n";903OS.indent(FullIndexWidth + Indent);904}905}906const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N);907bool IsEmitNode = isa<EmitNodeMatcher>(EN);908OS << (IsEmitNode ? "OPC_EmitNode" : "OPC_MorphNodeTo");909bool CompressVTs = EN->getNumVTs() < 3;910bool CompressNodeInfo = false;911if (CompressVTs) {912OS << EN->getNumVTs();913if (!EN->hasChain() && !EN->hasInGlue() && !EN->hasOutGlue() &&914!EN->hasMemRefs() && EN->getNumFixedArityOperands() == -1) {915CompressNodeInfo = true;916OS << "None";917} else if (EN->hasChain() && !EN->hasInGlue() && !EN->hasOutGlue() &&918!EN->hasMemRefs() && EN->getNumFixedArityOperands() == -1) {919CompressNodeInfo = true;920OS << "Chain";921} else if (!IsEmitNode && !EN->hasChain() && EN->hasInGlue() &&922!EN->hasOutGlue() && !EN->hasMemRefs() &&923EN->getNumFixedArityOperands() == -1) {924CompressNodeInfo = true;925OS << "GlueInput";926} else if (!IsEmitNode && !EN->hasChain() && !EN->hasInGlue() &&927EN->hasOutGlue() && !EN->hasMemRefs() &&928EN->getNumFixedArityOperands() == -1) {929CompressNodeInfo = true;930OS << "GlueOutput";931}932}933934const CodeGenInstruction &CGI = EN->getInstruction();935OS << ", TARGET_VAL(" << CGI.Namespace << "::" << CGI.TheDef->getName()936<< ")";937938if (!CompressNodeInfo) {939OS << ", 0";940if (EN->hasChain())941OS << "|OPFL_Chain";942if (EN->hasInGlue())943OS << "|OPFL_GlueInput";944if (EN->hasOutGlue())945OS << "|OPFL_GlueOutput";946if (EN->hasMemRefs())947OS << "|OPFL_MemRefs";948if (EN->getNumFixedArityOperands() != -1)949OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands();950}951OS << ",\n";952953OS.indent(FullIndexWidth + Indent + 4);954if (!CompressVTs) {955OS << EN->getNumVTs();956if (!OmitComments)957OS << "/*#VTs*/";958OS << ", ";959}960for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i)961OS << getEnumName(EN->getVT(i)) << ", ";962963OS << EN->getNumOperands();964if (!OmitComments)965OS << "/*#Ops*/";966OS << ", ";967unsigned NumOperandBytes = 0;968for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i)969NumOperandBytes += EmitVBRValue(EN->getOperand(i), OS);970971if (!OmitComments) {972// Print the result #'s for EmitNode.973if (const EmitNodeMatcher *E = dyn_cast<EmitNodeMatcher>(EN)) {974if (unsigned NumResults = EN->getNumVTs()) {975OS << " // Results =";976unsigned First = E->getFirstResultSlot();977for (unsigned i = 0; i != NumResults; ++i)978OS << " #" << First + i;979}980}981OS << '\n';982983if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {984OS.indent(FullIndexWidth + Indent)985<< "// Src: " << SNT->getPattern().getSrcPattern()986<< " - Complexity = " << SNT->getPattern().getPatternComplexity(CGP)987<< '\n';988OS.indent(FullIndexWidth + Indent)989<< "// Dst: " << SNT->getPattern().getDstPattern() << '\n';990}991} else992OS << '\n';993994return 4 + !CompressVTs + !CompressNodeInfo + EN->getNumVTs() +995NumOperandBytes + NumCoveredBytes;996}997case Matcher::CompleteMatch: {998const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N);999auto NumCoveredBytes = 0;1000if (InstrumentCoverage) {1001NumCoveredBytes = 3;1002OS << "OPC_Coverage, ";1003std::string src =1004GetPatFromTreePatternNode(CM->getPattern().getSrcPattern());1005std::string dst =1006GetPatFromTreePatternNode(CM->getPattern().getDstPattern());1007Record *PatRecord = CM->getPattern().getSrcRecord();1008std::string include_src = getIncludePath(PatRecord);1009unsigned Offset =1010getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));1011OS << "TARGET_VAL(" << Offset << "),\n";1012OS.indent(FullIndexWidth + Indent);1013}1014OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";1015unsigned NumResultBytes = 0;1016for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)1017NumResultBytes += EmitVBRValue(CM->getResult(i), OS);1018OS << '\n';1019if (!OmitComments) {1020OS.indent(FullIndexWidth + Indent)1021<< " // Src: " << CM->getPattern().getSrcPattern()1022<< " - Complexity = " << CM->getPattern().getPatternComplexity(CGP)1023<< '\n';1024OS.indent(FullIndexWidth + Indent)1025<< " // Dst: " << CM->getPattern().getDstPattern();1026}1027OS << '\n';1028return 2 + NumResultBytes + NumCoveredBytes;1029}1030}1031llvm_unreachable("Unreachable");1032}10331034/// This function traverses the matcher tree and emits all the nodes.1035/// The nodes have already been sized.1036unsigned MatcherTableEmitter::EmitMatcherList(const Matcher *N,1037const unsigned Indent,1038unsigned CurrentIdx,1039raw_ostream &OS) {1040unsigned Size = 0;1041while (N) {1042if (!OmitComments)1043OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";1044unsigned MatcherSize = EmitMatcher(N, Indent, CurrentIdx, OS);1045Size += MatcherSize;1046CurrentIdx += MatcherSize;10471048// If there are other nodes in this list, iterate to them, otherwise we're1049// done.1050N = N->getNext();1051}1052return Size;1053}10541055void MatcherTableEmitter::EmitNodePredicatesFunction(1056const std::vector<TreePattern *> &Preds, StringRef Decl, raw_ostream &OS) {1057if (Preds.empty())1058return;10591060BeginEmitFunction(OS, "bool", Decl, true /*AddOverride*/);1061OS << "{\n";1062OS << " switch (PredNo) {\n";1063OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n";1064for (unsigned i = 0, e = Preds.size(); i != e; ++i) {1065// Emit the predicate code corresponding to this pattern.1066TreePredicateFn PredFn(Preds[i]);1067assert(!PredFn.isAlwaysTrue() && "No code in this predicate");1068std::string PredFnCodeStr = PredFn.getCodeToRunOnSDNode();10691070OS << " case " << i << ": {\n";1071for (auto *SimilarPred : NodePredicatesByCodeToRun[PredFnCodeStr])1072OS << " // " << TreePredicateFn(SimilarPred).getFnName() << '\n';1073OS << PredFnCodeStr << "\n }\n";1074}1075OS << " }\n";1076OS << "}\n";1077EndEmitFunction(OS);1078}10791080void MatcherTableEmitter::EmitPredicateFunctions(raw_ostream &OS) {1081// Emit pattern predicates.1082if (!PatternPredicates.empty()) {1083BeginEmitFunction(OS, "bool",1084"CheckPatternPredicate(unsigned PredNo) const",1085true /*AddOverride*/);1086OS << "{\n";1087OS << " switch (PredNo) {\n";1088OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n";1089for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)1090OS << " case " << i << ": return " << PatternPredicates[i] << ";\n";1091OS << " }\n";1092OS << "}\n";1093EndEmitFunction(OS);1094}10951096// Emit Node predicates.1097EmitNodePredicatesFunction(1098NodePredicates, "CheckNodePredicate(SDNode *Node, unsigned PredNo) const",1099OS);1100EmitNodePredicatesFunction(1101NodePredicatesWithOperands,1102"CheckNodePredicateWithOperands(SDNode *Node, unsigned PredNo, "1103"const SmallVectorImpl<SDValue> &Operands) const",1104OS);11051106// Emit CompletePattern matchers.1107// FIXME: This should be const.1108if (!ComplexPatterns.empty()) {1109BeginEmitFunction(1110OS, "bool",1111"CheckComplexPattern(SDNode *Root, SDNode *Parent,\n"1112" SDValue N, unsigned PatternNo,\n"1113" SmallVectorImpl<std::pair<SDValue, SDNode *>> &Result)",1114true /*AddOverride*/);1115OS << "{\n";1116OS << " unsigned NextRes = Result.size();\n";1117OS << " switch (PatternNo) {\n";1118OS << " default: llvm_unreachable(\"Invalid pattern # in table?\");\n";1119for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) {1120const ComplexPattern &P = *ComplexPatterns[i];1121unsigned NumOps = P.getNumOperands();11221123if (P.hasProperty(SDNPHasChain))1124++NumOps; // Get the chained node too.11251126OS << " case " << i << ":\n";1127if (InstrumentCoverage)1128OS << " {\n";1129OS << " Result.resize(NextRes+" << NumOps << ");\n";1130if (InstrumentCoverage)1131OS << " bool Succeeded = " << P.getSelectFunc();1132else1133OS << " return " << P.getSelectFunc();11341135OS << "(";1136// If the complex pattern wants the root of the match, pass it in as the1137// first argument.1138if (P.hasProperty(SDNPWantRoot))1139OS << "Root, ";11401141// If the complex pattern wants the parent of the operand being matched,1142// pass it in as the next argument.1143if (P.hasProperty(SDNPWantParent))1144OS << "Parent, ";11451146OS << "N";1147for (unsigned i = 0; i != NumOps; ++i)1148OS << ", Result[NextRes+" << i << "].first";1149OS << ");\n";1150if (InstrumentCoverage) {1151OS << " if (Succeeded)\n";1152OS << " dbgs() << \"\\nCOMPLEX_PATTERN: " << P.getSelectFunc()1153<< "\\n\" ;\n";1154OS << " return Succeeded;\n";1155OS << " }\n";1156}1157}1158OS << " }\n";1159OS << "}\n";1160EndEmitFunction(OS);1161}11621163// Emit SDNodeXForm handlers.1164// FIXME: This should be const.1165if (!NodeXForms.empty()) {1166BeginEmitFunction(OS, "SDValue",1167"RunSDNodeXForm(SDValue V, unsigned XFormNo)",1168true /*AddOverride*/);1169OS << "{\n";1170OS << " switch (XFormNo) {\n";1171OS << " default: llvm_unreachable(\"Invalid xform # in table?\");\n";11721173// FIXME: The node xform could take SDValue's instead of SDNode*'s.1174for (unsigned i = 0, e = NodeXForms.size(); i != e; ++i) {1175const CodeGenDAGPatterns::NodeXForm &Entry =1176CGP.getSDNodeTransform(NodeXForms[i]);11771178Record *SDNode = Entry.first;1179const std::string &Code = Entry.second;11801181OS << " case " << i << ": { ";1182if (!OmitComments)1183OS << "// " << NodeXForms[i]->getName();1184OS << '\n';11851186std::string ClassName =1187std::string(CGP.getSDNodeInfo(SDNode).getSDClassName());1188if (ClassName == "SDNode")1189OS << " SDNode *N = V.getNode();\n";1190else1191OS << " " << ClassName << " *N = cast<" << ClassName1192<< ">(V.getNode());\n";1193OS << Code << "\n }\n";1194}1195OS << " }\n";1196OS << "}\n";1197EndEmitFunction(OS);1198}1199}12001201static StringRef getOpcodeString(Matcher::KindTy Kind) {1202switch (Kind) {1203case Matcher::Scope:1204return "OPC_Scope";1205case Matcher::RecordNode:1206return "OPC_RecordNode";1207case Matcher::RecordChild:1208return "OPC_RecordChild";1209case Matcher::RecordMemRef:1210return "OPC_RecordMemRef";1211case Matcher::CaptureGlueInput:1212return "OPC_CaptureGlueInput";1213case Matcher::MoveChild:1214return "OPC_MoveChild";1215case Matcher::MoveSibling:1216return "OPC_MoveSibling";1217case Matcher::MoveParent:1218return "OPC_MoveParent";1219case Matcher::CheckSame:1220return "OPC_CheckSame";1221case Matcher::CheckChildSame:1222return "OPC_CheckChildSame";1223case Matcher::CheckPatternPredicate:1224return "OPC_CheckPatternPredicate";1225case Matcher::CheckPredicate:1226return "OPC_CheckPredicate";1227case Matcher::CheckOpcode:1228return "OPC_CheckOpcode";1229case Matcher::SwitchOpcode:1230return "OPC_SwitchOpcode";1231case Matcher::CheckType:1232return "OPC_CheckType";1233case Matcher::SwitchType:1234return "OPC_SwitchType";1235case Matcher::CheckChildType:1236return "OPC_CheckChildType";1237case Matcher::CheckInteger:1238return "OPC_CheckInteger";1239case Matcher::CheckChildInteger:1240return "OPC_CheckChildInteger";1241case Matcher::CheckCondCode:1242return "OPC_CheckCondCode";1243case Matcher::CheckChild2CondCode:1244return "OPC_CheckChild2CondCode";1245case Matcher::CheckValueType:1246return "OPC_CheckValueType";1247case Matcher::CheckComplexPat:1248return "OPC_CheckComplexPat";1249case Matcher::CheckAndImm:1250return "OPC_CheckAndImm";1251case Matcher::CheckOrImm:1252return "OPC_CheckOrImm";1253case Matcher::CheckFoldableChainNode:1254return "OPC_CheckFoldableChainNode";1255case Matcher::CheckImmAllOnesV:1256return "OPC_CheckImmAllOnesV";1257case Matcher::CheckImmAllZerosV:1258return "OPC_CheckImmAllZerosV";1259case Matcher::EmitInteger:1260return "OPC_EmitInteger";1261case Matcher::EmitStringInteger:1262return "OPC_EmitStringInteger";1263case Matcher::EmitRegister:1264return "OPC_EmitRegister";1265case Matcher::EmitConvertToTarget:1266return "OPC_EmitConvertToTarget";1267case Matcher::EmitMergeInputChains:1268return "OPC_EmitMergeInputChains";1269case Matcher::EmitCopyToReg:1270return "OPC_EmitCopyToReg";1271case Matcher::EmitNode:1272return "OPC_EmitNode";1273case Matcher::MorphNodeTo:1274return "OPC_MorphNodeTo";1275case Matcher::EmitNodeXForm:1276return "OPC_EmitNodeXForm";1277case Matcher::CompleteMatch:1278return "OPC_CompleteMatch";1279}12801281llvm_unreachable("Unhandled opcode?");1282}12831284void MatcherTableEmitter::EmitHistogram(const Matcher *M, raw_ostream &OS) {1285if (OmitComments)1286return;12871288OS << " // Opcode Histogram:\n";1289for (unsigned i = 0, e = OpcodeCounts.size(); i != e; ++i) {1290OS << " // #"1291<< left_justify(getOpcodeString((Matcher::KindTy)i), HistOpcWidth)1292<< " = " << OpcodeCounts[i] << '\n';1293}1294OS << '\n';1295}12961297void llvm::EmitMatcherTable(Matcher *TheMatcher, const CodeGenDAGPatterns &CGP,1298raw_ostream &OS) {1299OS << "#if defined(GET_DAGISEL_DECL) && defined(GET_DAGISEL_BODY)\n";1300OS << "#error GET_DAGISEL_DECL and GET_DAGISEL_BODY cannot be both defined, ";1301OS << "undef both for inline definitions\n";1302OS << "#endif\n\n";13031304// Emit a check for omitted class name.1305OS << "#ifdef GET_DAGISEL_BODY\n";1306OS << "#define LOCAL_DAGISEL_STRINGIZE(X) LOCAL_DAGISEL_STRINGIZE_(X)\n";1307OS << "#define LOCAL_DAGISEL_STRINGIZE_(X) #X\n";1308OS << "static_assert(sizeof(LOCAL_DAGISEL_STRINGIZE(GET_DAGISEL_BODY)) > 1,"1309"\n";1310OS << " \"GET_DAGISEL_BODY is empty: it should be defined with the class "1311"name\");\n";1312OS << "#undef LOCAL_DAGISEL_STRINGIZE_\n";1313OS << "#undef LOCAL_DAGISEL_STRINGIZE\n";1314OS << "#endif\n\n";13151316OS << "#if !defined(GET_DAGISEL_DECL) && !defined(GET_DAGISEL_BODY)\n";1317OS << "#define DAGISEL_INLINE 1\n";1318OS << "#else\n";1319OS << "#define DAGISEL_INLINE 0\n";1320OS << "#endif\n\n";13211322OS << "#if !DAGISEL_INLINE\n";1323OS << "#define DAGISEL_CLASS_COLONCOLON GET_DAGISEL_BODY ::\n";1324OS << "#else\n";1325OS << "#define DAGISEL_CLASS_COLONCOLON\n";1326OS << "#endif\n\n";13271328BeginEmitFunction(OS, "void", "SelectCode(SDNode *N)", false /*AddOverride*/);1329MatcherTableEmitter MatcherEmitter(TheMatcher, CGP);13301331// First we size all the children of the three kinds of matchers that have1332// them. This is done by sharing the code in EmitMatcher(). but we don't1333// want to emit anything, so we turn off comments and use a null stream.1334bool SaveOmitComments = OmitComments;1335OmitComments = true;1336raw_null_ostream NullOS;1337unsigned TotalSize = MatcherEmitter.SizeMatcherList(TheMatcher, NullOS);1338OmitComments = SaveOmitComments;13391340// Now that the matchers are sized, we can emit the code for them to the1341// final stream.1342OS << "{\n";1343OS << " // Some target values are emitted as 2 bytes, TARGET_VAL handles\n";1344OS << " // this.\n";1345OS << " #define TARGET_VAL(X) X & 255, unsigned(X) >> 8\n";1346OS << " static const unsigned char MatcherTable[] = {\n";1347TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 1, 0, OS);1348OS << " 0\n }; // Total Array size is " << (TotalSize + 1)1349<< " bytes\n\n";13501351MatcherEmitter.EmitHistogram(TheMatcher, OS);13521353OS << " #undef TARGET_VAL\n";1354OS << " SelectCodeCommon(N, MatcherTable, sizeof(MatcherTable));\n";1355OS << "}\n";1356EndEmitFunction(OS);13571358// Next up, emit the function for node and pattern predicates:1359MatcherEmitter.EmitPredicateFunctions(OS);13601361if (InstrumentCoverage)1362MatcherEmitter.EmitPatternMatchTable(OS);13631364// Clean up the preprocessor macros.1365OS << "\n";1366OS << "#ifdef DAGISEL_INLINE\n";1367OS << "#undef DAGISEL_INLINE\n";1368OS << "#endif\n";1369OS << "#ifdef DAGISEL_CLASS_COLONCOLON\n";1370OS << "#undef DAGISEL_CLASS_COLONCOLON\n";1371OS << "#endif\n";1372OS << "#ifdef GET_DAGISEL_DECL\n";1373OS << "#undef GET_DAGISEL_DECL\n";1374OS << "#endif\n";1375OS << "#ifdef GET_DAGISEL_BODY\n";1376OS << "#undef GET_DAGISEL_BODY\n";1377OS << "#endif\n";1378}137913801381