123279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser//===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===// 223279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser// 323279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser// The LLVM Compiler Infrastructure 423279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser// 523279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser// This file is distributed under the University of Illinois Open Source 623279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser// License. See LICENSE.TXT for details. 723279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser// 823279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser//===----------------------------------------------------------------------===// 923279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser// 1023279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser// Templates to create dotty viewer and printer passes for GraphTraits graphs. 1123279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser// 1223279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser//===----------------------------------------------------------------------===// 1323279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 14674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H 15674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H 1623279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 1723279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser#include "llvm/Analysis/CFGPrinter.h" 18255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth#include "llvm/Pass.h" 19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/FileSystem.h" 2023279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 2123279f18a9759d94579de7e79be61c7aa790b8baTobias Grossernamespace llvm { 2223279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Default traits class for extracting a graph from an analysis pass. 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through. 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <typename AnalysisT, typename GraphT = AnalysisT *> 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstruct DefaultAnalysisGraphTraits { 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static GraphT getGraph(AnalysisT *A) { return A; } 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate < 3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 34a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickclass DOTGraphTraitsViewer : public FunctionPass { 35a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickpublic: 3696f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko DOTGraphTraitsViewer(StringRef GraphName, char &ID) 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : FunctionPass(ID), Name(GraphName) {} 3823279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &F) override { 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph); 42a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick std::string Title = GraphName + " for '" + F.getName().str() + "' function"; 43a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ViewGraph(Graph, Name, IsSimple, Title); 4523279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 4623279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser return false; 4723279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser } 4823279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 5023279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser AU.setPreservesAll(); 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addRequired<AnalysisT>(); 5223279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser } 53a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 54a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickprivate: 55a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick std::string Name; 5623279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser}; 5723279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate < 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 61a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickclass DOTGraphTraitsPrinter : public FunctionPass { 62a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickpublic: 6396f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko DOTGraphTraitsPrinter(StringRef GraphName, char &ID) 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : FunctionPass(ID), Name(GraphName) {} 65a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &F) override { 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 68a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick std::string Filename = Name + "." + F.getName().str() + ".dot"; 69a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick std::string ErrorInfo; 70a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 71a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick errs() << "Writing '" << Filename << "'..."; 72a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text); 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph); 75a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick std::string Title = GraphName + " for '" + F.getName().str() + "' function"; 76a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 77a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick if (ErrorInfo.empty()) 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines WriteGraph(File, Graph, IsSimple, Title); 79a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick else 80a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick errs() << " error opening file for writing!"; 81a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick errs() << "\n"; 82a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 83a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick return false; 84a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick } 85a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 87a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick AU.setPreservesAll(); 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addRequired<AnalysisT>(); 89a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick } 9023279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 91a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickprivate: 9223279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser std::string Name; 93a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick}; 94a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate < 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 98a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickclass DOTGraphTraitsModuleViewer : public ModulePass { 99a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickpublic: 10096f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID) 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : ModulePass(ID), Name(GraphName) {} 102a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override { 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph); 10623279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ViewGraph(Graph, Name, IsSimple, Title); 108a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 109a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick return false; 11023279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser } 11123279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 113a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick AU.setPreservesAll(); 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addRequired<AnalysisT>(); 115a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick } 11623279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 117a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickprivate: 118a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick std::string Name; 119a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick}; 120a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate < 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 124a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickclass DOTGraphTraitsModulePrinter : public ModulePass { 125a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickpublic: 12696f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID) 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : ModulePass(ID), Name(GraphName) {} 128a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override { 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 131a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick std::string Filename = Name + ".dot"; 13223279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser std::string ErrorInfo; 13323279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 134a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick errs() << "Writing '" << Filename << "'..."; 135a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text); 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph); 13823279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 13923279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser if (ErrorInfo.empty()) 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines WriteGraph(File, Graph, IsSimple, Title); 14123279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser else 14223279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser errs() << " error opening file for writing!"; 14323279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser errs() << "\n"; 144a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 14523279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser return false; 14623279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser } 14723279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 14923279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser AU.setPreservesAll(); 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addRequired<AnalysisT>(); 15123279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser } 152a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 153a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trickprivate: 154a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick std::string Name; 15523279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser}; 156a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 157a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick} // end namespace llvm 158a125cacf7d154d0e5cad47f011e619e45517c839Andrew Trick 15923279f18a9759d94579de7e79be61c7aa790b8baTobias Grosser#endif 160