llvm.org GIT mirror llvm / release_38 lib / Analysis / CFGPrinter.cpp
release_38

Tree @release_38 (Download .tar.gz)

CFGPrinter.cpp @release_38

002362c
2b37d7c
002362c
 
4ee451d
 
2b37d7c
002362c
 
3ee8fc9
002362c
 
 
 
 
 
 
 
 
c6e2d8a
88067b9
7259f14
1ca2a58
d0fde30
002362c
6726b6d
a196b99
081c34b
 
 
1cee94f
c37e6c0
a196b99
 
 
 
570e52c
a196b99
c37e6c0
a196b99
 
 
cd52a7a
a196b99
844731a
ce665bd
a196b99
844731a
6726b6d
a196b99
081c34b
 
 
1cee94f
c37e6c0
ad38936
a196b99
 
 
570e52c
a196b99
c37e6c0
a196b99
 
 
cd52a7a
a196b99
844731a
d8cc7be
ce665bd
a196b99
844731a
6726b6d
ecd94c8
081c34b
 
 
1cee94f
c37e6c0
2a9bbcb
103289e
2b37d7c
8c96862
 
 
 
002362c
 
103289e
 
002362c
 
 
570e52c
2b37d7c
c37e6c0
002362c
 
 
cd52a7a
002362c
844731a
02dd53e
ce665bd
1ca2a58
844731a
6726b6d
ecd94c8
081c34b
 
 
c37e6c0
 
2a9bbcb
103289e
8cbc94a
8c96862
 
 
 
8cbc94a
 
103289e
 
1ca2a58
 
570e52c
2b37d7c
c37e6c0
1ca2a58
 
 
cd52a7a
002362c
844731a
02dd53e
 
ce665bd
844731a
002362c
 
 
 
 
 
25ad1cc
002362c
 
 
 
68c7a1c
 
002362c
 
25ad1cc
002362c
c6e2d8a
 
 
 
 
 
 
 
 
//===- CFGPrinter.cpp - DOT printer for the control flow graph ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a '-dot-cfg' analysis pass, which emits the
// cfg.<fnname>.dot file for each function in the program, with a graph of the
// CFG for that function.
//
// The other main feature of this file is that it implements the
// Function::viewCFG method, which is useful for debugging passes which operate
// on the CFG.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Pass.h"
#include "llvm/Support/FileSystem.h"
using namespace llvm;

namespace {
  struct CFGViewer : public FunctionPass {
    static char ID; // Pass identifcation, replacement for typeid
    CFGViewer() : FunctionPass(ID) {
      initializeCFGOnlyViewerPass(*PassRegistry::getPassRegistry());
    }

    bool runOnFunction(Function &F) override {
      F.viewCFG();
      return false;
    }

    void print(raw_ostream &OS, const Module* = nullptr) const override {}

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.setPreservesAll();
    }
  };
}

char CFGViewer::ID = 0;
INITIALIZE_PASS(CFGViewer, "view-cfg", "View CFG of function", false, true)

namespace {
  struct CFGOnlyViewer : public FunctionPass {
    static char ID; // Pass identifcation, replacement for typeid
    CFGOnlyViewer() : FunctionPass(ID) {
      initializeCFGOnlyViewerPass(*PassRegistry::getPassRegistry());
    }

    bool runOnFunction(Function &F) override {
      F.viewCFGOnly();
      return false;
    }

    void print(raw_ostream &OS, const Module* = nullptr) const override {}

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.setPreservesAll();
    }
  };
}

char CFGOnlyViewer::ID = 0;
INITIALIZE_PASS(CFGOnlyViewer, "view-cfg-only",
                "View CFG of function (with no function bodies)", false, true)

namespace {
  struct CFGPrinter : public FunctionPass {
    static char ID; // Pass identification, replacement for typeid
    CFGPrinter() : FunctionPass(ID) {
      initializeCFGPrinterPass(*PassRegistry::getPassRegistry());
    }

    bool runOnFunction(Function &F) override {
      std::string Filename = ("cfg." + F.getName() + ".dot").str();
      errs() << "Writing '" << Filename << "'...";

      std::error_code EC;
      raw_fd_ostream File(Filename, EC, sys::fs::F_Text);

      if (!EC)
        WriteGraph(File, (const Function*)&F);
      else
        errs() << "  error opening file for writing!";
      errs() << "\n";
      return false;
    }

    void print(raw_ostream &OS, const Module* = nullptr) const override {}

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.setPreservesAll();
    }
  };
}

char CFGPrinter::ID = 0;
INITIALIZE_PASS(CFGPrinter, "dot-cfg", "Print CFG of function to 'dot' file", 
                false, true)

namespace {
  struct CFGOnlyPrinter : public FunctionPass {
    static char ID; // Pass identification, replacement for typeid
    CFGOnlyPrinter() : FunctionPass(ID) {
      initializeCFGOnlyPrinterPass(*PassRegistry::getPassRegistry());
    }

    bool runOnFunction(Function &F) override {
      std::string Filename = ("cfg." + F.getName() + ".dot").str();
      errs() << "Writing '" << Filename << "'...";

      std::error_code EC;
      raw_fd_ostream File(Filename, EC, sys::fs::F_Text);

      if (!EC)
        WriteGraph(File, (const Function*)&F, true);
      else
        errs() << "  error opening file for writing!";
      errs() << "\n";
      return false;
    }
    void print(raw_ostream &OS, const Module* = nullptr) const override {}

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.setPreservesAll();
    }
  };
}

char CFGOnlyPrinter::ID = 0;
INITIALIZE_PASS(CFGOnlyPrinter, "dot-cfg-only",
   "Print CFG of function to 'dot' file (with no function bodies)",
   false, true)

/// viewCFG - This function is meant for use from the debugger.  You can just
/// say 'call F->viewCFG()' and a ghostview window should pop up from the
/// program, displaying the CFG of the current function.  This depends on there
/// being a 'dot' and 'gv' program in your path.
///
void Function::viewCFG() const {
  ViewGraph(this, "cfg" + getName());
}

/// viewCFGOnly - This function is meant for use from the debugger.  It works
/// just like viewCFG, but it does not include the contents of basic blocks
/// into the nodes, just the label.  If you are only interested in the CFG
/// this can make the graph smaller.
///
void Function::viewCFGOnly() const {
  ViewGraph(this, "cfg" + getName(), true);
}

FunctionPass *llvm::createCFGPrinterPass () {
  return new CFGPrinter();
}

FunctionPass *llvm::createCFGOnlyPrinterPass () {
  return new CFGOnlyPrinter();
}