From 9ae7fafd99ba615f6926e6a300007ed17749ba8f Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Mon, 24 Mar 2025 13:57:32 +0100 Subject: [PATCH 1/7] TODO --- jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp | 6 +- jlm/llvm/Makefile.sub | 3 + jlm/llvm/backend/RegionSequentializer.cpp | 206 ++++++++++++++++++ jlm/llvm/backend/RegionSequentializer.hpp | 103 +++++++++ jlm/llvm/backend/RvsdgToIpGraphConverter.cpp | 48 ++-- jlm/llvm/backend/RvsdgToIpGraphConverter.hpp | 16 +- jlm/rvsdg/region.hpp | 10 +- jlm/tooling/Command.cpp | 7 +- tests/TestRvsdgs.hpp | 14 ++ .../backend/ExhaustiveSequentializerTests.cpp | 31 +++ .../backend/RvsdgToIpGraphConverterTests.cpp | 28 ++- tools/jlm-hls/jlm-hls.cpp | 6 +- 12 files changed, 443 insertions(+), 35 deletions(-) create mode 100644 jlm/llvm/backend/RegionSequentializer.cpp create mode 100644 jlm/llvm/backend/RegionSequentializer.hpp create mode 100644 tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp diff --git a/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp b/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp index 1e556b5cf..3bf7846ab 100644 --- a/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp +++ b/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp @@ -489,7 +489,11 @@ dump_ref(llvm::RvsdgModule & rhls, const util::filepath & path) } ::llvm::LLVMContext ctx; jlm::util::StatisticsCollector statisticsCollector; - auto jm2 = llvm::RvsdgToIpGraphConverter::CreateAndConvertModule(*reference, statisticsCollector); + auto sequentializer = std::make_shared(); + auto jm2 = llvm::RvsdgToIpGraphConverter::CreateAndConvertModule( + *reference, + statisticsCollector, + sequentializer); auto lm2 = llvm::IpGraphToLlvmConverter::CreateAndConvertModule(*jm2, ctx); std::error_code EC; ::llvm::raw_fd_ostream os(path.to_str(), EC); diff --git a/jlm/llvm/Makefile.sub b/jlm/llvm/Makefile.sub index 13c1c1a33..5693285a5 100644 --- a/jlm/llvm/Makefile.sub +++ b/jlm/llvm/Makefile.sub @@ -4,6 +4,7 @@ libllvm_SOURCES = \ jlm/llvm/backend/dot/DotWriter.cpp \ jlm/llvm/backend/IpGraphToLlvmConverter.cpp \ + jlm/llvm/backend/RegionSequentializer.cpp \ jlm/llvm/backend/RvsdgToIpGraphConverter.cpp \ \ jlm/llvm/frontend/ControlFlowRestructuring.cpp \ @@ -137,10 +138,12 @@ libllvm_HEADERS = \ jlm/llvm/ir/aggregation.hpp \ jlm/llvm/backend/dot/DotWriter.hpp \ jlm/llvm/backend/IpGraphToLlvmConverter.hpp \ + jlm/llvm/backend/RegionSequentializer.hpp \ jlm/llvm/backend/RvsdgToIpGraphConverter.hpp \ libllvm_TESTS += \ tests/jlm/llvm/backend/dot/DotWriterTests \ + tests/jlm/llvm/backend/ExhaustiveSequentializerTests \ tests/jlm/llvm/backend/IpGraphToLlvmConverterTests \ tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests \ tests/jlm/llvm/frontend/llvm/LoadTests \ diff --git a/jlm/llvm/backend/RegionSequentializer.cpp b/jlm/llvm/backend/RegionSequentializer.cpp new file mode 100644 index 000000000..1bc4bbe0b --- /dev/null +++ b/jlm/llvm/backend/RegionSequentializer.cpp @@ -0,0 +1,206 @@ +/* + * Copyright 2025 Nico Reißmann + * See COPYING for terms of redistribution. + */ + +#include +#include +#include +#include + +namespace jlm::llvm +{ + +RegionSequentializer::~RegionSequentializer() noexcept = default; + +// FIXME: add documentation +class ExhaustiveSingleRegionSequentializer final : public RegionSequentializer +{ +public: + ~ExhaustiveSingleRegionSequentializer() noexcept override = default; + + ExhaustiveSingleRegionSequentializer() = default; + + void + Initialize(rvsdg::Region & region) override + { + Sequentializations_ = std::vector(); + + util::HashSet visited; + std::vector sequentializedNodes; + ComputeSequentializations(region, visited, sequentializedNodes); + } + + void + ComputeNextSequentializations() override + { + if (HasMoreSequentializations()) + CurrentSequentialization_++; + else + CurrentSequentialization_ = 0; + } + + SequentializationMap + GetSequentializations() override + { + if (!HasMoreSequentializations()) + CurrentSequentialization_ = 0; + + const auto sequentialization = Sequentializations_[CurrentSequentialization_]; + + SequentializationMap sequentializationMap; + sequentializationMap[Region_] = sequentialization; + return sequentializationMap; + } + + bool + HasMoreSequentializations() const noexcept override + { + JLM_ASSERT(CurrentSequentialization_ < Sequentializations_.size()); + return (CurrentSequentialization_ + 1) != Sequentializations_.size(); + } + +private: + void + ComputeSequentializations( + const rvsdg::Region & region, + util::HashSet & visited, + std::vector & sequentializedNodes) noexcept + { + for (auto & node : region.Nodes()) + { + if (AllPredecessorsVisited(node, visited) && !visited.Contains(&node)) + { + sequentializedNodes.push_back(&node); + visited.Insert(&node); + + ComputeSequentializations(region, visited, sequentializedNodes); + + visited.Remove(&node); + sequentializedNodes.pop_back(); + } + } + + if (sequentializedNodes.size() == region.nnodes()) + { + Sequentializations_.emplace_back(sequentializedNodes); + } + } + + static bool + AllPredecessorsVisited( + const rvsdg::Node & node, + const util::HashSet & visited) + { + for (size_t n = 0; n < node.ninputs(); n++) + { + auto & origin = *node.input(n)->origin(); + if (const auto predecessor = rvsdg::TryGetOwnerNode(origin)) + { + if (!visited.Contains(predecessor)) + { + return false; + } + } + } + + return true; + } + + rvsdg::Region * Region_; + size_t CurrentSequentialization_ = 0; + std::vector Sequentializations_; +}; + +ExhaustiveRegionSequentializer::~ExhaustiveRegionSequentializer() noexcept = default; + +ExhaustiveRegionSequentializer::ExhaustiveRegionSequentializer() = default; + +void +ExhaustiveRegionSequentializer::Initialize(rvsdg::Region & region) +{ + auto sequentializer = std::make_unique(); + sequentializer->Initialize(region); + + for (auto & node : region.Nodes()) + { + if (const auto structuralNode = dynamic_cast(&node)) + { + for (size_t n = 0; n < structuralNode->nsubregions(); n++) + { + const auto subregion = structuralNode->subregion(n); + Initialize(*subregion); + } + } + } + + Sequentializers_[®ion] = std::move(sequentializer); +} + +void +ExhaustiveRegionSequentializer::ComputeNextSequentializations() +{ + for (auto & [region, sequentializer] : Sequentializers_) + { + sequentializer->ComputeNextSequentializations(); + CurrentSequentializations_[region] = std::move(sequentializer->GetSequentializations()[region]); + } +} + +SequentializationMap +ExhaustiveRegionSequentializer::GetSequentializations() +{ + return CurrentSequentializations_; +} + +bool +ExhaustiveRegionSequentializer::HasMoreSequentializations() const noexcept +{ + for (auto & [_, sequentializer] : Sequentializers_) + { + if (sequentializer->HasMoreSequentializations()) + return true; + } + + return false; +} + +IdempotentRegionSequentializer::~IdempotentRegionSequentializer() noexcept = default; + +IdempotentRegionSequentializer::IdempotentRegionSequentializer() = default; + +void +IdempotentRegionSequentializer::Initialize(rvsdg::Region & region) +{ + auto sequentialization = Sequentialization(); + for (const auto & node : rvsdg::TopDownTraverser(®ion)) + { + sequentialization.push_back(node); + if (auto structuralNode = dynamic_cast(node)) + { + for (size_t n = 0; n < structuralNode->nsubregions(); n++) + { + Initialize(*structuralNode->subregion(n)); + } + } + } + Sequentialization_[®ion] = std::move(sequentialization); +} + +void +IdempotentRegionSequentializer::ComputeNextSequentializations() +{} + +SequentializationMap +IdempotentRegionSequentializer::GetSequentializations() +{ + return Sequentialization_; +} + +bool +IdempotentRegionSequentializer::HasMoreSequentializations() const noexcept +{ + return true; +} + +} diff --git a/jlm/llvm/backend/RegionSequentializer.hpp b/jlm/llvm/backend/RegionSequentializer.hpp new file mode 100644 index 000000000..fdc4a6f53 --- /dev/null +++ b/jlm/llvm/backend/RegionSequentializer.hpp @@ -0,0 +1,103 @@ +/* + * Copyright 2025 Nico Reißmann + * See COPYING for terms of redistribution. + */ + +#ifndef JLM_LLVM_BACKEND_REGIONSEQUENTIALIZER_HPP +#define JLM_LLVM_BACKEND_REGIONSEQUENTIALIZER_HPP + +#include +#include +#include +#include + +namespace jlm::rvsdg +{ +class Node; +class Region; +} + +namespace jlm::llvm +{ + +using Sequentialization = std::vector; +using SequentializationMap = std::unordered_map; + +// FIXME: add documentation +class RegionSequentializer +{ +public: + virtual ~RegionSequentializer() noexcept; + + virtual void + Initialize(rvsdg::Region & region) = 0; + + virtual void + ComputeNextSequentializations() = 0; + + virtual SequentializationMap + GetSequentializations() = 0; + + virtual bool + HasMoreSequentializations() const noexcept = 0; +}; + +class ExhaustiveSingleRegionSequentializer; + +// FIXME: add documentation +class ExhaustiveRegionSequentializer final : public RegionSequentializer +{ +public: + ~ExhaustiveRegionSequentializer() noexcept override; + + ExhaustiveRegionSequentializer(); + + void + Initialize(rvsdg::Region & region) override; + + void + ComputeNextSequentializations() override; + + SequentializationMap + GetSequentializations() override; + + bool + HasMoreSequentializations() const noexcept override; + +private: + void + InitializeSequentializers(rvsdg::Region & topRegion); + + SequentializationMap CurrentSequentializations_; + std::unordered_map> + Sequentializers_; +}; + +// FIXME: add documentation +class IdempotentRegionSequentializer final : public RegionSequentializer +{ +public: + ~IdempotentRegionSequentializer() noexcept override; + + IdempotentRegionSequentializer(); + + void + Initialize(rvsdg::Region & region) override; + + void + ComputeNextSequentializations() override; + + SequentializationMap + GetSequentializations() override; + + bool + HasMoreSequentializations() const noexcept override; + +private: + rvsdg::Region * Region_; + SequentializationMap Sequentialization_; +}; + +} + +#endif // JLM_LLVM_BACKEND_REGIONSEQUENTIALIZER_HPP diff --git a/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp b/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp index e0639d974..bfde7d89a 100644 --- a/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp +++ b/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp @@ -129,7 +129,10 @@ class RvsdgToIpGraphConverter::Statistics final : public util::Statistics RvsdgToIpGraphConverter::~RvsdgToIpGraphConverter() = default; -RvsdgToIpGraphConverter::RvsdgToIpGraphConverter() = default; +RvsdgToIpGraphConverter::RvsdgToIpGraphConverter( + const std::shared_ptr & regionSequentializer) + : RegionSequentializer_(regionSequentializer) +{} std::unique_ptr RvsdgToIpGraphConverter::CreateInitialization(const delta::node & deltaNode) @@ -176,8 +179,8 @@ RvsdgToIpGraphConverter::ConvertRegion(rvsdg::Region & region) Context_->GetLastProcessedBasicBlock()->add_outedge(entryBlock); Context_->SetLastProcessedBasicBlock(entryBlock); - for (const auto & node : rvsdg::TopDownTraverser(®ion)) - ConvertNode(*node); + for (const auto & node : RegionSequentializer_->GetSequentializations()[®ion]) + ConvertIntraProceduralNode(*node); const auto exitBlock = basic_block::create(*Context_->GetControlFlowGraph()); Context_->GetLastProcessedBasicBlock()->add_outedge(exitBlock); @@ -604,20 +607,12 @@ RvsdgToIpGraphConverter::ConvertDeltaNode(const delta::node & deltaNode) } void -RvsdgToIpGraphConverter::ConvertNode(const rvsdg::Node & node) +RvsdgToIpGraphConverter::ConvertInterProceduralNode(const rvsdg::Node & node) { if (const auto lambdaNode = dynamic_cast(&node)) { ConvertLambdaNode(*lambdaNode); } - else if (const auto gammaNode = dynamic_cast(&node)) - { - ConvertGammaNode(*gammaNode); - } - else if (const auto thetaNode = dynamic_cast(&node)) - { - ConvertThetaNode(*thetaNode); - } else if (const auto phiNode = dynamic_cast(&node)) { ConvertPhiNode(*phiNode); @@ -626,6 +621,24 @@ RvsdgToIpGraphConverter::ConvertNode(const rvsdg::Node & node) { ConvertDeltaNode(*deltaNode); } + else + { + JLM_UNREACHABLE( + util::strfmt("Unhandled node type: ", node.GetOperation().debug_string()).c_str()); + } +} + +void +RvsdgToIpGraphConverter::ConvertIntraProceduralNode(const rvsdg::Node & node) +{ + if (const auto gammaNode = dynamic_cast(&node)) + { + ConvertGammaNode(*gammaNode); + } + else if (const auto thetaNode = dynamic_cast(&node)) + { + ConvertThetaNode(*thetaNode); + } else if (const auto simpleNode = dynamic_cast(&node)) { ConvertSimpleNode(*simpleNode); @@ -638,11 +651,11 @@ RvsdgToIpGraphConverter::ConvertNode(const rvsdg::Node & node) } void -RvsdgToIpGraphConverter::ConvertNodes(const rvsdg::Graph & graph) +RvsdgToIpGraphConverter::ConvertInterProceduralNodes(const rvsdg::Graph & graph) { for (const auto & node : rvsdg::TopDownTraverser(&graph.GetRootRegion())) { - ConvertNode(*node); + ConvertInterProceduralNode(*node); } } @@ -694,7 +707,7 @@ RvsdgToIpGraphConverter::ConvertModule( Context_ = Context::Create(*ipGraphModule); ConvertImports(rvsdgModule.Rvsdg()); - ConvertNodes(rvsdgModule.Rvsdg()); + ConvertInterProceduralNodes(rvsdgModule.Rvsdg()); statistics->End(*ipGraphModule); statisticsCollector.CollectDemandedStatistics(std::move(statistics)); @@ -705,9 +718,10 @@ RvsdgToIpGraphConverter::ConvertModule( std::unique_ptr RvsdgToIpGraphConverter::CreateAndConvertModule( RvsdgModule & rvsdgModule, - util::StatisticsCollector & statisticsCollector) + util::StatisticsCollector & statisticsCollector, + const std::shared_ptr & regionSequentializer) { - RvsdgToIpGraphConverter converter; + RvsdgToIpGraphConverter converter(regionSequentializer); return converter.ConvertModule(rvsdgModule, statisticsCollector); } diff --git a/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp b/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp index cec58eae8..be97e7336 100644 --- a/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp +++ b/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp @@ -6,6 +6,7 @@ #ifndef JLM_LLVM_BACKEND_RVSDGTOIPGRAPHCONVERTER_HPP #define JLM_LLVM_BACKEND_RVSDGTOIPGRAPHCONVERTER_HPP +#include #include #include @@ -52,7 +53,8 @@ class RvsdgToIpGraphConverter final public: ~RvsdgToIpGraphConverter(); - RvsdgToIpGraphConverter(); + explicit RvsdgToIpGraphConverter( + const std::shared_ptr & regionSequentializer); RvsdgToIpGraphConverter(const RvsdgToIpGraphConverter &) = delete; @@ -70,17 +72,21 @@ class RvsdgToIpGraphConverter final static std::unique_ptr CreateAndConvertModule( RvsdgModule & rvsdgModule, - util::StatisticsCollector & statisticsCollector); + util::StatisticsCollector & statisticsCollector, + const std::shared_ptr & regionSequentializer); private: void ConvertImports(const rvsdg::Graph & graph); void - ConvertNodes(const rvsdg::Graph & graph); + ConvertInterProceduralNodes(const rvsdg::Graph & graph); void - ConvertNode(const rvsdg::Node & node); + ConvertInterProceduralNode(const rvsdg::Node & node); + + void + ConvertIntraProceduralNode(const rvsdg::Node & node); void ConvertDeltaNode(const delta::node & deltaNode); @@ -116,6 +122,8 @@ class RvsdgToIpGraphConverter final RequiresSsaPhiOperation(const rvsdg::ThetaNode::LoopVar & loopVar, const variable & v); std::unique_ptr Context_; + + std::shared_ptr RegionSequentializer_; }; } diff --git a/jlm/rvsdg/region.hpp b/jlm/rvsdg/region.hpp index e4c4d44b6..8f0292918 100644 --- a/jlm/rvsdg/region.hpp +++ b/jlm/rvsdg/region.hpp @@ -239,17 +239,17 @@ class Region using TopNodeRange = util::IteratorRange; using TopNodeConstRange = util::IteratorRange; - using NodeIterator = region_nodes_list::iterator; - using NodeConstIterator = region_nodes_list::const_iterator; - using NodeRange = util::IteratorRange; - using NodeConstRange = util::IteratorRange; - using BottomNodeIterator = region_bottom_node_list::iterator; using BottomNodeConstIterator = region_bottom_node_list::const_iterator; using BottomNodeRange = util::IteratorRange; using BottomNodeConstRange = util::IteratorRange; public: + using NodeIterator = region_nodes_list::iterator; + using NodeConstIterator = region_nodes_list::const_iterator; + using NodeRange = util::IteratorRange; + using NodeConstRange = util::IteratorRange; + ~Region() noexcept; Region(rvsdg::Region * parent, Graph * graph); diff --git a/jlm/tooling/Command.cpp b/jlm/tooling/Command.cpp index c53703243..178308154 100644 --- a/jlm/tooling/Command.cpp +++ b/jlm/tooling/Command.cpp @@ -529,8 +529,11 @@ JlmOptCommand::PrintAsLlvm( const util::filepath & outputFile, util::StatisticsCollector & statisticsCollector) { - auto jlm_module = - llvm::RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector); + auto sequentializer = std::make_shared(); + auto jlm_module = llvm::RvsdgToIpGraphConverter::CreateAndConvertModule( + rvsdgModule, + statisticsCollector, + sequentializer); ::llvm::LLVMContext ctx; auto llvm_module = llvm::IpGraphToLlvmConverter::CreateAndConvertModule(*jlm_module, ctx); diff --git a/tests/TestRvsdgs.hpp b/tests/TestRvsdgs.hpp index 5cd6a9583..c3a023305 100644 --- a/tests/TestRvsdgs.hpp +++ b/tests/TestRvsdgs.hpp @@ -76,6 +76,13 @@ class RvsdgTest */ class StoreTest1 final : public RvsdgTest { +public: + rvsdg::LambdaNode & + GetLambdaNode() const noexcept + { + return *lambda; + } + private: std::unique_ptr SetupRvsdg() override; @@ -148,6 +155,13 @@ class StoreTest2 final : public RvsdgTest */ class LoadTest1 final : public RvsdgTest { +public: + const rvsdg::LambdaNode & + GetLambdaNode() const noexcept + { + return *lambda; + } + private: std::unique_ptr SetupRvsdg() override; diff --git a/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp b/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp new file mode 100644 index 000000000..65534eb3c --- /dev/null +++ b/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2025 Nico Reißmann + * See COPYING for terms of redistribution. + */ + +#include +#include +#include + +#if 0 +static int +Test() +{ + jlm::tests::LoadTest1 test; + test.InitializeTest(); + + jlm::llvm::ExhaustiveSingleRegionSequentializer sequentializer(*test.GetLambdaNode().subregion()); + assert(sequentializer.HasMoreSequentializations()); + + auto sequentializationMap = sequentializer.ComputeNextSequentialization(); + assert(sequentializationMap.has_value()); + assert(!sequentializer.HasMoreSequentializations()); + + sequentializationMap = sequentializer.ComputeNextSequentialization(); + assert(!sequentializationMap.has_value()); + + return 0; +} + +JLM_UNIT_TEST_REGISTER("jlm/llvm/backend/ExhaustiveSequentializerTests-Test", Test) +#endif diff --git a/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp b/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp index bb2abe433..4698f105e 100644 --- a/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp +++ b/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp @@ -49,7 +49,11 @@ GammaWithMatch() // Act StatisticsCollector statisticsCollector; - auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector); + auto sequentializer = std::make_shared(); + auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( + rvsdgModule, + statisticsCollector, + sequentializer); print(*module, stdout); // Assert @@ -101,7 +105,11 @@ GammaWithoutMatch() // Act StatisticsCollector statisticsCollector; - auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector); + auto sequentializer = std::make_shared(); + auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( + rvsdgModule, + statisticsCollector, + sequentializer); print(*module, stdout); // Assert @@ -158,7 +166,11 @@ EmptyGammaWithThreeSubregions() // Act StatisticsCollector statisticsCollector; - auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector); + auto sequentializer = std::make_shared(); + auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( + rvsdgModule, + statisticsCollector, + sequentializer); print(*module, stdout); // Assert @@ -211,7 +223,11 @@ PartialEmptyGamma() // Act StatisticsCollector statisticsCollector; - auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector); + auto sequentializer = std::make_shared(); + auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( + rvsdgModule, + statisticsCollector, + sequentializer); // Assert auto & ipg = module->ipgraph(); @@ -279,7 +295,9 @@ RecursiveData() // Act jlm::util::StatisticsCollector statisticsCollector; - auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rm, statisticsCollector); + auto sequentializer = std::make_shared(); + auto module = + RvsdgToIpGraphConverter::CreateAndConvertModule(rm, statisticsCollector, sequentializer); print(*module, stdout); // Assert diff --git a/tools/jlm-hls/jlm-hls.cpp b/tools/jlm-hls/jlm-hls.cpp index 4928db4fe..fb2c79bc7 100644 --- a/tools/jlm-hls/jlm-hls.cpp +++ b/tools/jlm-hls/jlm-hls.cpp @@ -35,7 +35,11 @@ llvmToFile(jlm::llvm::RvsdgModule & module, const jlm::util::filepath & fileName { llvm::LLVMContext ctx; jlm::util::StatisticsCollector statisticsCollector; - auto jm = jlm::llvm::RvsdgToIpGraphConverter::CreateAndConvertModule(module, statisticsCollector); + auto sequentializer = std::make_shared(); + auto jm = jlm::llvm::RvsdgToIpGraphConverter::CreateAndConvertModule( + module, + statisticsCollector, + sequentializer); auto lm = jlm::llvm::IpGraphToLlvmConverter::CreateAndConvertModule(*jm, ctx); std::error_code EC; llvm::raw_fd_ostream os(fileName.to_str(), EC); From 2535fcfc779d2d8a0d5d74fd0d169374dacf2fdf Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Tue, 25 Mar 2025 08:33:22 +0100 Subject: [PATCH 2/7] TODO --- jlm/llvm/backend/RegionSequentializer.cpp | 5 +++-- jlm/llvm/backend/RvsdgToIpGraphConverter.cpp | 3 ++- tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp | 5 +++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/jlm/llvm/backend/RegionSequentializer.cpp b/jlm/llvm/backend/RegionSequentializer.cpp index 1bc4bbe0b..70c8e03a7 100644 --- a/jlm/llvm/backend/RegionSequentializer.cpp +++ b/jlm/llvm/backend/RegionSequentializer.cpp @@ -173,10 +173,11 @@ void IdempotentRegionSequentializer::Initialize(rvsdg::Region & region) { auto sequentialization = Sequentialization(); - for (const auto & node : rvsdg::TopDownTraverser(®ion)) + for (const auto node : rvsdg::TopDownTraverser(®ion)) { sequentialization.push_back(node); - if (auto structuralNode = dynamic_cast(node)) + + if (const auto structuralNode = dynamic_cast(node)) { for (size_t n = 0; n < structuralNode->nsubregions(); n++) { diff --git a/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp b/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp index bfde7d89a..832173677 100644 --- a/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp +++ b/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp @@ -179,7 +179,8 @@ RvsdgToIpGraphConverter::ConvertRegion(rvsdg::Region & region) Context_->GetLastProcessedBasicBlock()->add_outedge(entryBlock); Context_->SetLastProcessedBasicBlock(entryBlock); - for (const auto & node : RegionSequentializer_->GetSequentializations()[®ion]) + auto sequentializationMap = RegionSequentializer_->GetSequentializations(); + for (const auto & node : sequentializationMap[®ion]) ConvertIntraProceduralNode(*node); const auto exitBlock = basic_block::create(*Context_->GetControlFlowGraph()); diff --git a/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp b/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp index 4698f105e..1b69fc759 100644 --- a/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp +++ b/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp @@ -50,6 +50,7 @@ GammaWithMatch() // Act StatisticsCollector statisticsCollector; auto sequentializer = std::make_shared(); + sequentializer->Initialize(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -106,6 +107,7 @@ GammaWithoutMatch() // Act StatisticsCollector statisticsCollector; auto sequentializer = std::make_shared(); + sequentializer->Initialize(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -167,6 +169,7 @@ EmptyGammaWithThreeSubregions() // Act StatisticsCollector statisticsCollector; auto sequentializer = std::make_shared(); + sequentializer->Initialize(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -224,6 +227,7 @@ PartialEmptyGamma() // Act StatisticsCollector statisticsCollector; auto sequentializer = std::make_shared(); + sequentializer->Initialize(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -296,6 +300,7 @@ RecursiveData() // Act jlm::util::StatisticsCollector statisticsCollector; auto sequentializer = std::make_shared(); + sequentializer->Initialize(rm.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rm, statisticsCollector, sequentializer); print(*module, stdout); From 6c2b8daf90aa96f095d7b20ecc9de77063c36038 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Tue, 25 Mar 2025 10:22:11 +0100 Subject: [PATCH 3/7] TODO --- jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp | 3 +- jlm/llvm/backend/RegionSequentializer.cpp | 269 ++++++++++-------- jlm/llvm/backend/RegionSequentializer.hpp | 142 +++++++-- jlm/llvm/backend/RvsdgToIpGraphConverter.cpp | 11 +- jlm/llvm/backend/RvsdgToIpGraphConverter.hpp | 6 +- jlm/tooling/Command.cpp | 3 +- .../backend/ExhaustiveSequentializerTests.cpp | 2 +- .../backend/RvsdgToIpGraphConverterTests.cpp | 20 +- tools/jlm-hls/jlm-hls.cpp | 3 +- 9 files changed, 293 insertions(+), 166 deletions(-) diff --git a/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp b/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp index 3bf7846ab..f651d0b07 100644 --- a/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp +++ b/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp @@ -489,7 +489,8 @@ dump_ref(llvm::RvsdgModule & rhls, const util::filepath & path) } ::llvm::LLVMContext ctx; jlm::util::StatisticsCollector statisticsCollector; - auto sequentializer = std::make_shared(); + auto sequentializer = std::make_shared( + reference->Rvsdg().GetRootRegion()); auto jm2 = llvm::RvsdgToIpGraphConverter::CreateAndConvertModule( *reference, statisticsCollector, diff --git a/jlm/llvm/backend/RegionSequentializer.cpp b/jlm/llvm/backend/RegionSequentializer.cpp index 70c8e03a7..f6e9409e3 100644 --- a/jlm/llvm/backend/RegionSequentializer.cpp +++ b/jlm/llvm/backend/RegionSequentializer.cpp @@ -11,150 +11,147 @@ namespace jlm::llvm { -RegionSequentializer::~RegionSequentializer() noexcept = default; +RegionSequentializer::~RegionSequentializer() = default; -// FIXME: add documentation -class ExhaustiveSingleRegionSequentializer final : public RegionSequentializer -{ -public: - ~ExhaustiveSingleRegionSequentializer() noexcept override = default; - - ExhaustiveSingleRegionSequentializer() = default; - - void - Initialize(rvsdg::Region & region) override - { - Sequentializations_ = std::vector(); - - util::HashSet visited; - std::vector sequentializedNodes; - ComputeSequentializations(region, visited, sequentializedNodes); - } +RegionSequentializer::RegionSequentializer(rvsdg::Region & region) + : Region_(®ion) +{} - void - ComputeNextSequentializations() override - { - if (HasMoreSequentializations()) - CurrentSequentialization_++; - else - CurrentSequentialization_ = 0; - } +ExhaustiveRegionSequentializer::ExhaustiveRegionSequentializer(rvsdg::Region & region) + : RegionSequentializer(region) +{ + util::HashSet visited; + std::vector sequentializedNodes; + ComputeSequentializations(region, visited, sequentializedNodes); +} - SequentializationMap - GetSequentializations() override - { - if (!HasMoreSequentializations()) - CurrentSequentialization_ = 0; +void +ExhaustiveRegionSequentializer::ComputeNextSequentialization() +{ + if (HasMoreSequentializations()) + CurrentSequentialization_++; + else + CurrentSequentialization_ = 0; +} - const auto sequentialization = Sequentializations_[CurrentSequentialization_]; +Sequentialization +ExhaustiveRegionSequentializer::GetSequentialization() +{ + if (!HasMoreSequentializations()) + CurrentSequentialization_ = 0; - SequentializationMap sequentializationMap; - sequentializationMap[Region_] = sequentialization; - return sequentializationMap; - } + return Sequentializations_[CurrentSequentialization_]; +} - bool - HasMoreSequentializations() const noexcept override - { - JLM_ASSERT(CurrentSequentialization_ < Sequentializations_.size()); - return (CurrentSequentialization_ + 1) != Sequentializations_.size(); - } +bool +ExhaustiveRegionSequentializer::HasMoreSequentializations() const noexcept +{ + JLM_ASSERT(CurrentSequentialization_ < Sequentializations_.size()); + return (CurrentSequentialization_ + 1) != Sequentializations_.size(); +} -private: - void - ComputeSequentializations( - const rvsdg::Region & region, - util::HashSet & visited, - std::vector & sequentializedNodes) noexcept +void +ExhaustiveRegionSequentializer::ComputeSequentializations( + const rvsdg::Region & region, + util::HashSet & visited, + std::vector & sequentializedNodes) noexcept +{ + for (auto & node : region.Nodes()) { - for (auto & node : region.Nodes()) + if (AllPredecessorsVisited(node, visited) && !visited.Contains(&node)) { - if (AllPredecessorsVisited(node, visited) && !visited.Contains(&node)) - { - sequentializedNodes.push_back(&node); - visited.Insert(&node); + sequentializedNodes.push_back(&node); + visited.Insert(&node); - ComputeSequentializations(region, visited, sequentializedNodes); + ComputeSequentializations(region, visited, sequentializedNodes); - visited.Remove(&node); - sequentializedNodes.pop_back(); - } + visited.Remove(&node); + sequentializedNodes.pop_back(); } + } - if (sequentializedNodes.size() == region.nnodes()) - { - Sequentializations_.emplace_back(sequentializedNodes); - } + if (sequentializedNodes.size() == region.nnodes()) + { + Sequentializations_.emplace_back(sequentializedNodes); } +} - static bool - AllPredecessorsVisited( - const rvsdg::Node & node, - const util::HashSet & visited) +bool +ExhaustiveRegionSequentializer::AllPredecessorsVisited( + const rvsdg::Node & node, + const util::HashSet & visited) +{ + for (size_t n = 0; n < node.ninputs(); n++) { - for (size_t n = 0; n < node.ninputs(); n++) + auto & origin = *node.input(n)->origin(); + if (const auto predecessor = rvsdg::TryGetOwnerNode(origin)) { - auto & origin = *node.input(n)->origin(); - if (const auto predecessor = rvsdg::TryGetOwnerNode(origin)) + if (!visited.Contains(predecessor)) { - if (!visited.Contains(predecessor)) - { - return false; - } + return false; } } - - return true; } - rvsdg::Region * Region_; - size_t CurrentSequentialization_ = 0; - std::vector Sequentializations_; -}; + return true; +} -ExhaustiveRegionSequentializer::~ExhaustiveRegionSequentializer() noexcept = default; +IdempotentRegionSequentializer::~IdempotentRegionSequentializer() noexcept = default; -ExhaustiveRegionSequentializer::ExhaustiveRegionSequentializer() = default; +IdempotentRegionSequentializer::IdempotentRegionSequentializer(rvsdg::Region & region) + : RegionSequentializer(region) +{} void -ExhaustiveRegionSequentializer::Initialize(rvsdg::Region & region) -{ - auto sequentializer = std::make_unique(); - sequentializer->Initialize(region); +IdempotentRegionSequentializer::ComputeNextSequentialization() +{} - for (auto & node : region.Nodes()) +Sequentialization +IdempotentRegionSequentializer::GetSequentialization() +{ + auto sequentialization = Sequentialization(); + for (const auto node : rvsdg::TopDownTraverser(&GetRegion())) { - if (const auto structuralNode = dynamic_cast(&node)) - { - for (size_t n = 0; n < structuralNode->nsubregions(); n++) - { - const auto subregion = structuralNode->subregion(n); - Initialize(*subregion); - } - } + sequentialization.push_back(node); } + return sequentialization; +} - Sequentializers_[®ion] = std::move(sequentializer); +bool +IdempotentRegionSequentializer::HasMoreSequentializations() const noexcept +{ + return true; +} + +RegionTreeSequentializer::~RegionTreeSequentializer() noexcept = default; + +RegionTreeSequentializer::RegionTreeSequentializer() = default; + +IdempotentRegionTreeSequentializer::~IdempotentRegionTreeSequentializer() noexcept = default; + +IdempotentRegionTreeSequentializer::IdempotentRegionTreeSequentializer(rvsdg::Region & region) +{ + InitializeSequentializers(region); } void -ExhaustiveRegionSequentializer::ComputeNextSequentializations() +IdempotentRegionTreeSequentializer::ComputeNextSequentializations() { for (auto & [region, sequentializer] : Sequentializers_) { - sequentializer->ComputeNextSequentializations(); - CurrentSequentializations_[region] = std::move(sequentializer->GetSequentializations()[region]); + sequentializer->ComputeNextSequentialization(); } } -SequentializationMap -ExhaustiveRegionSequentializer::GetSequentializations() +RegionSequentializer & +IdempotentRegionTreeSequentializer::GetSequentializer(rvsdg::Region & region) { - return CurrentSequentializations_; + JLM_ASSERT(Sequentializers_.find(®ion) != Sequentializers_.end()); + return *Sequentializers_[®ion]; } bool -ExhaustiveRegionSequentializer::HasMoreSequentializations() const noexcept +IdempotentRegionTreeSequentializer::HasMoreSequentializations() const noexcept { for (auto & [_, sequentializer] : Sequentializers_) { @@ -165,43 +162,79 @@ ExhaustiveRegionSequentializer::HasMoreSequentializations() const noexcept return false; } -IdempotentRegionSequentializer::~IdempotentRegionSequentializer() noexcept = default; +void +IdempotentRegionTreeSequentializer::InitializeSequentializers(rvsdg::Region & region) +{ + auto sequentializer = std::make_unique(region); + + for (auto & node : region.Nodes()) + { + if (const auto structuralNode = dynamic_cast(&node)) + { + for (size_t n = 0; n < structuralNode->nsubregions(); n++) + { + const auto subregion = structuralNode->subregion(n); + InitializeSequentializers(*subregion); + } + } + } + + Sequentializers_[®ion] = std::move(sequentializer); +} -IdempotentRegionSequentializer::IdempotentRegionSequentializer() = default; +ExhaustiveRegionTreeSequentializer::~ExhaustiveRegionTreeSequentializer() noexcept = default; + +ExhaustiveRegionTreeSequentializer::ExhaustiveRegionTreeSequentializer(rvsdg::Region & region) +{ + InitializeSequentializers(region); +} void -IdempotentRegionSequentializer::Initialize(rvsdg::Region & region) +ExhaustiveRegionTreeSequentializer::InitializeSequentializers(rvsdg::Region & region) { - auto sequentialization = Sequentialization(); - for (const auto node : rvsdg::TopDownTraverser(®ion)) - { - sequentialization.push_back(node); + auto sequentializer = std::make_unique(region); - if (const auto structuralNode = dynamic_cast(node)) + for (auto & node : region.Nodes()) + { + if (const auto structuralNode = dynamic_cast(&node)) { for (size_t n = 0; n < structuralNode->nsubregions(); n++) { - Initialize(*structuralNode->subregion(n)); + const auto subregion = structuralNode->subregion(n); + InitializeSequentializers(*subregion); } } } - Sequentialization_[®ion] = std::move(sequentialization); + + Sequentializers_[®ion] = std::move(sequentializer); } void -IdempotentRegionSequentializer::ComputeNextSequentializations() -{} +ExhaustiveRegionTreeSequentializer::ComputeNextSequentializations() +{ + for (auto & [region, sequentializer] : Sequentializers_) + { + sequentializer->ComputeNextSequentialization(); + } +} -SequentializationMap -IdempotentRegionSequentializer::GetSequentializations() +RegionSequentializer & +ExhaustiveRegionTreeSequentializer::GetSequentializer(rvsdg::Region & region) { - return Sequentialization_; + JLM_ASSERT(Sequentializers_.find(®ion) != Sequentializers_.end()); + return *Sequentializers_[®ion]; } bool -IdempotentRegionSequentializer::HasMoreSequentializations() const noexcept +ExhaustiveRegionTreeSequentializer::HasMoreSequentializations() const noexcept { - return true; + for (auto & [_, sequentializer] : Sequentializers_) + { + if (sequentializer->HasMoreSequentializations()) + return true; + } + + return false; } } diff --git a/jlm/llvm/backend/RegionSequentializer.hpp b/jlm/llvm/backend/RegionSequentializer.hpp index fdc4a6f53..dc955aeed 100644 --- a/jlm/llvm/backend/RegionSequentializer.hpp +++ b/jlm/llvm/backend/RegionSequentializer.hpp @@ -29,73 +29,163 @@ class RegionSequentializer public: virtual ~RegionSequentializer() noexcept; - virtual void - Initialize(rvsdg::Region & region) = 0; + explicit RegionSequentializer(rvsdg::Region & region); - virtual void - ComputeNextSequentializations() = 0; + RegionSequentializer(const RegionSequentializer &) = delete; + + RegionSequentializer(RegionSequentializer &&) = delete; - virtual SequentializationMap - GetSequentializations() = 0; + RegionSequentializer & + operator=(const RegionSequentializer &) = delete; + + RegionSequentializer & + operator=(RegionSequentializer &&) = delete; + + virtual Sequentialization + GetSequentialization() = 0; virtual bool HasMoreSequentializations() const noexcept = 0; -}; -class ExhaustiveSingleRegionSequentializer; + virtual void + ComputeNextSequentialization() = 0; + + rvsdg::Region & + GetRegion() const noexcept + { + return *Region_; + } + +private: + rvsdg::Region * Region_; +}; // FIXME: add documentation class ExhaustiveRegionSequentializer final : public RegionSequentializer { public: - ~ExhaustiveRegionSequentializer() noexcept override; + ~ExhaustiveRegionSequentializer() noexcept override = default; + + explicit ExhaustiveRegionSequentializer(rvsdg::Region & region); + + void + ComputeNextSequentialization() override; + + Sequentialization + GetSequentialization() override; + + bool + HasMoreSequentializations() const noexcept override; + +private: + void + ComputeSequentializations( + const rvsdg::Region & region, + util::HashSet & visited, + std::vector & sequentializedNodes) noexcept; + + static bool + AllPredecessorsVisited( + const rvsdg::Node & node, + const util::HashSet & visited); + + size_t CurrentSequentialization_ = 0; + std::vector Sequentializations_; +}; + +class IdempotentRegionSequentializer final : public RegionSequentializer +{ +public: + ~IdempotentRegionSequentializer() noexcept override; + + explicit IdempotentRegionSequentializer(rvsdg::Region & region); - ExhaustiveRegionSequentializer(); + Sequentialization + GetSequentialization() override; + + bool + HasMoreSequentializations() const noexcept override; void - Initialize(rvsdg::Region & region) override; + ComputeNextSequentialization() override; +}; + +// FIXME: add documentation +class RegionTreeSequentializer +{ +public: + virtual ~RegionTreeSequentializer() noexcept; + + RegionTreeSequentializer(); + + RegionTreeSequentializer(const RegionTreeSequentializer &) = delete; + + RegionTreeSequentializer(RegionTreeSequentializer &&) = delete; + + RegionTreeSequentializer & + operator=(const RegionTreeSequentializer &) = delete; + + RegionTreeSequentializer & + operator=(RegionTreeSequentializer &&) = delete; + + virtual void + ComputeNextSequentializations() = 0; + + virtual RegionSequentializer & + GetSequentializer(rvsdg::Region & region) = 0; + + virtual bool + HasMoreSequentializations() const noexcept = 0; +}; + +// FIXME: add documentation +class IdempotentRegionTreeSequentializer final : public RegionTreeSequentializer +{ +public: + ~IdempotentRegionTreeSequentializer() noexcept override; + + explicit IdempotentRegionTreeSequentializer(rvsdg::Region & region); void ComputeNextSequentializations() override; - SequentializationMap - GetSequentializations() override; + RegionSequentializer & + GetSequentializer(rvsdg::Region & region) override; bool HasMoreSequentializations() const noexcept override; private: void - InitializeSequentializers(rvsdg::Region & topRegion); + InitializeSequentializers(rvsdg::Region & region); - SequentializationMap CurrentSequentializations_; - std::unordered_map> + std::unordered_map> Sequentializers_; }; // FIXME: add documentation -class IdempotentRegionSequentializer final : public RegionSequentializer +class ExhaustiveRegionTreeSequentializer final : public RegionTreeSequentializer { public: - ~IdempotentRegionSequentializer() noexcept override; + ~ExhaustiveRegionTreeSequentializer() noexcept override; - IdempotentRegionSequentializer(); - - void - Initialize(rvsdg::Region & region) override; + explicit ExhaustiveRegionTreeSequentializer(rvsdg::Region & region); void ComputeNextSequentializations() override; - SequentializationMap - GetSequentializations() override; + RegionSequentializer & + GetSequentializer(rvsdg::Region & region) override; bool HasMoreSequentializations() const noexcept override; private: - rvsdg::Region * Region_; - SequentializationMap Sequentialization_; + void + InitializeSequentializers(rvsdg::Region & region); + + std::unordered_map> + Sequentializers_; }; } diff --git a/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp b/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp index 832173677..fe01a9397 100644 --- a/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp +++ b/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp @@ -130,8 +130,8 @@ class RvsdgToIpGraphConverter::Statistics final : public util::Statistics RvsdgToIpGraphConverter::~RvsdgToIpGraphConverter() = default; RvsdgToIpGraphConverter::RvsdgToIpGraphConverter( - const std::shared_ptr & regionSequentializer) - : RegionSequentializer_(regionSequentializer) + const std::shared_ptr & regionSequentializer) + : RegionTreeSequentializer_(regionSequentializer) {} std::unique_ptr @@ -179,8 +179,9 @@ RvsdgToIpGraphConverter::ConvertRegion(rvsdg::Region & region) Context_->GetLastProcessedBasicBlock()->add_outedge(entryBlock); Context_->SetLastProcessedBasicBlock(entryBlock); - auto sequentializationMap = RegionSequentializer_->GetSequentializations(); - for (const auto & node : sequentializationMap[®ion]) + auto sequentialization = + RegionTreeSequentializer_->GetSequentializer(region).GetSequentialization(); + for (const auto & node : sequentialization) ConvertIntraProceduralNode(*node); const auto exitBlock = basic_block::create(*Context_->GetControlFlowGraph()); @@ -720,7 +721,7 @@ std::unique_ptr RvsdgToIpGraphConverter::CreateAndConvertModule( RvsdgModule & rvsdgModule, util::StatisticsCollector & statisticsCollector, - const std::shared_ptr & regionSequentializer) + const std::shared_ptr & regionSequentializer) { RvsdgToIpGraphConverter converter(regionSequentializer); return converter.ConvertModule(rvsdgModule, statisticsCollector); diff --git a/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp b/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp index be97e7336..af3392bf0 100644 --- a/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp +++ b/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp @@ -54,7 +54,7 @@ class RvsdgToIpGraphConverter final ~RvsdgToIpGraphConverter(); explicit RvsdgToIpGraphConverter( - const std::shared_ptr & regionSequentializer); + const std::shared_ptr & regionSequentializer); RvsdgToIpGraphConverter(const RvsdgToIpGraphConverter &) = delete; @@ -73,7 +73,7 @@ class RvsdgToIpGraphConverter final CreateAndConvertModule( RvsdgModule & rvsdgModule, util::StatisticsCollector & statisticsCollector, - const std::shared_ptr & regionSequentializer); + const std::shared_ptr & regionSequentializer); private: void @@ -123,7 +123,7 @@ class RvsdgToIpGraphConverter final std::unique_ptr Context_; - std::shared_ptr RegionSequentializer_; + std::shared_ptr RegionTreeSequentializer_; }; } diff --git a/jlm/tooling/Command.cpp b/jlm/tooling/Command.cpp index 178308154..597d12c40 100644 --- a/jlm/tooling/Command.cpp +++ b/jlm/tooling/Command.cpp @@ -529,7 +529,8 @@ JlmOptCommand::PrintAsLlvm( const util::filepath & outputFile, util::StatisticsCollector & statisticsCollector) { - auto sequentializer = std::make_shared(); + auto sequentializer = std::make_shared( + rvsdgModule.Rvsdg().GetRootRegion()); auto jlm_module = llvm::RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, diff --git a/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp b/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp index 65534eb3c..56840a002 100644 --- a/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp +++ b/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp @@ -14,7 +14,7 @@ Test() jlm::tests::LoadTest1 test; test.InitializeTest(); - jlm::llvm::ExhaustiveSingleRegionSequentializer sequentializer(*test.GetLambdaNode().subregion()); + jlm::llvm::ExhaustiveRegionSequentializer sequentializer(*test.GetLambdaNode().subregion()); assert(sequentializer.HasMoreSequentializations()); auto sequentializationMap = sequentializer.ComputeNextSequentialization(); diff --git a/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp b/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp index 1b69fc759..ae6499c7f 100644 --- a/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp +++ b/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp @@ -49,8 +49,8 @@ GammaWithMatch() // Act StatisticsCollector statisticsCollector; - auto sequentializer = std::make_shared(); - sequentializer->Initialize(rvsdgModule.Rvsdg().GetRootRegion()); + auto sequentializer = + std::make_shared(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -106,8 +106,8 @@ GammaWithoutMatch() // Act StatisticsCollector statisticsCollector; - auto sequentializer = std::make_shared(); - sequentializer->Initialize(rvsdgModule.Rvsdg().GetRootRegion()); + auto sequentializer = + std::make_shared(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -168,8 +168,8 @@ EmptyGammaWithThreeSubregions() // Act StatisticsCollector statisticsCollector; - auto sequentializer = std::make_shared(); - sequentializer->Initialize(rvsdgModule.Rvsdg().GetRootRegion()); + auto sequentializer = + std::make_shared(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -226,8 +226,8 @@ PartialEmptyGamma() // Act StatisticsCollector statisticsCollector; - auto sequentializer = std::make_shared(); - sequentializer->Initialize(rvsdgModule.Rvsdg().GetRootRegion()); + auto sequentializer = + std::make_shared(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -299,8 +299,8 @@ RecursiveData() // Act jlm::util::StatisticsCollector statisticsCollector; - auto sequentializer = std::make_shared(); - sequentializer->Initialize(rm.Rvsdg().GetRootRegion()); + auto sequentializer = + std::make_shared(rm.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rm, statisticsCollector, sequentializer); print(*module, stdout); diff --git a/tools/jlm-hls/jlm-hls.cpp b/tools/jlm-hls/jlm-hls.cpp index fb2c79bc7..a424c07f0 100644 --- a/tools/jlm-hls/jlm-hls.cpp +++ b/tools/jlm-hls/jlm-hls.cpp @@ -35,7 +35,8 @@ llvmToFile(jlm::llvm::RvsdgModule & module, const jlm::util::filepath & fileName { llvm::LLVMContext ctx; jlm::util::StatisticsCollector statisticsCollector; - auto sequentializer = std::make_shared(); + auto sequentializer = std::make_shared( + module.Rvsdg().GetRootRegion()); auto jm = jlm::llvm::RvsdgToIpGraphConverter::CreateAndConvertModule( module, statisticsCollector, From 098ef96c6d149ea474c11219e822697118a1dc54 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Tue, 25 Mar 2025 10:37:15 +0100 Subject: [PATCH 4/7] TODO --- jlm/llvm/backend/RegionSequentializer.cpp | 6 +++--- .../backend/ExhaustiveSequentializerTests.cpp | 20 +++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/jlm/llvm/backend/RegionSequentializer.cpp b/jlm/llvm/backend/RegionSequentializer.cpp index f6e9409e3..fcc0eba18 100644 --- a/jlm/llvm/backend/RegionSequentializer.cpp +++ b/jlm/llvm/backend/RegionSequentializer.cpp @@ -38,7 +38,7 @@ Sequentialization ExhaustiveRegionSequentializer::GetSequentialization() { if (!HasMoreSequentializations()) - CurrentSequentialization_ = 0; + ComputeNextSequentialization(); return Sequentializations_[CurrentSequentialization_]; } @@ -46,8 +46,8 @@ ExhaustiveRegionSequentializer::GetSequentialization() bool ExhaustiveRegionSequentializer::HasMoreSequentializations() const noexcept { - JLM_ASSERT(CurrentSequentialization_ < Sequentializations_.size()); - return (CurrentSequentialization_ + 1) != Sequentializations_.size(); + JLM_ASSERT(CurrentSequentialization_ <= Sequentializations_.size()); + return CurrentSequentialization_ != Sequentializations_.size(); } void diff --git a/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp b/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp index 56840a002..c71a35cfb 100644 --- a/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp +++ b/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp @@ -7,25 +7,29 @@ #include #include -#if 0 static int Test() { jlm::tests::LoadTest1 test; test.InitializeTest(); - jlm::llvm::ExhaustiveRegionSequentializer sequentializer(*test.GetLambdaNode().subregion()); + jlm::llvm::ExhaustiveRegionTreeSequentializer sequentializer(*test.GetLambdaNode().subregion()); assert(sequentializer.HasMoreSequentializations()); - auto sequentializationMap = sequentializer.ComputeNextSequentialization(); - assert(sequentializationMap.has_value()); - assert(!sequentializer.HasMoreSequentializations()); + auto & regionSequentializer = sequentializer.GetSequentializer(*test.GetLambdaNode().subregion()); + while (sequentializer.HasMoreSequentializations()) + { + auto sequentialization = regionSequentializer.GetSequentialization(); + for (const auto & node : sequentialization) + { + std::cout << node->GetOperation().debug_string() << std::endl; + } + std::cout << std::endl; - sequentializationMap = sequentializer.ComputeNextSequentialization(); - assert(!sequentializationMap.has_value()); + sequentializer.ComputeNextSequentializations(); + } return 0; } JLM_UNIT_TEST_REGISTER("jlm/llvm/backend/ExhaustiveSequentializerTests-Test", Test) -#endif From f02a85ffe5c045b232a4fa4e97d3c2dda264ee07 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Wed, 26 Mar 2025 09:39:45 +0100 Subject: [PATCH 5/7] TODO --- jlm/llvm/backend/RegionSequentializer.cpp | 4 +- jlm/llvm/backend/RegionSequentializer.hpp | 49 ++++++++++++++++--- jlm/llvm/backend/RvsdgToIpGraphConverter.cpp | 2 +- .../backend/ExhaustiveSequentializerTests.cpp | 2 +- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/jlm/llvm/backend/RegionSequentializer.cpp b/jlm/llvm/backend/RegionSequentializer.cpp index fcc0eba18..7620ab9ef 100644 --- a/jlm/llvm/backend/RegionSequentializer.cpp +++ b/jlm/llvm/backend/RegionSequentializer.cpp @@ -144,7 +144,7 @@ IdempotentRegionTreeSequentializer::ComputeNextSequentializations() } RegionSequentializer & -IdempotentRegionTreeSequentializer::GetSequentializer(rvsdg::Region & region) +IdempotentRegionTreeSequentializer::GetRegionSequentializer(rvsdg::Region & region) { JLM_ASSERT(Sequentializers_.find(®ion) != Sequentializers_.end()); return *Sequentializers_[®ion]; @@ -219,7 +219,7 @@ ExhaustiveRegionTreeSequentializer::ComputeNextSequentializations() } RegionSequentializer & -ExhaustiveRegionTreeSequentializer::GetSequentializer(rvsdg::Region & region) +ExhaustiveRegionTreeSequentializer::GetRegionSequentializer(rvsdg::Region & region) { JLM_ASSERT(Sequentializers_.find(®ion) != Sequentializers_.end()); return *Sequentializers_[®ion]; diff --git a/jlm/llvm/backend/RegionSequentializer.hpp b/jlm/llvm/backend/RegionSequentializer.hpp index dc955aeed..b414ef2d4 100644 --- a/jlm/llvm/backend/RegionSequentializer.hpp +++ b/jlm/llvm/backend/RegionSequentializer.hpp @@ -21,9 +21,13 @@ namespace jlm::llvm { using Sequentialization = std::vector; -using SequentializationMap = std::unordered_map; -// FIXME: add documentation +/** + * The RegionSequentializer class computes sequentializations, i.e., topological orderings, for a + * single region. The interface permits the computation of different sequentializations + * by invoking ComputeNextSequentialization(). It can be checked whether there are still orderings + * available by invoking HasMoreSequentializations(). + */ class RegionSequentializer { public: @@ -41,15 +45,29 @@ class RegionSequentializer RegionSequentializer & operator=(RegionSequentializer &&) = delete; + /** + * @return The current sequentialization of the region. Nodes are stored in dependency-order in + * the sequentialization, i.e., nodes without any dependency appear first in the + * sequentialization. + */ virtual Sequentialization GetSequentialization() = 0; + /** + * @return True, if there are more sequentializations to return, otherwise false. + */ virtual bool HasMoreSequentializations() const noexcept = 0; + /** + * Computes the next sequentialization of the region. + */ virtual void ComputeNextSequentialization() = 0; + /** + * @return The region for which sequentializations are computed. + */ rvsdg::Region & GetRegion() const noexcept { @@ -60,7 +78,22 @@ class RegionSequentializer rvsdg::Region * Region_; }; -// FIXME: add documentation +/** + * The ExhaustiveRegionSequentializer computes all sequentializations of a region. It is + * possible to iterate through these sequentializations as follows: + * + * \code{.c} + * while(sequentializer.HasMoreSequentializations) + * { + * auto sequentialization = sequentializer.GetSequentialization(); + * ... + * sequentializer.ComputeNextSequentialization(); + * } + * \endcode + * + * The sequentializer will wrap around after the "last" sequentialization and + * return the "first" sequentialization again. + */ class ExhaustiveRegionSequentializer final : public RegionSequentializer { public: @@ -93,6 +126,10 @@ class ExhaustiveRegionSequentializer final : public RegionSequentializer std::vector Sequentializations_; }; +/** + * The IdempotentRegionSequentializer computes a single sequentialization of a region and + * only ever returns this single sequentialization. + */ class IdempotentRegionSequentializer final : public RegionSequentializer { public: @@ -132,7 +169,7 @@ class RegionTreeSequentializer ComputeNextSequentializations() = 0; virtual RegionSequentializer & - GetSequentializer(rvsdg::Region & region) = 0; + GetRegionSequentializer(rvsdg::Region & region) = 0; virtual bool HasMoreSequentializations() const noexcept = 0; @@ -150,7 +187,7 @@ class IdempotentRegionTreeSequentializer final : public RegionTreeSequentializer ComputeNextSequentializations() override; RegionSequentializer & - GetSequentializer(rvsdg::Region & region) override; + GetRegionSequentializer(rvsdg::Region & region) override; bool HasMoreSequentializations() const noexcept override; @@ -175,7 +212,7 @@ class ExhaustiveRegionTreeSequentializer final : public RegionTreeSequentializer ComputeNextSequentializations() override; RegionSequentializer & - GetSequentializer(rvsdg::Region & region) override; + GetRegionSequentializer(rvsdg::Region & region) override; bool HasMoreSequentializations() const noexcept override; diff --git a/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp b/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp index fe01a9397..46c326eb5 100644 --- a/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp +++ b/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp @@ -180,7 +180,7 @@ RvsdgToIpGraphConverter::ConvertRegion(rvsdg::Region & region) Context_->SetLastProcessedBasicBlock(entryBlock); auto sequentialization = - RegionTreeSequentializer_->GetSequentializer(region).GetSequentialization(); + RegionTreeSequentializer_->GetRegionSequentializer(region).GetSequentialization(); for (const auto & node : sequentialization) ConvertIntraProceduralNode(*node); diff --git a/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp b/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp index c71a35cfb..e685c2cf0 100644 --- a/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp +++ b/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp @@ -16,7 +16,7 @@ Test() jlm::llvm::ExhaustiveRegionTreeSequentializer sequentializer(*test.GetLambdaNode().subregion()); assert(sequentializer.HasMoreSequentializations()); - auto & regionSequentializer = sequentializer.GetSequentializer(*test.GetLambdaNode().subregion()); + auto & regionSequentializer = sequentializer.GetRegionSequentializer(*test.GetLambdaNode().subregion()); while (sequentializer.HasMoreSequentializations()) { auto sequentialization = regionSequentializer.GetSequentialization(); From e65fa7c59a7679856e4f600523234a5ac9fb00bf Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Wed, 26 Mar 2025 10:41:54 +0100 Subject: [PATCH 6/7] TODO --- jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp | 6 +- jlm/llvm/backend/RegionSequentializer.cpp | 99 +++++-------- jlm/llvm/backend/RegionSequentializer.hpp | 130 ++++++++---------- jlm/llvm/backend/RvsdgToIpGraphConverter.cpp | 10 +- jlm/llvm/backend/RvsdgToIpGraphConverter.hpp | 7 +- jlm/tooling/Command.cpp | 4 +- .../backend/ExhaustiveSequentializerTests.cpp | 7 +- .../backend/RvsdgToIpGraphConverterTests.cpp | 11 +- tools/jlm-hls/jlm-hls.cpp | 4 +- 9 files changed, 115 insertions(+), 163 deletions(-) diff --git a/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp b/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp index f651d0b07..bcf0efebe 100644 --- a/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp +++ b/jlm/hls/backend/rvsdg2rhls/rvsdg2rhls.cpp @@ -488,9 +488,9 @@ dump_ref(llvm::RvsdgModule & rhls, const util::filepath & path) << "\n"; } ::llvm::LLVMContext ctx; - jlm::util::StatisticsCollector statisticsCollector; - auto sequentializer = std::make_shared( - reference->Rvsdg().GetRootRegion()); + util::StatisticsCollector statisticsCollector; + auto sequentializer = + llvm::CreateIdempotentRegionTreeSequentializer(reference->Rvsdg().GetRootRegion()); auto jm2 = llvm::RvsdgToIpGraphConverter::CreateAndConvertModule( *reference, statisticsCollector, diff --git a/jlm/llvm/backend/RegionSequentializer.cpp b/jlm/llvm/backend/RegionSequentializer.cpp index 7620ab9ef..bda79006f 100644 --- a/jlm/llvm/backend/RegionSequentializer.cpp +++ b/jlm/llvm/backend/RegionSequentializer.cpp @@ -125,17 +125,12 @@ IdempotentRegionSequentializer::HasMoreSequentializations() const noexcept RegionTreeSequentializer::~RegionTreeSequentializer() noexcept = default; -RegionTreeSequentializer::RegionTreeSequentializer() = default; - -IdempotentRegionTreeSequentializer::~IdempotentRegionTreeSequentializer() noexcept = default; - -IdempotentRegionTreeSequentializer::IdempotentRegionTreeSequentializer(rvsdg::Region & region) -{ - InitializeSequentializers(region); -} +RegionTreeSequentializer::RegionTreeSequentializer(SequentializerMap sequentializerMap) + : Sequentializers_(std::move(sequentializerMap)) +{} void -IdempotentRegionTreeSequentializer::ComputeNextSequentializations() +RegionTreeSequentializer::ComputeNextSequentializations() { for (auto & [region, sequentializer] : Sequentializers_) { @@ -143,15 +138,8 @@ IdempotentRegionTreeSequentializer::ComputeNextSequentializations() } } -RegionSequentializer & -IdempotentRegionTreeSequentializer::GetRegionSequentializer(rvsdg::Region & region) -{ - JLM_ASSERT(Sequentializers_.find(®ion) != Sequentializers_.end()); - return *Sequentializers_[®ion]; -} - bool -IdempotentRegionTreeSequentializer::HasMoreSequentializations() const noexcept +RegionTreeSequentializer::HasMoreSequentializations() const noexcept { for (auto & [_, sequentializer] : Sequentializers_) { @@ -162,37 +150,20 @@ IdempotentRegionTreeSequentializer::HasMoreSequentializations() const noexcept return false; } -void -IdempotentRegionTreeSequentializer::InitializeSequentializers(rvsdg::Region & region) -{ - auto sequentializer = std::make_unique(region); - - for (auto & node : region.Nodes()) - { - if (const auto structuralNode = dynamic_cast(&node)) - { - for (size_t n = 0; n < structuralNode->nsubregions(); n++) - { - const auto subregion = structuralNode->subregion(n); - InitializeSequentializers(*subregion); - } - } - } - - Sequentializers_[®ion] = std::move(sequentializer); -} - -ExhaustiveRegionTreeSequentializer::~ExhaustiveRegionTreeSequentializer() noexcept = default; - -ExhaustiveRegionTreeSequentializer::ExhaustiveRegionTreeSequentializer(rvsdg::Region & region) +Sequentialization +RegionTreeSequentializer::GetSequentialization(rvsdg::Region & region) { - InitializeSequentializers(region); + JLM_ASSERT(Sequentializers_.find(®ion) != Sequentializers_.end()); + return Sequentializers_[®ion]->GetSequentialization(); } +template void -ExhaustiveRegionTreeSequentializer::InitializeSequentializers(rvsdg::Region & region) +InitializeUniformRegionTreeSequentializer( + rvsdg::Region & region, + SequentializerMap & sequentializerMap) { - auto sequentializer = std::make_unique(region); + auto sequentializer = std::make_unique(region); for (auto & node : region.Nodes()) { @@ -201,40 +172,34 @@ ExhaustiveRegionTreeSequentializer::InitializeSequentializers(rvsdg::Region & re for (size_t n = 0; n < structuralNode->nsubregions(); n++) { const auto subregion = structuralNode->subregion(n); - InitializeSequentializers(*subregion); + InitializeUniformRegionTreeSequentializer( + *subregion, + sequentializerMap); } } } - Sequentializers_[®ion] = std::move(sequentializer); -} - -void -ExhaustiveRegionTreeSequentializer::ComputeNextSequentializations() -{ - for (auto & [region, sequentializer] : Sequentializers_) - { - sequentializer->ComputeNextSequentialization(); - } + sequentializerMap[®ion] = std::move(sequentializer); } -RegionSequentializer & -ExhaustiveRegionTreeSequentializer::GetRegionSequentializer(rvsdg::Region & region) +RegionTreeSequentializer +CreateIdempotentRegionTreeSequentializer(rvsdg::Region & rootRegion) { - JLM_ASSERT(Sequentializers_.find(®ion) != Sequentializers_.end()); - return *Sequentializers_[®ion]; + SequentializerMap sequentializerMap; + InitializeUniformRegionTreeSequentializer( + rootRegion, + sequentializerMap); + return RegionTreeSequentializer(std::move(sequentializerMap)); } -bool -ExhaustiveRegionTreeSequentializer::HasMoreSequentializations() const noexcept +RegionTreeSequentializer +CreateExhaustiveRegionTreeSequentializer(rvsdg::Region & rootRegion) { - for (auto & [_, sequentializer] : Sequentializers_) - { - if (sequentializer->HasMoreSequentializations()) - return true; - } - - return false; + SequentializerMap sequentializerMap; + InitializeUniformRegionTreeSequentializer( + rootRegion, + sequentializerMap); + return RegionTreeSequentializer(std::move(sequentializerMap)); } } diff --git a/jlm/llvm/backend/RegionSequentializer.hpp b/jlm/llvm/backend/RegionSequentializer.hpp index b414ef2d4..4b717cb4e 100644 --- a/jlm/llvm/backend/RegionSequentializer.hpp +++ b/jlm/llvm/backend/RegionSequentializer.hpp @@ -27,6 +27,17 @@ using Sequentialization = std::vector; * single region. The interface permits the computation of different sequentializations * by invoking ComputeNextSequentialization(). It can be checked whether there are still orderings * available by invoking HasMoreSequentializations(). + * + * Thus, all sequentializations can be obtained as follows: + * + * \code{.c} + * while(sequentializer.HasMoreSequentializations) + * { + * auto sequentialization = sequentializer.GetSequentialization(); + * ... + * sequentializer.ComputeNextSequentialization(); + * } + * \endcode */ class RegionSequentializer { @@ -79,20 +90,9 @@ class RegionSequentializer }; /** - * The ExhaustiveRegionSequentializer computes all sequentializations of a region. It is - * possible to iterate through these sequentializations as follows: - * - * \code{.c} - * while(sequentializer.HasMoreSequentializations) - * { - * auto sequentialization = sequentializer.GetSequentialization(); - * ... - * sequentializer.ComputeNextSequentialization(); - * } - * \endcode - * - * The sequentializer will wrap around after the "last" sequentialization and - * return the "first" sequentialization again. + * The ExhaustiveRegionSequentializer class computes all sequentializations of a region. The + * sequentializer will wrap around after the "last" sequentialization and return the "first" + * sequentialization again. */ class ExhaustiveRegionSequentializer final : public RegionSequentializer { @@ -127,8 +127,8 @@ class ExhaustiveRegionSequentializer final : public RegionSequentializer }; /** - * The IdempotentRegionSequentializer computes a single sequentialization of a region and - * only ever returns this single sequentialization. + * The IdempotentRegionSequentializer class computes a single sequentialization of a region + * and only ever returns this single sequentialization. */ class IdempotentRegionSequentializer final : public RegionSequentializer { @@ -147,13 +147,20 @@ class IdempotentRegionSequentializer final : public RegionSequentializer ComputeNextSequentialization() override; }; -// FIXME: add documentation -class RegionTreeSequentializer +using SequentializerMap = + std::unordered_map>; + +/** + * The RegionTreeSequentializer class extends the concepts of the RegionSequentializer from a single + * region to a region tree. Thus, it computes the sequentializations for a root region and all its + * subregions. + */ +class RegionTreeSequentializer final { public: - virtual ~RegionTreeSequentializer() noexcept; + ~RegionTreeSequentializer() noexcept; - RegionTreeSequentializer(); + explicit RegionTreeSequentializer(SequentializerMap sequentializerMap); RegionTreeSequentializer(const RegionTreeSequentializer &) = delete; @@ -165,65 +172,48 @@ class RegionTreeSequentializer RegionTreeSequentializer & operator=(RegionTreeSequentializer &&) = delete; - virtual void - ComputeNextSequentializations() = 0; - - virtual RegionSequentializer & - GetRegionSequentializer(rvsdg::Region & region) = 0; - - virtual bool - HasMoreSequentializations() const noexcept = 0; -}; - -// FIXME: add documentation -class IdempotentRegionTreeSequentializer final : public RegionTreeSequentializer -{ -public: - ~IdempotentRegionTreeSequentializer() noexcept override; - - explicit IdempotentRegionTreeSequentializer(rvsdg::Region & region); - + /** + * Computes the next sequentialization for the regions in the tree. + */ void - ComputeNextSequentializations() override; + ComputeNextSequentializations(); - RegionSequentializer & - GetRegionSequentializer(rvsdg::Region & region) override; + /** + * @param region A (sub-)region of the region tree. + * @return The current sequentialization of the region. + */ + Sequentialization + GetSequentialization(rvsdg::Region & region); + /** + * @return True, if there are more sequentializations to return, otherwise false. + */ bool - HasMoreSequentializations() const noexcept override; + HasMoreSequentializations() const noexcept; private: - void - InitializeSequentializers(rvsdg::Region & region); - - std::unordered_map> - Sequentializers_; + SequentializerMap Sequentializers_; }; -// FIXME: add documentation -class ExhaustiveRegionTreeSequentializer final : public RegionTreeSequentializer -{ -public: - ~ExhaustiveRegionTreeSequentializer() noexcept override; - - explicit ExhaustiveRegionTreeSequentializer(rvsdg::Region & region); - - void - ComputeNextSequentializations() override; - - RegionSequentializer & - GetRegionSequentializer(rvsdg::Region & region) override; - - bool - HasMoreSequentializations() const noexcept override; - -private: - void - InitializeSequentializers(rvsdg::Region & region); +/** + * Creates an instance of RegionTreeSequentializer where IdempotentRegionSequentializer instances + * are used for all regions in the tree. + * + * @param rootRegion The root of the region tree. + * @return An instance of RegionTreeSequentializer. + */ +RegionTreeSequentializer +CreateIdempotentRegionTreeSequentializer(rvsdg::Region & rootRegion); - std::unordered_map> - Sequentializers_; -}; +/** + * Creates an instance of RegionTreeSequentializer where IdempotentRegionSequentializer instances + * are used for all regions in the tree. + * + * @param rootRegion The root of the region tree. + * @return An instance of RegionTreeSequentializer. + */ +RegionTreeSequentializer +CreateExhaustiveRegionTreeSequentializer(rvsdg::Region & rootRegion); } diff --git a/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp b/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp index 46c326eb5..1ff8540f1 100644 --- a/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp +++ b/jlm/llvm/backend/RvsdgToIpGraphConverter.cpp @@ -129,9 +129,8 @@ class RvsdgToIpGraphConverter::Statistics final : public util::Statistics RvsdgToIpGraphConverter::~RvsdgToIpGraphConverter() = default; -RvsdgToIpGraphConverter::RvsdgToIpGraphConverter( - const std::shared_ptr & regionSequentializer) - : RegionTreeSequentializer_(regionSequentializer) +RvsdgToIpGraphConverter::RvsdgToIpGraphConverter(RegionTreeSequentializer & regionSequentializer) + : RegionTreeSequentializer_(®ionSequentializer) {} std::unique_ptr @@ -179,8 +178,7 @@ RvsdgToIpGraphConverter::ConvertRegion(rvsdg::Region & region) Context_->GetLastProcessedBasicBlock()->add_outedge(entryBlock); Context_->SetLastProcessedBasicBlock(entryBlock); - auto sequentialization = - RegionTreeSequentializer_->GetRegionSequentializer(region).GetSequentialization(); + const auto sequentialization = RegionTreeSequentializer_->GetSequentialization(region); for (const auto & node : sequentialization) ConvertIntraProceduralNode(*node); @@ -721,7 +719,7 @@ std::unique_ptr RvsdgToIpGraphConverter::CreateAndConvertModule( RvsdgModule & rvsdgModule, util::StatisticsCollector & statisticsCollector, - const std::shared_ptr & regionSequentializer) + RegionTreeSequentializer & regionSequentializer) { RvsdgToIpGraphConverter converter(regionSequentializer); return converter.ConvertModule(rvsdgModule, statisticsCollector); diff --git a/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp b/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp index af3392bf0..919281ea2 100644 --- a/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp +++ b/jlm/llvm/backend/RvsdgToIpGraphConverter.hpp @@ -53,8 +53,7 @@ class RvsdgToIpGraphConverter final public: ~RvsdgToIpGraphConverter(); - explicit RvsdgToIpGraphConverter( - const std::shared_ptr & regionSequentializer); + explicit RvsdgToIpGraphConverter(RegionTreeSequentializer & regionSequentializer); RvsdgToIpGraphConverter(const RvsdgToIpGraphConverter &) = delete; @@ -73,7 +72,7 @@ class RvsdgToIpGraphConverter final CreateAndConvertModule( RvsdgModule & rvsdgModule, util::StatisticsCollector & statisticsCollector, - const std::shared_ptr & regionSequentializer); + RegionTreeSequentializer & regionSequentializer); private: void @@ -123,7 +122,7 @@ class RvsdgToIpGraphConverter final std::unique_ptr Context_; - std::shared_ptr RegionTreeSequentializer_; + RegionTreeSequentializer * RegionTreeSequentializer_; }; } diff --git a/jlm/tooling/Command.cpp b/jlm/tooling/Command.cpp index 597d12c40..5ccc8e785 100644 --- a/jlm/tooling/Command.cpp +++ b/jlm/tooling/Command.cpp @@ -529,8 +529,8 @@ JlmOptCommand::PrintAsLlvm( const util::filepath & outputFile, util::StatisticsCollector & statisticsCollector) { - auto sequentializer = std::make_shared( - rvsdgModule.Rvsdg().GetRootRegion()); + auto sequentializer = + llvm::CreateIdempotentRegionTreeSequentializer(rvsdgModule.Rvsdg().GetRootRegion()); auto jlm_module = llvm::RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, diff --git a/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp b/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp index e685c2cf0..679cb2a10 100644 --- a/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp +++ b/tests/jlm/llvm/backend/ExhaustiveSequentializerTests.cpp @@ -13,13 +13,14 @@ Test() jlm::tests::LoadTest1 test; test.InitializeTest(); - jlm::llvm::ExhaustiveRegionTreeSequentializer sequentializer(*test.GetLambdaNode().subregion()); + auto & lambdaRegion = *test.GetLambdaNode().subregion(); + auto sequentializer = + jlm::llvm::CreateExhaustiveRegionTreeSequentializer(*test.GetLambdaNode().subregion()); assert(sequentializer.HasMoreSequentializations()); - auto & regionSequentializer = sequentializer.GetRegionSequentializer(*test.GetLambdaNode().subregion()); while (sequentializer.HasMoreSequentializations()) { - auto sequentialization = regionSequentializer.GetSequentialization(); + auto sequentialization = sequentializer.GetSequentialization(lambdaRegion); for (const auto & node : sequentialization) { std::cout << node->GetOperation().debug_string() << std::endl; diff --git a/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp b/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp index ae6499c7f..a85e153f2 100644 --- a/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp +++ b/tests/jlm/llvm/backend/RvsdgToIpGraphConverterTests.cpp @@ -50,7 +50,7 @@ GammaWithMatch() // Act StatisticsCollector statisticsCollector; auto sequentializer = - std::make_shared(rvsdgModule.Rvsdg().GetRootRegion()); + CreateIdempotentRegionTreeSequentializer(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -107,7 +107,7 @@ GammaWithoutMatch() // Act StatisticsCollector statisticsCollector; auto sequentializer = - std::make_shared(rvsdgModule.Rvsdg().GetRootRegion()); + CreateIdempotentRegionTreeSequentializer(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -169,7 +169,7 @@ EmptyGammaWithThreeSubregions() // Act StatisticsCollector statisticsCollector; auto sequentializer = - std::make_shared(rvsdgModule.Rvsdg().GetRootRegion()); + CreateIdempotentRegionTreeSequentializer(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -227,7 +227,7 @@ PartialEmptyGamma() // Act StatisticsCollector statisticsCollector; auto sequentializer = - std::make_shared(rvsdgModule.Rvsdg().GetRootRegion()); + CreateIdempotentRegionTreeSequentializer(rvsdgModule.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule( rvsdgModule, statisticsCollector, @@ -299,8 +299,7 @@ RecursiveData() // Act jlm::util::StatisticsCollector statisticsCollector; - auto sequentializer = - std::make_shared(rm.Rvsdg().GetRootRegion()); + auto sequentializer = CreateIdempotentRegionTreeSequentializer(rm.Rvsdg().GetRootRegion()); auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rm, statisticsCollector, sequentializer); print(*module, stdout); diff --git a/tools/jlm-hls/jlm-hls.cpp b/tools/jlm-hls/jlm-hls.cpp index a424c07f0..5f5a96da9 100644 --- a/tools/jlm-hls/jlm-hls.cpp +++ b/tools/jlm-hls/jlm-hls.cpp @@ -35,8 +35,8 @@ llvmToFile(jlm::llvm::RvsdgModule & module, const jlm::util::filepath & fileName { llvm::LLVMContext ctx; jlm::util::StatisticsCollector statisticsCollector; - auto sequentializer = std::make_shared( - module.Rvsdg().GetRootRegion()); + auto sequentializer = + jlm::llvm::CreateIdempotentRegionTreeSequentializer(module.Rvsdg().GetRootRegion()); auto jm = jlm::llvm::RvsdgToIpGraphConverter::CreateAndConvertModule( module, statisticsCollector, From 7c8f694a520ab261f7dd164c950943a19e3effb2 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Fri, 28 Mar 2025 18:21:49 +0100 Subject: [PATCH 7/7] TODO --- jlm/llvm/backend/RegionSequentializer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jlm/llvm/backend/RegionSequentializer.cpp b/jlm/llvm/backend/RegionSequentializer.cpp index bda79006f..bea7c0e8e 100644 --- a/jlm/llvm/backend/RegionSequentializer.cpp +++ b/jlm/llvm/backend/RegionSequentializer.cpp @@ -11,7 +11,7 @@ namespace jlm::llvm { -RegionSequentializer::~RegionSequentializer() = default; +RegionSequentializer::~RegionSequentializer() noexcept = default; RegionSequentializer::RegionSequentializer(rvsdg::Region & region) : Region_(®ion)