CFGPrinter.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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 external functions that can be called to explicitly
  11. // instantiate the CFG printer.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_ANALYSIS_CFGPRINTER_H
  15. #define LLVM_ANALYSIS_CFGPRINTER_H
  16. #include "llvm/IR/CFG.h"
  17. #include "llvm/IR/Constants.h"
  18. #include "llvm/IR/Function.h"
  19. #include "llvm/IR/Instructions.h"
  20. #include "llvm/Support/GraphWriter.h"
  21. namespace llvm {
  22. template<>
  23. struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
  24. DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
  25. static std::string getGraphName(const Function *F) {
  26. return "CFG for '" + F->getName().str() + "' function";
  27. }
  28. static std::string getSimpleNodeLabel(const BasicBlock *Node,
  29. const Function *) {
  30. if (!Node->getName().empty())
  31. return Node->getName().str();
  32. std::string Str;
  33. raw_string_ostream OS(Str);
  34. Node->printAsOperand(OS, false);
  35. return OS.str();
  36. }
  37. static std::string getCompleteNodeLabel(const BasicBlock *Node,
  38. const Function *) {
  39. enum { MaxColumns = 80 };
  40. std::string Str;
  41. raw_string_ostream OS(Str);
  42. if (Node->getName().empty()) {
  43. Node->printAsOperand(OS, false);
  44. OS << ":";
  45. }
  46. OS << *Node;
  47. std::string OutStr = OS.str();
  48. if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
  49. // Process string output to make it nicer...
  50. unsigned ColNum = 0;
  51. unsigned LastSpace = 0;
  52. for (unsigned i = 0; i != OutStr.length(); ++i) {
  53. if (OutStr[i] == '\n') { // Left justify
  54. OutStr[i] = '\\';
  55. OutStr.insert(OutStr.begin()+i+1, 'l');
  56. ColNum = 0;
  57. LastSpace = 0;
  58. } else if (OutStr[i] == ';') { // Delete comments!
  59. unsigned Idx = OutStr.find('\n', i+1); // Find end of line
  60. OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
  61. --i;
  62. } else if (ColNum == MaxColumns) { // Wrap lines.
  63. // Wrap very long names even though we can't find a space.
  64. if (!LastSpace)
  65. LastSpace = i;
  66. OutStr.insert(LastSpace, "\\l...");
  67. ColNum = i - LastSpace;
  68. LastSpace = 0;
  69. i += 3; // The loop will advance 'i' again.
  70. }
  71. else
  72. ++ColNum;
  73. if (OutStr[i] == ' ')
  74. LastSpace = i;
  75. }
  76. return OutStr;
  77. }
  78. std::string getNodeLabel(const BasicBlock *Node,
  79. const Function *Graph) {
  80. if (isSimple())
  81. return getSimpleNodeLabel(Node, Graph);
  82. else
  83. return getCompleteNodeLabel(Node, Graph);
  84. }
  85. static std::string getEdgeSourceLabel(const BasicBlock *Node,
  86. succ_const_iterator I) {
  87. // Label source of conditional branches with "T" or "F"
  88. if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
  89. if (BI->isConditional())
  90. return (I == succ_begin(Node)) ? "T" : "F";
  91. // Label source of switch edges with the associated value.
  92. if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
  93. unsigned SuccNo = I.getSuccessorIndex();
  94. if (SuccNo == 0) return "def";
  95. std::string Str;
  96. raw_string_ostream OS(Str);
  97. SwitchInst::ConstCaseIt Case =
  98. SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
  99. OS << Case.getCaseValue()->getValue();
  100. return OS.str();
  101. }
  102. return "";
  103. }
  104. };
  105. } // End llvm namespace
  106. namespace llvm {
  107. class PassRegistry; // HLSL Change
  108. class FunctionPass;
  109. FunctionPass *createCFGPrinterPass ();
  110. FunctionPass *createCFGOnlyPrinterPass ();
  111. void initializeCFGPrinterPasses(PassRegistry &Registry); // HLSL Change
  112. } // End llvm namespace
  113. #endif