MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
mim::Analysis Class Reference

Traverses the current World using Rewriter infrastructure while staying in the same world. More...

#include <mim/phase.h>

Inheritance diagram for mim::Analysis:
[legend]

Public Member Functions

Construction & Destruction
 Analysis (World &world, std::string name)
 Analysis (World &world, flags_t annex)
virtual void reset ()
 Clears the rewriter map and resets Phase::todo() for the next fixed-point iteration.
Getters
bool is_bootstrapping () const
 < Disambiguates the Phase/Rewriter double base; for an Analysis both denote the same World.
Worldworld ()
Sparse Fixed-Point Iteration
bool is_sparse () const
 Does the current round only re-drain last round's dirty mutables?
void make_dense ()
 Forces whole-World rounds unconditionally.
size_t version () const
 Bumped on every observable lattice change; snapshot it around a code region to detect changes.
Public Member Functions inherited from mim::Phase
 Phase (World &world, std::string name)
 Phase (World &world, flags_t annex)
virtual ~Phase ()=default
virtual std::unique_ptr< Phaserecreate ()
 Creates a new instance; needed by a fixed-point PhaseMan.
virtual void apply (const App *)
 Invoked if your Phase has additional args.
virtual void apply (Phase &)
 Dito, but invoked by Phase::recreate.
virtual bool redirects () const
 If true, Phase::create uses take_resolved().
virtual std::unique_ptr< Phasetake_resolved ()
 The Phase to use instead; nullptr means elide.
Worldworld ()
Driverdriver ()
Loglog () const
std::string_view name () const
flags_t annex () const
const Vector< std::string > & args ()
 Command-line arguments passed to this Phase's plugin via -X <plugin>:<arg>.
bool todo () const
void invalidate (bool todo=true)
 Signals that another round of fixed-point iteration is required, either as part of.
virtual void run ()
 Entry point and generates some debug output; invokes Phase::start.
void profile_count (std::string_view key, uint64_t n=1)
 Adds n to the custom Profiler counter key of the current run; no-op unless profiling is enabled.
Public Member Functions inherited from mim::Rewriter
template<class D = Def>
D * curr_mut () const
 Rewriter (std::unique_ptr< World > &&ptr)
 Rewriter (World &world)
virtual ~Rewriter ()
void reset (std::unique_ptr< World > &&ptr)
void reset ()
Worldworld ()
virtual void push ()
virtual void pop ()
virtual const Defmap (const Def *old_def, const Def *new_def)
const Defmap (const Def *old_def, Defs new_defs)
const Defmap (Defs old_defs, const Def *new_def)
const Defmap (Defs old_defs, Defs new_defs)
virtual const Deflookup (const Def *old_def)
 Lookup old_def by searching in reverse through the stack of maps.
virtual const Defrewrite (const Def *)
virtual const Defrewrite_imm (const Def *)
virtual const Defrewrite_stub (Def *, Def *)
virtual DefVec rewrite (Defs)
virtual const Defrewrite_imm_Seq (const Seq *seq)
virtual const Defrewrite_mut_Seq (Seq *seq)

Protected Member Functions

Rewrite
virtual void prepare ()
 Run before the main analysis.
virtual void finalize ()
 Run after the main analysis - only in full rounds, so it always sees the complete abstract World.
void start () override
 Actual entry.
virtual void rewrite_annex (flags_t, Sym, const Def *)
virtual void rewrite_external (Def *)
const Defrewrite_imm_Proxy (const Proxy *proxy) override
 By default: ignore Proxys.
Defrewrite_mut (Def *) override
 Schedules mut for a breadth-first visit of its dependencies and records mut -> mut.
Protected Member Functions inherited from mim::Rewriter
auto enter (Def *new_mut)
 Updates curr_mut() to new_mut and restores it at the end of the scope.

lattice

const auto & lattice () const
 The whole map; used e.g. to diff two fixed-point runs.
const Deflattice (const Def *def) const
bool is_top (const Def *def) const
bool lattice_force (const Def *concr, const Def *abstr)
 Non-monotone write of concr ↦ abstr into lattice() and map().
