Jlm
Transformation.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2025 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <jlm/rvsdg/graph.hpp>
9 
10 #include <fstream>
11 
12 namespace jlm::rvsdg
13 {
14 
15 Transformation::~Transformation() noexcept = default;
16 
17 class TransformationSequence::Statistics final : public util::Statistics
18 {
19 public:
20  ~Statistics() noexcept override = default;
21 
22  explicit Statistics(const util::FilePath & sourceFile)
23  : util::Statistics(Id::RvsdgOptimization, sourceFile)
24  {}
25 
26  void
27  StartMeasuring() noexcept
28  {
29  AddTimer(Label::Timer).start();
30  }
31 
32  void
33  StartTransformationMeasuring(size_t passNumber, std::string_view passName, const Graph & graph)
34  {
35  const auto fullName = util::strfmt(std::setw(3), std::setfill('0'), passNumber, "-", passName);
36 
37  const auto totalNodes = nnodes(&graph.GetRootRegion());
38  AddMeasurement(fullName + "-#RvsdgNodesBefore", totalNodes);
39 
40  JLM_ASSERT(currentTransformationTimer_ == nullptr);
41  currentTransformationTimer_ = &AddTimer(fullName + "-Timer");
42  currentTransformationTimer_->start();
43  }
44 
45  void
47  {
48  JLM_ASSERT(currentTransformationTimer_ != nullptr);
49  currentTransformationTimer_->stop();
50  currentTransformationTimer_ = nullptr;
51  }
52 
53  void
54  EndMeasuring(const Graph & graph) noexcept
55  {
56  GetTimer(Label::Timer).stop();
57  AddMeasurement(Label::NumRvsdgNodesAfter, nnodes(&graph.GetRootRegion()));
58  }
59 
60  static std::unique_ptr<Statistics>
61  Create(const util::FilePath & sourceFile)
62  {
63  return std::make_unique<Statistics>(sourceFile);
64  }
65 
66  static bool
68  {
69  return collector.IsDemanded(Id::RvsdgOptimization);
70  }
71 
72 private:
73  util::Timer * currentTransformationTimer_ = nullptr;
74 };
75 
77 
78 void
80  RvsdgModule & rvsdgModule,
81  util::StatisticsCollector & statisticsCollector)
82 {
83  std::unique_ptr<Statistics> statistics;
84  if (Statistics::IsDemandedBy(statisticsCollector))
85  statistics = Statistics::Create(rvsdgModule.SourceFilePath().value());
86 
87  if (statistics)
88  statistics->StartMeasuring();
89 
90  size_t numPasses = 0;
91  if (DumpRvsdgDotGraphs_)
92  {
93  DumpDotGraphs(
94  rvsdgModule,
95  statisticsCollector.GetSettings().GetOrCreateOutputDirectory(),
96  "Pristine",
97  numPasses);
98  numPasses++;
99  }
100 
101  for (const auto & transformation : Transformations_)
102  {
103  if (statistics)
104  statistics->StartTransformationMeasuring(
105  numPasses,
106  transformation->GetName(),
107  rvsdgModule.Rvsdg());
108 
109  transformation->Run(rvsdgModule, statisticsCollector);
110 
111  if (statistics)
112  statistics->EndTransformationMeasuring();
113 
114  if (DumpRvsdgDotGraphs_)
115  {
116  DumpDotGraphs(
117  rvsdgModule,
118  statisticsCollector.GetSettings().GetOrCreateOutputDirectory(),
119  "After" + std::string(transformation->GetName()),
120  numPasses);
121  }
122 
123  numPasses++;
124  }
125 
126  if (statistics)
127  {
128  statistics->EndMeasuring(rvsdgModule.Rvsdg());
129  statisticsCollector.CollectDemandedStatistics(std::move(statistics));
130  }
131 }
132 
133 void
135  RvsdgModule & rvsdgModule,
136  const util::FilePath & outputDir,
137  const std::string & passName,
138  size_t numPass) const
139 {
140  JLM_ASSERT(outputDir.Exists() && outputDir.IsDirectory());
141 
142  util::graph::Writer graphWriter;
143  DotWriter_.WriteGraphs(graphWriter, rvsdgModule.Rvsdg().GetRootRegion(), true);
144 
145  std::stringstream filePath;
146  filePath << outputDir.to_str() << "/" << std::setw(3) << std::setfill('0') << numPass << "-"
147  << passName << ".dot";
148 
149  std::ofstream outputFile;
150  outputFile.open(filePath.str());
151  graphWriter.outputAllGraphs(outputFile, util::graph::OutputFormat::Dot);
152  outputFile.close();
153 }
154 
155 }
util::graph::Graph & WriteGraphs(util::graph::Writer &writer, const Region &region, bool emitTypeGraph)
Definition: DotWriter.cpp:198
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
Graph & Rvsdg() noexcept
Definition: RvsdgModule.hpp:57
static std::unique_ptr< Statistics > Create(const util::FilePath &sourceFile)
void EndMeasuring(const Graph &graph) noexcept
void StartTransformationMeasuring(size_t passNumber, std::string_view passName, const Graph &graph)
static bool IsDemandedBy(const util::StatisticsCollector &collector)
void DumpDotGraphs(RvsdgModule &rvsdgModule, const util::FilePath &filePath, const std::string &passName, size_t numPass) const
~TransformationSequence() noexcept override
virtual ~Transformation() noexcept
bool IsDirectory() const noexcept
Determines whether file path is a directory.
Definition: file.hpp:233
const std::string & to_str() const noexcept
Definition: file.hpp:275
bool Exists() const noexcept
Determines whether the file path exists.
Definition: file.hpp:222
bool IsDemanded(Statistics::Id id) const noexcept
Definition: Statistics.hpp:537
void outputAllGraphs(std::ostream &out, OutputFormat format)
#define JLM_ASSERT(x)
Definition: common.hpp:16
size_t nnodes(const jlm::rvsdg::Region *region) noexcept
Definition: region.cpp:629
static std::string strfmt(Args... args)
Definition: strfmt.hpp:35