LCOV - code coverage report
Current view: top level - include/llvm/Analysis - CFGPrinter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 37 74 50.0 %
Date: 2017-09-14 15:23:50 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- CFGPrinter.h - CFG printer external interface -----------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file defines a 'dot-cfg' analysis pass, which emits the
      11             : // cfg.<fnname>.dot file for each function in the program, with a graph of the
      12             : // CFG for that function.
      13             : //
      14             : // This file defines external functions that can be called to explicitly
      15             : // instantiate the CFG printer.
      16             : //
      17             : //===----------------------------------------------------------------------===//
      18             : 
      19             : #ifndef LLVM_ANALYSIS_CFGPRINTER_H
      20             : #define LLVM_ANALYSIS_CFGPRINTER_H
      21             : 
      22             : #include "llvm/IR/CFG.h"
      23             : #include "llvm/IR/Constants.h"
      24             : #include "llvm/IR/Function.h"
      25             : #include "llvm/IR/Instructions.h"
      26             : #include "llvm/IR/PassManager.h"
      27             : #include "llvm/Support/GraphWriter.h"
      28             : 
      29             : namespace llvm {
      30             : class CFGViewerPass
      31             :     : public PassInfoMixin<CFGViewerPass> {
      32             : public:
      33             :   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
      34             : };
      35             : 
      36             : class CFGOnlyViewerPass
      37             :     : public PassInfoMixin<CFGOnlyViewerPass> {
      38             : public:
      39             :   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
      40             : };
      41             : 
      42             : class CFGPrinterPass
      43             :     : public PassInfoMixin<CFGPrinterPass> {
      44             : public:
      45             :   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
      46             : };
      47             : 
      48             : class CFGOnlyPrinterPass
      49             :     : public PassInfoMixin<CFGOnlyPrinterPass> {
      50             : public:
      51             :   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
      52             : };
      53             : 
      54             : template<>
      55             : struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
      56             : 
      57           8 :   DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
      58             : 
      59           2 :   static std::string getGraphName(const Function *F) {
      60           8 :     return "CFG for '" + F->getName().str() + "' function";
      61             :   }
      62             : 
      63           0 :   static std::string getSimpleNodeLabel(const BasicBlock *Node,
      64             :                                         const Function *) {
      65           0 :     if (!Node->getName().empty())
      66           0 :       return Node->getName().str();
      67             : 
      68           0 :     std::string Str;
      69           0 :     raw_string_ostream OS(Str);
      70             : 
      71           0 :     Node->printAsOperand(OS, false);
      72           0 :     return OS.str();
      73             :   }
      74             : 
      75          22 :   static std::string getCompleteNodeLabel(const BasicBlock *Node,
      76             :                                           const Function *) {
      77             :     enum { MaxColumns = 80 };
      78          44 :     std::string Str;
      79          44 :     raw_string_ostream OS(Str);
      80             : 
      81          44 :     if (Node->getName().empty()) {
      82           0 :       Node->printAsOperand(OS, false);
      83           0 :       OS << ":";
      84             :     }
      85             : 
      86          44 :     OS << *Node;
      87          44 :     std::string OutStr = OS.str();
      88          88 :     if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
      89             : 
      90             :     // Process string output to make it nicer...
      91             :     unsigned ColNum = 0;
      92             :     unsigned LastSpace = 0;
      93        5022 :     for (unsigned i = 0; i != OutStr.length(); ++i) {
      94        5000 :       if (OutStr[i] == '\n') {                            // Left justify
      95         132 :         OutStr[i] = '\\';
      96         396 :         OutStr.insert(OutStr.begin()+i+1, 'l');
      97          66 :         ColNum = 0;
      98          66 :         LastSpace = 0;
      99        4868 :       } else if (OutStr[i] == ';') {                      // Delete comments!
     100          18 :         unsigned Idx = OutStr.find('\n', i+1);            // Find end of line
     101         126 :         OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
     102          18 :         --i;
     103        2416 :       } else if (ColNum == MaxColumns) {                  // Wrap lines.
     104             :         // Wrap very long names even though we can't find a space.
     105           0 :         if (!LastSpace)
     106           0 :           LastSpace = i;
     107           0 :         OutStr.insert(LastSpace, "\\l...");
     108           0 :         ColNum = i - LastSpace;
     109           0 :         LastSpace = 0;
     110           0 :         i += 3; // The loop will advance 'i' again.
     111             :       }
     112             :       else
     113        2416 :         ++ColNum;
     114        5000 :       if (OutStr[i] == ' ')
     115        1058 :         LastSpace = i;
     116             :     }
     117          22 :     return OutStr;
     118             :   }
     119             : 
     120           4 :   std::string getNodeLabel(const BasicBlock *Node,
     121             :                            const Function *Graph) {
     122           8 :     if (isSimple())
     123           0 :       return getSimpleNodeLabel(Node, Graph);
     124             :     else
     125           4 :       return getCompleteNodeLabel(Node, Graph);
     126             :   }
     127             : 
     128           4 :   static std::string getEdgeSourceLabel(const BasicBlock *Node,
     129             :                                         succ_const_iterator I) {
     130             :     // Label source of conditional branches with "T" or "F"
     131           8 :     if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
     132           4 :       if (BI->isConditional())
     133           0 :         return (I == succ_begin(Node)) ? "T" : "F";
     134             : 
     135             :     // Label source of switch edges with the associated value.
     136           4 :     if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
     137           0 :       unsigned SuccNo = I.getSuccessorIndex();
     138             : 
     139           0 :       if (SuccNo == 0) return "def";
     140             : 
     141           0 :       std::string Str;
     142           0 :       raw_string_ostream OS(Str);
     143           0 :       auto Case = *SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
     144           0 :       OS << Case.getCaseValue()->getValue();
     145           0 :       return OS.str();
     146             :     }
     147           8 :     return "";
     148             :   }
     149             : 
     150             :   /// Display the raw branch weights from PGO.
     151           2 :   std::string getEdgeAttributes(const BasicBlock *Node, succ_const_iterator I,
     152             :                                 const Function *F) {
     153           2 :     const TerminatorInst *TI = Node->getTerminator();
     154           2 :     if (TI->getNumSuccessors() == 1)
     155           4 :       return "";
     156             : 
     157           0 :     MDNode *WeightsNode = TI->getMetadata(LLVMContext::MD_prof);
     158           0 :     if (!WeightsNode)
     159           0 :       return "";
     160             : 
     161           0 :     MDString *MDName = cast<MDString>(WeightsNode->getOperand(0));
     162           0 :     if (MDName->getString() != "branch_weights")
     163           0 :       return "";
     164             : 
     165           0 :     unsigned OpNo = I.getSuccessorIndex() + 1;
     166           0 :     if (OpNo >= WeightsNode->getNumOperands())
     167           0 :       return "";
     168             :     ConstantInt *Weight =
     169           0 :         mdconst::dyn_extract<ConstantInt>(WeightsNode->getOperand(OpNo));
     170             :     if (!Weight)
     171           0 :       return "";
     172             : 
     173             :     // Prepend a 'W' to indicate that this is a weight rather than the actual
     174             :     // profile count (due to scaling).
     175           0 :     Twine Attrs = "label=\"W:" + Twine(Weight->getZExtValue()) + "\"";
     176           0 :     return Attrs.str();
     177             :   }
     178             : };
     179             : } // End llvm namespace
     180             : 
     181             : namespace llvm {
     182             :   class FunctionPass;
     183             :   FunctionPass *createCFGPrinterLegacyPassPass ();
     184             :   FunctionPass *createCFGOnlyPrinterLegacyPassPass ();
     185             : } // End llvm namespace
     186             : 
     187             : #endif

Generated by: LCOV version 1.13