Index: include/llvm/Analysis/RegionInfo.h =================================================================== --- include/llvm/Analysis/RegionInfo.h +++ include/llvm/Analysis/RegionInfo.h @@ -846,6 +846,19 @@ void recalculate(Function &F, DominatorTree *DT, PostDominatorTree *PDT, DominanceFrontier *DF); + +#ifndef NDEBUG + /// @brief Opens a viewer to show the GraphViz visualization of the regions. + /// + /// Useful during debugging as an alternative to dump(). + void view(); + + /// @brief Opens a viewer to show the GraphViz visalization of this region + /// without instructions in the BasicBlocks. + /// + /// Useful during debugging as an alternative to dump(). + void viewOnly(); +#endif }; class RegionInfoPass : public FunctionPass { Index: include/llvm/Analysis/RegionPrinter.h =================================================================== --- include/llvm/Analysis/RegionPrinter.h +++ include/llvm/Analysis/RegionPrinter.h @@ -17,10 +17,55 @@ namespace llvm { class FunctionPass; + class Function; + class RegionInfo; + FunctionPass *createRegionViewerPass(); FunctionPass *createRegionOnlyViewerPass(); FunctionPass *createRegionPrinterPass(); FunctionPass *createRegionOnlyPrinterPass(); + +#ifndef NDEBUG + /// @brief Open a viewer to display the GraphViz vizualization of the analysis + /// result. + /// + /// Practical to call in the debugger. + /// Includes the instructions in each BasicBlock. + /// + /// @param RI The analysis to display. + void viewRegion(llvm::RegionInfo *RI); + + /// @brief Analyze the regions of a function and open its GraphViz + /// visualization in a viewer. + /// + /// Useful to call in the debugger. + /// Includes the instructions in each BasicBlock. + /// The result of a new analysis may differ from the RegionInfo the pass + /// manager currently holds. + /// + /// @param F Function to analyze. + void viewRegion(const llvm::Function *F); + + /// @brief Open a viewer to display the GraphViz vizualization of the analysis + /// result. + /// + /// Useful to call in the debugger. + /// Shows only the BasicBlock names without their instructions. + /// + /// @param RI The analysis to display. + void viewRegionOnly(llvm::RegionInfo *RI); + + /// @brief Analyze the regions of a function and open its GraphViz + /// visualization in a viewer. + /// + /// Useful to call in the debugger. + /// Shows only the BasicBlock names without their instructions. + /// The result of a new analysis may differ from the RegionInfo the pass + /// manager currently holds. + /// + /// @param F Function to analyze. + void viewRegionOnly(const llvm::Function *F); +#endif } // End llvm namespace #endif Index: lib/Analysis/RegionInfo.cpp =================================================================== --- lib/Analysis/RegionInfo.cpp +++ lib/Analysis/RegionInfo.cpp @@ -21,6 +21,9 @@ #include #include #include +#ifndef NDEBUG +#include "llvm/Analysis/RegionPrinter.h" +#endif using namespace llvm; @@ -103,6 +106,12 @@ calculate(F); } +#ifndef NDEBUG +void RegionInfo::view() { viewRegion(this); } + +void RegionInfo::viewOnly() { viewRegionOnly(this); } +#endif + //===----------------------------------------------------------------------===// // RegionInfoPass implementation // Index: lib/Analysis/RegionPrinter.cpp =================================================================== --- lib/Analysis/RegionPrinter.cpp +++ lib/Analysis/RegionPrinter.cpp @@ -20,6 +20,9 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#ifndef NDEBUG +#include "llvm/IR/LegacyPassManager.h" +#endif using namespace llvm; @@ -224,3 +227,41 @@ return new RegionOnlyViewer(); } +#ifndef NDEBUG +static void viewRegionInfo(RegionInfo *RI, bool ShortNames) { + assert(RI && "Argument must be non-null"); + + llvm::Function *F = RI->getTopLevelRegion()->getEntry()->getParent(); + std::string GraphName = DOTGraphTraits::getGraphName(RI); + + llvm::ViewGraph(RI, "reg", ShortNames, + Twine(GraphName) + " for '" + F->getName() + "' function"); +} + +static void invokeFunctionPass(const Function *F, FunctionPass *ViewerPass) { + assert(F && "Argument must be non-null"); + assert(!F->isDeclaration() && "Function must have an implementation"); + + // The viewer and analysis passes do not modify anything, so we can safely + // remove the const qualifier + auto NonConstF = const_cast(F); + + llvm::legacy::FunctionPassManager FPM(NonConstF->getParent()); + FPM.add(ViewerPass); + FPM.doInitialization(); + FPM.run(*NonConstF); + FPM.doFinalization(); +} + +void llvm::viewRegion(RegionInfo *RI) { viewRegionInfo(RI, false); } + +void llvm::viewRegion(const Function *F) { + invokeFunctionPass(F, createRegionViewerPass()); +} + +void llvm::viewRegionOnly(RegionInfo *RI) { viewRegionInfo(RI, true); } + +void llvm::viewRegionOnly(const Function *F) { + invokeFunctionPass(F, createRegionOnlyViewerPass()); +} +#endif