1 //===- GIMatchDag.cpp - A DAG representation of a pattern to be matched ---===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "GIMatchDag.h"
11 #include "llvm/Support/Format.h"
12 #include "llvm/TableGen/Record.h"
13 #include "../CodeGenInstruction.h"
17 void GIMatchDag::writeDOTGraph(raw_ostream
&OS
, StringRef ID
) const {
18 const auto writePorts
= [&](StringRef Prefix
,
19 const GIMatchDagOperandList
&Operands
) {
20 StringRef Separator
= "";
22 for (const auto &Op
: enumerate(Operands
)) {
23 OS
<< Separator
<< "<" << Prefix
<< format("%d", Op
.index()) << ">"
24 << "#" << Op
.index() << " $" << Op
.value().getName();
30 OS
<< "digraph \"" << ID
<< "\" {\n"
31 << " rankdir=\"BT\"\n";
32 for (const auto &N
: InstrNodes
) {
33 OS
<< " " << format("Node%p", &*N
) << " [shape=record,label=\"{";
34 writePorts("s", N
->getOperandInfo());
35 OS
<< "|" << N
->getName();
36 if (N
->getOpcodeAnnotation())
37 OS
<< "|" << N
->getOpcodeAnnotation()->TheDef
->getName();
39 OS
<< "|Match starts here";
41 SmallVector
<std::pair
<unsigned, StringRef
>, 8> ToPrint
;
42 for (const auto &Assignment
: N
->user_assigned_operand_names())
43 ToPrint
.emplace_back(Assignment
.first
, Assignment
.second
);
45 StringRef Separator
= "";
46 for (const auto &Assignment
: ToPrint
) {
47 OS
<< Separator
<< "$" << Assignment
.second
<< "=getOperand("
48 << Assignment
.first
<< ")";
51 OS
<< format("|%p|", &N
);
52 writePorts("d", N
->getOperandInfo());
59 for (const auto &E
: Edges
) {
60 const char *FromFmt
= "Node%p:s%d:n";
61 const char *ToFmt
= "Node%p:d%d:s";
62 if (E
->getFromMO()->isDef() && !E
->getToMO()->isDef())
63 std::swap(FromFmt
, ToFmt
);
64 auto From
= format(FromFmt
, E
->getFromMI(), E
->getFromMO()->getIdx());
65 auto To
= format(ToFmt
, E
->getToMI(), E
->getToMO()->getIdx());
66 if (E
->getFromMO()->isDef() && !E
->getToMO()->isDef())
69 OS
<< " " << From
<< " -> " << To
<< " [label=\"$" << E
->getName();
70 if (E
->getFromMO()->isDef() == E
->getToMO()->isDef())
71 OS
<< " INVALID EDGE!";
73 if (E
->getFromMO()->isDef() == E
->getToMO()->isDef())
75 else if (E
->getFromMO()->isDef() && !E
->getToMO()->isDef())
76 OS
<< ",dir=back,arrowtail=crow";
80 for (const auto &N
: PredicateNodes
) {
81 OS
<< " " << format("Pred%p", &*N
) << " [shape=record,label=\"{";
82 writePorts("s", N
->getOperandInfo());
83 OS
<< "|" << N
->getName() << "|";
84 N
->printDescription(OS
);
85 OS
<< format("|%p|", &N
);
86 writePorts("d", N
->getOperandInfo());
87 OS
<< "}\",style=dotted]\n";
90 for (const auto &E
: PredicateDependencies
) {
91 const char *FromMIFmt
= "Node%p:e";
92 const char *FromMOFmt
= "Node%p:s%d:n";
93 const char *ToFmt
= "Pred%p:d%d:s";
94 auto To
= format(ToFmt
, E
->getPredicate(), E
->getPredicateOp()->getIdx());
95 auto Style
= "[style=dotted]";
96 if (E
->getRequiredMO()) {
98 format(FromMOFmt
, E
->getRequiredMI(), E
->getRequiredMO()->getIdx());
99 OS
<< " " << From
<< " -> " << To
<< " " << Style
<< "\n";
102 auto From
= format(FromMIFmt
, E
->getRequiredMI());
103 OS
<< " " << From
<< " -> " << To
<< " " << Style
<< "\n";
109 LLVM_DUMP_METHOD
void GIMatchDag::print(raw_ostream
&OS
) const {
110 OS
<< "matchdag {\n";
111 for (const auto &N
: InstrNodes
) {
116 for (const auto &E
: Edges
) {
122 for (const auto &P
: PredicateNodes
) {
127 for (const auto &D
: PredicateDependencies
) {
135 raw_ostream
&llvm::operator<<(raw_ostream
&OS
, const GIMatchDag
&G
) {