40 if (trace1.isDeadEnd())
43 auto & trace1Output = trace1.getOutput();
47 if (
const auto [node, ioBarrierOp] =
54 if (
const auto [node, memoryHoistBarrierOp] =
56 node && memoryHoistBarrierOp)
58 return TraceStepResult::createStepOutput(
66 if (
const auto [node, loadOp] =
70 if (is<MemoryStateType>(trace1Output.Type()))
74 return TraceStepResult::createStepOutput(*memoryStateInput.origin());
93 return tracer.
trace(output, withinRegion);
101 if (
const auto [_, constant] =
105 const auto & rep = constant->Representation();
106 if (rep.is_known() && rep.nbits() <= 64)
111 if (
const auto [_, constant] =
115 const auto & rep = constant->value();
116 if (rep.is_known() && rep.nbits() <= 64)
121 if (
const auto [sextNode, sextOp] =
126 if (!inputValue.has_value())
130 const auto inputBits = sextOp->nsrcbits();
134 if (
const auto [zextNode, zextOp] =
139 if (!inputValue.has_value())
143 const auto inputBits = zextOp->nsrcbits();
147 if (
const auto [truncNode, truncOp] =
152 if (!inputValue.has_value())
155 const auto outputBits = truncOp->ndstbits();
164std::optional<int64_t>
170 int64_t offsetInBytes = 0;
173 offsetInBytes += gepConstant.getOffsetInBytes();
176 return offsetInBytes;
183 std::vector<GetElementPtrOperation::Constant> gepConstants;
190 if (
const auto [gepNode, gepOperation] =
195 gepConstantOpt.has_value())
197 base = gepNode->input(0)->origin();
198 gepConstants.emplace_back(gepConstantOpt.value());
213 std::optional<int64_t> offsetInBytes,
215 const size_t maxTraceCollectionSize)
227 if (!it->second.has_value())
231 const auto prevOffset = *it->second;
234 if (offsetInBytes.has_value() && *offsetInBytes == prevOffset)
238 offsetInBytes = std::nullopt;
244 if (
const auto [gepNode, gepOperation] =
252 if (offsetInBytes.has_value())
255 gepConstant.has_value())
256 offsetInBytes = *offsetInBytes + gepConstant->getOffsetInBytes();
258 offsetInBytes = std::nullopt;
265 maxTraceCollectionSize);
269 if (
const auto [node, select] =
274 node->input(1)->origin(),
277 maxTraceCollectionSize)
279 node->input(2)->origin(),
282 maxTraceCollectionSize);
294 auto exitVar = gamma->MapOutputExitVar(*basePointer);
295 for (
auto result : exitVar.branchResult)
302 maxTraceCollectionSize))
315 auto loopVar = theta->MapOutputLoopVar(*basePointer);
320 loopVar.post->origin(),
323 maxTraceCollectionSize);
329 auto loopVar = theta->MapPreLoopVar(*basePointer);
336 loopVar.post->origin(),
339 maxTraceCollectionSize)
341 loopVar.input->origin(),
344 maxTraceCollectionSize);
348 traceCollection.
TopOrigins[basePointer] = offsetInBytes;
356 const size_t maxTraceCollectionSize)
362 maxTraceCollectionSize);
static rvsdg::Input & getBaseAddressInput(rvsdg::Node &node)
static std::optional< Constant > tryGetAsConstant(const rvsdg::SimpleNode &gepNode)
static rvsdg::Input & BarredInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & MapMemoryStateOutputToInput(const rvsdg::Output &output)
static rvsdg::Input & getAddressInput(const rvsdg::Node &node) noexcept
bool traceThroughHoistBarriers_
bool traceThroughLoadedStates_
TraceStepResult traceStep(rvsdg::Output &output, BackEdgeState backEdgeState, const rvsdg::Region *withinRegion) override
void setRegionPredicateCheckingEnabled(bool value) noexcept
void setEnterPhiNodes(bool value) noexcept
virtual TraceStepResult traceStep(Output &output, BackEdgeState backEdgeState, const Region *withinRegion)
Output & trace(Output &output)
void setStructuralNodePolicy(StructuralNodePolicy value) noexcept
@ traceThroughIfDetectedInvariant
Represent acyclic RVSDG subgraphs.
Global memory state passed between functions.
bool TraceAllPointerOrigins(TracedPointerOrigin p, TraceCollection &traceCollection, const size_t maxTraceCollectionSize)
static bool traceAllPointerOriginsInternal(const rvsdg::Output *basePointer, std::optional< int64_t > offsetInBytes, TraceCollection &traceCollection, const size_t maxTraceCollectionSize)
rvsdg::Output & traceOutput(rvsdg::Output &output, bool mayEnterSubregions, const rvsdg::Region *withinRegion)
TracedPointerOrigin TracePointerOriginPrecise(const rvsdg::Output &p)
std::optional< int64_t > tryGetConstantSignedInteger(const rvsdg::Output &output)
static bool ThetaLoopVarIsInvariant(const ThetaNode::LoopVar &loopVar) noexcept
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
int64_t truncateAndZeroExtend(int64_t value, uint64_t keepBits)
int64_t truncateAndSignExtend(int64_t value, uint64_t keepBits)
std::unordered_map< const rvsdg::Output *, std::optional< int64_t > > TopOrigins
std::unordered_map< const rvsdg::Output *, std::optional< int64_t > > AllTracedOutputs
std::optional< std::vector< GetElementPtrOperation::Constant > > gepConstants
const rvsdg::Output * BasePointer
std::optional< int64_t > getOffsetInBytes() const noexcept