GIMatchDag.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //===- GIMatchDag.cpp - A DAG representation of a pattern to be matched ---===//
  2. //
  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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "GIMatchDag.h"
  9. #include "llvm/Support/Format.h"
  10. #include "llvm/TableGen/Record.h"
  11. #include "../CodeGenInstruction.h"
  12. using namespace llvm;
  13. void GIMatchDag::writeDOTGraph(raw_ostream &OS, StringRef ID) const {
  14. const auto writePorts = [&](StringRef Prefix,
  15. const GIMatchDagOperandList &Operands) {
  16. StringRef Separator = "";
  17. OS << "{";
  18. for (const auto &Op : enumerate(Operands)) {
  19. OS << Separator << "<" << Prefix << format("%d", Op.index()) << ">"
  20. << "#" << Op.index() << " $" << Op.value().getName();
  21. Separator = "|";
  22. }
  23. OS << "}";
  24. };
  25. OS << "digraph \"" << ID << "\" {\n"
  26. << " rankdir=\"BT\"\n";
  27. for (const auto &N : InstrNodes) {
  28. OS << " " << format("Node%p", &*N) << " [shape=record,label=\"{";
  29. writePorts("s", N->getOperandInfo());
  30. OS << "|" << N->getName();
  31. if (N->getOpcodeAnnotation())
  32. OS << "|" << N->getOpcodeAnnotation()->TheDef->getName();
  33. if (N->isMatchRoot())
  34. OS << "|Match starts here";
  35. OS << "|";
  36. SmallVector<std::pair<unsigned, StringRef>, 8> ToPrint;
  37. for (const auto &Assignment : N->user_assigned_operand_names())
  38. ToPrint.emplace_back(Assignment.first, Assignment.second);
  39. llvm::sort(ToPrint);
  40. StringRef Separator = "";
  41. for (const auto &Assignment : ToPrint) {
  42. OS << Separator << "$" << Assignment.second << "=getOperand("
  43. << Assignment.first << ")";
  44. Separator = ", ";
  45. }
  46. OS << llvm::format("|%p|", &N);
  47. writePorts("d", N->getOperandInfo());
  48. OS << "}\"";
  49. if (N->isMatchRoot())
  50. OS << ",color=red";
  51. OS << "]\n";
  52. }
  53. for (const auto &E : Edges) {
  54. const char *FromFmt = "Node%p:s%d:n";
  55. const char *ToFmt = "Node%p:d%d:s";
  56. if (E->getFromMO()->isDef() && !E->getToMO()->isDef())
  57. std::swap(FromFmt, ToFmt);
  58. auto From = format(FromFmt, E->getFromMI(), E->getFromMO()->getIdx());
  59. auto To = format(ToFmt, E->getToMI(), E->getToMO()->getIdx());
  60. if (E->getFromMO()->isDef() && !E->getToMO()->isDef())
  61. std::swap(From, To);
  62. OS << " " << From << " -> " << To << " [label=\"$" << E->getName();
  63. if (E->getFromMO()->isDef() == E->getToMO()->isDef())
  64. OS << " INVALID EDGE!";
  65. OS << "\"";
  66. if (E->getFromMO()->isDef() == E->getToMO()->isDef())
  67. OS << ",color=red";
  68. else if (E->getFromMO()->isDef() && !E->getToMO()->isDef())
  69. OS << ",dir=back,arrowtail=crow";
  70. OS << "]\n";
  71. }
  72. for (const auto &N : PredicateNodes) {
  73. OS << " " << format("Pred%p", &*N) << " [shape=record,label=\"{";
  74. writePorts("s", N->getOperandInfo());
  75. OS << "|" << N->getName() << "|";
  76. N->printDescription(OS);
  77. OS << llvm::format("|%p|", &N);
  78. writePorts("d", N->getOperandInfo());
  79. OS << "}\",style=dotted]\n";
  80. }
  81. for (const auto &E : PredicateDependencies) {
  82. const char *FromMIFmt = "Node%p:e";
  83. const char *FromMOFmt = "Node%p:s%d:n";
  84. const char *ToFmt = "Pred%p:d%d:s";
  85. auto To = format(ToFmt, E->getPredicate(), E->getPredicateOp()->getIdx());
  86. auto Style = "[style=dotted]";
  87. if (E->getRequiredMO()) {
  88. auto From =
  89. format(FromMOFmt, E->getRequiredMI(), E->getRequiredMO()->getIdx());
  90. OS << " " << From << " -> " << To << " " << Style << "\n";
  91. continue;
  92. }
  93. auto From = format(FromMIFmt, E->getRequiredMI());
  94. OS << " " << From << " -> " << To << " " << Style << "\n";
  95. }
  96. OS << "}\n";
  97. }
  98. LLVM_DUMP_METHOD void GIMatchDag::print(raw_ostream &OS) const {
  99. OS << "matchdag {\n";
  100. for (const auto &N : InstrNodes) {
  101. OS << " ";
  102. N->print(OS);
  103. OS << "\n";
  104. }
  105. for (const auto &E : Edges) {
  106. OS << " ";
  107. E->print(OS);
  108. OS << "\n";
  109. }
  110. for (const auto &P : PredicateNodes) {
  111. OS << " ";
  112. P->print(OS);
  113. OS << "\n";
  114. }
  115. for (const auto &D : PredicateDependencies) {
  116. OS << " ";
  117. D->print(OS);
  118. OS << "\n";
  119. }
  120. OS << "}\n";
  121. }
  122. raw_ostream &llvm::operator<<(raw_ostream &OS, const GIMatchDag &G) {
  123. G.print(OS);
  124. return OS;
  125. }