43 static std::unique_ptr<Statistics>
46 return std::make_unique<Statistics>(sourceFile);
83 for (
auto phiLambdaNode : phiLambdaNodes)
96 simpleNode.GetOperation(),
115 JLM_ASSERT(isGammaNode || isThetaNode || isLambdaNode);
119 for (
auto & node : region.
Nodes())
137 if (is<CallOperation>(simpleNode))
148 const auto isGammaNode = !!
dynamic_cast<rvsdg::GammaNode *
>(&structuralNode);
149 const auto isThetaNode = !!
dynamic_cast<rvsdg::ThetaNode *
>(&structuralNode);
152 for (
auto & subregion : structuralNode.
Subregions())
165 exitvar.output->divert_users(*invariantOrigin);
175 for (
const auto & loopVar : thetaNode.
GetLoopVars())
179 if (rvsdg::is<IOStateType>(loopVar.input->Type()))
183 loopVar.output->divert_users(loopVar.input->origin());
191 if (!correlationOpt.has_value())
195 auto & correlation = correlationOpt.value();
198 if (!subregionRolesOpt.has_value())
203 auto roles = *subregionRolesOpt;
204 auto & gammaNode = correlation->gammaNode();
209 if (rvsdg::TryGetRegionParentNode<rvsdg::GammaNode>(entryVarArgument))
211 auto roleVar = gammaNode.MapBranchArgument(entryVarArgument);
212 if (
auto entryVar = std::get_if<rvsdg::GammaNode::EntryVar>(&roleVar))
228 auto & loopVarPostOperand = *loopVar.
post->
origin();
229 if (rvsdg::TryGetOwnerNode<rvsdg::GammaNode>(loopVarPostOperand) != &gammaNode)
235 auto [branchResult, _] = gammaNode.MapOutputExitVar(loopVarPostOperand);
240 auto & entryVarArgument = *branchResult[roles.repetitionSubregion->index()]->origin();
241 divertLoopVar(loopVar, entryVarArgument);
246 auto & entryVarArgument = *branchResult[roles.exitSubregion->index()]->origin();
247 divertLoopVar(loopVar, entryVarArgument);
258 auto callType = callTypeClassifier->GetCallType();
267 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(callTypeClassifier->GetLambdaOutput());
278 const auto results = lambdaNode.GetFunctionResults();
280 for (
size_t n = 0; n < callNode.
noutputs(); n++)
282 const auto callOutput = callNode.
output(n);
284 auto & lambdaResult = *results[n];
285 auto origin = lambdaResult.origin();
286 if (rvsdg::TryGetRegionParentNode<rvsdg::LambdaNode>(*origin) == &lambdaNode)
288 if (
auto ctxvar = lambdaNode.MapBinderContextVar(*origin))
311 if (callExitSplit ==
nullptr || callEntryMerge ==
nullptr || lambdaEntrySplit ==
nullptr
312 || lambdaExitMerge ==
nullptr)
315 const auto callExitSplitOp =
316 *util::assertedCast<const CallExitMemoryStateSplitOperation>(&callExitSplit->GetOperation());
317 for (
const auto memoryNodeId : callExitSplitOp.getMemoryNodeIds())
327 if (result !=
nullptr && argument !=
nullptr)
330 if (result->origin() != argument)
345 output->divert_users(input->origin());
static rvsdg::Input * tryMapMemoryNodeIdToInput(const rvsdg::SimpleNode &node, MemoryNodeId memoryNodeId)
static rvsdg::Output * tryMapMemoryNodeIdToOutput(const rvsdg::SimpleNode &node, MemoryNodeId memoryNodeId)
static rvsdg::Input * Argument(const rvsdg::Node &node, const size_t n)
static rvsdg::SimpleNode * tryGetMemoryStateExitSplit(const rvsdg::Node &callNode) noexcept
static std::unique_ptr< CallTypeClassifier > ClassifyCall(const rvsdg::SimpleNode &callNode)
Classifies a call node.
static size_t NumArguments(const rvsdg::Node &node) noexcept
static rvsdg::SimpleNode * tryGetMemoryStateEntryMerge(const rvsdg::Node &callNode) noexcept
Get address of compiled function object.
~Statistics() override=default
static std::unique_ptr< Statistics > Create(const util::FilePath &sourceFile)
Statistics(const util::FilePath &sourceFile)
Invariant Value Redirection Optimization.
static void RedirectGammaOutputs(rvsdg::GammaNode &gammaNode)
static void RedirectCallOutputs(rvsdg::SimpleNode &callNode)
~InvariantValueRedirection() override
static void RedirectInRegion(rvsdg::Region ®ion)
static void RedirectInSubregions(rvsdg::StructuralNode &structuralNode)
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
static void RedirectInRootRegion(rvsdg::Graph &rvsdg)
static void redirectThetaGammaOutputs(rvsdg::ThetaNode &thetaNode)
static void RedirectThetaOutputs(rvsdg::ThetaNode &thetaNode)
static rvsdg::Output * tryMapMemoryNodeIdToOutput(const rvsdg::SimpleNode &node, MemoryNodeId memoryNodeId)
static rvsdg::Input * tryMapMemoryNodeIdToInput(const rvsdg::SimpleNode &node, MemoryNodeId memoryNodeId)
Interpret pointer as callable function.
Conditional operator / pattern matching.
std::vector< ExitVar > GetExitVars() const
Gets all exit variables for this gamma.
Region & GetRootRegion() const noexcept
rvsdg::Region * subregion() const noexcept
size_t noutputs() const noexcept
void divert_users(jlm::rvsdg::Output *new_origin)
bool IsDead() const noexcept
A phi node represents the fixpoint of mutually recursive definitions.
static std::vector< rvsdg::LambdaNode * > ExtractLambdaNodes(const PhiNode &phiNode)
Represent acyclic RVSDG subgraphs.
rvsdg::StructuralNode * node() const noexcept
NodeRange Nodes() noexcept
const std::optional< util::FilePath > & SourceFilePath() const noexcept
NodeOutput * output(size_t index) const noexcept
SubregionIteratorRange Subregions()
std::vector< LoopVar > GetLoopVars() const
Returns all loop variables.
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
util::Timer & GetTimer(const std::string &name)
util::Timer & AddTimer(std::string name)
Global memory state passed between functions.
rvsdg::SimpleNode * tryGetMemoryStateEntrySplit(const rvsdg::LambdaNode &lambdaNode) noexcept
std::optional< std::unique_ptr< ThetaGammaPredicateCorrelation > > computeThetaGammaPredicateCorrelation(rvsdg::ThetaNode &thetaNode)
std::optional< GammaSubregionRoles > determineGammaSubregionRoles(const ThetaGammaPredicateCorrelation &correlation)
rvsdg::SimpleNode * tryGetMemoryStateExitMerge(const rvsdg::LambdaNode &lambdaNode) noexcept
void MatchTypeOrFail(T &obj, const Fns &... fns)
Pattern match over subclass type of given object.
static bool ThetaLoopVarIsInvariant(const ThetaNode::LoopVar &loopVar) noexcept
std::optional< rvsdg::Output * > GetGammaInvariantOrigin(const GammaNode &gamma, const GammaNode::ExitVar &exitvar)
Determines whether a gamma exit var is path-invariant.
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).
static const char * Timer