docc 0.8.3 (0d44999b)
C++ API Reference
Loading...
Searching...
No Matches
sdfg::passes::loop_fusion::LoopFusionPass Class Reference

A pass that performs loop fusion on a StructuredSDFG. More...

#include <sdfg/passes/loop_fusion/loop_fusion_pass.h>

Inheritance diagram for sdfg::passes::loop_fusion::LoopFusionPass:
[legend]

Classes

struct  State

Public Member Functions

 LoopFusionPass (const LoopFusionConfig &config)
 LoopFusionPass ()
std::string name () override
bool run_pass (builder::StructuredSDFGBuilder &builder, analysis::AnalysisManager &analysis_manager) override
Public Member Functions inherited from sdfg::passes::Pass
 Pass ()=default
 Pass (const Options &options)
virtual ~Pass ()=default
virtual std::vector< OptionSpec > options ()
bool run (builder::SDFGBuilder &builder, bool create_report=false)
bool run (builder::StructuredSDFGBuilder &builder, analysis::AnalysisManager &analysis_manager, bool create_report=false)
virtual bool run_pass (builder::SDFGBuilder &builder)
virtual void invalidates (analysis::AnalysisManager &analysis_manager, bool applied)

Protected Member Functions

const symbolic::Assumption * find_indvar_boundaries (const symbolic::Symbol &indvar, const symbolic::Assumptions &assumptions)
Protected Member Functions inherited from sdfg::passes::Pass
template<class T>
T option (const OptionKey< T > &key, T fallback=T{}) const

Friends

class LoopFusionHandler

Detailed Description

A pass that performs loop fusion on a StructuredSDFG.

Though mostly between Maps at this point.

Current impl. walks the SDFG in execution order with a sliding window (of 3). It can only fuse loops in the same sequence and at most with 1 independent block in between them and it does not retry past fused loops other then using the result of the last fusion as start of the next (which works for simple chains that always fuse forward)

The pass builds a FusionLoopCandidate cache at the start and then maintains all the data (assumptions, indvars, arguments) across modifications

The core function is in LoopFusionHandler::match, which gets called for candidate pairs. It then tries

  • fusion by-domain
    • can fuse intermediate levels of loops (that contain further, arbitrary loops)
    • checks iteration domain for exact equality for all levels that will be fused across (only supported for "map-stacks", which are perfectly nested & parallel)
    • checks for overlapping indirect memory usages (can fuse if there is no overlap at all, just no conflicts)
    • checks the subsets on all overlapping usages to match exactly
    • further nested loops indvars are represented by their iteration bounds, stepsize and nesting level for those exact matches
  • fusion by-access via MapFusionByAccessWorker
    • if the domain or subset checks fail, we proceed to the more complex case, that collects every access and solves for all reads being covered by matching writes.
    • this can fuse only innermost loops with restrictive content, but can handle changes in iteration domain
    • when the domains are not equal, it needs to copy one loop and replaces reads with the direct results of the productions, elliding the indirect memory accesses
    • when the domains are equal, it keeps indirect accesses in same as by-domain (so the fused loop is a full replacement for both source loops), leaving the RedundantLoadElimination and cleanup of superfluous accesses for other passes
    • by-access is currently restricted to fusing single-block producers into a larger consumer and specific reduction patterns

Either way needs to rely only on the data cached in the FusionLoopCandidate and LoopAnalysis as only those are kept up-to-date. After every change, LoopAnalysis and cached data update... functions need to be called to maintain the cached data.

Eventually, this should become a Dataflow-based pass, that will fixpoint iterate, can fuse loops that are further apart and can prioritize the order of fusions other then greedy, forward-only. It was designed such that the match() can still be called in that case

Constructor & Destructor Documentation

◆ LoopFusionPass() [1/2]

sdfg::passes::loop_fusion::LoopFusionPass::LoopFusionPass ( const LoopFusionConfig & config)

◆ LoopFusionPass() [2/2]

sdfg::passes::loop_fusion::LoopFusionPass::LoopFusionPass ( )

Member Function Documentation

◆ find_indvar_boundaries()

const symbolic::Assumption * sdfg::passes::loop_fusion::LoopFusionPass::find_indvar_boundaries ( const symbolic::Symbol & indvar,
const symbolic::Assumptions & assumptions )
protected

◆ name()

std::string sdfg::passes::loop_fusion::LoopFusionPass::name ( )
inlineoverridevirtual

Implements sdfg::passes::Pass.

◆ run_pass()

bool sdfg::passes::loop_fusion::LoopFusionPass::run_pass ( builder::StructuredSDFGBuilder & builder,
analysis::AnalysisManager & analysis_manager )
overridevirtual

Reimplemented from sdfg::passes::Pass.

◆ LoopFusionHandler

friend class LoopFusionHandler
friend

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