49static const bool ENABLE_PTGAA = std::getenv(
"JLM_ENABLE_SVF_PTGAA");
53 !std::getenv(
"JLM_DISABLE_REGION_PREDICATE_CHECK");
84 throw std::logic_error(
"Unhandled alias analysis query response!");
107 "#ForwardedLoadsWithoutMemoryState";
135 const size_t numLoadsWithMemoryState,
136 const size_t numLoadsWithoutMemoryState,
137 const size_t numLoadsTracedtoDeltaNode,
138 const size_t numForwardedLoadsWithMemoryState,
139 const size_t numForwardedLoadsWithoutMemoryState,
181 static std::unique_ptr<Statistics>
184 return std::make_unique<Statistics>(sourceFile);
216 operator()(
const std::pair<rvsdg::Output *, rvsdg::Region *> & value)
const
218 return std::hash<rvsdg::Output *>()(value.first) ^ std::hash<rvsdg::Region *>()(value.second);
222 std::unordered_map<std::pair<rvsdg::Output *, rvsdg::Region *>,
rvsdg::Output *, OutputRegionHash>
244 for (
auto & node : region.
Nodes())
257 context_->outputTracer.clearCache();
272 for (
auto node : traverser)
278 for (
auto & subregion : gammaNode.
Subregions())
289 if (is<LoadNonVolatileOperation>(&simpleNode))
351 return kind == other.kind &&
node == other.node;
357 return !(*
this == other);
450 if (!lastValueOrigin.isKnown())
461 if (!lastValueOrigin.isKnown())
479 std::optional<ValueOrigin>
482 if (loopBackEdgeMaybeTaken)
506 std::optional<ValueOrigin>
509 if (loopBackEdgeMaybeTaken)
543 const auto response =
558 JLM_ASSERT(is<LoadOperation>(&otherLoadNode));
568 const auto response =
601 const auto [_, inserted] =
608 const auto [it, inserted] =
612 if (!inserted && it->second != result)
619 const auto region = regionResult->region();
620 const auto [it, inserted] =
624 if (!inserted && it->second != result)
640 if (
auto [storeNode, storeOp] =
642 storeNode && storeOp)
651 switch (aliasReponse)
694 if (
auto [otherLoadNode, otherLoadOp] =
696 otherLoadNode && otherLoadOp)
705 switch (aliasReponse)
744 if (
auto [joinNode, joinOp] =
748 if (joinNode->ninputs() == 0)
751 for (
auto & input : joinNode->Inputs())
754 if (!result.isKnown())
759 const auto sharedLastValueOrigin =
762 JLM_ASSERT(sharedLastValueOrigin->second.isKnown());
763 return sharedLastValueOrigin->second;
767 if (
auto [allocaNode, allocaOp] =
769 allocaNode && allocaOp)
777 const auto exitVar = gammaNode->MapOutputExitVar(tracedOutput);
781 std::optional<ValueOrigin> commonValueOrigin;
782 const auto addObservedValueOrigin = [&](
ValueOrigin origin)
788 if (!commonValueOrigin.has_value())
789 commonValueOrigin = origin;
790 else if (commonValueOrigin.value() != origin)
794 for (
auto branchResult : exitVar.branchResult)
798 if (!loopBackEdgeTaken)
803 auto & fromRegion = *branchResult->region();
809 std::make_pair(&fromRegion, loopBackEdgeTaken),
811 addObservedValueOrigin(valueOrigin);
820 if (!lastValueOrigin.isKnown())
824 addObservedValueOrigin(lastValueOrigin);
828 if (!commonValueOrigin.has_value())
832 if (commonValueOrigin->isKnown())
838 if (commonValueOrigin->node->region()->node() != gammaNode)
839 return *commonValueOrigin;
850 const auto loopVar = thetaNode->MapOutputLoopVar(tracedOutput);
855 if (!lastValueOrigin.isKnown())
861 && lastValueOrigin.node == thetaNode)
867 if (loopBackEdgeTaken)
872 if (!lastValueOrigin.isKnown())
876 && lastValueOrigin.node == thetaNode)
888 || lastValueOrigin.node->region() == thetaNode->subregion());
895 const auto loopVar = thetaNode->MapPreLoopVar(tracedOutput);
900 if (!inputLastValueOrigin.isKnown())
940 std::pair<rvsdg::Input *, bool>,
950 std::pair<rvsdg::Node *, bool>,
961 std::pair<rvsdg::Region *, bool>,
985 JLM_ASSERT(is<LoadNonVolatileOperation>(&loadNode));
989 context_->numLoadsWithoutMemoryState++;
994 context_->numLoadsWithMemoryState++;
1002 JLM_ASSERT(is<LoadNonVolatileOperation>(&loadNode));
1005 context_->statistics.startTracing();
1012 context_->statistics.stopTracing();
1017 if (shouldForwardValueOrigins)
1019 context_->statistics.startForwarding();
1021 context_->statistics.stopForwarding();
1028 JLM_ASSERT(is<LoadNonVolatileOperation>(&loadNode));
1031 context_->statistics.startTracing();
1033 context_->statistics.stopTracing();
1034 if (!tracedDelta.has_value())
1039 context_->statistics.startForwarding();
1041 context_->statistics.stopForwarding();
1044std::optional<StoreValueForwarding::TracedDelta>
1047 JLM_ASSERT(is<LoadNonVolatileOperation>(&loadNode));
1052 if (!gepConstantsOpt.has_value())
1054 return std::nullopt;
1060 return std::nullopt;
1063 context_->numLoadsTracedToDeltaNode++;
1064 return std::optional<TracedDelta>({ deltaNode, gepConstantsOpt.value() });
1087 RegionSlice & regionSlice,
1092 regionSlice.arguments.insert(&output);
1097 if (visited.Contains(&node))
1100 regionSlice.nodes.push_back(&node);
1101 for (
auto & input : node.Inputs())
1103 compute(*input.origin(), regionSlice, visited);
1107 RegionSlice regionSlice;
1109 compute(output, regionSlice, visited);
1117 const RegionSlice & regionSlice,
1120 for (
auto it = regionSlice.nodes.rbegin(); it != regionSlice.nodes.rend(); ++it)
1123 node->copy(&targetRegion, substitutionMap);
1130 auto deltaNode = util::assertedCast<rvsdg::DeltaNode>(output.
region()->
node());
1135 for (
auto oldArgument : regionSlice.arguments.Items())
1137 auto ctxVar = deltaNode->MapBinderContextVar(*oldArgument);
1139 substitutionMap.
insert(oldArgument, &newArgument);
1143 return substitutionMap.
lookup(output);
1148 const uint64_t elementOffsetInBytes,
1151 const std::shared_ptr<const rvsdg::Type> & loadedType)
1156 node->GetOperation(),
1159 JLM_ASSERT(elementOffsetInBytes == 0);
1160 auto copiedOutput = ©DeltaRegionSlice(output, targetRegion);
1162 const auto loadBitType = util::assertedCast<const rvsdg::BitType>(loadedType.get());
1163 const auto copiedBitType =
1164 util::assertedCast<const rvsdg::BitType>(copiedOutput->Type().get());
1165 if (copiedBitType->nbits() == loadBitType->nbits())
1167 return *copiedOutput;
1170 if (loadBitType->nbits() < copiedBitType->nbits())
1172 return *TruncOperation::createNode(*copiedOutput, loadedType).output(0);
1176 return *copiedOutput;
1205 if (is<PointerType>(loadedType))
1210 if (
const auto bitType = std::dynamic_pointer_cast<const rvsdg::BitType>(loadedType))
1215 if (
const auto floatType = std::dynamic_pointer_cast<const FloatingPointType>(loadedType))
1221 if (
const auto vectorType = std::dynamic_pointer_cast<const FixedVectorType>(loadedType))
1226 throw std::logic_error(
"Unsupported load type");
1230 const auto arrayType = constantArrayOperation.type();
1231 const auto elementSizeInBytes =
GetTypeAllocSize(*arrayType->GetElementType());
1233 const auto index = elementOffsetInBytes / elementSizeInBytes;
1235 elementOffsetInBytes - (elementSizeInBytes * index),
1236 *node->input(index)->origin(),
1242 const auto arrayType = constantDataArrayOperation.type();
1243 const auto elementSizeInBytes =
GetTypeAllocSize(*arrayType->GetElementType());
1245 const auto index = elementOffsetInBytes / elementSizeInBytes;
1247 elementOffsetInBytes - (elementSizeInBytes * index),
1248 *node->input(index)->origin(),
1254 auto & structType = constantStruct.type();
1256 for (
size_t n = 0; n < structType.numElements(); ++n)
1258 auto fieldOffsetInBytes = structType.GetFieldOffset(n);
1260 if (fieldOffsetInBytes == elementOffsetInBytes)
1262 return copyDeltaElement(0, *node->input(n)->origin(), targetRegion, loadedType);
1265 if (fieldOffsetInBytes > elementOffsetInBytes)
1267 fieldOffsetInBytes = structType.GetFieldOffset(n - 1);
1269 elementOffsetInBytes - fieldOffsetInBytes,
1270 *node->input(n - 1)->origin(),
1276 const auto lastElementIndex = structType.numElements() - 1;
1277 const auto fieldOffsetInBytes = structType.GetFieldOffset(lastElementIndex);
1278 JLM_ASSERT(fieldOffsetInBytes <= elementOffsetInBytes);
1280 elementOffsetInBytes - fieldOffsetInBytes,
1281 *node->input(lastElementIndex)->origin(),
1287 throw std::logic_error(
"Unsupported operation: " + node->DebugString());
1297 throw std::logic_error(
"Unsupported output owner");
1301StoreValueForwarding::forwardLoadWithoutMemoryStates(
1305 JLM_ASSERT(is<LoadNonVolatileOperation>(&loadNode));
1306 JLM_ASSERT(LoadOperation::numMemoryStates(loadNode) == 0);
1307 const auto loadOperation =
1318 const uint64_t offsetInBytes =
1324 loadOperation->GetLoadedType());
1326 if (*loadOperation->GetLoadedType() != *newOutput.Type())
1332 LoadOperation::LoadedValueOutput(loadNode).divert_users(&newOutput);
1333 context_->numForwardedLoadsWithoutMemoryState++;
1340 context_->numForwardedLoadsWithMemoryState++;
1342 auto & loadNode = tracingInfo.
loadNode;
1343 auto & loadedValueOutput = LoadOperation::LoadedValueOutput(loadNode);
1344 auto & loadRegion = *loadNode.region();
1348 JLM_ASSERT(lastValueOrigin.has_value() && lastValueOrigin->isKnown());
1349 auto & valueOriginOutput = getValueOriginOutput(*lastValueOrigin, loadRegion, tracingInfo);
1352 connectUnroutedLoopPosts(tracingInfo);
1355 loadedValueOutput.divert_users(&valueOriginOutput);
1358 for (
auto & memoryStateOutput : LoadNonVolatileOperation::MemoryStateOutputs(loadNode))
1360 auto & memoryStateInput =
1361 LoadNonVolatileOperation::MapMemoryStateOutputToInput(memoryStateOutput);
1362 memoryStateOutput.divert_users(memoryStateInput.origin());
1368StoreValueForwarding::getValueOriginOutput(
1375 if (valueOrigin.
kind == ValueOrigin::Kind::Uninitialized)
1378 return *UndefValueOperation::Create(targetRegion, tracingInfo.
loadedType);
1381 if (valueOrigin.
kind == ValueOrigin::Kind::StoreNode)
1384 auto & storedValue = *StoreOperation::StoredValueInput(*valueOrigin.
node).origin();
1386 return routeOutputToRegion(storedValue, targetRegion);
1389 if (valueOrigin.
kind == ValueOrigin::Kind::LoadNode)
1392 auto & loadedValue = LoadOperation::LoadedValueOutput(*valueOrigin.
node);
1394 return routeOutputToRegion(loadedValue, targetRegion);
1398 if (valueOrigin.
kind == ValueOrigin::Kind::GammaNodeOutput)
1404 auto [it, inserted] = tracingInfo.
createdExitVars.emplace(gammaNode,
nullptr);
1407 std::vector<rvsdg::Output *> lastValueOriginPerSubregion;
1408 for (
auto & subregion : gammaNode->Subregions())
1417 JLM_ASSERT(lastValueOrigin.has_value() && lastValueOrigin->isKnown());
1418 auto & valueOriginOutput = getValueOriginOutput(*lastValueOrigin, subregion, tracingInfo);
1419 lastValueOriginPerSubregion.push_back(&valueOriginOutput);
1422 auto exitVar = gammaNode->AddExitVar(lastValueOriginPerSubregion);
1423 it->second = exitVar.output;
1427 return routeOutputToRegion(*it->second, targetRegion);
1431 if (valueOrigin.
kind == ValueOrigin::Kind::ThetaNodeOutput
1432 || valueOrigin.
kind == ValueOrigin::Kind::ThetaNodePre)
1450 if (lastValueOrigin.has_value())
1453 auto & outerRegion = *thetaNode->region();
1454 initialValue = &getValueOriginOutput(*lastValueOrigin, outerRegion, tracingInfo);
1460 initialValue = UndefValueOperation::Create(*thetaNode->region(), tracingInfo.
loadedType);
1466 auto loopVar = thetaNode->AddLoopVar(initialValue);
1467 auto [it, inserted] = tracingInfo.
createdLoopVars.emplace(thetaNode, loopVar);
1477 switch (valueOrigin.
kind)
1479 case ValueOrigin::Kind::ThetaNodePre:
1480 return routeOutputToRegion(*loopVarSlot->second.pre, targetRegion);
1481 case ValueOrigin::Kind::ThetaNodeOutput:
1482 return routeOutputToRegion(*loopVarSlot->second.output, targetRegion);
1507 JLM_ASSERT(lastValueOrigin.has_value() && lastValueOrigin->isKnown());
1508 auto & origin = getValueOriginOutput(*lastValueOrigin, *post->region(), tracingInfo);
1509 post->divert_to(&origin);
1516 if (output.
region() == ®ion)
1522 JLM_UNREACHABLE(
"root region reached during attempt at routing output into region");
1527 auto & outerOutput = routeOutputToRegion(output, *gammaNode->
region());
1530 if (
auto it = context_->routedOutputs.find({ &outerOutput, ®ion });
1531 it != context_->routedOutputs.end())
1535 auto & branchArgument = *it->second;
1536 if (gammaNode->mapBranchArgumentToInput(branchArgument).origin() == &outerOutput)
1539 return branchArgument;
1544 auto entryVar = gammaNode->AddEntryVar(&outerOutput);
1545 for (
auto branchArgument : entryVar.branchArgument)
1547 context_->routedOutputs[{ &outerOutput, branchArgument->region() }] = branchArgument;
1550 return *entryVar.branchArgument[region.
index()];
1556 auto & outerOutput = routeOutputToRegion(output, *thetaNode->
region());
1559 if (
auto it = context_->routedOutputs.find({ &outerOutput, ®ion });
1560 it != context_->routedOutputs.end())
1564 auto & loopVarPre = *it->second;
1565 if (thetaNode->MapPreLoopVar(loopVarPre).input->origin() == &outerOutput)
1573 auto loopVar = thetaNode->AddLoopVar(&outerOutput);
1574 context_->routedOutputs[{ &outerOutput, ®ion }] = loopVar.pre;
1575 return *loopVar.pre;
1578 JLM_UNREACHABLE(
"routeOutputToRegion reached unhandled structural node");
1581static std::unique_ptr<aa::AliasAnalysis>
1584 auto localAA = std::make_unique<aa::LocalAliasAnalysis>();
1589 localAA->setMaxTraceCollectionSize(1);
1597 auto ptgAA = std::make_unique<aa::PointsToGraphAliasAnalysis>(std::move(ptg));
1599 return std::make_unique<aa::ChainedAliasAnalysis>(std::move(localAA), std::move(ptgAA));
1603StoreValueForwarding::Run(
1608 auto statistics = Statistics::Create(module.
SourceFilePath().value());
1610 context_ = std::make_unique<Context>(*aliasAnalysis, *statistics);
1612 statistics->StartStatistics();
1614 auto & rvsdg =
module.Rvsdg();
1615 traverseInterProceduralRegion(rvsdg.GetRootRegion());
1617 statistics->StopStatistics(
1618 context_->numLoadsWithMemoryState,
1619 context_->numLoadsWithoutMemoryState,
1620 context_->numLoadsTracedToDeltaNode,
1621 context_->numForwardedLoadsWithMemoryState,
1622 context_->numForwardedLoadsWithoutMemoryState,
1623 context_->storeAAResponses,
1624 context_->loadAAResponses);
static jlm::util::StatisticsCollector statisticsCollector
std::vector< rvsdg::Node * > nodes
util::HashSet< rvsdg::Output * > arguments
static rvsdg::SimpleNode & createNode(rvsdg::Region ®ion, std::shared_ptr< const rvsdg::Type > type)
static rvsdg::Node & createNode(rvsdg::Region ®ion, fpsize size, const ::llvm::APFloat &constant)
static ::llvm::APFloat getZeroRepresentation(fpsize size)
ConstantPointerNullOperation class.
static rvsdg::Node & createNode(rvsdg::Region ®ion)
Get address of compiled function object.
static rvsdg::Node & Create(rvsdg::Region ®ion, IntegerValueRepresentation representation)
static size_t numMemoryStates(const rvsdg::SimpleNode &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)
std::optional< ValueOrigin > getLastValueOriginBeforeNode(rvsdg::Node &node, bool loopBackEdgeMaybeTaken)
ValueOrigin getLastValueOriginBeforeInput(rvsdg::Input &input, bool loopBackEdgeTaken)
std::unordered_map< std::pair< rvsdg::Region *, bool >, ValueOrigin, util::Hash< std::pair< rvsdg::Region *, bool > > > lastValueOriginInRegion
std::unordered_map< rvsdg::GammaNode *, rvsdg::Output * > createdExitVars
rvsdg::SimpleNode & loadNode
std::unordered_map< rvsdg::SimpleNode *, StoreNodeInfo > storeNodeInfo
LoadTracingInfo(rvsdg::SimpleNode &loadNode, OutputTracer &tracer, aa::AliasAnalysis &aliasAnalysis, rvsdg::RegionPredicateTrace ®ionPredicateTrace)
std::unordered_map< std::pair< rvsdg::Input *, bool >, ValueOrigin, util::Hash< std::pair< rvsdg::Input *, bool > > > lastValueOriginBeforeInput
AliasQueryResponseCounter loadAAResponses
std::unordered_map< rvsdg::SimpleNode *, LoadNodeInfo > loadNodeInfo
bool traceAllMemoryStateInputs()
ValueOrigin getLastValueOriginBeforeInputInternal(rvsdg::Input &input, bool loopBackEdgeTaken)
std::unordered_map< rvsdg::ThetaNode *, rvsdg::ThetaNode::LoopVar > createdLoopVars
std::optional< ValueOrigin > getLastValueOriginInRegion(rvsdg::Region ®ion, bool loopBackEdgeMaybeTaken)
std::queue< rvsdg::Input * > unroutedLoopVarPosts
aa::AliasAnalysis::AliasQueryResponse queryAliasAnalysisWithLoad(rvsdg::SimpleNode &otherLoadNode)
aa::AliasAnalysis & aliasAnalysis
std::shared_ptr< const rvsdg::Type > loadedType
rvsdg::Output * loadedAddress
rvsdg::RegionPredicateTrace & regionPredicateTrace
AliasQueryResponseCounter storeAAResponses
std::unordered_map< std::pair< rvsdg::Node *, bool >, ValueOrigin, util::Hash< std::pair< rvsdg::Node *, bool > > > lastValueOriginBeforeNode
aa::AliasAnalysis::AliasQueryResponse queryAliasAnalysisWithStore(rvsdg::SimpleNode &storeNode)
util::HashSet< rvsdg::Input * > loopVarPostsToTrace
void setTraceThroughLoadedStates(bool traceThroughLoadedStates)
static rvsdg::Input & StoredValueInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & MapMemoryStateOutputToInput(const rvsdg::Output &output)
static rvsdg::Input & AddressInput(const rvsdg::Node &node) noexcept
Store Value Forwarding Statistics class.
void stopTracing() noexcept
void StopStatistics(const size_t numLoadsWithMemoryState, const size_t numLoadsWithoutMemoryState, const size_t numLoadsTracedtoDeltaNode, const size_t numForwardedLoadsWithMemoryState, const size_t numForwardedLoadsWithoutMemoryState, const AliasQueryResponseCounter &storeAAResponses, const AliasQueryResponseCounter &loadAAResponses) noexcept
~Statistics() override=default
static constexpr auto ForwardingLabel_
static constexpr auto numMayAliasLoadLabel_
static constexpr auto numMustAliasLoadLabel_
static constexpr auto numNoAliasLoadLabel_
static constexpr auto NumLoadsWithMemoryStateLabel_
static constexpr auto numMayAliasStoreLabel_
static std::unique_ptr< Statistics > Create(const util::FilePath &sourceFile)
void StartStatistics() noexcept
static constexpr auto NumForwardedLoadsWithoutMemoryStateLabel_
Statistics(const util::FilePath &sourceFile)
static constexpr auto numNoAliasStoreLabel_
static constexpr auto numMustAliasStoreLabel_
void startForwarding() noexcept
static constexpr auto NumLoadsWithoutMemoryStateLabel_
static constexpr auto NumLoadsTracedToDeltaNodeLabel_
void stopForwarding() noexcept
static constexpr auto TracingLabel_
static constexpr auto NumForwardedLoadsWithMemoryStateLabel_
void startTracing() noexcept
Store Value Forwarding Optimization.
void processLoadWithoutMemoryStates(rvsdg::SimpleNode &loadNode)
void processLoad(rvsdg::SimpleNode &loadNode)
~StoreValueForwarding() noexcept override
std::unique_ptr< Context > context_
void forwardValueOrigins(LoadTracingInfo &tracingInfo)
void processLoadWithMemoryStates(rvsdg::SimpleNode &loadNode)
void forwardLoadWithoutMemoryStates(rvsdg::SimpleNode &loadNode, const TracedDelta &tracedDelta)
std::optional< TracedDelta > traceLoadWithoutMemoryStates(const rvsdg::SimpleNode &loadNode)
void traverseInterProceduralRegion(rvsdg::Region ®ion)
void traverseIntraProceduralRegion(rvsdg::Region ®ion)
virtual AliasQueryResponse Query(const rvsdg::Output &p1, size_t s1, const rvsdg::Output &p2, size_t s2)=0
std::unique_ptr< PointsToGraph > Analyze(const rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
rvsdg::Input & result() const noexcept
Conditional operator / pattern matching.
NodeOutput * output(size_t index) const noexcept
rvsdg::Region * region() const noexcept
void setTraceThroughStructuralNodes(bool value) noexcept
Output & trace(Output &output)
rvsdg::Region * region() const noexcept
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
Traces region reachability by predicate assertions.
bool CheckPredicatesSatisfiable(Region &originRegion, Region &targetRegion)
Checks for dynamic reachability between two regions.
Represents the result of a region.
Represent acyclic RVSDG subgraphs.
void prune(bool recursive)
size_t index() const noexcept
bool IsRootRegion() const noexcept
rvsdg::StructuralNode * node() const noexcept
static bool isAncestor(const rvsdg::Region ®ion, const rvsdg::Region &ancestor) noexcept
NodeRange Nodes() noexcept
const std::optional< util::FilePath > & SourceFilePath() const noexcept
const SimpleOperation & GetOperation() const noexcept override
NodeOutput * output(size_t index) const noexcept
SubregionIteratorRange Subregions()
void insert(const Output *original, Output *substitute)
Output & lookup(const Output &original) const
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)
Global memory state passed between functions.
static const bool USE_TRIVIAL_LOCALAA
size_t GetTypeAllocSize(const rvsdg::Type &type)
static rvsdg::Output & copyDeltaElement(const uint64_t elementOffsetInBytes, rvsdg::Output &output, rvsdg::Region &targetRegion, const std::shared_ptr< const rvsdg::Type > &loadedType)
rvsdg::Output & traceOutput(rvsdg::Output &output, const rvsdg::Region *withinRegion)
static const bool ENABLE_REGION_PREDICATE_CHECK
static const bool DISABLE_LOAD_LOAD_FORWARDING
static std::unique_ptr< aa::AliasAnalysis > createAliasAnalysis(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector)
static void copyRegionSlice(rvsdg::Region &targetRegion, const RegionSlice ®ionSlice, rvsdg::SubstitutionMap &substitutionMap)
TracedPointerOrigin TracePointerOriginPrecise(const rvsdg::Output &p)
static RegionSlice computeRegionSlice(rvsdg::Output &output)
static rvsdg::Output & copyDeltaRegionSlice(rvsdg::Output &output, rvsdg::Region &targetRegion)
size_t GetTypeStoreSize(const rvsdg::Type &type)
static const bool ENABLE_PTGAA
void MatchTypeWithDefault(T &obj, const Fns &... fns)
Pattern match over subclass type of given object with default handler.
void MatchTypeOrFail(T &obj, const Fns &... fns)
Pattern match over subclass type of given object.
Output & RouteToRegion(Output &output, Region ®ion)
Region * TryGetOwnerRegion(const rvsdg::Input &input) noexcept
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
size_t numNoAliasAnalysisQueries
void addResponse(aa::AliasAnalysis::AliasQueryResponse response)
void addFromCounter(const AliasQueryResponseCounter &other)
size_t numMayAliasAnalysisQueries
size_t numMustAliasAnalysisQueries
std::size_t operator()(const std::pair< rvsdg::Output *, rvsdg::Region * > &value) const
aa::AliasAnalysis & aliasAnalysis
size_t numForwardedLoadsWithoutMemoryState
size_t numLoadsTracedToDeltaNode
Context(aa::AliasAnalysis &aliasAnalysis, Statistics &statistics) noexcept
AliasQueryResponseCounter loadAAResponses
size_t numLoadsWithoutMemoryState
rvsdg::RegionPredicateTrace regionPredicateTrace
size_t numLoadsWithMemoryState
size_t numForwardedLoadsWithMemoryState
AliasQueryResponseCounter storeAAResponses
std::unordered_map< std::pair< rvsdg::Output *, rvsdg::Region * >, rvsdg::Output *, OutputRegionHash > routedOutputs
OutputTracer outputTracer
std::vector< GetElementPtrOperation::Constant > gepConstants
rvsdg::DeltaNode * deltaNode
static ValueOrigin createUninitialized()
static ValueOrigin createGammaNodeOutput(rvsdg::GammaNode &gammaNode)
static ValueOrigin createThetaNodeOutput(rvsdg::ThetaNode &thetaNode)
bool operator!=(const ValueOrigin &other) const noexcept
static ValueOrigin createLoadNode(rvsdg::SimpleNode &loadNode)
static ValueOrigin createStoreNode(rvsdg::SimpleNode &storeNode)
static ValueOrigin createUnknown()
bool operator==(const ValueOrigin &other) const noexcept
static ValueOrigin createThetaNodePre(rvsdg::ThetaNode &thetaNode)