123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- //===- GIMatchDag.cpp - A DAG representation of a pattern to be matched ---===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "GIMatchDag.h"
- #include "llvm/Support/Format.h"
- #include "llvm/TableGen/Record.h"
- #include "../CodeGenInstruction.h"
- using namespace llvm;
- void GIMatchDag::writeDOTGraph(raw_ostream &OS, StringRef ID) const {
- const auto writePorts = [&](StringRef Prefix,
- const GIMatchDagOperandList &Operands) {
- StringRef Separator = "";
- OS << "{";
- for (const auto &Op : enumerate(Operands)) {
- OS << Separator << "<" << Prefix << format("%d", Op.index()) << ">"
- << "#" << Op.index() << " $" << Op.value().getName();
- Separator = "|";
- }
- OS << "}";
- };
- OS << "digraph \"" << ID << "\" {\n"
- << " rankdir=\"BT\"\n";
- for (const auto &N : InstrNodes) {
- OS << " " << format("Node%p", &*N) << " [shape=record,label=\"{";
- writePorts("s", N->getOperandInfo());
- OS << "|" << N->getName();
- if (N->getOpcodeAnnotation())
- OS << "|" << N->getOpcodeAnnotation()->TheDef->getName();
- if (N->isMatchRoot())
- OS << "|Match starts here";
- OS << "|";
- SmallVector<std::pair<unsigned, StringRef>, 8> ToPrint;
- for (const auto &Assignment : N->user_assigned_operand_names())
- ToPrint.emplace_back(Assignment.first, Assignment.second);
- llvm::sort(ToPrint);
- StringRef Separator = "";
- for (const auto &Assignment : ToPrint) {
- OS << Separator << "$" << Assignment.second << "=getOperand("
- << Assignment.first << ")";
- Separator = ", ";
- }
- OS << format("|%p|", &N);
- writePorts("d", N->getOperandInfo());
- OS << "}\"";
- if (N->isMatchRoot())
- OS << ",color=red";
- OS << "]\n";
- }
- for (const auto &E : Edges) {
- const char *FromFmt = "Node%p:s%d:n";
- const char *ToFmt = "Node%p:d%d:s";
- if (E->getFromMO()->isDef() && !E->getToMO()->isDef())
- std::swap(FromFmt, ToFmt);
- auto From = format(FromFmt, E->getFromMI(), E->getFromMO()->getIdx());
- auto To = format(ToFmt, E->getToMI(), E->getToMO()->getIdx());
- if (E->getFromMO()->isDef() && !E->getToMO()->isDef())
- std::swap(From, To);
- OS << " " << From << " -> " << To << " [label=\"$" << E->getName();
- if (E->getFromMO()->isDef() == E->getToMO()->isDef())
- OS << " INVALID EDGE!";
- OS << "\"";
- if (E->getFromMO()->isDef() == E->getToMO()->isDef())
- OS << ",color=red";
- else if (E->getFromMO()->isDef() && !E->getToMO()->isDef())
- OS << ",dir=back,arrowtail=crow";
- OS << "]\n";
- }
- for (const auto &N : PredicateNodes) {
- OS << " " << format("Pred%p", &*N) << " [shape=record,label=\"{";
- writePorts("s", N->getOperandInfo());
- OS << "|" << N->getName() << "|";
- N->printDescription(OS);
- OS << format("|%p|", &N);
- writePorts("d", N->getOperandInfo());
- OS << "}\",style=dotted]\n";
- }
- for (const auto &E : PredicateDependencies) {
- const char *FromMIFmt = "Node%p:e";
- const char *FromMOFmt = "Node%p:s%d:n";
- const char *ToFmt = "Pred%p:d%d:s";
- auto To = format(ToFmt, E->getPredicate(), E->getPredicateOp()->getIdx());
- auto Style = "[style=dotted]";
- if (E->getRequiredMO()) {
- auto From =
- format(FromMOFmt, E->getRequiredMI(), E->getRequiredMO()->getIdx());
- OS << " " << From << " -> " << To << " " << Style << "\n";
- continue;
- }
- auto From = format(FromMIFmt, E->getRequiredMI());
- OS << " " << From << " -> " << To << " " << Style << "\n";
- }
- OS << "}\n";
- }
- LLVM_DUMP_METHOD void GIMatchDag::print(raw_ostream &OS) const {
- OS << "matchdag {\n";
- for (const auto &N : InstrNodes) {
- OS << " ";
- N->print(OS);
- OS << "\n";
- }
- for (const auto &E : Edges) {
- OS << " ";
- E->print(OS);
- OS << "\n";
- }
- for (const auto &P : PredicateNodes) {
- OS << " ";
- P->print(OS);
- OS << "\n";
- }
- for (const auto &D : PredicateDependencies) {
- OS << " ";
- D->print(OS);
- OS << "\n";
- }
- OS << "}\n";
- }
- raw_ostream &llvm::operator<<(raw_ostream &OS, const GIMatchDag &G) {
- G.print(OS);
- return OS;
- }
|