26#include <unordered_map>
70 uint64_t numExternalNode,
71 uint64_t numNonEscaped)
86 const uint64_t totalMemoryStates = numRefOnly + numModOnly + numModRef;
98 uint64_t numRefOnly = 0;
99 uint64_t numModOnly = 0;
100 uint64_t numModRef = 0;
102 uint64_t numAllocas = 0;
103 uint64_t numMallocs = 0;
104 uint64_t numDeltas = 0;
105 uint64_t numImports = 0;
106 uint64_t numLambdas = 0;
107 uint64_t numExternalNode = 0;
109 uint64_t numNonEscaped = 0;
111 for (
const auto [memoryNode, modRefEffect] : memoryNodes.
getModRefNodes())
113 switch (modRefEffect)
131 const auto kind = pointsToGraph.
getNodeKind(memoryNode);
153 throw std::logic_error(
"Unknown MemoryNode kind");
261 static std::unique_ptr<EncodingStatistics>
264 return std::make_unique<EncodingStatistics>(sourceFile);
324 JLM_ASSERT(is<MemoryStateType>(state.Type()));
331 const std::vector<MemoryNodeStatePair *> & memoryNodeStatePairs,
332 const std::vector<rvsdg::Output *> & states)
334 JLM_ASSERT(memoryNodeStatePairs.size() == states.size());
335 for (
size_t n = 0; n < memoryNodeStatePairs.size(); n++)
341 const std::vector<MemoryNodeStatePair *> & memoryNodeStatePairs,
344 auto it = states.
begin();
345 for (
auto memoryNodeStatePair : memoryNodeStatePairs)
347 memoryNodeStatePair->ReplaceState(*it);
353 static std::vector<rvsdg::Output *>
354 States(
const std::vector<MemoryNodeStatePair *> & memoryNodeStatePairs)
356 std::vector<rvsdg::Output *> states;
357 for (
auto & memoryNodeStatePair : memoryNodeStatePairs)
358 states.push_back(memoryNodeStatePair->State_);
383 if (
const auto it =
states_.find(memoryNode); it !=
states_.end())
389 const MemoryNodeStatePair *
401 MemoryNodeStatePair *
404 if (
const auto statePair =
TryGetState(memoryNode))
406 throw std::logic_error(
"Memory node does not have a state.");
409 std::vector<MemoryNodeStatePair *>
412 std::vector<MemoryNodeStatePair *> memoryNodeStatePairs;
413 for (
const auto [memoryNode, modRefEffect] : modRefSet.
getModRefNodes())
416 memoryNodeStatePairs.push_back(
GetState(memoryNode));
419 return memoryNodeStatePairs;
429 std::vector<MemoryNodeStatePair *>
432 std::vector<MemoryNodeStatePair *> memoryNodeStatePairs;
435 if (
const auto statePair =
TryGetState(memoryNode))
436 memoryNodeStatePairs.push_back(statePair);
439 return memoryNodeStatePairs;
449 MemoryNodeStatePair *
452 auto [it, added] =
states_.insert({ memoryNode, { memoryNode, state } });
454 throw std::logic_error(
"Memory node already has a state.");
458 static std::unique_ptr<StateMap>
461 return std::make_unique<StateMap>();
467 std::unordered_map<PointsToGraph::NodeIndex, MemoryNodeStatePair>
states_;
519 std::vector<StateMap::MemoryNodeStatePair *>
535 std::vector<StateMap::MemoryNodeStatePair *>
541 std::vector<StateMap::MemoryNodeStatePair *>
577 std::unordered_map<const rvsdg::Region *, std::unique_ptr<StateMap>>
StateMaps_;
636 static std::unique_ptr<MemoryStateEncoder::Context>
639 return std::make_unique<Context>(modRefSummary);
653static std::vector<MemoryNodeId>
656 std::vector<MemoryNodeId> memoryNodeIds;
659 memoryNodeIds.push_back(memoryNode);
662 return memoryNodeIds;
667MemoryStateEncoder::MemoryStateEncoder() = default;
671 rvsdg::RvsdgModule & rvsdgModule,
675 Context_ = Context::Create(modRefSummary);
678 statistics->Start(rvsdgModule.Rvsdg());
679 EncodeRegion(rvsdgModule.Rvsdg().GetRootRegion());
682 statistics->AddIntraProceduralRegionMemoryStateCounts(
683 Context_->GetInterProceduralRegionCounter());
684 statistics->AddLoadMemoryStateCounts(Context_->GetLoadCounter());
685 statistics->AddStoreMemoryStateCounts(Context_->GetStoreCounter());
686 statistics->AddCallEntryMergeStateCounts(Context_->GetCallEntryMergeCounter());
704 for (
const auto node : traverser)
726 else if (
auto deltaNode =
dynamic_cast<const rvsdg::DeltaNode *
>(&structuralNode))
730 else if (
auto phiNode =
dynamic_cast<const rvsdg::PhiNode *
>(&structuralNode))
734 else if (
auto gammaNode =
dynamic_cast<rvsdg::GammaNode *
>(&structuralNode))
738 else if (
auto thetaNode =
dynamic_cast<rvsdg::ThetaNode *
>(&structuralNode))
751 MatchTypeWithDefault(
755 EncodeAlloca(simpleNode);
759 EncodeMalloc(simpleNode);
763 EncodeLoad(simpleNode);
767 EncodeStore(simpleNode);
771 EncodeCall(simpleNode);
775 EncodeFree(simpleNode);
779 EncodeMemcpy(simpleNode);
783 EncodeMemset(simpleNode);
787 EncodeMemmove(simpleNode);
796 JLM_ASSERT(!hasMemoryState(simpleNode));
805 auto & stateMap =
Context_->GetRegionalizedStateMap();
806 auto & allocaMemoryNodes = stateMap.GetSimpleNodeModRef(allocaNode).getModRefNodes();
808 if (allocaMemoryNodes.size() == 0)
812 auto allocaMemoryNode = allocaMemoryNodes.begin()->first;
813 auto & allocaNodeStateOutput = *allocaNode.
output(1);
817 if (
const auto statePair = stateMap.TryGetState(*allocaNode.
region(), allocaMemoryNode))
821 auto & joinOutput = *joinNode.
output(0);
822 statePair->ReplaceState(joinOutput);
826 stateMap.InsertState(allocaMemoryNode, allocaNodeStateOutput);
834 auto & stateMap =
Context_->GetRegionalizedStateMap();
835 auto & mallocMemoryNodes = stateMap.GetSimpleNodeModRef(mallocNode).getModRefNodes();
837 if (mallocMemoryNodes.size() == 0)
841 auto mallocMemoryNode = mallocMemoryNodes.begin()->first;
849 if (
const auto statePair = stateMap.TryGetState(*mallocNode.
region(), mallocMemoryNode))
853 auto & joinOutput = *joinNode.
output(0);
854 statePair->ReplaceState(joinOutput);
858 stateMap.InsertState(mallocMemoryNode, mallocNodeStateOutput);
866 auto & stateMap =
Context_->GetRegionalizedStateMap();
868 const auto & modRefSet = stateMap.GetSimpleNodeModRef(node);
869 Context_->GetLoadCounter().CountEntity(
870 Context_->GetModRefSummary().GetPointsToGraph(),
873 const auto memoryNodeStatePairs = stateMap.GetExistingStates(*node.
region(), modRefSet);
879 memoryNodeStatePairs,
886 auto & stateMap =
Context_->GetRegionalizedStateMap();
888 const auto & modRefSet = stateMap.GetSimpleNodeModRef(node);
889 Context_->GetStoreCounter().CountEntity(
890 Context_->GetModRefSummary().GetPointsToGraph(),
893 const auto memoryNodeStatePairs = stateMap.GetExistingStates(*node.
region(), modRefSet);
899 memoryNodeStatePairs,
907 auto & stateMap =
Context_->GetRegionalizedStateMap();
911 auto memoryNodeStatePairs = stateMap.GetExistingStates(freeNode);
920 memoryNodeStatePairs,
921 { outputs.begin(), std::prev(outputs.end()) });
927 const auto region = callNode.
region();
928 auto & regionalizedStateMap =
Context_->GetRegionalizedStateMap();
930 const auto & memoryNodes = regionalizedStateMap.GetSimpleNodeModRef(callNode);
931 Context_->GetCallEntryMergeCounter().CountEntity(
932 Context_->GetModRefSummary().GetPointsToGraph(),
935 const auto statePairs = regionalizedStateMap.GetExistingStates(*region, memoryNodes);
937 std::vector<rvsdg::Output *> inputStates;
938 std::vector<MemoryNodeId> memoryNodeIds;
939 for (
auto statePair : statePairs)
941 inputStates.emplace_back(&statePair->State());
942 memoryNodeIds.push_back(statePair->MemoryNode());
945 auto & entryMergeNode =
960 auto & stateMap =
Context_->GetRegionalizedStateMap();
962 auto memoryNodeStatePairs = stateMap.GetExistingStates(memcpyNode);
974 auto & stateMap =
Context_->GetRegionalizedStateMap();
976 auto memoryNodeStatePairs = stateMap.GetExistingStates(memsetNode);
988 auto & stateMap =
Context_->GetRegionalizedStateMap();
990 auto memoryNodeStatePairs = stateMap.GetExistingStates(memmoveNode);
1011 const auto & modRefSet =
Context_->GetModRefSummary().GetLambdaEntryModRef(lambdaNode);
1012 Context_->GetInterProceduralRegionCounter().CountEntity(
1013 Context_->GetModRefSummary().GetPointsToGraph(),
1017 auto & stateMap =
Context_->GetRegionalizedStateMap();
1019 stateMap.PushRegion(*lambdaNode.
subregion());
1020 auto & lambdaEntrySplitNode =
1025 for (
const auto [memoryNode, _] : modRefSet.getModRefNodes())
1026 stateMap.InsertState(memoryNode, *states[n++]);
1028 if (!states.empty())
1045 memoryStateArgument.divertUsersWhere(
1057 const auto & modRefSet =
Context_->GetModRefSummary().GetLambdaExitModRef(lambdaNode);
1058 auto & stateMap =
Context_->GetRegionalizedStateMap();
1061 std::vector<rvsdg::Output *> states;
1062 std::vector<MemoryNodeId> memoryNodeIds;
1063 auto & subregion = *lambdaNode.
subregion();
1064 const auto memoryNodeStatePairs = stateMap.GetStates(subregion, modRefSet);
1065 for (
const auto memoryNodeStatePair : memoryNodeStatePairs)
1067 states.push_back(&memoryNodeStatePair->State());
1068 memoryNodeIds.push_back(memoryNodeStatePair->MemoryNode());
1071 const auto mergedState =
1073 memoryStateResult.divert_to(mergedState);
1075 stateMap.PopRegion(*lambdaNode.
subregion());
1093 for (
auto & subregion : gammaNode.
Subregions())
1094 Context_->GetRegionalizedStateMap().PushRegion(subregion);
1098 for (
auto & subregion : gammaNode.
Subregions())
1103 for (
auto & subregion : gammaNode.
Subregions())
1104 Context_->GetRegionalizedStateMap().PopRegion(subregion);
1110 auto region = gammaNode.
region();
1111 auto & stateMap =
Context_->GetRegionalizedStateMap();
1112 auto & modRefSet =
Context_->GetModRefSummary().GetGammaEntryModRef(gammaNode);
1115 for ([[maybe_unused]]
auto & subregion : gammaNode.
Subregions())
1116 Context_->GetInterProceduralRegionCounter().CountEntity(
1117 Context_->GetModRefSummary().GetPointsToGraph(),
1120 auto memoryNodeStatePairs = stateMap.GetExistingStates(*region, modRefSet);
1121 for (
auto & memoryNodeStatePair : memoryNodeStatePairs)
1123 auto gammaInput = gammaNode.
AddEntryVar(&memoryNodeStatePair->State());
1124 for (
auto & argument : gammaInput.branchArgument)
1125 stateMap.InsertState(memoryNodeStatePair->MemoryNode(), *argument);
1132 auto & stateMap =
Context_->GetRegionalizedStateMap();
1133 auto & modRefSet =
Context_->GetModRefSummary().GetGammaExitModRef(gammaNode);
1134 auto memoryNodeStatePairs = stateMap.GetExistingStates(*gammaNode.
region(), modRefSet);
1136 for (
auto & memoryNodeStatePair : memoryNodeStatePairs)
1138 std::vector<rvsdg::Output *> states;
1140 for (
auto & subregion : gammaNode.
Subregions())
1142 auto & state = stateMap.GetState(subregion, memoryNodeStatePair->MemoryNode())->State();
1143 states.push_back(&state);
1147 memoryNodeStatePair->ReplaceState(*state);
1163std::vector<rvsdg::Output *>
1166 auto region = thetaNode.
region();
1167 auto & stateMap =
Context_->GetRegionalizedStateMap();
1168 const auto & memoryNodes =
Context_->GetModRefSummary().GetThetaModRef(thetaNode);
1169 Context_->GetInterProceduralRegionCounter().CountEntity(
1170 Context_->GetModRefSummary().GetPointsToGraph(),
1173 std::vector<rvsdg::Output *> thetaStateOutputs;
1174 auto memoryNodeStatePairs = stateMap.GetExistingStates(*region, memoryNodes);
1175 for (
auto & memoryNodeStatePair : memoryNodeStatePairs)
1177 auto loopvar = thetaNode.
AddLoopVar(&memoryNodeStatePair->State());
1178 stateMap.InsertState(memoryNodeStatePair->MemoryNode(), *loopvar.pre);
1179 thetaStateOutputs.push_back(loopvar.output);
1182 return thetaStateOutputs;
1188 const std::vector<rvsdg::Output *> & thetaStateOutputs)
1191 auto & stateMap =
Context_->GetRegionalizedStateMap();
1192 const auto & memoryNodes =
Context_->GetModRefSummary().GetThetaModRef(thetaNode);
1193 auto memoryNodeStatePairs = stateMap.GetExistingStates(*thetaNode.
region(), memoryNodes);
1195 JLM_ASSERT(memoryNodeStatePairs.size() == thetaStateOutputs.size());
1196 for (
size_t n = 0; n < thetaStateOutputs.size(); n++)
1198 auto thetaStateOutput = thetaStateOutputs[n];
1199 auto & memoryNodeStatePair = memoryNodeStatePairs[n];
1200 auto memoryNode = memoryNodeStatePair->MemoryNode();
1202 JLM_ASSERT(loopvar.input->origin() == &memoryNodeStatePair->State());
1204 auto & subregionState = stateMap.GetState(*subregion, memoryNode)->State();
1205 loopvar.post->divert_to(&subregionState);
1206 memoryNodeStatePair->ReplaceState(*thetaStateOutput);
1213 const std::vector<rvsdg::Output *> & memoryStates)
1217 if (
const auto loadVolatileOperation =
1224 loadVolatileOperation->GetLoadedType(),
1225 loadVolatileOperation->GetAlignment());
1230 oldLoadedValueOutput.divert_users(&newLoadedValueOutput);
1231 oldIOStateOutput.divert_users(&newIOStateOutput);
1235 if (
const auto loadNonVolatileOperation =
1241 loadNonVolatileOperation->GetLoadedType(),
1242 loadNonVolatileOperation->GetAlignment());
1245 oldLoadedValueOutput.divert_users(&newLoadedValueOutput);
1255 const std::vector<rvsdg::Output *> & memoryStates)
1257 if (
const auto oldStoreVolatileOperation =
1265 oldStoreVolatileOperation->GetAlignment());
1268 oldIOStateOutput.divert_users(&newIOStateOutput);
1269 return newStoreNode;
1272 if (
const auto oldStoreNonVolatileOperation =
1279 oldStoreNonVolatileOperation->GetAlignment());
1285std::vector<rvsdg::Output *>
1288 const std::vector<rvsdg::Output *> & memoryStates)
1296 if (is<MemCpyVolatileOperation>(memcpyNode.
GetOperation()))
1299 auto & newMemcpyNode =
1307 return { std::next(results.begin()), results.end() };
1309 if (is<MemCpyNonVolatileOperation>(memcpyNode.
GetOperation()))
1314 throw std::logic_error(
"Unhandled memcpy operation type.");
1317std::vector<rvsdg::Output *>
1320 const std::vector<rvsdg::Output *> & memoryStates)
1328 if (is<MemSetNonVolatileOperation>(memsetNode.
GetOperation()))
1334 throw std::logic_error(
"Unhandled memset operation type.");
1337std::vector<rvsdg::Output *>
1340 const std::vector<rvsdg::Output *> & memoryStates)
1344 auto & destOperand = *memmoveNode.
input(0)->
origin();
1345 auto & srcOperand = *memmoveNode.
input(1)->
origin();
1346 auto & lengthOperand = *memmoveNode.
input(2)->
origin();
1348 if (is<MemMoveNonVolatileOperation>(memmoveNode.
GetOperation()))
1357 throw std::logic_error(
"Unhandled memmove operation type.");
static jlm::util::StatisticsCollector statisticsCollector
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
Dead Node Elimination Optimization.
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *pointer, const std::vector< const Variable * > &memoryStates, const Variable *iOState)
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 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::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 std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *destination, const Variable *source, const Variable *length, const std::vector< const Variable * > &memoryStates)
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::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::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 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 & AddressInput(const rvsdg::Node &node) noexcept
static rvsdg::Node::OutputIteratorRange MemoryStateOutputs(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)
Statistics class for memory state encoder encoding.
static constexpr auto NumMaxMemoryState_
void AddStoreMemoryStateCounts(const MemoryStateTypeCounter &counter)
static constexpr auto NumStoreOperations_
static constexpr auto NumIntraProceduralRegions_
void AddCallEntryMergeStateCounts(const MemoryStateTypeCounter &counter)
static constexpr auto NumTotalRefOnlyStates_
static constexpr auto NumTotalMallocState_
static constexpr auto NumTotalAllocaState_
void AddLoadMemoryStateCounts(const MemoryStateTypeCounter &counter)
static constexpr auto NumCallEntryMergeOperations_
static constexpr auto RegionArgumentStateSuffix_
static constexpr auto NumTotalNonEscapedState_
static constexpr auto NumTotalModRefStates_
static constexpr auto LoadStateSuffix_
void AddMemoryStateTypeCounter(const std::string &suffix, const MemoryStateTypeCounter &counter)
void AddIntraProceduralRegionMemoryStateCounts(const MemoryStateTypeCounter &counter)
static constexpr auto CallEntryMergeStateSuffix_
EncodingStatistics(const util::FilePath &sourceFile)
static constexpr auto NumMaxNonEscapedMemoryState_
static constexpr auto NumTotalExternalNodeState_
static constexpr auto NumTotalDeltaState_
~EncodingStatistics() override=default
static constexpr auto NumTotalImportState_
static constexpr auto StoreStateSuffix_
static constexpr auto NumTotalLambdaState_
static constexpr auto NumLoadOperations_
static constexpr auto NumTotalModOnlyStates_
static std::unique_ptr< EncodingStatistics > Create(const util::FilePath &sourceFile)
void Start(const rvsdg::Graph &graph)
Context for the memory state encoder.
MemoryStateTypeCounter & GetStoreCounter()
Context(const ModRefSummary &modRefSummary)
RegionalizedStateMap RegionalizedStateMap_
static std::unique_ptr< MemoryStateEncoder::Context > Create(const ModRefSummary &modRefSummary)
Context & operator=(const Context &)=delete
RegionalizedStateMap & GetRegionalizedStateMap() noexcept
MemoryStateTypeCounter LoadCounter_
Context & operator=(Context &&)=delete
MemoryStateTypeCounter & GetLoadCounter()
Context(const Context &)=delete
MemoryStateTypeCounter CallEntryMergeCounter_
const ModRefSummary & GetModRefSummary() const noexcept
MemoryStateTypeCounter InterProceduralRegionCounter_
MemoryStateTypeCounter & GetCallEntryMergeCounter()
MemoryStateTypeCounter StoreCounter_
MemoryStateTypeCounter & GetInterProceduralRegionCounter()
const ModRefSummary & ModRefSummary_
Context(Context &&)=delete
static std::vector< rvsdg::Output * > ReplaceMemcpyNode(const rvsdg::SimpleNode &memcpyNode, const std::vector< rvsdg::Output * > &memoryStates)
void EncodeMalloc(const rvsdg::SimpleNode &mallocNode)
void EncodeCall(const rvsdg::SimpleNode &callNode)
void EncodeLambdaEntry(const rvsdg::LambdaNode &lambdaNode)
void EncodeAlloca(const rvsdg::SimpleNode &allocaNode)
static rvsdg::SimpleNode & ReplaceStoreNode(const rvsdg::SimpleNode &node, const std::vector< rvsdg::Output * > &memoryStates)
void EncodeStructuralNode(rvsdg::StructuralNode &structuralNode)
void EncodeDelta(const rvsdg::DeltaNode &deltaNode)
void EncodeLambda(const rvsdg::LambdaNode &lambda)
void EncodeLoad(const rvsdg::SimpleNode &node)
void EncodeGammaExit(rvsdg::GammaNode &gammaNode)
void EncodeStore(const rvsdg::SimpleNode &node)
std::unique_ptr< Context > Context_
void EncodeGammaEntry(rvsdg::GammaNode &gammaNode)
static std::vector< rvsdg::Output * > ReplaceMemmoveNode(const rvsdg::SimpleNode &memmoveNode, const std::vector< rvsdg::Output * > &memoryStates)
void EncodeRegion(rvsdg::Region ®ion)
static rvsdg::SimpleNode & ReplaceLoadNode(const rvsdg::SimpleNode &node, const std::vector< rvsdg::Output * > &memoryStates)
void EncodeMemmove(const rvsdg::SimpleNode &memmoveNode)
~MemoryStateEncoder() noexcept
void EncodeSimpleNode(const rvsdg::SimpleNode &simpleNode)
std::vector< rvsdg::Output * > EncodeThetaEntry(rvsdg::ThetaNode &thetaNode)
void EncodePhi(const rvsdg::PhiNode &phiNode)
static std::vector< rvsdg::Output * > ReplaceMemsetNode(const rvsdg::SimpleNode &memsetNode, const std::vector< rvsdg::Output * > &memoryStates)
void EncodeMemcpy(const rvsdg::SimpleNode &memcpyNode)
void EncodeGamma(rvsdg::GammaNode &gammaNode)
void EncodeFree(const rvsdg::SimpleNode &freeNode)
void EncodeMemset(const rvsdg::SimpleNode &memsetNode)
void EncodeLambdaExit(const rvsdg::LambdaNode &lambdaNode)
void EncodeThetaExit(rvsdg::ThetaNode &thetaNode, const std::vector< rvsdg::Output * > &thetaStateOutputs)
void EncodeTheta(rvsdg::ThetaNode &thetaNode)
const std::unordered_map< PointsToGraph::NodeIndex, ModRefEffect > & getModRefNodes() const
virtual const ModRefSet & GetSimpleNodeModRef(const rvsdg::SimpleNode &node) const =0
bool isExternallyAvailable(NodeIndex index) const
NodeKind getNodeKind(NodeIndex index) const
Hash map for mapping Rvsdg regions to StateMap class instances.
std::unordered_map< const rvsdg::Region *, std::unique_ptr< StateMap > > StateMaps_
std::vector< StateMap::MemoryNodeStatePair * > GetExistingStates(const rvsdg::Region ®ion, const ModRefSet &modRefSet) const
StateMap::MemoryNodeStatePair * TryGetState(const rvsdg::Region ®ion, PointsToGraph::NodeIndex memoryNode) const
const ModRefSummary & ModRefSummary_
void PushRegion(const rvsdg::Region ®ion)
StateMap::MemoryNodeStatePair * GetState(const rvsdg::Region ®ion, PointsToGraph::NodeIndex memoryNode)
std::vector< StateMap::MemoryNodeStatePair * > GetStates(const rvsdg::Region ®ion, const ModRefSet &modRefSet)
RegionalizedStateMap & operator=(const RegionalizedStateMap &)=delete
const ModRefSet & GetSimpleNodeModRef(const rvsdg::SimpleNode &node) const
bool HasState(const rvsdg::Region ®ion, PointsToGraph::NodeIndex memoryNode) const
std::vector< StateMap::MemoryNodeStatePair * > GetExistingStates(const rvsdg::SimpleNode &node) const
RegionalizedStateMap & operator=(RegionalizedStateMap &&)=delete
RegionalizedStateMap(RegionalizedStateMap &&)=delete
RegionalizedStateMap(const ModRefSummary &modRefSummary)
StateMap & GetStateMap(const rvsdg::Region ®ion) const noexcept
RegionalizedStateMap(const RegionalizedStateMap &)=delete
StateMap::MemoryNodeStatePair * InsertState(PointsToGraph::NodeIndex memoryNode, rvsdg::Output &state)
void PopRegion(const rvsdg::Region ®ion)
static std::vector< rvsdg::Output * > States(const std::vector< MemoryNodeStatePair * > &memoryNodeStatePairs)
static void ReplaceStates(const std::vector< MemoryNodeStatePair * > &memoryNodeStatePairs, const rvsdg::Node::OutputIteratorRange &states)
static void ReplaceStates(const std::vector< MemoryNodeStatePair * > &memoryNodeStatePairs, const std::vector< rvsdg::Output * > &states)
void ReplaceState(rvsdg::Output &state) noexcept
PointsToGraph::NodeIndex MemoryNode_
rvsdg::Output & State() const noexcept
MemoryNodeStatePair(PointsToGraph::NodeIndex memoryNode, rvsdg::Output &state)
PointsToGraph::NodeIndex MemoryNode() const noexcept
Hash map for mapping points-to graph memory nodes to RVSDG memory states.
std::unordered_map< PointsToGraph::NodeIndex, MemoryNodeStatePair > states_
StateMap & operator=(const StateMap &)=delete
MemoryNodeStatePair * GetState(PointsToGraph::NodeIndex memoryNode)
std::vector< MemoryNodeStatePair * > GetExistingStates(const ModRefSet &modRefSet)
StateMap & operator=(StateMap &&)=delete
std::vector< MemoryNodeStatePair * > GetStates(const ModRefSet &modRefSet)
StateMap(const StateMap &)=delete
const MemoryNodeStatePair * TryGetState(PointsToGraph::NodeIndex memoryNode) const noexcept
static std::unique_ptr< StateMap > Create()
bool HasState(PointsToGraph::NodeIndex memoryNode) const noexcept
MemoryNodeStatePair * TryGetState(PointsToGraph::NodeIndex memoryNode) noexcept
MemoryNodeStatePair * InsertState(PointsToGraph::NodeIndex memoryNode, rvsdg::Output &state)
StateMap(StateMap &&)=delete
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
rvsdg::Region * region() const noexcept
size_t ninputs() const noexcept
size_t noutputs() const noexcept
rvsdg::Region * region() const noexcept
void divert_users(jlm::rvsdg::Output *new_origin)
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
A phi node represents the fixpoint of mutually recursive definitions.
rvsdg::Region * subregion() const noexcept
Represent acyclic RVSDG subgraphs.
const SimpleOperation & GetOperation() const noexcept override
NodeInput * input(size_t index) const noexcept
NodeOutput * output(size_t index) const noexcept
SubregionIteratorRange Subregions()
LoopVar MapOutputLoopVar(const rvsdg::Output &output) const
Maps variable at exit to full varibale description.
rvsdg::Region * subregion() const noexcept
LoopVar AddLoopVar(rvsdg::Output *origin)
Creates a new loop-carried variable.
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
util::Timer & GetTimer(const std::string &name)
Statistics(const Statistics::Id &statisticsId, util::FilePath sourceFile)
util::Timer & AddTimer(std::string name)
void AddMeasurement(std::string name, T value)
#define JLM_UNREACHABLE(msg)
static std::vector< MemoryNodeId > GetMemoryNodeIds(const ModRefSet &modRefSet)
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.
Helper struct for counting up MemoryNodes, among some set of entities that use them.
void CountEntity(const PointsToGraph &pointsToGraph, const ModRefSet &memoryNodes)
uint64_t MaxNonEscapedMemoryStateEntity
void CountEntity(uint64_t numRefOnly, uint64_t numModOnly, uint64_t numModRef, uint64_t numAllocas, uint64_t numMallocs, uint64_t numDeltas, uint64_t numImports, uint64_t numLambdas, uint64_t numExternalNode, uint64_t numNonEscaped)
uint64_t MaxMemoryStateEntity
rvsdg::Output * output
Output of gamma.