47 static std::unique_ptr<Statistics>
50 return std::make_unique<Statistics>(sourceFile);
80 static std::unique_ptr<Context>
83 return std::make_unique<Context>(lambdaNode);
88 std::unordered_map<const rvsdg::Node *, rvsdg::Region *>
TargetRegion_{};
100 if (!is<MemoryStateType>(loopVar.
output->
Type()))
109 if (userNode != originNode)
135 const auto roleVar = gammaNode->MapBranchArgument(output);
136 if (
const auto entryVar = std::get_if<rvsdg::GammaNode::EntryVar>(&roleVar))
147 const auto loopVar = thetaNode->MapPreLoopVar(output);
164 return context_->getTargetRegion(*gammaNode);
170 return context_->getTargetRegion(*thetaNode);
176 return context_->getTargetRegion(*node);
179 throw std::logic_error(
"Unhandled output type!");
192 const auto outputType = node.
output(0)->
Type();
193 if (is<rvsdg::ControlType>(outputType))
197 return context_->getLambdaSubregion();
203 for (
auto & input : node.
Inputs())
206 if (&targetRegion == node.
region())
214 if (greatestCommonTargetRegion
215 && greatestCommonTargetRegion->
getDepth() >= targetRegion.getDepth())
217 greatestCommonTargetRegion = &targetRegion;
222 return *greatestCommonTargetRegion;
235 context_->addTargetRegion(structuralNode, *structuralNode.
region());
238 for (
auto & subregion : structuralNode.
Subregions())
246 context_->addTargetRegion(*node, targetRegion);
250 throw std::logic_error(
"Unhandled node type!");
258 if (output.
region() == &targetRegion)
264 const auto roleVar = gammaNode->MapBranchArgument(output);
265 if (
const auto entryVar = std::get_if<rvsdg::GammaNode::EntryVar>(&roleVar))
274 const auto loopVar = thetaNode->MapPreLoopVar(output);
279 throw std::logic_error(
"Unhandled output type!");
282std::vector<rvsdg::Output *>
285 std::vector<rvsdg::Output *> operands;
286 for (
auto & input : node.
Inputs())
289 operands.push_back(&operand);
298 auto & targetRegion =
context_->getTargetRegion(node);
302 const auto copiedNode = node.
copy(&targetRegion, operands);
306 auto itOrg = std::begin(node.
Outputs());
307 const auto endOrg = std::end(node.
Outputs());
308 auto itCpy = std::begin(copiedNode->Outputs());
309 const auto endCpy = std::end(copiedNode->Outputs());
310 JLM_ASSERT(std::distance(itOrg, endOrg) == std::distance(itCpy, endCpy));
312 for (; itOrg != endOrg; ++itOrg, ++itCpy)
314 auto & outputOrg = *itOrg;
315 auto & outputCpy = *itCpy;
317 outputOrg.divert_users(&newOutputOrg);
328 auto & targetRegion =
context_->getTargetRegion(*node);
329 if (&targetRegion != node->region())
337 for (
auto & subregion : structuralNode->Subregions())
383 throw std::logic_error(
util::strfmt(
"Unhandled node type: ", node->DebugString()));
393 statistics->start(rvsdgModule.
Rvsdg());
395 statistics->end(rvsdgModule.
Rvsdg());
static jlm::util::StatisticsCollector statisticsCollector
Context(rvsdg::LambdaNode &lambdaNode)
rvsdg::Region * LambdaSubregion_
void addTargetRegion(const rvsdg::Node &node, rvsdg::Region ®ion) noexcept
std::unordered_map< const rvsdg::Node *, rvsdg::Region * > TargetRegion_
rvsdg::Region & getTargetRegion(const rvsdg::Node &node) const noexcept
static std::unique_ptr< Context > create(rvsdg::LambdaNode &lambdaNode)
rvsdg::Region & getLambdaSubregion() const noexcept
void end(const rvsdg::Graph &graph) noexcept
Statistics(const util::FilePath &sourceFile)
static std::unique_ptr< Statistics > Create(const util::FilePath &sourceFile)
~Statistics() override=default
void start(const rvsdg::Graph &graph) noexcept
Node Hoisting Transformation.
void hoistNodesInRootRegion(rvsdg::Region ®ion)
void hoistNodes(rvsdg::Region ®ion)
void hoistNodesInLambda(rvsdg::LambdaNode &lambdaNode)
void Run(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
~NodeHoisting() noexcept override
rvsdg::Region & computeTargetRegion(const rvsdg::Node &node) const
static std::vector< rvsdg::Output * > getOperandsFromTargetRegion(rvsdg::Node &node, rvsdg::Region &targetRegion)
std::unique_ptr< Context > context_
static bool isInvariantMemoryStateLoopVar(const rvsdg::ThetaNode::LoopVar &loopVar)
void copyNodeToTargetRegion(rvsdg::Node &node) const
void markNodes(const rvsdg::Region ®ion)
static rvsdg::Output & getOperandFromTargetRegion(rvsdg::Output &output, rvsdg::Region &targetRegion)
Region & GetRootRegion() const noexcept
rvsdg::Region * subregion() const noexcept
NodeOutput * output(size_t index) const noexcept
OutputIteratorRange Outputs() noexcept
rvsdg::Region * region() const noexcept
InputIteratorRange Inputs() noexcept
size_t ninputs() const noexcept
size_t noutputs() const noexcept
virtual Node * copy(rvsdg::Region *region, const std::vector< jlm::rvsdg::Output * > &operands) const
rvsdg::Region * region() const noexcept
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
size_t nusers() const noexcept
A phi node represents the fixpoint of mutually recursive definitions.
Represent acyclic RVSDG subgraphs.
void prune(bool recursive)
size_t getDepth() const noexcept
const std::optional< util::FilePath > & SourceFilePath() const noexcept
SubregionIteratorRange Subregions()
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
util::Timer & GetTimer(const std::string &name)
util::Timer & AddTimer(std::string name)
void AddMeasurement(std::string name, T value)
Global memory state passed between functions.
void MatchTypeWithDefault(T &obj, const Fns &... fns)
Pattern match over subclass type of given object with default handler.
static bool ThetaLoopVarIsInvariant(const ThetaNode::LoopVar &loopVar) noexcept
Output & RouteToRegion(Output &output, Region ®ion)
@ State
Designate a state type.
detail::TopDownTraverserGeneric< true > TopDownConstTraverser
Traverser for visiting every node in a const region in a top down order.
size_t ninputs(const rvsdg::Region *region) noexcept
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
detail::TopDownTraverserGeneric< false > TopDownTraverser
Traverser for visiting every node in a region in a top down order.
static std::string strfmt(Args... args)
Description of a loop-carried variable.
rvsdg::Output * pre
Variable before iteration (input argument to subregion).
rvsdg::Output * output
Variable at loop exit (output of theta).
rvsdg::Input * post
Variable after iteration (output result from subregion).