24 for (
auto & node : region.
Nodes())
47 for (
const auto constant : constants.Items())
51 std::unordered_map<rvsdg::Region *, rvsdg::Node *> distributedConstants;
52 distributedConstants[constant->region()] = constant;
54 auto insertAndDivertToNewConstant =
58 const auto region = output.
region();
60 const auto it = distributedConstants.find(region);
61 if (it == distributedConstants.end())
63 newConstant = oldConstant.
copy(region, {});
64 distributedConstants[region] = newConstant;
68 newConstant = it->second;
75 for (
const auto output :
outputs.Items())
78 if (rvsdg::TryGetOwnerNode<rvsdg::GammaNode>(*output)
79 || rvsdg::TryGetOwnerNode<rvsdg::ThetaNode>(*output)
80 || rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*output)
81 || rvsdg::TryGetRegionParentNode<rvsdg::ThetaNode>(*output))
83 insertAndDivertToNewConstant(*output, *constant);
86 else if (
const auto gammaNode = rvsdg::TryGetRegionParentNode<rvsdg::GammaNode>(*output))
89 auto roleVar = gammaNode->MapBranchArgument(*output);
90 if (
const auto entryVar = std::get_if<rvsdg::GammaNode::EntryVar>(&roleVar))
92 for (
const auto argument : entryVar->branchArgument)
94 insertAndDivertToNewConstant(*argument, *constant);
100 throw std::logic_error(
"Unhandled output type");
112 for (
auto & node : region.
Nodes())
118 for (
auto & subregion : gammaNode.
Subregions())
120 collect(subregion, constants);
125 collect(*thetaNode.subregion(), constants);
131 constants.insert(&simpleNode);
138 collect(region, constants);
151 for (
auto & user : output.
Users())
154 if (
const auto thetaNode = rvsdg::TryGetOwnerNode<rvsdg::ThetaNode>(user))
156 const auto loopVar = thetaNode->MapInputLoopVar(user);
163 else if (
const auto thetaNode = rvsdg::TryGetRegionParentNode<rvsdg::ThetaNode>(user))
165 if (&user != thetaNode->predicate())
167 const auto loopVar = thetaNode->MapPostLoopVar(user);
172 else if (
const auto gammaNode = rvsdg::TryGetOwnerNode<rvsdg::GammaNode>(user))
174 auto roleVar = gammaNode->MapInput(user);
175 if (
const auto entryVar = std::get_if<rvsdg::GammaNode::EntryVar>(&roleVar))
177 for (
const auto argument : entryVar->branchArgument)
184 else if (
const auto gammaNode = rvsdg::TryGetRegionParentNode<rvsdg::GammaNode>(user))
186 const auto exitVar = gammaNode->MapBranchResultExitVar(user);
194 rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(user)
195 || rvsdg::TryGetRegionParentNode<rvsdg::LambdaNode>(user))
201 throw std::logic_error(
"Unexpected node type");
static void distributeConstantsInRootRegion(rvsdg::Region ®ion)
static util::HashSet< rvsdg::Output * > collectOutputs(const rvsdg::SimpleNode &constantNode)
static void distributeConstantsInLambda(const rvsdg::LambdaNode &lambdaNode)
void Run(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
~ConstantDistribution() noexcept override
static util::HashSet< rvsdg::SimpleNode * > collectConstants(rvsdg::Region ®ion)
Conditional operator / pattern matching.
Region & GetRootRegion() const noexcept
rvsdg::Region * subregion() const noexcept
NodeOutput * output(size_t index) 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
void divert_users(jlm::rvsdg::Output *new_origin)
A phi node represents the fixpoint of mutually recursive definitions.
Represent acyclic RVSDG subgraphs.
NodeRange Nodes() noexcept
NodeOutput * output(size_t index) const noexcept
SubregionIteratorRange Subregions()
static bool is_constant(const rvsdg::Node *node)
void MatchTypeOrFail(T &obj, const Fns &... fns)
Pattern match over subclass type of given object.
static bool ThetaLoopVarIsInvariant(const ThetaNode::LoopVar &loopVar) noexcept
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
std::optional< rvsdg::Output * > GetGammaInvariantOrigin(const GammaNode &gamma, const GammaNode::ExitVar &exitvar)
Determines whether a gamma exit var is path-invariant.