MachineCFGPrinter.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. //===- MachineCFGPrinter.cpp - DOT Printer for Machine Functions ----------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines the `-dot-machine-cfg` analysis pass, which emits
  11. // Machine Function in DOT format in file titled `<prefix>.<function-name>.dot.
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/CodeGen/MachineCFGPrinter.h"
  14. #include "llvm/CodeGen/MachineBasicBlock.h"
  15. #include "llvm/CodeGen/MachineFunctionPass.h"
  16. #include "llvm/CodeGen/TargetSubtargetInfo.h"
  17. #include "llvm/InitializePasses.h"
  18. #include "llvm/Pass.h"
  19. #include "llvm/PassRegistry.h"
  20. #include "llvm/Support/GraphWriter.h"
  21. using namespace llvm;
  22. #define DEBUG_TYPE "dot-machine-cfg"
  23. static cl::opt<std::string>
  24. MCFGFuncName("mcfg-func-name", cl::Hidden,
  25. cl::desc("The name of a function (or its substring)"
  26. " whose CFG is viewed/printed."));
  27. static cl::opt<std::string> MCFGDotFilenamePrefix(
  28. "mcfg-dot-filename-prefix", cl::Hidden,
  29. cl::desc("The prefix used for the Machine CFG dot file names."));
  30. static cl::opt<bool>
  31. CFGOnly("dot-mcfg-only", cl::init(false), cl::Hidden,
  32. cl::desc("Print only the CFG without blocks body"));
  33. static void writeMCFGToDotFile(MachineFunction &MF) {
  34. std::string Filename =
  35. (MCFGDotFilenamePrefix + "." + MF.getName() + ".dot").str();
  36. errs() << "Writing '" << Filename << "'...";
  37. std::error_code EC;
  38. raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);
  39. DOTMachineFuncInfo MCFGInfo(&MF);
  40. if (!EC)
  41. WriteGraph(File, &MCFGInfo, CFGOnly);
  42. else
  43. errs() << " error opening file for writing!";
  44. errs() << '\n';
  45. }
  46. namespace {
  47. class MachineCFGPrinter : public MachineFunctionPass {
  48. public:
  49. static char ID;
  50. MachineCFGPrinter();
  51. bool runOnMachineFunction(MachineFunction &MF) override;
  52. void getAnalysisUsage(AnalysisUsage &AU) const override {
  53. AU.setPreservesCFG();
  54. MachineFunctionPass::getAnalysisUsage(AU);
  55. }
  56. };
  57. } // namespace
  58. char MachineCFGPrinter::ID = 0;
  59. char &llvm::MachineCFGPrinterID = MachineCFGPrinter::ID;
  60. INITIALIZE_PASS(MachineCFGPrinter, DEBUG_TYPE, "Machine CFG Printer Pass",
  61. false, true)
  62. /// Default construct and initialize the pass.
  63. MachineCFGPrinter::MachineCFGPrinter() : MachineFunctionPass(ID) {
  64. initializeMachineCFGPrinterPass(*PassRegistry::getPassRegistry());
  65. }
  66. bool MachineCFGPrinter::runOnMachineFunction(MachineFunction &MF) {
  67. if (!MCFGFuncName.empty() && !MF.getName().contains(MCFGFuncName))
  68. return false;
  69. errs() << "Writing Machine CFG for function ";
  70. errs().write_escaped(MF.getName()) << '\n';
  71. writeMCFGToDotFile(MF);
  72. return false;
  73. }