227 lines · cpp
1//===- DomPrinter.cpp - DOT printer for the dominance trees ------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit10// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the11// program, with a graph of the dominance/postdominance tree of that12// function.13//14// There are also passes available to directly call dotty ('-view-dom' or15// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the16// names of the bbs are printed, but the content is hidden.17//18//===----------------------------------------------------------------------===//19 20#include "llvm/Analysis/DomPrinter.h"21#include "llvm/Analysis/DOTGraphTraitsPass.h"22#include "llvm/Analysis/PostDominators.h"23#include "llvm/InitializePasses.h"24 25using namespace llvm;26 27 28void DominatorTree::viewGraph(const Twine &Name, const Twine &Title) {29#ifndef NDEBUG30 ViewGraph(this, Name, false, Title);31#else32 errs() << "DomTree dump not available, build with DEBUG\n";33#endif // NDEBUG34}35 36void DominatorTree::viewGraph() {37#ifndef NDEBUG38 this->viewGraph("domtree", "Dominator Tree for function");39#else40 errs() << "DomTree dump not available, build with DEBUG\n";41#endif // NDEBUG42}43 44namespace {45struct LegacyDominatorTreeWrapperPassAnalysisGraphTraits {46 static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {47 return &DTWP->getDomTree();48 }49};50 51struct DomViewerWrapperPass52 : public DOTGraphTraitsViewerWrapperPass<53 DominatorTreeWrapperPass, false, DominatorTree *,54 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {55 static char ID;56 DomViewerWrapperPass()57 : DOTGraphTraitsViewerWrapperPass<58 DominatorTreeWrapperPass, false, DominatorTree *,59 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {}60};61 62struct DomOnlyViewerWrapperPass63 : public DOTGraphTraitsViewerWrapperPass<64 DominatorTreeWrapperPass, true, DominatorTree *,65 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {66 static char ID;67 DomOnlyViewerWrapperPass()68 : DOTGraphTraitsViewerWrapperPass<69 DominatorTreeWrapperPass, true, DominatorTree *,70 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {}71};72 73struct LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits {74 static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {75 return &PDTWP->getPostDomTree();76 }77};78 79struct PostDomViewerWrapperPass80 : public DOTGraphTraitsViewerWrapperPass<81 PostDominatorTreeWrapperPass, false, PostDominatorTree *,82 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {83 static char ID;84 PostDomViewerWrapperPass()85 : DOTGraphTraitsViewerWrapperPass<86 PostDominatorTreeWrapperPass, false, PostDominatorTree *,87 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom",88 ID) {}89};90 91struct PostDomOnlyViewerWrapperPass92 : public DOTGraphTraitsViewerWrapperPass<93 PostDominatorTreeWrapperPass, true, PostDominatorTree *,94 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {95 static char ID;96 PostDomOnlyViewerWrapperPass()97 : DOTGraphTraitsViewerWrapperPass<98 PostDominatorTreeWrapperPass, true, PostDominatorTree *,99 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>(100 "postdomonly", ID) {}101};102} // end anonymous namespace103 104char DomViewerWrapperPass::ID = 0;105INITIALIZE_PASS(DomViewerWrapperPass, "view-dom",106 "View dominance tree of function", false, false)107 108char DomOnlyViewerWrapperPass::ID = 0;109INITIALIZE_PASS(DomOnlyViewerWrapperPass, "view-dom-only",110 "View dominance tree of function (with no function bodies)",111 false, false)112 113char PostDomViewerWrapperPass::ID = 0;114INITIALIZE_PASS(PostDomViewerWrapperPass, "view-postdom",115 "View postdominance tree of function", false, false)116 117char PostDomOnlyViewerWrapperPass::ID = 0;118INITIALIZE_PASS(PostDomOnlyViewerWrapperPass, "view-postdom-only",119 "View postdominance tree of function "120 "(with no function bodies)",121 false, false)122 123namespace {124struct DomPrinterWrapperPass125 : public DOTGraphTraitsPrinterWrapperPass<126 DominatorTreeWrapperPass, false, DominatorTree *,127 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {128 static char ID;129 DomPrinterWrapperPass()130 : DOTGraphTraitsPrinterWrapperPass<131 DominatorTreeWrapperPass, false, DominatorTree *,132 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {}133};134 135struct DomOnlyPrinterWrapperPass136 : public DOTGraphTraitsPrinterWrapperPass<137 DominatorTreeWrapperPass, true, DominatorTree *,138 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {139 static char ID;140 DomOnlyPrinterWrapperPass()141 : DOTGraphTraitsPrinterWrapperPass<142 DominatorTreeWrapperPass, true, DominatorTree *,143 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {}144};145 146struct PostDomPrinterWrapperPass147 : public DOTGraphTraitsPrinterWrapperPass<148 PostDominatorTreeWrapperPass, false, PostDominatorTree *,149 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {150 static char ID;151 PostDomPrinterWrapperPass()152 : DOTGraphTraitsPrinterWrapperPass<153 PostDominatorTreeWrapperPass, false, PostDominatorTree *,154 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom",155 ID) {}156};157 158struct PostDomOnlyPrinterWrapperPass159 : public DOTGraphTraitsPrinterWrapperPass<160 PostDominatorTreeWrapperPass, true, PostDominatorTree *,161 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {162 static char ID;163 PostDomOnlyPrinterWrapperPass()164 : DOTGraphTraitsPrinterWrapperPass<165 PostDominatorTreeWrapperPass, true, PostDominatorTree *,166 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>(167 "postdomonly", ID) {}168};169} // end anonymous namespace170 171char DomPrinterWrapperPass::ID = 0;172INITIALIZE_PASS(DomPrinterWrapperPass, "dot-dom",173 "Print dominance tree of function to 'dot' file", false, false)174 175char DomOnlyPrinterWrapperPass::ID = 0;176INITIALIZE_PASS(DomOnlyPrinterWrapperPass, "dot-dom-only",177 "Print dominance tree of function to 'dot' file "178 "(with no function bodies)",179 false, false)180 181char PostDomPrinterWrapperPass::ID = 0;182INITIALIZE_PASS(PostDomPrinterWrapperPass, "dot-postdom",183 "Print postdominance tree of function to 'dot' file", false,184 false)185 186char PostDomOnlyPrinterWrapperPass::ID = 0;187INITIALIZE_PASS(PostDomOnlyPrinterWrapperPass, "dot-postdom-only",188 "Print postdominance tree of function to 'dot' file "189 "(with no function bodies)",190 false, false)191 192// Create methods available outside of this file, to use them193// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by194// the link time optimization.195 196FunctionPass *llvm::createDomPrinterWrapperPassPass() {197 return new DomPrinterWrapperPass();198}199 200FunctionPass *llvm::createDomOnlyPrinterWrapperPassPass() {201 return new DomOnlyPrinterWrapperPass();202}203 204FunctionPass *llvm::createDomViewerWrapperPassPass() {205 return new DomViewerWrapperPass();206}207 208FunctionPass *llvm::createDomOnlyViewerWrapperPassPass() {209 return new DomOnlyViewerWrapperPass();210}211 212FunctionPass *llvm::createPostDomPrinterWrapperPassPass() {213 return new PostDomPrinterWrapperPass();214}215 216FunctionPass *llvm::createPostDomOnlyPrinterWrapperPassPass() {217 return new PostDomOnlyPrinterWrapperPass();218}219 220FunctionPass *llvm::createPostDomViewerWrapperPassPass() {221 return new PostDomViewerWrapperPass();222}223 224FunctionPass *llvm::createPostDomOnlyViewerWrapperPassPass() {225 return new PostDomOnlyViewerWrapperPass();226}227