CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
175 lines
6.3 KiB
C++
175 lines
6.3 KiB
C++
//===- DDGPrinter.cpp - DOT printer for the data dependence graph ----------==//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the `-dot-ddg` analysis pass, which emits DDG in DOT format
|
|
// in a file named `ddg.<graph-name>.dot` for each loop in a function.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Analysis/DDGPrinter.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/GraphWriter.h"
|
|
|
|
using namespace llvm;
|
|
|
|
static cl::opt<bool> DotOnly("dot-ddg-only", cl::Hidden,
|
|
cl::desc("simple ddg dot graph"));
|
|
static cl::opt<std::string> DDGDotFilenamePrefix(
|
|
"dot-ddg-filename-prefix", cl::init("ddg"), cl::Hidden,
|
|
cl::desc("The prefix used for the DDG dot file names."));
|
|
|
|
static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly = false);
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
// Implementation of DDG DOT Printer for a loop
|
|
//===--------------------------------------------------------------------===//
|
|
PreservedAnalyses DDGDotPrinterPass::run(Loop &L, LoopAnalysisManager &AM,
|
|
LoopStandardAnalysisResults &AR,
|
|
LPMUpdater &U) {
|
|
writeDDGToDotFile(*AM.getResult<DDGAnalysis>(L, AR), DotOnly);
|
|
return PreservedAnalyses::all();
|
|
}
|
|
|
|
static void writeDDGToDotFile(DataDependenceGraph &G, bool DOnly) {
|
|
std::string Filename =
|
|
Twine(DDGDotFilenamePrefix + "." + G.getName() + ".dot").str();
|
|
errs() << "Writing '" << Filename << "'...";
|
|
|
|
std::error_code EC;
|
|
raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);
|
|
|
|
if (!EC)
|
|
// We only provide the constant verson of the DOTGraphTrait specialization,
|
|
// hence the conversion to const pointer
|
|
WriteGraph(File, (const DataDependenceGraph *)&G, DOnly);
|
|
else
|
|
errs() << " error opening file for writing!";
|
|
errs() << "\n";
|
|
}
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
// DDG DOT Printer Implementation
|
|
//===--------------------------------------------------------------------===//
|
|
std::string DDGDotGraphTraits::getNodeLabel(const DDGNode *Node,
|
|
const DataDependenceGraph *Graph) {
|
|
if (isSimple())
|
|
return getSimpleNodeLabel(Node, Graph);
|
|
else
|
|
return getVerboseNodeLabel(Node, Graph);
|
|
}
|
|
|
|
std::string DDGDotGraphTraits::getEdgeAttributes(
|
|
const DDGNode *Node, GraphTraits<const DDGNode *>::ChildIteratorType I,
|
|
const DataDependenceGraph *G) {
|
|
const DDGEdge *E = static_cast<const DDGEdge *>(*I.getCurrent());
|
|
if (isSimple())
|
|
return getSimpleEdgeAttributes(Node, E, G);
|
|
else
|
|
return getVerboseEdgeAttributes(Node, E, G);
|
|
}
|
|
|
|
bool DDGDotGraphTraits::isNodeHidden(const DDGNode *Node,
|
|
const DataDependenceGraph *Graph) {
|
|
if (isSimple() && isa<RootDDGNode>(Node))
|
|
return true;
|
|
assert(Graph && "expected a valid graph pointer");
|
|
return Graph->getPiBlock(*Node) != nullptr;
|
|
}
|
|
|
|
std::string DDGDotGraphTraits::getNodeAttributes(const DDGNode *Node,
|
|
const DataDependenceGraph *) {
|
|
if (isa<PiBlockDDGNode>(Node))
|
|
return "shape=box, style=\"rounded,filled\", fillcolor=lightyellow, "
|
|
"color=darkorange, penwidth=3";
|
|
if (isa<SimpleDDGNode>(Node) &&
|
|
Node->getKind() == DDGNode::NodeKind::MultiInstruction)
|
|
return "style=filled, fillcolor=lightcyan";
|
|
return "";
|
|
}
|
|
|
|
std::string
|
|
DDGDotGraphTraits::getSimpleNodeLabel(const DDGNode *Node,
|
|
const DataDependenceGraph *G) {
|
|
std::string Str;
|
|
raw_string_ostream OS(Str);
|
|
if (isa<SimpleDDGNode>(Node))
|
|
for (auto *II : static_cast<const SimpleDDGNode *>(Node)->getInstructions())
|
|
OS << *II << "\n";
|
|
else if (isa<PiBlockDDGNode>(Node))
|
|
OS << "pi-block\nwith\n"
|
|
<< cast<PiBlockDDGNode>(Node)->getNodes().size() << " nodes\n";
|
|
else if (isa<RootDDGNode>(Node))
|
|
OS << "root\n";
|
|
else
|
|
llvm_unreachable("Unimplemented type of node");
|
|
return OS.str();
|
|
}
|
|
|
|
std::string
|
|
DDGDotGraphTraits::getVerboseNodeLabel(const DDGNode *Node,
|
|
const DataDependenceGraph *G) {
|
|
std::string Str;
|
|
raw_string_ostream OS(Str);
|
|
OS << "<kind:" << Node->getKind() << ">\n";
|
|
if (isa<SimpleDDGNode>(Node))
|
|
for (auto *II : static_cast<const SimpleDDGNode *>(Node)->getInstructions())
|
|
OS << *II << "\n";
|
|
else if (isa<PiBlockDDGNode>(Node)) {
|
|
OS << "--- start of nodes in pi-block ---\n";
|
|
unsigned Count = 0;
|
|
const auto &PNodes = cast<PiBlockDDGNode>(Node)->getNodes();
|
|
for (auto *PN : PNodes) {
|
|
OS << getVerboseNodeLabel(PN, G);
|
|
if (++Count != PNodes.size())
|
|
OS << "\n";
|
|
}
|
|
OS << "--- end of nodes in pi-block ---\n";
|
|
} else if (isa<RootDDGNode>(Node))
|
|
OS << "root\n";
|
|
else
|
|
llvm_unreachable("Unimplemented type of node");
|
|
return OS.str();
|
|
}
|
|
|
|
/// EdgeKind to DOT color mapping:
|
|
/// - MemoryDependence: red
|
|
/// - RegisterDefUse: blue
|
|
/// - Rooted/Unknown=default (no attribute).
|
|
static void writeEdgeKindColorAttr(raw_ostream &OS, DDGEdge::EdgeKind Kind) {
|
|
if (Kind == DDGEdge::EdgeKind::MemoryDependence)
|
|
OS << ", color=red";
|
|
else if (Kind == DDGEdge::EdgeKind::RegisterDefUse)
|
|
OS << ", color=blue";
|
|
}
|
|
|
|
std::string DDGDotGraphTraits::getSimpleEdgeAttributes(
|
|
const DDGNode *Src, const DDGEdge *Edge, const DataDependenceGraph *G) {
|
|
std::string Str;
|
|
raw_string_ostream OS(Str);
|
|
DDGEdge::EdgeKind Kind = Edge->getKind();
|
|
OS << "label=\"[" << Kind << "]\"";
|
|
writeEdgeKindColorAttr(OS, Kind);
|
|
return OS.str();
|
|
}
|
|
|
|
std::string DDGDotGraphTraits::getVerboseEdgeAttributes(
|
|
const DDGNode *Src, const DDGEdge *Edge, const DataDependenceGraph *G) {
|
|
std::string Str;
|
|
raw_string_ostream OS(Str);
|
|
DDGEdge::EdgeKind Kind = Edge->getKind();
|
|
OS << "label=\"[";
|
|
if (Kind == DDGEdge::EdgeKind::MemoryDependence)
|
|
OS << G->getDependenceString(*Src, Edge->getTargetNode());
|
|
else
|
|
OS << Kind;
|
|
OS << "]\"";
|
|
writeEdgeKindColorAttr(OS, Kind);
|
|
return OS.str();
|
|
}
|