36#include <unordered_map>
47 !std::getenv(
"JLM_DISABLE_OPERATION_SIZE_BLOCKING");
54 !std::getenv(
"JLM_DISABLE_CONSTANT_MEMORY_BLOCKING");
67 !std::getenv(
"JLM_DISABLE_FUNCTION_SIMPLE_ALLOCA_ALLOWLIST");
74 !std::getenv(
"JLM_DISABLE_CALL_SIMPLE_ALLOCA_ALLOWLIST");
82 !std::getenv(
"JLM_DISABLE_EXTERN_SIMPLE_ALLOCA_ALLOWLIST");
100 "ModRefSetSizeBeforeMaterialization";
104 "#ModRefSetsCallingExternalFunction";
106 "ModRefSetSizeAfterMaterialization";
189 size_t numModRefSetsMaterialized,
190 size_t modRefSetSizeBeforeMaterialization,
191 size_t modRefSetSizeAfterFiltering,
192 size_t numModRefSetsWithEffectOnExternal,
193 size_t numModRefSetsCallingExternalFunction,
194 size_t modRefSetSizeAfterMaterialization)
203 numModRefSetsCallingExternalFunction);
213 static std::unique_ptr<Statistics>
216 return std::make_unique<Statistics>(rvsdgModule, pointsToGraph);
238 static constexpr uint32_t
NoneSize = std::numeric_limits<uint32_t>::max();
251 [[nodiscard]] std::optional<size_t>
268 [[nodiscard]] std::optional<size_t>
285 minSize = std::min<size_t>(minSize,
NoneSize - 1);
304 minSize = std::min<size_t>(minSize,
NoneSize - 1);
377 const auto [it, inserted] =
modRefNodes_.insert({ memoryNode, modRefEffect });
382 auto oldEffects = it->second;
383 it->second = oldEffects | modRefEffect;
384 return it->second != oldEffects;
400 bool isExternallyAvailable,
401 std::optional<size_t> memoryNodeSize,
407 if (isExternallyAvailable)
563 .
addMemoryNode(ptgNode, isExternallyAvailable, memoryNodeSize, modRefEffect);
610 const auto it =
nodeMap_.find(&node);
624 auto [it, inserted] =
nodeMap_.insert({ &node, 0 });
628 it->second = created;
636 [[nodiscard]]
const std::vector<ModRefSetIndex> &
642 [[nodiscard]] std::string
646 std::stringstream ss;
647 ss <<
"{MRS#" << index <<
"; ";
648 const auto mayRefMinSize = modRefSet.getRefExternalMinSize();
649 if (mayRefMinSize.has_value())
650 ss <<
"RefExt>=" << *mayRefMinSize <<
" bytes; ";
651 const auto mayModMinSize = modRefSet.getModExternalMinSize();
652 if (mayModMinSize.has_value())
653 ss <<
"ModExt>=" << *mayModMinSize <<
" bytes; ";
654 if (modRefSet.mayCallExternalFunction())
655 ss <<
"MayCallExt; ";
658 for (
auto [memoryNode, modRefEffect] : modRefSet.getModRefNodes())
666 switch (modRefEffect)
721 [[nodiscard]]
static std::unique_ptr<RegionAwareModRefSummary>
724 return std::make_unique<RegionAwareModRefSummary>(pointsToGraph);
759 std::unordered_map<const rvsdg::Node *, ModRefSetIndex>
nodeMap_;
812 std::unordered_map<ModRefSetIndex, util::HashSet<PointsToGraph::NodeIndex>>
860 const rvsdg::RvsdgModule & rvsdgModule,
865 Context_ = std::make_unique<Context>(pointsToGraph);
866 auto statistics = Statistics::Create(rvsdgModule, pointsToGraph);
868 statistics->StartCreateSimpleAllocasSetStatistics();
869 Context_->SimpleAllocas = CreateSimpleAllocaSet(pointsToGraph);
870 statistics->StopCreateSimpleAllocasSetStatistics(Context_->SimpleAllocas.Size());
875 addModRefSetSimpleAllocaAllowlist(ModRefSummary_->getExternModRefSet(), {});
878 statistics->StartAnnotationStatistics();
880 annotateInterproceduralRegion(rvsdgModule.Rvsdg().GetRootRegion());
881 statistics->StopAnnotationStatistics(
882 Context_->Functions.size(),
883 Context_->FunctionsCallingSetjmp.Size());
885 removeSimpleAllocasAroundSetjmp();
887 statistics->StartSolvingStatistics();
888 SolveModRefSetConstraintGraph();
889 statistics->StopSolvingStatistics();
893 statistics->startReadOnlyMemoryDetectionStatistics();
894 determineReadOnlyMemory();
895 statistics->stopReadOnlyMemoryDetectionStatistics(Context_->ReadOnlyMemoryNodes.Size());
898 statistics->startModRefSetMaterializationStatistics();
900 statistics->stopModRefSetMaterializationStatistics(
901 Context_->numModRefSetsMaterialized,
902 Context_->modRefSetSizeBeforeMaterialization,
903 Context_->modRefSetSizeAfterFiltering,
904 Context_->numModRefSetsWithEffectOnExternal,
905 Context_->numModRefSetsCallingExternalFunction,
906 Context_->modRefSetSizeAfterMaterialization);
913 statistics->addMemoryStateDistribution(distribution);
918 return std::move(ModRefSummary_);
927 std::queue<PointsToGraph::NodeIndex> notSimple;
938 simpleAllocas.
insert(ptgNode);
940 notSimple.push(ptgNode);
944 while (!notSimple.empty())
946 const auto ptgNode = notSimple.front();
953 if (simpleAllocas.
Remove(targetPtgNode))
954 notSimple.push(targetPtgNode);
958 return simpleAllocas;
964 const auto & pointsToGraph =
Context_->pointsToGraph;
968 while (!
nodes.empty())
970 const auto ptgNode =
nodes.front();
973 for (
const auto targetPtgNode : pointsToGraph.getExplicitTargets(ptgNode).Items())
976 if (!
Context_->SimpleAllocas.Contains(targetPtgNode))
979 if (reachableSimpleAllocas.
insert(targetPtgNode))
980 nodes.push(targetPtgNode);
984 return reachableSimpleAllocas;
991 const auto & pointsToGraph =
Context_->pointsToGraph;
994 std::queue<PointsToGraph::NodeIndex>
nodes;
999 const auto ptgNode = pointsToGraph.getNodeForRegister(*argument);
1000 nodes.push(ptgNode);
1010 const auto & pointsToGraph =
Context_->pointsToGraph;
1013 std::queue<PointsToGraph::NodeIndex>
nodes;
1015 for (
size_t i = 0; i < numArguments; i++)
1021 const auto ptgNode = pointsToGraph.getNodeForRegister(argument);
1022 nodes.push(ptgNode);
1031 for (
auto setjmpCaller :
Context_->FunctionsCallingSetjmp.Items())
1033 const auto reachableFromArguments =
1035 Context_->SimpleAllocas.DifferenceWith(reachableFromArguments);
1046 Context_->ModRefSetSimpleConstraints[from].push_back(to);
1054 auto [_, inserted] =
1055 Context_->ModRefSetSimpleAllocaAllowlist.emplace(std::make_pair(index, std::move(blocklist)));
1062 for (
auto & node : region.
Nodes())
1080 Context_->Functions.push_back(&lambda);
1094 const auto lambdaPtgNode =
Context_->pointsToGraph.getNodeForLambda(lambda);
1095 if (
Context_->pointsToGraph.isExternallyAvailable(lambdaPtgNode))
1107 for (
auto & node : region.
Nodes())
1130 const auto modRefSet =
ModRefSummary_->getOrCreateSetForNode(structuralNode, lambda);
1132 for (
auto & subregion : structuralNode.
Subregions())
1140std::optional<ModRefSetIndex>
1145 return MatchTypeWithDefault(
1149 return AnnotateLoad(simpleNode, lambda);
1153 return AnnotateStore(simpleNode, lambda);
1157 return AnnotateAlloca(simpleNode, lambda);
1161 return AnnotateMalloc(simpleNode, lambda);
1165 return AnnotateFree(simpleNode, lambda);
1169 return AnnotateMemcpy(simpleNode, lambda);
1173 return AnnotateMemset(simpleNode, lambda);
1177 return AnnotateMemmove(simpleNode, lambda);
1181 return AnnotateCall(simpleNode, lambda);
1186 return std::nullopt;
1188 [&]() -> std::optional<ModRefSetIndex>
1191 JLM_ASSERT(!hasMemoryState(simpleNode));
1192 return std::nullopt;
1200 std::optional<size_t> minTargetSize,
1203 const auto & pointsToGraph =
Context_->pointsToGraph;
1205 const auto registerPtgNode = pointsToGraph.getNodeForRegister(origin);
1213 const auto targetSize = pointsToGraph.tryGetNodeSize(targetPtgNode);
1214 if (targetSize.has_value() && *targetSize < minTargetSize)
1217 ModRefSummary_->addExplicitMemoryNodeToSet(modRefSetIndex, targetPtgNode, modRefEffect);
1221 if (pointsToGraph.isTargetingAllExternallyAvailable(registerPtgNode))
1225 ModRefSummary_->markSetAsReferencingExternal(modRefSetIndex, minTargetSize.value_or(0));
1229 ModRefSummary_->markSetAsModifyingExternal(modRefSetIndex, minTargetSize.value_or(0));
1233 for (
const auto targetPtgNode : pointsToGraph.getExplicitTargets(registerPtgNode).Items())
1237 !pointsToGraph.isTargetingAllExternallyAvailable(registerPtgNode)
1238 || !pointsToGraph.isExternallyAvailable(targetPtgNode));
1239 tryAddToModRefSet(targetPtgNode);
1248 const auto nodeModRef =
ModRefSummary_->getOrCreateSetForNode(loadNode, lambda);
1250 const auto loadOperation = util::assertedCast<const LoadOperation>(&loadNode.
GetOperation());
1262 const auto nodeModRef =
ModRefSummary_->getOrCreateSetForNode(storeNode, lambda);
1264 const auto storeOperation = util::assertedCast<const StoreOperation>(&storeNode.
GetOperation());
1276 const auto nodeModRef =
ModRefSummary_->getOrCreateSetForNode(allocaNode, lambda);
1277 const auto allocaMemoryNode =
Context_->pointsToGraph.getNodeForAlloca(allocaNode);
1289 const auto nodeModRef =
ModRefSummary_->getOrCreateSetForNode(mallocNode, lambda);
1290 const auto mallocMemoryNode =
Context_->pointsToGraph.getNodeForMalloc(mallocNode);
1304 const auto nodeModRef =
ModRefSummary_->getOrCreateSetForNode(freeNode, lambda);
1319 const auto nodeModRef =
ModRefSummary_->getOrCreateSetForNode(memcpyNode, lambda);
1336 const auto nodeModRef =
ModRefSummary_->getOrCreateSetForNode(memmoveNode, lambda);
1353 const auto nodeModRef =
ModRefSummary_->getOrCreateSetForNode(memsetNode, lambda);
1369 const auto & pointsToGraph =
Context_->pointsToGraph;
1372 const auto callModRef =
ModRefSummary_->getOrCreateSetForNode(callNode, lambda);
1375 const auto targetPtr = callNode.
input(0)->
origin();
1376 const auto targetPtgNode =
Context_->pointsToGraph.getNodeForRegister(*targetPtr);
1379 for (
const auto calleePtgNode : pointsToGraph.getExplicitTargets(targetPtgNode).Items())
1381 const auto kind = pointsToGraph.getNodeKind(calleePtgNode);
1384 const auto & calleeLambda = pointsToGraph.getLambdaForNode(calleePtgNode);
1385 const auto targetModRefSet =
1386 ModRefSummary_->getOrCreateSetForNode(calleeLambda, calleeLambda);
1394 if (pointsToGraph.isTargetingAllExternallyAvailable(targetPtgNode))
1409 if (classification->isSetjmpCall())
1411 Context_->FunctionsCallingSetjmp.insert(&lambda);
1434 for (
auto target :
Context_->ModRefSetSimpleConstraints[workItem])
1441 if (
auto allowlist =
Context_->ModRefSetSimpleAllocaAllowlist.find(target);
1442 allowlist !=
Context_->ModRefSetSimpleAllocaAllowlist.end())
1447 if (
Context_->SimpleAllocas.Contains(memoryNode))
1449 if (!allowlist->second.Contains(memoryNode))
1453 changed |=
ModRefSummary_->addMemoryNodeToSet(target, memoryNode, mayMod);
1461 changed |=
ModRefSummary_->addMemoryNodeToSet(target, memoryNode, mayMod);
1478 for (
auto & [index, allowlist] :
Context_->ModRefSetSimpleAllocaAllowlist)
1480 for (
auto [memoryNode, _] :
ModRefSummary_->getModRefSet(index).getModRefNodes())
1482 if (
Context_->SimpleAllocas.Contains(memoryNode) && !allowlist.Contains(memoryNode))
1492 const auto externModRefSet =
ModRefSummary_->getExternModRefSet();
1493 for (
auto [memoryNode, modRefEffect] :
1504 if (
ModRefSummary_->GetPointsToGraph().isExternallyAvailable(memoryNode))
1513 Context_->ReadOnlyMemoryNodes.insert(memoryNode);
1520 for (
auto function :
Context_->Functions)
1531 const auto & externModRefNodes =
1539 std::vector<PointsToGraph::NodeIndex> materializeExternallyAvailable;
1543 std::vector<std::pair<PointsToGraph::NodeIndex, ModRefEffect>> materializeFromCallToExtern;
1548 if (
Context_->ReadOnlyMemoryNodes.Contains(memoryNode))
1551 bool inserted = keepMemoryNodes.
insert(memoryNode);
1555 if (pointsToGraph.isExternallyAvailable(memoryNode))
1556 materializeExternallyAvailable.push_back(memoryNode);
1557 else if (
auto it = externModRefNodes.find(memoryNode); it != externModRefNodes.end())
1558 materializeFromCallToExtern.push_back(*it);
1565 const auto & allModRefSets =
ModRefSummary_->getAllSetsInFunction(lambda);
1566 for (
auto modRefSetIndex : allModRefSets)
1568 const auto & modRefSet =
ModRefSummary_->getModRefSet(modRefSetIndex);
1569 Context_->numModRefSetsMaterialized++;
1570 Context_->modRefSetSizeBeforeMaterialization += modRefSet.getModRefNodes().size();
1572 auto effectOnExternalNode = modRefSet.getImplicitModRefEffectForExternal(std::nullopt);
1579 for (
auto [memoryNode, modRefEffect] : modRefSet.getModRefNodes())
1586 markToKeep(memoryNode);
1592 for (
auto modRefSetIndex : allModRefSets)
1595 modRefSet.keepSubsetOfExplicitMemoryNodes(keepMemoryNodes);
1596 Context_->modRefSetSizeAfterFiltering += modRefSet.getModRefNodes().size();
1601 auto effectOnAllExternalNodes = modRefSet.getImplicitModRefEffectForExternal(1);
1602 auto effectOnLargeExternalNodes = modRefSet.getImplicitModRefEffectForExternal(std::nullopt);
1609 Context_->modRefSetSizeAfterMaterialization += modRefSet.getModRefNodes().size();
1615 if (effectOnLargeExternalNodes == effectOnAllExternalNodes)
1617 for (
auto memoryNode : materializeExternallyAvailable)
1619 modRefSet.addExplicitMemoryNode(memoryNode, effectOnLargeExternalNodes);
1625 for (
auto memoryNode : materializeExternallyAvailable)
1627 const auto memoryNodeSize = pointsToGraph.tryGetNodeSize(memoryNode);
1628 const auto modRefEffect = modRefSet.getImplicitModRefEffectForExternal(memoryNodeSize);
1630 modRefSet.addExplicitMemoryNode(memoryNode, modRefEffect);
1636 if (modRefSet.mayCallExternalFunction())
1638 Context_->numModRefSetsCallingExternalFunction++;
1639 for (
auto [memoryNode, modRefEffect] : materializeFromCallToExtern)
1641 modRefSet.addExplicitMemoryNode(memoryNode, modRefEffect);
1645 Context_->numModRefSetsWithEffectOnExternal++;
1646 Context_->modRefSetSizeAfterMaterialization += modRefSet.getModRefNodes().size();
1655 std::ostringstream ss;
1657 ss <<
"ExternModRefSet: "
1660 auto indent = [&](
size_t depth,
char c =
'-')
1662 for (
size_t i = 0; i < depth; i++)
1666 std::function<void(
const rvsdg::Node &,
size_t)> toRegionTree =
1683 for (
auto & region : structuralNode->Subregions())
1685 indent(depth + 1,
'-');
1686 ss <<
"RegionID: " << region.getRegionId() << std::endl;
1687 for (
auto & n : region.Nodes())
1688 toRegionTree(n, depth + 2);
1693 ss <<
"RootRegion:" << std::endl;
1695 toRegionTree(node, 0);
1700std::unique_ptr<ModRefSummary>
1710std::unique_ptr<ModRefSummary>
std::vector< rvsdg::Node * > nodes
static std::unique_ptr< CallTypeClassifier > ClassifyCall(const rvsdg::SimpleNode &callNode)
Classifies a call node.
static rvsdg::Input * Argument(const rvsdg::Node &node, const size_t n)
static size_t NumArguments(const rvsdg::Node &node) noexcept
static rvsdg::Input & getAddressInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & AddressInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & sourceInput(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 & destinationInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & lengthInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & sourceInput(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::Input & AddressInput(const rvsdg::Node &node) noexcept
std::unordered_map< PointsToGraph::NodeIndex, ModRefEffect > modRefNodes_
const std::unordered_map< PointsToGraph::NodeIndex, ModRefEffect > & getModRefNodes() const
size_t numNodes() const noexcept
size_t numMemoryNodes() const noexcept
bool isExternallyAvailable(NodeIndex index) const
std::string getNodeDebugString(NodeIndex index, char separator=' ') const
std::optional< size_t > tryGetNodeSize(NodeIndex index) const noexcept
const util::HashSet< NodeIndex > & getExplicitTargets(NodeIndex index) const
NodeKind getNodeKind(NodeIndex index) const
bool isMemoryNode(NodeIndex index) const
static constexpr NodeIndex externalMemoryNode
bool markAsReferencingExternal(size_t minSize)
uint32_t refExternalOfSize_
ModRefEffect getImplicitModRefEffectForExternal(std::optional< size_t > size) const noexcept
bool markAsModifyingExternal(size_t minSize)
std::optional< size_t > getRefExternalMinSize() const
bool propagateFlags(const RegionAwareModRefSet &other)
bool addExplicitMemoryNode(PointsToGraph::NodeIndex memoryNode, ModRefEffect modRefEffect)
bool markAsCallingExternalFunction()
static constexpr uint32_t NoneSize
void keepSubsetOfExplicitMemoryNodes(const util::HashSet< PointsToGraph::NodeIndex > &filter)
std::optional< size_t > getModExternalMinSize() const
bool addMemoryNode(PointsToGraph::NodeIndex memoryNode, bool isExternallyAvailable, std::optional< size_t > memoryNodeSize, ModRefEffect modRefEffect)
uint32_t modExternalOfSize_
bool callsExternalFunction_
RegionAwareModRefSet()=default
bool mayCallExternalFunction() const
Region-aware mod/ref summarizer statistics.
static constexpr auto NumReadOnlyMemoryNodesDetectedLabel_
void StartAnnotationStatistics()
static constexpr auto NumModRefSetsCallingExternalFunctionLabel_
void stopReadOnlyMemoryDetectionStatistics(size_t numReadOnlyMemoryNodesDetected)
void stopModRefSetMaterializationStatistics(size_t numModRefSetsMaterialized, size_t modRefSetSizeBeforeMaterialization, size_t modRefSetSizeAfterFiltering, size_t numModRefSetsWithEffectOnExternal, size_t numModRefSetsCallingExternalFunction, size_t modRefSetSizeAfterMaterialization)
static constexpr auto memoryStateDistributionLabel_
void StartSolvingStatistics()
void StopAnnotationStatistics(size_t numFunctions, size_t numFunctionsCallingSetjmp)
static constexpr auto NumSimpleAllocas_
~Statistics() override=default
static constexpr auto ModRefSetSizeBeforeMaterializationLabel_
static constexpr auto NumFunctions_
static std::unique_ptr< Statistics > Create(const rvsdg::RvsdgModule &rvsdgModule, const PointsToGraph &pointsToGraph)
static constexpr auto NumFunctionsCallingSetjmp_
static constexpr auto SimpleAllocasSetTimer_
void startReadOnlyMemoryDetectionStatistics()
void startModRefSetMaterializationStatistics()
void StartCreateSimpleAllocasSetStatistics()
static constexpr auto ReadOnlyDetectionTimer_
static constexpr auto NumRvsdgRegionsLabel_
static constexpr auto SolvingTimer_
Statistics(const rvsdg::RvsdgModule &rvsdgModule, const PointsToGraph &pointsToGraph)
void StopSolvingStatistics()
static constexpr auto NumModRefSetsMaterializedLabel_
void StopCreateSimpleAllocasSetStatistics(uint64_t numSimpleAllocas)
static constexpr auto AnnotationTimer_
static constexpr auto ModRefSetSizeAfterFilteringLabel_
static constexpr auto ModRefSetSizeAfterMaterializationLabel_
void addMemoryStateDistribution(const std::vector< MemoryStateSummary > &memoryStateDistribution)
static constexpr auto ModRefSetMaterializationTimer_
static constexpr auto NumModRefSetsWithEffectOnExternalLabel_
Region-aware mod/ref summarizer.
ModRefSetIndex AnnotateStore(const rvsdg::SimpleNode &storeNode, const rvsdg::LambdaNode &lambda)
ModRefSetIndex AnnotateMalloc(const rvsdg::SimpleNode &mallocNode, const rvsdg::LambdaNode &lambda)
void SolveModRefSetConstraintGraph()
void annotateInterproceduralRegion(const rvsdg::Region ®ion)
static util::HashSet< PointsToGraph::NodeIndex > CreateSimpleAllocaSet(const PointsToGraph &pointsToGraph)
ModRefSetIndex AnnotateLoad(const rvsdg::SimpleNode &loadNode, const rvsdg::LambdaNode &lambda)
void addPointerOriginTargets(ModRefSetIndex modRefSetIndex, const rvsdg::Output &origin, std::optional< size_t > minTargetSize, ModRefEffect modRefEffect)
ModRefSetIndex AnnotateMemcpy(const rvsdg::SimpleNode &memcpyNode, const rvsdg::LambdaNode &lambda)
static std::unique_ptr< ModRefSummary > Create(const rvsdg::RvsdgModule &rvsdgModule, const PointsToGraph &pointsToGraph, util::StatisticsCollector &statisticsCollector)
void materializeSetsInFunction(const rvsdg::LambdaNode &lambda)
~RegionAwareModRefSummarizer() noexcept override
void removeSimpleAllocasAroundSetjmp()
std::optional< ModRefSetIndex > AnnotateSimpleNode(const rvsdg::SimpleNode &simpleNode, const rvsdg::LambdaNode &lambda)
ModRefSetIndex AnnotateAlloca(const rvsdg::SimpleNode &allocaNode, const rvsdg::LambdaNode &lambda)
std::unique_ptr< RegionAwareModRefSummary > ModRefSummary_
void AddModRefSimpleConstraint(ModRefSetIndex from, ModRefSetIndex to)
bool verifySimpleAllocaAllowlists() const
std::unique_ptr< ModRefSummary > SummarizeModRefs(const rvsdg::RvsdgModule &rvsdgModule, const PointsToGraph &pointsToGraph, util::StatisticsCollector &statisticsCollector) override
util::HashSet< PointsToGraph::NodeIndex > getSimpleAllocasReachableFromRegionArguments(const rvsdg::Region ®ion)
void addModRefSetSimpleAllocaAllowlist(ModRefSetIndex index, util::HashSet< PointsToGraph::NodeIndex > allowlist)
static std::string ToRegionTree(const rvsdg::Graph &rvsdg, const RegionAwareModRefSummary &modRefSummary)
void determineReadOnlyMemory()
util::HashSet< PointsToGraph::NodeIndex > getReachableSimpleAllocas(std::queue< PointsToGraph::NodeIndex > &nodes)
ModRefSetIndex AnnotateMemset(const rvsdg::SimpleNode &memsetNode, const rvsdg::LambdaNode &lambda)
util::HashSet< PointsToGraph::NodeIndex > getSimpleAllocasReachableFromCallArguments(const rvsdg::SimpleNode &call)
ModRefSetIndex AnnotateMemmove(const rvsdg::SimpleNode &memmoveNode, const rvsdg::LambdaNode &lambda)
std::unique_ptr< Context > Context_
void AnnotateRegion(const rvsdg::Region ®ion, ModRefSetIndex modRefSet, const rvsdg::LambdaNode &lambda)
void AnnotateFunction(const rvsdg::LambdaNode &lambda)
ModRefSetIndex AnnotateFree(const rvsdg::SimpleNode &freeNode, const rvsdg::LambdaNode &lambda)
ModRefSetIndex AnnotateStructuralNode(const rvsdg::StructuralNode &structuralNode, const rvsdg::LambdaNode &lambda)
ModRefSetIndex AnnotateCall(const rvsdg::SimpleNode &callNode, const rvsdg::LambdaNode &lambda)
Mod/Ref summary of region-aware mod/ref summarizer.
const std::vector< ModRefSetIndex > & getAllSetsInFunction(const rvsdg::LambdaNode &lambdaNode)
std::string getModRefSetDebugString(ModRefSetIndex index) const
ModRefSetIndex getOrCreateSetForNode(const rvsdg::Node &node, const rvsdg::LambdaNode &lambdaNode)
static std::unique_ptr< RegionAwareModRefSummary > Create(const PointsToGraph &pointsToGraph)
RegionAwareModRefSummary & operator=(const RegionAwareModRefSummary &)=delete
bool markSetAsModifyingExternal(ModRefSetIndex index, size_t minSize)
ModRefSetIndex externModRefSet_
const RegionAwareModRefSet & getModRefSet(ModRefSetIndex index) const
const ModRefSet & GetLambdaEntryModRef(const rvsdg::LambdaNode &lambda) const override
bool hasSetForNode(const rvsdg::Node &node) const
bool addMemoryNodeToSet(ModRefSetIndex index, PointsToGraph::NodeIndex ptgNode, ModRefEffect modRefEffect)
const ModRefSet & GetSimpleNodeModRef(const rvsdg::SimpleNode &node) const override
RegionAwareModRefSummary(const PointsToGraph &pointsToGraph)
bool markSetAsReferencingExternal(ModRefSetIndex index, size_t minSize)
bool markSetAsCallingExternalFunction(ModRefSetIndex index)
RegionAwareModRefSummary(const RegionAwareModRefSummary &)=delete
std::vector< RegionAwareModRefSet > modRefSets_
std::unordered_map< const rvsdg::Node *, ModRefSetIndex > nodeMap_
RegionAwareModRefSet & getModRefSet(ModRefSetIndex index)
const ModRefSet & GetGammaExitModRef(const rvsdg::GammaNode &gamma) const override
const PointsToGraph & GetPointsToGraph() const noexcept override
std::unordered_map< const rvsdg::LambdaNode *, std::vector< ModRefSetIndex > > modRefSetsInFunction_
ModRefSetIndex createModRefSet()
ModRefSetIndex getExternModRefSet() const noexcept
const ModRefSet & GetGammaEntryModRef(const rvsdg::GammaNode &gamma) const override
const ModRefSet & GetLambdaExitModRef(const rvsdg::LambdaNode &lambda) const override
ModRefSetIndex getSetForNode(const rvsdg::Node &node) const
size_t NumModRefSets() const noexcept
const PointsToGraph & pointsToGraph_
const ModRefSet & GetThetaModRef(const rvsdg::ThetaNode &theta) const override
bool addExplicitMemoryNodeToSet(ModRefSetIndex index, PointsToGraph::NodeIndex ptgNode, ModRefEffect modRefEffect)
Conditional operator / pattern matching.
Region & GetRootRegion() const noexcept
rvsdg::Region * subregion() const noexcept
Id GetNodeId() const noexcept
virtual std::string DebugString() const =0
A phi node represents the fixpoint of mutually recursive definitions.
rvsdg::Region * subregion() const noexcept
Represent acyclic RVSDG subgraphs.
RegionArgumentRange Arguments() noexcept
static size_t NumRegions(const rvsdg::Region ®ion) noexcept
NodeRange Nodes() noexcept
const SimpleOperation & GetOperation() const noexcept override
NodeInput * input(size_t index) const noexcept
SubregionIteratorRange Subregions()
bool insert(ItemType item)
bool Contains(const ItemType &item) const noexcept
bool Remove(ItemType item)
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)
void PushWorkItem(T item) override
bool HasMoreWorkItems() const noexcept override
#define JLM_UNREACHABLE(msg)
static const bool ENABLE_READ_ONLY_DETECTION
bool IsPointerCompatible(const rvsdg::Output &value)
bool isEffectSubset(ModRefEffect subset, ModRefEffect superset)
std::string toString(const std::vector< MemoryStateSummary > &memoryStateDistribution)
bool mayEffectModify(ModRefEffect effect)
static const bool ENABLE_EXTERN_SIMPLE_ALLOCA_ALLOWLIST
bool mayEffectReference(ModRefEffect effect)
static const bool ENABLE_CONSTANT_MEMORY_BLOCKING
static const bool ENABLE_OPERATION_SIZE_BLOCKING
static const bool ENABLE_CALL_SIMPLE_ALLOCA_ALLOWLIST
static const bool ENABLE_FUNCTION_SIMPLE_ALLOCA_ALLOWLIST
std::vector< MemoryStateSummary > collectMemoryStateDistribution(const rvsdg::Graph &rvsdg, const ModRefSummary &modRefSummary)
static util::StatisticsCollector statisticsCollector
size_t GetTypeStoreSize(const rvsdg::Type &type)
std::optional< int64_t > tryGetConstantSignedInteger(const rvsdg::Output &output)
void MatchTypeOrFail(T &obj, const Fns &... fns)
Pattern match over subclass type of given object.
void MatchType(T &obj, const Fns &... fns)
Pattern match over subclass type of given object.
size_t nnodes(const jlm::rvsdg::Region *region) noexcept
size_t numModRefSetsWithEffectOnExternal
size_t numModRefSetsCallingExternalFunction
size_t modRefSetSizeBeforeMaterialization
size_t modRefSetSizeAfterFiltering
std::unordered_map< ModRefSetIndex, util::HashSet< PointsToGraph::NodeIndex > > ModRefSetSimpleAllocaAllowlist
Context(const PointsToGraph &ptg)
util::HashSet< PointsToGraph::NodeIndex > SimpleAllocas
util::HashSet< const rvsdg::LambdaNode * > FunctionsCallingSetjmp
size_t modRefSetSizeAfterMaterialization
size_t numModRefSetsMaterialized
const PointsToGraph & pointsToGraph
util::HashSet< PointsToGraph::NodeIndex > ReadOnlyMemoryNodes
std::vector< std::vector< ModRefSetIndex > > ModRefSetSimpleConstraints
std::vector< const rvsdg::LambdaNode * > Functions