bool lattice (const Def *concr, const Def *abstr)
 Writes concr ↦ abstr into lattice() and map().
bool pin (const Def *def)
 Monotonically forces def to ⊤ (keep as is).
void taint (Def *mut)
 Additionally schedules mut for the next sparse round.

Additional Inherited Members

Static Public Member Functions inherited from mim::Phase
static std::unique_ptr< Phasecreate (const Flags2Phases &phases, const Def *def)
template<class A, class P>
static void hook (Flags2Phases &phases)
template<class P, class... Args>
static void run (Args &&... args)
 Runs a single Phase.
Protected Attributes inherited from mim::Phase
std::string name_
Protected Attributes inherited from mim::Rewriter
std::deque< Def2Defold2news_

Detailed Description

Traverses the current World using Rewriter infrastructure while staying in the same world.

It recursively rewrites

  1. all World::annexes() (during which Analysis::is_bootstrapping() is true), and then
  2. all World::externals() (during which it is false).

Analysis provides a reusable lattice() mapping old Defs to abstract values, represented as ordinary MimIR Defs.

Fixed-point iteration is sparse by default: whenever a lattice write changes observable information, the mutable currently being drained is recorded as dirty. The next round then re-drains only those dirty mutables - plus everything reachable from them - instead of walking the whole World. At the start of such a round, the accumulated lattice() is replayed into the rewriter map, so a dirty mutable's body sees the substitutions its (non-revisited) producers installed in earlier rounds. Since dirt tracks writers - not readers - a sparse round may miss affected mutables; hence, once sparse rounds quiesce, one final full round certifies the fixed point.

Note
You can override
See also
Analysis
SSA without Dominance for how an Analysis substitutes Def::nests for the classical SSA dominance check.

Definition at line 149 of file phase.h.

Constructor & Destructor Documentation

◆ Analysis() [1/2]

mim::Analysis::Analysis ( World & world,
std::string name )
inline

◆ Analysis() [2/2]

mim::Analysis::Analysis ( World & world,
flags_t annex )
inline

Definition at line 156 of file phase.h.

References mim::Phase::annex(), mim::Phase::Phase(), mim::Rewriter::Rewriter(), and world().

Member Function Documentation

◆ finalize()

virtual void mim::Analysis::finalize ( )
inlineprotectedvirtual

Run after the main analysis - only in full rounds, so it always sees the complete abstract World.

Definition at line 256 of file phase.h.

Referenced by start().

◆ is_bootstrapping()

bool mim::Analysis::is_bootstrapping ( ) const
inline

< Disambiguates the Phase/Rewriter double base; for an Analysis both denote the same World.

Definition at line 171 of file phase.h.

◆ is_sparse()

bool mim::Analysis::is_sparse ( ) const
inline

Does the current round only re-drain last round's dirty mutables?

Definition at line 176 of file phase.h.

◆ is_top()

bool mim::Analysis::is_top ( const Def * def) const
inline
Returns
whether def is pinned to ⊤ (def ↦ def).

Definition at line 197 of file phase.h.

◆ lattice() [1/3]

const auto & mim::Analysis::lattice ( ) const
inline

The whole map; used e.g. to diff two fixed-point runs.

Definition at line 188 of file phase.h.

Referenced by pin().

◆ lattice() [2/3]

bool mim::Analysis::lattice ( const Def * concr,
const Def * abstr )
inlineprotected

Writes concr ↦ abstr into lattice() and map().

invalidate()s - and thereby triggers another fixed-point round - iff this changes observable information: an existing entry was overwritten, or a fresh fact other than ⊤ was inserted. Freshly inserting ⊤ (concr ↦ concr) stays silent, as it is indistinguishable from absent for consumers. Every change also touch()es curr_mut() - the seed set of the next sparse round.

Returns
true iff this changed observable information - i.e. iff it invalidate()d.

Definition at line 229 of file phase.h.

References mim::Rewriter::map().

◆ lattice() [3/3]

const Def * mim::Analysis::lattice ( const Def * def) const
inline
Returns
the abstract value recorded for def, or nullptr if unknown.

