Jlm
Loading...
Searching...
No Matches
RegionPredicateTrace.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2026 Helge Bahmann <hcb@chaoticmind.net>
3 * See COPYING for terms of redistribution.
4 */
5
6#ifndef JLM_RVSDG_REGIONPREDICATETRACE_HPP
7#define JLM_RVSDG_REGIONPREDICATETRACE_HPP
8
10#include <jlm/rvsdg/graph.hpp>
11#include <jlm/rvsdg/node.hpp>
12#include <jlm/util/HashSet.hpp>
13
14#include <unordered_map>
15
16namespace jlm::rvsdg
17{
18
25{
26public:
30 static inline PredicateValueRange
32 {
33 return PredicateValueRange(type.nalternatives(), false);
34 }
35
39 static inline PredicateValueRange
41 {
42 return PredicateValueRange(type.nalternatives(), true);
43 }
44
48 static inline PredicateValueRange
50 {
51 auto pred = PredicateValueRange(value.nalternatives(), false);
52 pred.values_[value.alternative()] = true;
53 return pred;
54 }
55
59 void
61 {
62 auto size = std::min(values_.size(), other.values_.size());
63 for (std::size_t n = 0; n < size; ++n)
64 {
65 values_[n] = values_[n] || other.values_[n];
66 }
67 }
68
72 bool
73 AllowsValue(std::size_t alternative) const noexcept
74 {
75 return values_.size() > alternative && values_[alternative];
76 }
77
78private:
79 inline PredicateValueRange(std::size_t nalternatives, bool init_value)
80 : values_(nalternatives, init_value)
81 {}
82
83 std::vector<bool> values_;
84};
85
95using PredicateSatRequired = std::vector<std::pair<Input *, std::size_t>>;
96
106{
107public:
109
111
139
158
189 bool
191
192private:
193 // For a given input, its RegionPredRange provides a map from regions to the
194 // set of values than can end up being routed to the input, from results of the region.
195 using RegionPredRange = std::unordered_map<Region *, PredicateValueRange>;
196 class Observer;
197
198 void
199 Clear();
200
201 void
202 ObserveRegion(Region & region);
203
211 const PredicateValueRange &
214 Input & input,
215 std::unordered_map<Input *, PredicateValueRange> & visitedInputs,
216 const ControlType & type);
217
222 Compute(
224 Input & input,
225 std::unordered_map<Input *, PredicateValueRange> & visitedInputs,
226 const ControlType & type);
227
228 // For a given input, gives the regions where we know which the set of values
229 // the region may provide to the input
230 std::unordered_map<Input *, RegionPredRange> predAssignment_;
231
232 // For a given target region, what predicates must be satisfied to reach it
233 std::unordered_map<Region *, PredicateSatRequired> predSat_;
234
235 // Observers registered on region to inform the tracer when caches must be invalidated
236 std::unordered_map<Region *, std::unique_ptr<Observer>> observers_;
237};
238
247{
248public:
250
258 [[nodiscard]] bool
260
268 void
269 clearCaches();
270
271private:
278 getPossibleValues(Output & output);
279
282
293 bool
295 Output & output,
296 size_t value,
297 std::vector<Region *> & impossibleOrigins);
298
299 bool
301 Output & output,
302 size_t value,
303 std::vector<Region *> & impossibleOrigins);
304
315 [[nodiscard]] bool
316 canCurrentOriginSatisfyRequirement(Output & output, size_t value);
317
318 // The possible values an output of control type may have.
319 std::unordered_map<Output *, PredicateValueRange> predicateValueRanges_;
320
321 // Map from (output, required value) to a list of origin regions that cannot provide the value,
322 // without control flow taking any back-edges around the origin region.
323 std::unordered_map<
324 std::pair<Output *, size_t>,
325 std::vector<Region *>,
328
329 // The ancestors of the current origin region.
330 // Not a cache, updates for every call to \ref isReachableFromRegion.
332};
333
334}
335
336#endif // JLM_RVSDG_REGIONTRACE_HPP
class providing guarantees about unreachability of regions from other regions.
bool markRequiredPredicateValueInternal(Output &output, size_t value, std::vector< Region * > &impossibleOrigins)
bool markRequiredPredicateValue(Output &output, size_t value, std::vector< Region * > &impossibleOrigins)
std::unordered_map< std::pair< Output *, size_t >, std::vector< Region * >, util::Hash< std::pair< Output *, size_t > > > impossibleOriginRegions_
std::unordered_map< Output *, PredicateValueRange > predicateValueRanges_
PredicateValueRange getPossibleValuesInternal(Output &output)
bool canCurrentOriginSatisfyRequirement(Output &output, size_t value)
bool isReachableFromRegion(Region &targetRegion, Region &originRegion)
PredicateValueRange & getPossibleValues(Output &output)
size_t nalternatives() const noexcept
Definition control.hpp:42
size_t nalternatives() const noexcept
Definition control.hpp:89
size_t alternative() const noexcept
Definition control.hpp:83
Value range for a predicate.
bool AllowsValue(std::size_t alternative) const noexcept
Checks whether value range allows a specific value.
static PredicateValueRange CreateEmpty(const ControlType &type)
Constructs empty value range (unsatisfiable predicate range).
void UpdateUnion(const PredicateValueRange &other)
Takes union of two value ranges.
PredicateValueRange(std::size_t nalternatives, bool init_value)
static PredicateValueRange CreateSingleValue(const ControlValueRepresentation &value)
Definite value range (exactly one value possible).
static PredicateValueRange CreateUnknown(const ControlType &type)
Constructs full value range (every value possible).
Traces region reachability by predicate assertions.
PredicateValueRange GetRegionPredicateAssignConstraints(Region &region, Input &predUse)
Computes value range for a predicate when exiting a region.
PredicateSatRequired GetRegionSatRequired(Region &region)
Computes required predicate assignments for region.
std::unordered_map< Region *, PredicateSatRequired > predSat_
bool CheckPredicatesSatisfiable(Region &originRegion, Region &targetRegion)
Checks for dynamic reachability between two regions.
PredicateValueRange Compute(RegionPredRange &regionPredRange, Input &input, std::unordered_map< Input *, PredicateValueRange > &visitedInputs, const ControlType &type)
const PredicateValueRange & ComputeAndRecord(RegionPredRange &regionPredRange, Input &input, std::unordered_map< Input *, PredicateValueRange > &visitedInputs, const ControlType &type)
std::unordered_map< Region *, PredicateValueRange > RegionPredRange
std::unordered_map< Input *, RegionPredRange > predAssignment_
std::unordered_map< Region *, std::unique_ptr< Observer > > observers_
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872
std::vector< std::pair< Input *, std::size_t > > PredicateSatRequired
Describes which predicates need to be satisfied.