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);
222 operator()(
const std::pair<rvsdg::Output *, rvsdg::Region *> & value)
const
224 return std::hash<rvsdg::Output *>()(value.first) ^ std::hash<rvsdg::Region *>()(value.second);
228 std::unordered_map<std::pair<rvsdg::Output *, rvsdg::Region *>,
rvsdg::Output *, OutputRegionHash>
250 for (
auto & node : region.
Nodes())
263 context_->outputTracer.clearInvarianceCache();
278 for (
auto node : traverser)
284 for (
auto & subregion : gammaNode.
Subregions())
295 if (is<LoadNonVolatileOperation>(&simpleNode))
357 return kind == other.kind &&
node == other.node;
363 return !(*
this == other);
456 if (!lastValueOrigin.isKnown())
467 if (!lastValueOrigin.isKnown())
485 std::optional<ValueOrigin>
488 if (loopBackEdgeMaybeTaken)
512 std::optional<ValueOrigin>
515 if (loopBackEdgeMaybeTaken)
549 const auto response =
564 JLM_ASSERT(is<LoadOperation>(&otherLoadNode));
571 const auto & tracedOtherLoadAddress =
llvm::traceOutput(otherLoadAddress,
false);
574 const auto response =
607 const auto [_, inserted] =
614 const auto [it, inserted] =
618 if (!inserted && it->second != result)
625 const auto region = regionResult->region();
626 const auto [it, inserted] =
630 if (!inserted && it->second != result)
646 if (
auto [storeNode, storeOp] =
648 storeNode && storeOp)
657 switch (aliasReponse)
700 if (
auto [otherLoadNode, otherLoadOp] =
702 otherLoadNode && otherLoadOp)
711 switch (aliasReponse)
750 if (
auto [joinNode, joinOp] =
754 if (joinNode->ninputs() == 0)
757 for (
auto & input : joinNode->Inputs())
760 if (!result.isKnown())
765 const auto sharedLastValueOrigin =
768 JLM_ASSERT(sharedLastValueOrigin->second.isKnown());
769 return sharedLastValueOrigin->second;
773 if (
auto [allocaNode, allocaOp] =
775 allocaNode && allocaOp)
783 const auto exitVar = gammaNode->MapOutputExitVar(tracedOutput);
787 std::optional<ValueOrigin> commonValueOrigin;
788 const auto addObservedValueOrigin = [&](
ValueOrigin origin)
794 if (!commonValueOrigin.has_value())
795 commonValueOrigin = origin;
796 else if (commonValueOrigin.value() != origin)
800 for (
auto branchResult : exitVar.branchResult)
804 if (!loopBackEdgeTaken)
809 auto & valueOriginRegion = *branchResult->region();
816 std::make_pair(&valueOriginRegion, loopBackEdgeTaken),
818 addObservedValueOrigin(valueOrigin);
827 if (!lastValueOrigin.isKnown())
831 addObservedValueOrigin(lastValueOrigin);
835 if (!commonValueOrigin.has_value())
839 if (commonValueOrigin->isKnown())
845 if (commonValueOrigin->node->region()->node() != gammaNode)
846 return *commonValueOrigin;
857 const auto loopVar = thetaNode->MapOutputLoopVar(tracedOutput);
862 if (!lastValueOrigin.isKnown())
868 && lastValueOrigin.node == thetaNode)
874 if (loopBackEdgeTaken)
879 if (!lastValueOrigin.isKnown())
883 && lastValueOrigin.node == thetaNode)
895 || lastValueOrigin.node->region() == thetaNode->subregion());
902 const auto loopVar = thetaNode->MapPreLoopVar(tracedOutput);
907 if (!inputLastValueOrigin.isKnown())
947 std::pair<rvsdg::Input *, bool>,
957 std::pair<rvsdg::Node *, bool>,
968 std::pair<rvsdg::Region *, bool>,
992 JLM_ASSERT(is<LoadNonVolatileOperation>(&loadNode));
996 context_->numLoadsWithoutMemoryState++;
1001 context_->numLoadsWithMemoryState++;
1009 JLM_ASSERT(is<LoadNonVolatileOperation>(&loadNode));
1012 context_->statistics.startTracing();
1019 context_->statistics.stopTracing();
1024 if (shouldForwardValueOrigins)
1026 context_->statistics.startForwarding();
1028 context_->statistics.stopForwarding();
1035 JLM_ASSERT(is<LoadNonVolatileOperation>(&loadNode));
1038 context_->statistics.startTracing();
1040 context_->statistics.stopTracing();
1041 if (!tracedDelta.has_value())
1046 context_->statistics.startForwarding();
1048 context_->statistics.stopForwarding();
1051std::optional<StoreValueForwarding::TracedDelta>
1054 JLM_ASSERT(is<LoadNonVolatileOperation>(&loadNode));
1059 if (!gepConstantsOpt.has_value())
1061 return std::nullopt;
1067 return std::nullopt;
1070 context_->numLoadsTracedToDeltaNode++;
1071 return std::optional<TracedDelta>({ deltaNode, gepConstantsOpt.value() });
1094 RegionSlice & regionSlice,
1099 regionSlice.arguments.insert(&output);
1104 if (visited.Contains(&node))
1107 regionSlice.nodes.push_back(&node);
1108 for (
auto & input : node.Inputs())
1110 compute(*input.origin(), regionSlice, visited);
1114 RegionSlice regionSlice;
1116 compute(output, regionSlice, visited);
1124 const RegionSlice & regionSlice,
1127 for (
auto it = regionSlice.nodes.rbegin(); it != regionSlice.nodes.rend(); ++it)
1130 node->copy(&targetRegion, substitutionMap);
1137 auto deltaNode = util::assertedCast<rvsdg::DeltaNode>(output.
region()->
node());
1142 for (
auto oldArgument : regionSlice.arguments.Items())
1144 auto ctxVar = deltaNode->MapBinderContextVar(*oldArgument);
1146 substitutionMap.
insert(oldArgument, &newArgument);
1150 return substitutionMap.
lookup(output);
1155 const uint64_t elementOffsetInBytes,
1158 const std::shared_ptr<const rvsdg::Type> & loadedType)
1163 node->GetOperation(),
1166 JLM_ASSERT(elementOffsetInBytes == 0);
1167 auto copiedOutput = ©DeltaRegionSlice(output, targetRegion);
1169 const auto loadBitType = util::assertedCast<const rvsdg::BitType>(loadedType.get());
1170 const auto copiedBitType =
1171 util::assertedCast<const rvsdg::BitType>(copiedOutput->Type().get());
1172 if (copiedBitType->nbits() == loadBitType->nbits())
1174 return *copiedOutput;
1177 if (loadBitType->nbits() < copiedBitType->nbits())
1179 return *TruncOperation::createNode(*copiedOutput, loadedType).output(0);
1183 return *copiedOutput;
1212 if (is<PointerType>(loadedType))
1217 if (
const auto bitType = std::dynamic_pointer_cast<const rvsdg::BitType>(loadedType))
1222 if (
const auto floatType = std::dynamic_pointer_cast<const FloatingPointType>(loadedType))
1228 if (
const auto vectorType = std::dynamic_pointer_cast<const FixedVectorType>(loadedType))
1233 throw std::logic_error(
"Unsupported load type");
1237 const auto arrayType = constantArrayOperation.type();
1238 const auto elementSizeInBytes =
GetTypeAllocSize(*arrayType->GetElementType());
1240 const auto index = elementOffsetInBytes / elementSizeInBytes;
1242 elementOffsetInBytes - (elementSizeInBytes * index),
1243 *node->input(index)->origin(),
1249 const auto arrayType = constantDataArrayOperation.type();
1250 const auto elementSizeInBytes =
GetTypeAllocSize(*arrayType->GetElementType());
1252 const auto index = elementOffsetInBytes / elementSizeInBytes;
1254 elementOffsetInBytes - (elementSizeInBytes * index),
1255 *node->input(index)->origin(),
1261 auto & structType = constantStruct.type();
1263 for (
size_t n = 0; n < structType.numElements(); ++n)
1265 auto fieldOffsetInBytes = structType.GetFieldOffset(n);
1267 if (fieldOffsetInBytes == elementOffsetInBytes)
1269 return copyDeltaElement(0, *node->input(n)->origin(), targetRegion, loadedType);
1272 if (fieldOffsetInBytes > elementOffsetInBytes)
1274 fieldOffsetInBytes = structType.GetFieldOffset(n - 1);
1276 elementOffsetInBytes - fieldOffsetInBytes,
1277 *node->input(n - 1)->origin(),
1283 const auto lastElementIndex = structType.numElements() - 1;
1284 const auto fieldOffsetInBytes = structType.GetFieldOffset(lastElementIndex);
1285 JLM_ASSERT(fieldOffsetInBytes <= elementOffsetInBytes);
1287 elementOffsetInBytes - fieldOffsetInBytes,
1288 *node->input(lastElementIndex)->origin(),
1294 throw std::logic_error(
"Unsupported operation: " + node->DebugString());
1304 throw std::logic_error(
"Unsupported output owner");
1308StoreValueForwarding::forwardLoadWithoutMemoryStates(
1312 JLM_ASSERT(is<LoadNonVolatileOperation>(&loadNode));
1313 JLM_ASSERT(LoadOperation::numMemoryStates(loadNode) == 0);
1314 const auto loadOperation =
1325 const uint64_t offsetInBytes =
1331 loadOperation->GetLoadedType());
1333 if (*loadOperation->GetLoadedType() != *newOutput.Type())
1339 LoadOperation::LoadedValueOutput(loadNode).divert_users(&newOutput);
1340 context_->numForwardedLoadsWithoutMemoryState++;
1347 context_->numForwardedLoadsWithMemoryState++;
1349 auto & loadNode = tracingInfo.
loadNode;
1350 auto & loadedValueOutput = LoadOperation::LoadedValueOutput(loadNode);
1351 auto & loadRegion = *loadNode.region();
1355 JLM_ASSERT(lastValueOrigin.has_value() && lastValueOrigin->isKnown());
1356 auto & valueOriginOutput = getValueOriginOutput(*lastValueOrigin, loadRegion, tracingInfo);
1359 connectUnroutedLoopPosts(tracingInfo);
1362 loadedValueOutput.divert_users(&valueOriginOutput);
1365 for (
auto & memoryStateOutput : LoadNonVolatileOperation::MemoryStateOutputs(loadNode))
1367 auto & memoryStateInput =
1368 LoadNonVolatileOperation::MapMemoryStateOutputToInput(memoryStateOutput);
1369 memoryStateOutput.divert_users(memoryStateInput.origin());
1375StoreValueForwarding::getValueOriginOutput(
1382 if (valueOrigin.
kind == ValueOrigin::Kind::Uninitialized)
1385 return *UndefValueOperation::Create(targetRegion, tracingInfo.
loadedType);
1388 if (valueOrigin.
kind == ValueOrigin::Kind::StoreNode)
1391 auto & storedValue = *StoreOperation::StoredValueInput(*valueOrigin.
node).origin();
1393 return routeOutputToRegion(storedValue, targetRegion);
1396 if (valueOrigin.
kind == ValueOrigin::Kind::LoadNode)
1399 auto & loadedValue = LoadOperation::LoadedValueOutput(*valueOrigin.
node);
1401 return routeOutputToRegion(loadedValue, targetRegion);
1405 if (valueOrigin.
kind == ValueOrigin::Kind::GammaNodeOutput)
1411 auto [it, inserted] = tracingInfo.
createdExitVars.emplace(gammaNode,
nullptr);
1414 std::vector<rvsdg::Output *> lastValueOriginPerSubregion;
1415 for (
auto & subregion : gammaNode->Subregions())
1424 JLM_ASSERT(lastValueOrigin.has_value() && lastValueOrigin->isKnown());
1425 auto & valueOriginOutput = getValueOriginOutput(*lastValueOrigin, subregion, tracingInfo);
1426 lastValueOriginPerSubregion.push_back(&valueOriginOutput);
1429 auto exitVar = gammaNode->AddExitVar(lastValueOriginPerSubregion);
1430 it->second = exitVar.output;
1434 return routeOutputToRegion(*it->second, targetRegion);
1438 if (valueOrigin.
kind == ValueOrigin::Kind::ThetaNodeOutput
1439 || valueOrigin.
kind == ValueOrigin::Kind::ThetaNodePre)
1457 if (lastValueOrigin.has_value())
1460 auto & outerRegion = *thetaNode->region();
1461 initialValue = &getValueOriginOutput(*lastValueOrigin, outerRegion, tracingInfo);
1467 initialValue = UndefValueOperation::Create(*thetaNode->region(), tracingInfo.
loadedType);
1473 auto loopVar = thetaNode->AddLoopVar(initialValue);
1474 auto [it, inserted] = tracingInfo.
createdLoopVars.emplace(thetaNode, loopVar);
1484 switch (valueOrigin.
kind)
1486 case ValueOrigin::Kind::ThetaNodePre:
1487 return routeOutputToRegion(*loopVarSlot->second.pre, targetRegion);
1488 case ValueOrigin::Kind::ThetaNodeOutput:
1489 return routeOutputToRegion(*loopVarSlot->second.output, targetRegion);
1514 JLM_ASSERT(lastValueOrigin.has_value() && lastValueOrigin->isKnown());
1515 auto & origin = getValueOriginOutput(*lastValueOrigin, *post->region(), tracingInfo);
1516 post->divert_to(&origin);
1523 if (output.
region() == ®ion)
1529 JLM_UNREACHABLE(
"root region reached during attempt at routing output into region");
1534 auto & outerOutput = routeOutputToRegion(output, *gammaNode->
region());
1537 if (
auto it = context_->routedOutputs.find({ &outerOutput, ®ion });
1538 it != context_->routedOutputs.end())
1542 auto & branchArgument = *it->second;
1543 if (gammaNode->mapBranchArgumentToInput(branchArgument).origin() == &outerOutput)
1546 return branchArgument;
1551 auto entryVar = gammaNode->AddEntryVar(&outerOutput);
1552 for (
auto branchArgument : entryVar.branchArgument)
1554 context_->routedOutputs[{ &outerOutput, branchArgument->region() }] = branchArgument;
1557 return *entryVar.branchArgument[region.
index()];
1563 auto & outerOutput = routeOutputToRegion(output, *thetaNode->
region());
1566 if (
auto it = context_->routedOutputs.find({ &outerOutput, ®ion });
1567 it != context_->routedOutputs.end())
1571 auto & loopVarPre = *it->second;
1572 if (thetaNode->MapPreLoopVar(loopVarPre).input->origin() == &outerOutput)
1580 auto loopVar = thetaNode->AddLoopVar(&outerOutput);
1581 context_->routedOutputs[{ &outerOutput, ®ion }] = loopVar.pre;
1582 return *loopVar.pre;
1585 JLM_UNREACHABLE(
"routeOutputToRegion reached unhandled structural node");
1588static std::unique_ptr<aa::AliasAnalysis>
1591 auto localAA = std::make_unique<aa::LocalAliasAnalysis>();
1596 localAA->setMaxTraceCollectionSize(1);
1604 auto ptgAA = std::make_unique<aa::PointsToGraphAliasAnalysis>(std::move(ptg));
1606 return std::make_unique<aa::ChainedAliasAnalysis>(std::move(localAA), std::move(ptgAA));
1610StoreValueForwarding::Run(
1615 auto statistics = Statistics::Create(module.
SourceFilePath().value());
1617 context_ = std::make_unique<Context>(*aliasAnalysis, *statistics);
1619 statistics->StartStatistics();
1621 auto & rvsdg =
module.Rvsdg();
1622 traverseInterProceduralRegion(rvsdg.GetRootRegion());
1624 statistics->StopStatistics(
1625 context_->numLoadsWithMemoryState,
1626 context_->numLoadsWithoutMemoryState,
1627 context_->numLoadsTracedToDeltaNode,
1628 context_->numForwardedLoadsWithMemoryState,
1629 context_->numForwardedLoadsWithoutMemoryState,
1630 context_->storeAAResponses,
1631 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
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)
rvsdg::AlternativeRegionPredicateTracer & regionPredicateTracer
std::queue< rvsdg::Input * > unroutedLoopVarPosts
aa::AliasAnalysis::AliasQueryResponse queryAliasAnalysisWithLoad(rvsdg::SimpleNode &otherLoadNode)
aa::AliasAnalysis & aliasAnalysis
LoadTracingInfo(rvsdg::SimpleNode &loadNode, OutputTracer &tracer, aa::AliasAnalysis &aliasAnalysis, rvsdg::AlternativeRegionPredicateTracer ®ionPredicateTracer)
std::shared_ptr< const rvsdg::Type > loadedType
rvsdg::Output * loadedAddress
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(const 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
class providing guarantees about unreachability of regions from other regions.
bool isReachableFromRegion(Region &targetRegion, Region &originRegion)
rvsdg::Input & result() const noexcept
Conditional operator / pattern matching.
NodeOutput * output(size_t index) const noexcept
rvsdg::Region * region() const noexcept
void setRegionPredicateCheckingEnabled(bool value) noexcept
void setInvarianceCaching(bool value) noexcept
Output & trace(Output &output)
void setStructuralNodePolicy(StructuralNodePolicy value) noexcept
@ traceThroughIfDetectedInvariant
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
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)
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)
rvsdg::Output & traceOutput(rvsdg::Output &output, bool mayEnterSubregions, const rvsdg::Region *withinRegion)
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
rvsdg::AlternativeRegionPredicateTracer regionPredicateTracer
Context(aa::AliasAnalysis &aliasAnalysis, Statistics &statistics) noexcept
AliasQueryResponseCounter loadAAResponses
size_t numLoadsWithoutMemoryState
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)