Definition at line 191 of file phase.h.

◆ lattice_force()

bool mim::Analysis::lattice_force ( const Def * concr,
const Def * abstr )
inlineprotected

Non-monotone write of concr ↦ abstr into lattice() and map().

This is the escape hatch for analyses that must overwrite an earlier round's value (descending from ⊤ is fine). invalidate()s iff the stored value changed; an absent entry counts as changed - even for ⊤ - since a non-monotone lattice's consumers may well distinguish ⊥ from ⊤. Every change also touch()es curr_mut() - the seed set of the next sparse round.

Returns
true iff this changed the entry - i.e. iff it invalidate()d.

Definition at line 213 of file phase.h.

References mim::Rewriter::map().

◆ make_dense()

void mim::Analysis::make_dense ( )
inline

Forces whole-World rounds unconditionally.

Definition at line 179 of file phase.h.

◆ pin()

bool mim::Analysis::pin ( const Def * def)
inlineprotected

Monotonically forces def to ⊤ (keep as is).

Returns
true iff this changed observable information - i.e. iff it invalidate()d.

Definition at line 244 of file phase.h.

References lattice().

◆ prepare()

virtual void mim::Analysis::prepare ( )
inlineprotectedvirtual

Run before the main analysis.

Definition at line 254 of file phase.h.

Referenced by start().

◆ reset()

void mim::Analysis::reset ( )
virtual

Clears the rewriter map and resets Phase::todo() for the next fixed-point iteration.

lattice() is preserved across iterations so that abstract values accumulated in earlier rounds remain available - this is what makes fixed-point convergence possible. The dirty set survives as well; start() consumes it to decide whether the round can be sparse.

See also
RWPhase::analyze

Definition at line 51 of file phase.cpp.

References mim::Rewriter::old2news_, and mim::Rewriter::push().

◆ rewrite_annex()

void mim::Analysis::rewrite_annex ( flags_t ,
Sym ,
const Def * def )
protectedvirtual

Definition at line 101 of file phase.cpp.

References mim::Rewriter::rewrite().

Referenced by start().

◆ rewrite_external()

void mim::Analysis::rewrite_external ( Def * mut)
protectedvirtual

Reimplemented in mim::plug::gpu::phase::MemChecks.

Definition at line 102 of file phase.cpp.

References mim::Rewriter::rewrite().

Referenced by mim::plug::gpu::phase::MemChecks::rewrite_external(), and start().

◆ rewrite_imm_Proxy()

const Def * mim::Analysis::rewrite_imm_Proxy ( const Proxy * proxy)
inlineoverrideprotected

By default: ignore Proxys.

Definition at line 260 of file phase.h.

◆ rewrite_mut()

Def * mim::Analysis::rewrite_mut ( Def * mut)
overrideprotectedvirtual

Schedules mut for a breadth-first visit of its dependencies and records mut -> mut.

Mutables are enqueued instead of recursed into; Analysis::drain then walks them in BFS order. The mut -> mut entry doubles as the per-round "already scheduled" marker (Rewriter::old2news_ is cleared by reset()), so each mutable's deps are visited at most once per fixed-point round.

Reimplemented from mim::Rewriter.

Definition at line 104 of file phase.cpp.

References mim::Rewriter::lookup(), and mim::Rewriter::map().

◆ start()

void mim::Analysis::start ( )
overrideprotectedvirtual

◆ taint()

void mim::Analysis::taint ( Def * mut)
inlineprotected

Additionally schedules mut for the next sparse round.

Use this when a lattice change must re-visit other mutables than curr_mut() - e.g. all call sites of a Lam whose var's abstract value changed.

Definition at line 249 of file phase.h.

◆ version()

size_t mim::Analysis::version ( ) const
inline

Bumped on every observable lattice change; snapshot it around a code region to detect changes.

Definition at line 181 of file phase.h.

◆ world()

World & mim::Phase::world ( )
inline

Definition at line 77 of file phase.h.

Referenced by Analysis(), Analysis(), mim::plug::gpu::phase::MemChecks::MemChecks(), and start().


The documentation for this class was generated from the following files: