41 static std::unique_ptr<Statistics>
44 return std::make_unique<Statistics>(sourceFile);
73 for (
auto & output : node.
Outputs())
75 for (
const auto & user : output.Users())
77 const auto successor = rvsdg::TryGetOwnerNode<rvsdg::Node>(user);
78 if (successor != &singleSuccessor)
91 for (
size_t i = 0; i < node->
ninputs(); i++)
94 std::size_t index = 0;
95 for (
auto input : ev.branchArgument)
105 for (
size_t o = 0; o < node->
noutputs(); o++)
109 auto entryvar = std::get<rvsdg::GammaNode::EntryVar>(gamma->
MapInput(user));
110 entryvar.branchArgument[r]->divert_users(copy->output(o));
122 std::vector<rvsdg::GammaNode::EntryVar> entryvars;
123 for (
size_t n = 0; n < node->
noutputs(); n++)
127 entryvars.push_back(std::get<rvsdg::GammaNode::EntryVar>(gamma->
MapInput(user)));
140 while (index < evs.size())
142 const auto & ev = evs[index];
143 auto node = rvsdg::TryGetOwnerNode<rvsdg::Node>(*ev.input->origin());
144 auto tmp = rvsdg::TryGetOwnerNode<rvsdg::Node>(*gamma->
predicate()->
origin());
167 for (
auto & output : node.
Outputs())
169 for (
auto & user : output.Users())
171 if (
const auto userNode = rvsdg::TryGetOwnerNode<rvsdg::Node>(user))
173 if (dependentNodes.insert(userNode))
175 collect(*userNode, dependentNodes);
183 collect(node, dependentNodes);
184 return dependentNodes;
187 std::vector<rvsdg::Node *>
195 std::vector<rvsdg::Node *> sortedNodes;
196 for (
auto & node : nodes.
Items())
198 sortedNodes.push_back(node);
205 [&depthMap](
const auto * node1,
const auto * node2)
207 JLM_ASSERT(depthMap.find(node1) != depthMap.end());
208 JLM_ASSERT(depthMap.find(node2) != depthMap.end());
209 return depthMap[node1] < depthMap[node2];
219 const auto sortedDependentNodes =
sortByDepth(dependentNodes);
224 for (
auto & node : sortedDependentNodes)
227 std::unordered_map<rvsdg::Region *, std::vector<rvsdg::Output *>> subregionOperands;
228 for (
auto & input : node->Inputs())
230 auto & oldOperand = *input.origin();
231 if (rvsdg::TryGetOwnerNode<rvsdg::Node>(oldOperand) == &gammaNode)
234 for (
const auto branchResult : branchResults)
236 subregionOperands[branchResult->region()].push_back(branchResult->origin());
241 auto [_, branchArguments] = gammaNode.
AddEntryVar(&oldOperand);
242 for (
auto branchArgument : branchArguments)
244 subregionOperands[branchArgument->region()].push_back(branchArgument);
250 std::unordered_map<rvsdg::Region *, std::vector<rvsdg::Output *>> subregionOutputs;
251 for (
auto & subregion : gammaNode.
Subregions())
253 const auto copiedNode = node->copy(&subregion, subregionOperands.at(&subregion));
258 for (
auto & output : node->Outputs())
260 std::vector<rvsdg::Output *> branchResultOperands;
261 for (
auto & subregion : gammaNode.
Subregions())
263 branchResultOperands.push_back(subregionOutputs[&subregion][output.index()]);
266 auto [_, exitVarOutput] = gammaNode.
AddExitVar(branchResultOperands);
267 output.divert_users(exitVarOutput);
271 return dependentNodes.Size();
280 std::unordered_set<const rvsdg::Input *> inputs;
281 for (
size_t n = 0; n < node->
noutputs(); n++)
285 inputs.insert(&user);
290 std::unordered_set<rvsdg::Region *> subregions;
291 for (
const auto & input : inputs)
294 [&subregions](
const auto & rolevar)
298 for (
const auto & argument : rolevar.branchArgument)
300 if (argument->nusers() != 0)
301 subregions.insert(argument->region());
304 else if constexpr (std::is_same<
305 std::decay_t<decltype(rolevar)>,
308 for (
const auto & argument : rolevar.matchContent)
310 if (argument->nusers() != 0)
311 subregions.insert(argument->region());
316 JLM_UNREACHABLE(
"A gamma input must either be the match variable or an entry variable");
322 return subregions.size();
335 auto prednode = rvsdg::TryGetOwnerNode<rvsdg::Node>(*gamma->
predicate()->
origin());
340 while (index < evs.size())
342 const auto & ev = evs[index];
343 auto node = rvsdg::TryGetOwnerNode<rvsdg::Node>(*ev.input->origin());
378 for (
size_t n = 0; n < structnode->nsubregions(); n++)
379 pull(structnode->subregion(n));
389 statistics->start(module.
Rvsdg());
391 statistics->end(module.
Rvsdg());
static jlm::util::StatisticsCollector statisticsCollector
void end(const rvsdg::Graph &graph) noexcept
~Statistics() override=default
Statistics(const util::FilePath &sourceFile)
static std::unique_ptr< Statistics > Create(const util::FilePath &sourceFile)
void start(const rvsdg::Graph &graph) noexcept
Node Sinking Optimization.
static std::vector< rvsdg::Node * > sortByDepth(const util::HashSet< rvsdg::Node * > &nodes)
static util::HashSet< rvsdg::Node * > collectDependentNodes(const rvsdg::Node &node)
static size_t sinkDependentNodesIntoGamma(rvsdg::GammaNode &gammaNode)
~NodeSinking() noexcept override
Conditional operator / pattern matching.
void RemoveEntryVars(const std::vector< EntryVar > &entryVars)
Removes the given entry variables.
ExitVar MapOutputExitVar(const rvsdg::Output &output) const
Maps gamma output to exit variable description.
std::variant< MatchVar, EntryVar > MapInput(const rvsdg::Input &input) const
Maps gamma input to its role (match variable or entry variable).
EntryVar AddEntryVar(rvsdg::Output *origin)
Routes a variable into the gamma branches.
std::vector< EntryVar > GetEntryVars() const
Gets all entry variables for this gamma.
rvsdg::Input * predicate() const noexcept
ExitVar AddExitVar(const std::vector< rvsdg::Output * > &values)
Routes per-branch result of gamma to output.
Region & GetRootRegion() const noexcept
OutputIteratorRange Outputs() noexcept
NodeInput * input(size_t index) const noexcept
NodeOutput * output(size_t index) const 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
Represent acyclic RVSDG subgraphs.
size_t numNodes() const noexcept
const std::optional< util::FilePath > & SourceFilePath() const noexcept
SubregionIteratorRange Subregions()
size_t nsubregions() const noexcept
rvsdg::Region * subregion(size_t index) const noexcept
IteratorRange< ItemConstIterator > Items() const noexcept
bool IsEmpty() const noexcept
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)
#define JLM_UNREACHABLE(msg)
Global memory state passed between functions.
static void pullin_node(rvsdg::GammaNode *gamma, rvsdg::Node *node)
static void cleanup(rvsdg::GammaNode *gamma, rvsdg::Node *node)
static size_t is_used_in_nsubregions(const rvsdg::GammaNode *gamma, const rvsdg::Node *node)
static bool empty(const rvsdg::GammaNode *gamma)
void pullin_top(rvsdg::GammaNode *gamma)
static bool isSingleSuccessor(const rvsdg::Node &node, const rvsdg::Node &singleSuccessor)
void pull(rvsdg::GammaNode *gamma)
static void remove(Node *node)
std::unordered_map< const Node *, size_t > computeDepthMap(const Region ®ion)
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
size_t ninputs(const rvsdg::Region *region) noexcept
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
A variable routed into all gamma regions.
The match/discriminator variable of this gamma node.
static const char * Timer
static const char * NumRvsdgInputsAfter
static const char * NumRvsdgInputsBefore