Jlm
Loading...
Searching...
No Matches
CallSummary.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2018 Nico Reißmann <nico.reissmann@gmail.com>
3 * Copyright 2025 Helge Bahmann <hcb@chaoticmind.net>
4 * See COPYING for terms of redistribution.
5 */
6
8
11#include <jlm/rvsdg/gamma.hpp>
12#include <jlm/rvsdg/Phi.hpp>
13#include <jlm/rvsdg/theta.hpp>
14
15#include <deque>
16
17namespace jlm::llvm
18{
19
20static void
21AddToWorklist(std::deque<rvsdg::Input *> & worklist, rvsdg::Output & output)
22{
23 for (auto & user : output.Users())
24 {
25 worklist.emplace_back(&user);
26 }
27}
28
29CallSummary
31{
32 std::deque<rvsdg::Input *> worklist;
33 AddToWorklist(worklist, *lambdaNode.output());
34
35 std::vector<rvsdg::SimpleNode *> directCalls;
36 rvsdg::GraphExport * rvsdgExport = nullptr;
37 std::vector<rvsdg::Input *> otherUsers;
38
39 while (!worklist.empty())
40 {
41 auto input = worklist.front();
42 worklist.pop_front();
43
44 if (auto lambdaNode = rvsdg::TryGetOwnerNode<rvsdg::LambdaNode>(*input))
45 {
46 auto & argument = *lambdaNode->MapInputContextVar(*input).inner;
47 AddToWorklist(worklist, argument);
48 continue;
49 }
50
52 {
53 otherUsers.emplace_back(input);
54 continue;
55 }
56
57 if (auto gammaNode = rvsdg::TryGetOwnerNode<rvsdg::GammaNode>(*input))
58 {
59 auto rolevar = gammaNode->MapInput(*input);
60 if (auto entryvar = std::get_if<rvsdg::GammaNode::EntryVar>(&rolevar))
61 {
62 for (auto & argument : entryvar->branchArgument)
63 {
64 AddToWorklist(worklist, *argument);
65 }
66 }
67 continue;
68 }
69
71 {
72 auto output = gamma->MapBranchResultExitVar(*input).output;
73 AddToWorklist(worklist, *output);
74 continue;
75 }
76
77 if (auto theta = rvsdg::TryGetOwnerNode<rvsdg::ThetaNode>(*input))
78 {
79 auto loopvar = theta->MapInputLoopVar(*input);
80 AddToWorklist(worklist, *loopvar.pre);
81 continue;
82 }
83
85 {
86 auto loopvar = theta->MapPostLoopVar(*input);
87 AddToWorklist(worklist, *loopvar.output);
88 continue;
89 }
90
91 if (auto phi = rvsdg::TryGetOwnerNode<rvsdg::PhiNode>(*input))
92 {
93 auto ctxvar = phi->MapInputContextVar(*input);
94 AddToWorklist(worklist, *ctxvar.inner);
95 continue;
96 }
97
99 {
100 auto fixvar = phi->MapResultFixVar(*input);
101 AddToWorklist(worklist, *fixvar.recref);
102
103 auto output = fixvar.output;
104 AddToWorklist(worklist, *output);
105 continue;
106 }
107
108 if (auto deltaNode = rvsdg::TryGetOwnerNode<rvsdg::DeltaNode>(*input))
109 {
110 auto ctxVar = deltaNode->MapInputContextVar(*input);
111 AddToWorklist(worklist, *ctxVar.inner);
112 continue;
113 }
114
116 {
117 otherUsers.emplace_back(input);
118 continue;
119 }
120
121 auto inputNode = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*input);
122 if (is<CallOperation>(inputNode) && input == inputNode->input(0))
123 {
124 directCalls.emplace_back(inputNode);
125 continue;
126 }
127
128 if (auto graphExport = dynamic_cast<rvsdg::GraphExport *>(input))
129 {
130 rvsdgExport = graphExport;
131 continue;
132 }
133
135 {
136 otherUsers.emplace_back(input);
137 continue;
138 }
139
140 JLM_UNREACHABLE("This should have never happened!");
141 }
142
143 return CallSummary{ rvsdgExport, std::move(directCalls), std::move(otherUsers) };
144}
145
146}
ContextVar MapInputContextVar(const rvsdg::Input &input) const noexcept
Maps input to context variable.
Definition lambda.cpp:81
rvsdg::Output * output() const noexcept
Definition lambda.cpp:177
UsersRange Users()
Definition node.hpp:354
#define JLM_UNREACHABLE(msg)
Definition common.hpp:43
Global memory state passed between functions.
static void AddToWorklist(std::deque< rvsdg::Input * > &worklist, rvsdg::Output &output)
CallSummary ComputeCallSummary(const rvsdg::LambdaNode &lambdaNode)
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872
rvsdg::Output * inner
Access to bound object in subregion.
Definition lambda.hpp:117