26#include <unordered_map>
37struct MemoryStateTypeCounter final
73 uint64_t numExternalNode,
74 uint64_t numNonEscaped)
89 const uint64_t totalMemoryStates = numRefOnly + numModOnly + numModRef;
99 CountEntity(
const PointsToGraph & pointsToGraph,
const ModRefSet & memoryNodes)
101 uint64_t numRefOnly = 0;
102 uint64_t numModOnly = 0;
103 uint64_t numModRef = 0;
105 uint64_t numAllocas = 0;
106 uint64_t numMallocs = 0;
107 uint64_t numDeltas = 0;
108 uint64_t numImports = 0;
109 uint64_t numLambdas = 0;
110 uint64_t numExternalNode = 0;
112 uint64_t numNonEscaped = 0;
114 for (
const auto [memoryNode, modRefEffect] : memoryNodes.getModRefNodes())
116 switch (modRefEffect)
131 if (!pointsToGraph.isExternallyAvailable(memoryNode))
134 const auto kind = pointsToGraph.getNodeKind(memoryNode);
156 throw std::logic_error(
"Unknown MemoryNode kind");
298 static std::unique_ptr<Statistics>
301 return std::make_unique<Statistics>(sourceFile);
345 if (
const auto it =
states_.find(modRefNode); it !=
states_.end())
356 throw std::logic_error(
"Memory node does not have a state.");
372 std::vector<rvsdg::Output *>
375 std::vector<rvsdg::Output *> memoryStates;
376 for (
auto & modRefNode : modRefNodes)
380 memoryStates.push_back(state);
392 memoryStates.push_back(&undefOutput);
403 throw std::logic_error(
"Unknown modRefNode in StateMap");
405 states_[modRefNode] = &memoryState;
410 const std::vector<MemoryNodeId> & modRefNodes,
415 ==
static_cast<size_t>(std::distance(memoryStates.
begin(), memoryStates.
end())));
418 for (
auto & memoryState : memoryStates)
420 auto & modRefNode = modRefNodes[i++];
435 if (
auto [_, added] =
states_.insert({ modRefNode, &state }); !added)
436 throw std::logic_error(
"Memory node already has a state.");
440 std::unordered_map<PointsToGraph::NodeIndex, rvsdg::Output *>
states_;
443static std::vector<MemoryNodeId>
446 std::vector<MemoryNodeId> memoryNodeIds;
449 memoryNodeIds.push_back(memoryNode);
452 return memoryNodeIds;
457MemoryStateEncoder::MemoryStateEncoder() = default;
461 rvsdg::RvsdgModule & rvsdgModule,
465 modRefSummary_ = &modRefSummary;
466 statistics_ = Statistics::Create(rvsdgModule.SourceFilePath().value());
467 auto & rvsdg = rvsdgModule.Rvsdg();
473 auto counters = gatherStatistics(rvsdg.GetRootRegion());
474 statistics_->AddCounters(*counters);
477 statistics_->StartEncoding(rvsdg);
478 encodeInterProcedural(rvsdg.GetRootRegion());
479 statistics_->StopEncoding(encodingCounter_);
528 MatchTypeWithDefault(
529 simpleNode.GetOperation(),
532 encodeAlloca(simpleNode, stateMap);
536 encodeMalloc(simpleNode, stateMap);
540 encodeLoad(simpleNode, stateMap);
544 encodeStore(simpleNode, stateMap);
548 encodeCall(simpleNode, stateMap);
552 encodeFree(simpleNode, stateMap);
556 encodeMemcpy(simpleNode, stateMap);
560 encodeMemset(simpleNode, stateMap);
564 encodeMemmove(simpleNode, stateMap);
573 JLM_ASSERT(!hasMemoryState(simpleNode));
579std::unique_ptr<MemoryStateEncoder::MemoryStateTypeCounters>
590 for (
const auto & node : region.
Nodes())
596 gather(*phiNode.
subregion(), modRefSummary, counters);
609 gather(*lambdaNode.subregion(), modRefSummary, counters);
618 gather(*thetaNode.subregion(), modRefSummary, counters);
623 for (
auto & subregion : gammaNode.Subregions())
629 gather(subregion, modRefSummary, counters);
634 MatchTypeWithDefault(
635 simpleNode.GetOperation(),
638 counters.numAllocaNodes++;
642 counters.numMallocNodes++;
644 [&modRefSummary, &counters, &simpleNode](
const LoadOperation &)
646 const auto & modRefSet = modRefSummary.GetSimpleNodeModRef(simpleNode);
647 counters.loadCounter.CountEntity(modRefSummary.GetPointsToGraph(), modRefSet);
648 counters.numLoadNodes++;
652 const auto & modRefSet = modRefSummary.GetSimpleNodeModRef(simpleNode);
653 counters.storeCounter.CountEntity(modRefSummary.GetPointsToGraph(), modRefSet);
654 counters.numStoreNodes++;
656 [&modRefSummary, &counters, &simpleNode](
const CallOperation &)
658 const auto & memoryNodes = modRefSummary.GetSimpleNodeModRef(simpleNode);
659 counters.callEntryMergeCounter.CountEntity(
660 modRefSummary.GetPointsToGraph(),
662 counters.numCallNodes++;
666 counters.numFreeNodes++;
670 counters.numMemCpyNodes++;
674 counters.numMemSetNodes++;
678 counters.numMemMoveNodes++;
687 JLM_ASSERT(!hasMemoryState(simpleNode));
693 auto counters = std::make_unique<MemoryStateTypeCounters>();
705 if (allocaMemoryNodes.size() == 0)
709 auto allocaMemoryNode = allocaMemoryNodes.begin()->first;
710 auto & allocaNodeStateOutput = *allocaNode.
output(1);
714 if (
const auto memoryState = stateMap.
tryGetState(allocaMemoryNode))
717 auto & joinOutput = *joinNode.
output(0);
718 stateMap.
updateState(allocaMemoryNode, joinOutput);
722 stateMap.
insertState(allocaMemoryNode, allocaNodeStateOutput);
733 if (mallocMemoryNodes.size() == 0)
737 auto mallocMemoryNode = mallocMemoryNodes.begin()->first;
745 if (
const auto memoryState = stateMap.
tryGetState(mallocMemoryNode))
748 auto & joinOutput = *joinNode.
output(0);
749 stateMap.
updateState(mallocMemoryNode, joinOutput);
753 stateMap.
insertState(mallocMemoryNode, mallocNodeStateOutput);
771 const auto memoryStateOperand =
778 memoryStateInput.divert_to(memStateOperands[n++]);
804 const auto memoryStateOperand =
811 memoryStateInput.divert_to(memStateOperands[n++]);
843 auto oldMemStateOperand =
871 stateMap.
updateStates(modRefNodes, exitSplitNode.Outputs());
924 auto & lambdaEntrySplitNode =
929 for (
const auto modRefNode : modRefNodes)
930 subregionStateMap.
insertState(modRefNode, *memStates[n++]);
932 if (!memStates.empty())
949 memoryStateArgument.divertUsersWhere(
958 auto & lambdaSubregion = *lambdaNode.
subregion();
965 const auto memStateOperands = subregionStateMap.
getOrCreateStates(modRefNodes, lambdaSubregion);
972 memoryStateResult.divert_to(lambdaExitMergNode.output(0));
975 lambdaSubregion.prune(
false);
981 std::vector<StateMap> subregionStateMap(gammaNode.
nsubregions());
990 for (
auto & modRefNode : modRefNodes)
992 auto gammaInput = gammaNode.
AddEntryVar(memStateOperands[n++]);
993 for (
auto argument : gammaInput.branchArgument)
994 subregionStateMap[argument->region()->index()].insertState(modRefNode, *argument);
998 for (
auto & subregion : gammaNode.
Subregions())
1006 for (
auto modRefNode : modRefNodes)
1008 std::vector<rvsdg::Output *> memStateOperands;
1009 for (
auto & subregion : gammaNode.
Subregions())
1011 auto & state = subregionStateMap[subregion.index()].getState(modRefNode);
1012 memStateOperands.push_back(&state);
1020 for (
auto & subregion : gammaNode.
Subregions())
1021 subregion.prune(
false);
1033 std::vector<rvsdg::ThetaNode::LoopVar> loopVars;
1036 for (
auto & modRefNode : modRefNodes)
1038 auto loopVar = thetaNode.
AddLoopVar(memStateOperands[n++]);
1039 subregionStateMap.
insertState(modRefNode, *loopVar.pre);
1040 loopVars.push_back(loopVar);
1048 JLM_ASSERT(modRefNodes.size() == loopVars.size());
1049 JLM_ASSERT(memStateOperands.size() == loopVars.size());
1050 for (
size_t n = 0; n < loopVars.size(); n++)
1052 const auto loopVar = loopVars[n];
1053 const auto modRefNode = modRefNodes[n];
1055 auto & subregionState = subregionStateMap.
getState(modRefNode);
1056 loopVar.post->divert_to(&subregionState);
1057 stateMap.
updateState(modRefNode, *loopVar.output);
1067 const std::vector<rvsdg::Output *> & memoryStates)
1071 if (
const auto loadVolatileOperation =
1078 loadVolatileOperation->GetLoadedType(),
1079 loadVolatileOperation->GetAlignment());
1084 oldLoadedValueOutput.divert_users(&newLoadedValueOutput);
1085 oldIOStateOutput.divert_users(&newIOStateOutput);
1088 const auto oldMemStateOperand =
1097 if (
const auto loadNonVolatileOperation =
1103 loadNonVolatileOperation->GetLoadedType(),
1104 loadNonVolatileOperation->GetAlignment());
1107 oldLoadedValueOutput.divert_users(&newLoadedValueOutput);
1110 const auto oldMemStateOperand =
1125 const std::vector<rvsdg::Output *> & memoryStates)
1129 if (
const auto oldStoreVolatileOperation =
1137 oldStoreVolatileOperation->GetAlignment());
1140 oldIOStateOutput.divert_users(&newIOStateOutput);
1143 const auto oldMemStateOperand =
1149 return newStoreNode;
1152 if (
const auto oldStoreNonVolatileOperation =
1157 const auto oldMemStateOperand =
1167 oldStoreNonVolatileOperation->GetAlignment());
1176 const std::vector<rvsdg::Output *> & memoryStates)
1184 if (is<MemCpyVolatileOperation>(memCpyNode.
GetOperation()))
1198 auto oldMemStateOperand =
1204 return newMemCpyNode;
1207 if (is<MemCpyNonVolatileOperation>(memCpyNode.
GetOperation()))
1211 auto oldMemStateOperand =
1220 throw std::logic_error(
"Unhandled memcpy operation type.");
1226 const std::vector<rvsdg::Output *> & memoryStates)
1234 if (is<MemSetNonVolatileOperation>(memsetNode.
GetOperation()))
1238 auto oldMemStateOperand =
1247 throw std::logic_error(
"Unhandled memset operation type.");
1253 const std::vector<rvsdg::Output *> & memoryStates)
1261 if (is<MemMoveNonVolatileOperation>(memmoveNode.
GetOperation()))
1265 auto oldMemStateOperand =
1278 throw std::logic_error(
"Unhandled memmove operation type.");
uint64_t MaxMemoryStateEntity
uint64_t MaxNonEscapedMemoryStateEntity
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands, std::vector< MemoryNodeId > memoryNodeIds)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &operand, std::vector< MemoryNodeId > memoryNodeIds)
static rvsdg::Output & GetMemoryStateOutput(const rvsdg::Node &node) noexcept
static rvsdg::Input & GetMemoryStateInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & getAddressInput(const rvsdg::Node &node) noexcept
static rvsdg::Node::OutputIteratorRange memoryStateOutputs(const rvsdg::Node &node) noexcept
static rvsdg::Input & getIOStateInput(const rvsdg::Node &node) noexcept
static rvsdg::Output & getIOStateOutput(const rvsdg::Node &node) noexcept
static rvsdg::Input & mapMemoryStateOutputToInput(rvsdg::Output &output) noexcept
static rvsdg::SimpleNode & createNode(rvsdg::Output &pointer, rvsdg::Output &iOState, const std::vector< rvsdg::Output * > &memoryStates)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &operand, std::vector< MemoryNodeId > memoryNodeIds)
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands, const std::vector< MemoryNodeId > &memoryNodeIds)
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, std::unique_ptr< LoadNonVolatileOperation > loadOperation, const std::vector< rvsdg::Output * > &operands)
static size_t numMemoryStates(const rvsdg::SimpleNode &node) noexcept
static rvsdg::Node::OutputIteratorRange MemoryStateOutputs(const rvsdg::Node &node) noexcept
static rvsdg::Output & LoadedValueOutput(const rvsdg::Node &node)
static rvsdg::Input & AddressInput(const rvsdg::Node &node) noexcept
static rvsdg::Node::InputIteratorRange MemoryStateInputs(const rvsdg::Node &node) noexcept
static rvsdg::Input & MapMemoryStateOutputToInput(const rvsdg::Output &output)
static rvsdg::Input & IOStateInput(const rvsdg::Node &node) noexcept
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, std::unique_ptr< LoadVolatileOperation > loadOperation, const std::vector< rvsdg::Output * > &operands)
static rvsdg::Output & IOStateOutput(const rvsdg::Node &node)
static rvsdg::Output & memoryStateOutput(const rvsdg::Node &node)
static rvsdg::SimpleNode & createNode(rvsdg::Output &destination, rvsdg::Output &source, rvsdg::Output &length, const std::vector< rvsdg::Output * > &memoryStates)
static rvsdg::Input & sourceInput(const rvsdg::Node &node) noexcept
static rvsdg::Node::OutputIteratorRange memoryStateOutputs(const rvsdg::Node &node) noexcept
static rvsdg::Input & destinationInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & countInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & mapMemoryStateOutputToInput(const rvsdg::Output &output)
static rvsdg::Input & getIOStateInput(const rvsdg::Node &node) noexcept
static rvsdg::Output & getIOStateOutput(const rvsdg::Node &node)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &destination, rvsdg::Output &source, rvsdg::Output &length, rvsdg::Output &ioState, const std::vector< rvsdg::Output * > &memoryStates)
static rvsdg::SimpleNode & createNode(rvsdg::Output &dest, rvsdg::Output &src, rvsdg::Output &length, const std::vector< rvsdg::Output * > &memoryStates)
static rvsdg::Input & destinationInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & lengthInput(const rvsdg::Node &node) noexcept
static rvsdg::Node::OutputIteratorRange memoryStateOutputs(const rvsdg::Node &node) noexcept
static rvsdg::Input & mapMemoryStateOutputToInput(const rvsdg::Output &output)
static rvsdg::Input & sourceInput(const rvsdg::Node &node) noexcept
static rvsdg::SimpleNode & createNode(rvsdg::Output &destination, rvsdg::Output &value, rvsdg::Output &length, const std::vector< rvsdg::Output * > &memoryStates)
static rvsdg::Input & valueInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & lengthInput(const rvsdg::Node &node) noexcept
static rvsdg::Node::OutputIteratorRange memoryStateOutputs(const rvsdg::Node &node) noexcept
static rvsdg::Input & mapMemoryStateOutputToInput(const rvsdg::Output &output)
static rvsdg::Input & destinationInput(const rvsdg::Node &node) noexcept
static rvsdg::SimpleNode & CreateNode(const std::vector< rvsdg::Output * > &operands)
static rvsdg::Output * Create(const std::vector< rvsdg::Output * > &operands)
static std::shared_ptr< const MemoryStateType > Create()
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &address, rvsdg::Output &value, const std::vector< rvsdg::Output * > &memoryStates, size_t alignment)
static rvsdg::Input & StoredValueInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & MapMemoryStateOutputToInput(const rvsdg::Output &output)
static size_t numMemoryStates(const rvsdg::SimpleNode &node) noexcept
static rvsdg::Input & AddressInput(const rvsdg::Node &node) noexcept
static rvsdg::Node::OutputIteratorRange MemoryStateOutputs(const rvsdg::Node &node) noexcept
static rvsdg::Node::InputIteratorRange getMemoryStateInputs(const rvsdg::Node &node) noexcept
static rvsdg::Output & IOStateOutput(const rvsdg::Node &node) noexcept
static rvsdg::Input & IOStateInput(const rvsdg::Node &node) noexcept
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, std::unique_ptr< StoreVolatileOperation > storeOperation, const std::vector< rvsdg::Output * > &operands)
static jlm::rvsdg::Output * Create(rvsdg::Region ®ion, std::shared_ptr< const jlm::rvsdg::Type > type)
Hash map for mapping points-to graph memory nodes to RVSDG memory states.
StateMap & operator=(const StateMap &)=delete
void updateStates(const std::vector< MemoryNodeId > &modRefNodes, const rvsdg::Node::OutputIteratorRange &memoryStates)
void insertState(PointsToGraph::NodeIndex modRefNode, rvsdg::Output &state)
std::unordered_map< PointsToGraph::NodeIndex, rvsdg::Output * > states_
StateMap(const StateMap &)=delete
std::vector< rvsdg::Output * > getOrCreateStates(const std::vector< MemoryNodeId > &modRefNodes, rvsdg::Region ®ion)
StateMap(StateMap &&)=delete
rvsdg::Output * tryGetState(const PointsToGraph::NodeIndex modRefNode) noexcept
rvsdg::Output & getState(const PointsToGraph::NodeIndex modRefNode)
void updateState(const MemoryNodeId modRefNode, rvsdg::Output &memoryState)
StateMap & operator=(StateMap &&)=delete
Statistics class for memory state encoder encoding.
static constexpr auto NumReplacedLoadsLabel_
static constexpr auto NumTotalAllocaState_
static constexpr auto NumRedirectedStoresLabel_
static constexpr auto NumMaxMemoryState_
void AddMemoryStateTypeCounter(const std::string &suffix, const MemoryStateTypeCounter &counter)
static constexpr auto NumTotalNonEscapedState_
static constexpr auto NumCallEntryMergeOperations_
static constexpr auto StoreStateSuffix_
static constexpr auto EncodingTimerLabel_
static constexpr auto NumReplacedStoresLabel_
static constexpr auto NumTotalRefOnlyStates_
static constexpr auto NumIntraProceduralRegions_
static constexpr auto NumTotalDeltaState_
~Statistics() override=default
static std::unique_ptr< Statistics > Create(const util::FilePath &sourceFile)
static constexpr auto NumTotalLambdaState_
void AddCounters(const MemoryStateTypeCounters &counters)
void StopEncoding(const EncodingCounter &counter)
Statistics(const util::FilePath &sourceFile)
static constexpr auto NumRedirectedLoadsLabel_
static constexpr auto NumTotalMallocState_
static constexpr auto LoadStateSuffix_
static constexpr auto NumLoadOperations_
static constexpr auto NumTotalImportState_
static constexpr auto NumTotalModRefStates_
static constexpr auto NumMaxNonEscapedMemoryState_
static constexpr auto NumStoreOperations_
static constexpr auto CallEntryMergeStateSuffix_
static constexpr auto NumTotalModOnlyStates_
static constexpr auto RegionArgumentStateSuffix_
static constexpr auto NumTotalExternalNodeState_
void StartEncoding(const rvsdg::Graph &graph)
const ModRefSummary * modRefSummary_
void encodeMemmove(const rvsdg::SimpleNode &memmoveNode, StateMap &stateMap) const
void encodeStore(const rvsdg::SimpleNode &node, StateMap &stateMap)
void encodeMemcpy(const rvsdg::SimpleNode &memcpyNode, StateMap &stateMap) const
void encodeMalloc(const rvsdg::SimpleNode &mallocNode, StateMap &stateMap) const
void encodeTheta(rvsdg::ThetaNode &thetaNode, StateMap &stateMap)
void encodeIntraProcedural(rvsdg::Region ®ion, StateMap &stateMap)
static rvsdg::SimpleNode & replaceStoreNode(const rvsdg::SimpleNode &node, const std::vector< rvsdg::Output * > &memoryStates)
static rvsdg::SimpleNode & replaceMemmoveNode(const rvsdg::SimpleNode &memmoveNode, const std::vector< rvsdg::Output * > &memoryStates)
void encodeLambda(const rvsdg::LambdaNode &lambda)
void encodeLoad(const rvsdg::SimpleNode &node, StateMap &stateMap)
static rvsdg::SimpleNode & replaceMemcpyNode(const rvsdg::SimpleNode &memCpyNode, const std::vector< rvsdg::Output * > &memoryStates)
void encodeMemset(const rvsdg::SimpleNode &memsetNode, StateMap &stateMap) const
~MemoryStateEncoder() noexcept
void encodeCall(const rvsdg::SimpleNode &callNode, StateMap &stateMap) const
static rvsdg::SimpleNode & replaceLoadNode(const rvsdg::SimpleNode &node, const std::vector< rvsdg::Output * > &memoryStates)
void encodeFree(const rvsdg::SimpleNode &freeNode, StateMap &stateMap) const
void encodeAlloca(const rvsdg::SimpleNode &allocaNode, StateMap &stateMap) const
EncodingCounter encodingCounter_
std::unique_ptr< MemoryStateTypeCounters > gatherStatistics(const rvsdg::Region ®ion) const
void encodeInterProcedural(rvsdg::Region ®ion)
static rvsdg::SimpleNode & replaceMemsetNode(const rvsdg::SimpleNode &memsetNode, const std::vector< rvsdg::Output * > &memoryStates)
void encodeGamma(rvsdg::GammaNode &gammaNode, StateMap &stateMap)
const std::unordered_map< PointsToGraph::NodeIndex, ModRefEffect > & getModRefNodes() const
virtual const ModRefSet & GetGammaEntryModRef(const rvsdg::GammaNode &gamma) const =0
virtual const ModRefSet & GetThetaModRef(const rvsdg::ThetaNode &theta) const =0
virtual const ModRefSet & GetLambdaExitModRef(const rvsdg::LambdaNode &lambda) const =0
virtual const ModRefSet & GetLambdaEntryModRef(const rvsdg::LambdaNode &lambda) const =0
virtual const PointsToGraph & GetPointsToGraph() const noexcept=0
virtual const ModRefSet & GetGammaExitModRef(const rvsdg::GammaNode &gamma) const =0
virtual const ModRefSet & GetSimpleNodeModRef(const rvsdg::SimpleNode &node) const =0
Conditional operator / pattern matching.
EntryVar AddEntryVar(rvsdg::Output *origin)
Routes a variable into the gamma branches.
ExitVar AddExitVar(const std::vector< rvsdg::Output * > &values)
Routes per-branch result of gamma to output.
Region & GetRootRegion() const noexcept
rvsdg::Region * subregion() const noexcept
bool IsDead() const noexcept
Determines whether the node is dead.
rvsdg::Region * region() const noexcept
void divert_users(jlm::rvsdg::Output *new_origin)
A phi node represents the fixpoint of mutually recursive definitions.
rvsdg::Region * subregion() const noexcept
Represent acyclic RVSDG subgraphs.
void prune(bool recursive)
NodeRange Nodes() noexcept
const SimpleOperation & GetOperation() const noexcept override
NodeOutput * output(size_t index) const noexcept
SubregionIteratorRange Subregions()
size_t nsubregions() const noexcept
rvsdg::Region * subregion() const noexcept
LoopVar AddLoopVar(rvsdg::Output *origin)
Creates a new loop-carried variable.
bool IsDemanded(Statistics::Id id) 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)
static std::vector< MemoryNodeId > getModRefSetNodes(const ModRefSet &modRefSet)
static util::StatisticsCollector statisticsCollector
rvsdg::Input & GetMemoryStateRegionResult(const rvsdg::LambdaNode &lambdaNode) noexcept
rvsdg::Output & GetMemoryStateRegionArgument(const rvsdg::LambdaNode &lambdaNode) noexcept
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
size_t nnodes(const jlm::rvsdg::Region *region) noexcept
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
detail::TopDownTraverserGeneric< false > TopDownTraverser
Traverser for visiting every node in a region in a top down order.
size_t numRedirectedLoads
size_t numRedirectedStores
MemoryStateTypeCounter interProceduralRegionCounter
MemoryStateTypeCounter callEntryMergeCounter
MemoryStateTypeCounter storeCounter
MemoryStateTypeCounter loadCounter
rvsdg::Output * output
Output of gamma.