LCOV - code coverage report
Current view: top level - include/llvm/Analysis - CFGPrinter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 38 53 71.7 %
Date: 2018-10-20 13:21:21 Functions: 6 6 100.0 %
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             :   DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
      58             : 
      59           3 :   static std::string getGraphName(const Function *F) {
      60           9 :     return "CFG for '" + F->getName().str() + "' function";
      61             :   }
      62             : 
      63           4 :   static std::string getSimpleNodeLabel(const BasicBlock *Node,
      64             :                                         const Function *) {
      65           4 :     if (!Node->getName().empty())
      66           8 :       return Node->getName().str();
      67             : 
      68             :     std::string Str;
      69           0 :     raw_string_ostream OS(Str);
      70             : 
      71           0 :     Node->printAsOperand(OS, false);
      72             :     return OS.str();
      73             :   }
      74             : 
      75          21 :   static std::string getCompleteNodeLabel(const BasicBlock *Node,
      76             :                                           const Function *) {
      77             :     enum { MaxColumns = 80 };
      78             :     std::string Str;
      79          21 :     raw_string_ostream OS(Str);
      80             : 
      81          21 :     if (Node->getName().empty()) {
      82           0 :       Node->printAsOperand(OS, false);
      83           0 :       OS << ":";
      84             :     }
      85             : 
      86             :     OS << *Node;
      87             :     std::string OutStr = OS.str();
      88          21 :     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        2560 :     for (unsigned i = 0; i != OutStr.length(); ++i) {
      94        2539 :       if (OutStr[i] == '\n') {                            // Left justify
      95          65 :         OutStr[i] = '\\';
      96             :         OutStr.insert(OutStr.begin()+i+1, 'l');
      97             :         ColNum = 0;
      98             :         LastSpace = 0;
      99        2474 :       } else if (OutStr[i] == ';') {                      // Delete comments!
     100          18 :         unsigned Idx = OutStr.find('\n', i+1);            // Find end of line
     101          18 :         OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
     102          18 :         --i;
     103        2456 :       } else if (ColNum == MaxColumns) {                  // Wrap lines.
     104             :         // Wrap very long names even though we can't find a space.
     105           0 :         if (!LastSpace)
     106             :           LastSpace = i;
     107           0 :         OutStr.insert(LastSpace, "\\l...");
     108           0 :         ColNum = i - LastSpace;
     109             :         LastSpace = 0;
     110           0 :         i += 3; // The loop will advance 'i' again.
     111             :       }
     112             :       else
     113        2456 :         ++ColNum;
     114        5078 :       if (OutStr[i] == ' ')
     115             :         LastSpace = i;
     116             :     }
     117          21 :     return OutStr;
     118             :   }
     119             : 
     120           7 :   std::string getNodeLabel(const BasicBlock *Node,
     121             :                            const Function *Graph) {
     122           7 :     if (isSimple())
     123           4 :       return getSimpleNodeLabel(Node, Graph);
     124             :     else
     125           3 :       return getCompleteNodeLabel(Node, Graph);
     126             :   }
     127             : 
     128          10 :   static std::string getEdgeSourceLabel(const BasicBlock *Node,
     129             :                                         succ_const_iterator I) {
     130             :     // Label source of conditional branches with "T" or "F"
     131          10 :     if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
     132          10 :       if (BI->isConditional())
     133           6 :         return (I == succ_begin(Node)) ? "T" : "F";
     134             : 
     135             :     // Label source of switch edges with the associated value.
     136             :     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             :       std::string Str;
     142           0 :       raw_string_ostream OS(Str);
     143             :       auto Case = *SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
     144             :       OS << Case.getCaseValue()->getValue();
     145             :       return OS.str();
     146             :     }
     147           6 :     return "";
     148             :   }
     149             : 
     150             :   /// Display the raw branch weights from PGO.
     151           5 :   std::string getEdgeAttributes(const BasicBlock *Node, succ_const_iterator I,
     152             :                                 const Function *F) {
     153           5 :     const Instruction *TI = Node->getTerminator();
     154           5 :     if (TI->getNumSuccessors() == 1)
     155           3 :       return "";
     156             : 
     157             :     MDNode *WeightsNode = TI->getMetadata(LLVMContext::MD_prof);
     158           2 :     if (!WeightsNode)
     159           0 :       return "";
     160             : 
     161             :     MDString *MDName = cast<MDString>(WeightsNode->getOperand(0));
     162           2 :     if (MDName->getString() != "branch_weights")
     163           0 :       return "";
     164             : 
     165           2 :     unsigned OpNo = I.getSuccessorIndex() + 1;
     166           2 :     if (OpNo >= WeightsNode->getNumOperands())
     167           0 :       return "";
     168             :     ConstantInt *Weight =
     169             :         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           4 :     return ("label=\"W:" + Twine(Weight->getZExtValue()) + "\"").str();
     176             :   }
     177             : };
     178             : } // End llvm namespace
     179             : 
     180             : namespace llvm {
     181             :   class FunctionPass;
     182             :   FunctionPass *createCFGPrinterLegacyPassPass ();
     183             :   FunctionPass *createCFGOnlyPrinterLegacyPassPass ();
     184             : } // End llvm namespace
     185             : 
     186             : #endif

Generated by: LCOV version 1.13