18 : enableCaching_(enableCaching)
24 return trace(output,
nullptr);
59 if (
const auto traceResultOpt =
lookupInCache(output); traceResultOpt.has_value())
61 return traceResultOpt.value();
67 Output * commonOrigin =
nullptr;
68 Input * gammaInput =
nullptr;
70 for (
auto branchResult : exitVar.branchResult)
72 auto tracedInner = branchResult->
origin();
78 tracedInner = &
trace(*tracedInner, tracedInner->region());
82 if (TryGetRegionParentNode<GammaNode>(*tracedInner) != &gammaNode)
90 if (commonOrigin ==
nullptr)
92 commonOrigin = &outerOrigin;
94 else if (commonOrigin != &outerOrigin)
108 if (
const auto traceResultOpt =
lookupInCache(output); traceResultOpt.has_value())
110 return traceResultOpt.value();
125 if (tracedInner == loopVar.pre)
132 if (TryGetRegionParentNode<ThetaNode>(*tracedInner) == &thetaNode)
154 if (
const auto gammaNode = TryGetOwnerNode<GammaNode>(output))
163 if (
const auto gammaNode = TryGetRegionParentNode<GammaNode>(output))
169 if (
const auto thetaNode = TryGetOwnerNode<ThetaNode>(output))
180 if (
const auto thetaNode = TryGetRegionParentNode<ThetaNode>(output))
187 const auto loopVar = thetaNode->MapPreLoopVar(output);
190 const auto inputOrigin = loopVar.input->origin();
198 if (postOrigin == inputOrigin)
211 if (
const auto lambda = TryGetRegionParentNode<LambdaNode>(output))
214 if (
const auto ctxVar = lambda->MapBinderContextVar(output))
215 return *ctxVar->input->origin();
221 if (
const auto delta = TryGetRegionParentNode<DeltaNode>(output))
224 const auto ctxVar = delta->MapBinderContextVar(output);
225 return *ctxVar.input->origin();
229 if (
const auto phiNode = TryGetOwnerNode<PhiNode>(output))
233 const auto fixVar = phiNode->MapOutputFixVar(output);
234 return *fixVar.result->origin();
240 if (
const auto phiNode = TryGetRegionParentNode<PhiNode>(output))
245 const auto argument = phiNode->MapArgument(output);
246 if (
const auto ctxVar = std::get_if<PhiNode::ContextVar>(&argument))
249 return *ctxVar->input->origin();
261 return traceResult !=
nullptr ? traceResult->
origin() :
nullptr;
265 return traceResult !=
nullptr ? traceResult->
origin() :
nullptr;
268 std::optional<Output *>
276 return it->second !=
nullptr ? it->second->origin() :
nullptr;
285 constexpr
bool enableCaching =
false;
288 return tracer.
trace(output);
294 constexpr
bool enableCaching =
false;
296 return tracer.
trace(output, withinRegion);
Conditional operator / pattern matching.
ExitVar MapOutputExitVar(const rvsdg::Output &output) const
Maps gamma output to exit variable description.
const rvsdg::Input & mapBranchArgumentToInput(const rvsdg::Output &output) const
Maps branch subregion entry argument to its corresponding gamma input.
Output * tryTraceThroughGamma(GammaNode &gammaNode, Output &output)
void setInterprocedural(bool value) noexcept
Output * insertInCache(const Output &output, Input *traceResult)
Output & trace(Output &output)
virtual Output & traceStep(Output &output, const rvsdg::Region *withinRegion)
bool traceThroughStrucutalNodes_
std::unordered_map< const Output *, Input * > traceCache_
OutputTracer(bool enableCaching) noexcept
Output * tryTraceThroughTheta(ThetaNode &thetaNode, Output &output)
std::optional< Output * > lookupInCache(const Output &output)
Represent acyclic RVSDG subgraphs.
LoopVar MapOutputLoopVar(const rvsdg::Output &output) const
Maps variable at exit to full varibale description.
LoopVar MapPreLoopVar(const rvsdg::Output &argument) const
Maps variable at start of loop iteration to full varibale description.
rvsdg::Region * subregion() const noexcept
static Output & mapGammaArgumentToOrigin(GammaNode &gammaNode, Output &output)
static bool ThetaLoopVarIsInvariant(const ThetaNode::LoopVar &loopVar) noexcept
Output & traceOutput(Output &output, const rvsdg::Region *withinRegion)
Output & traceOutputIntraProcedurally(Output &output)
Region * TryGetOwnerRegion(const rvsdg::Input &input) noexcept
rvsdg::Input * post
Variable after iteration (output result from subregion).