This source file includes following definitions.
- apply_split
 
- compute_loop_bounds_after_split
 
#include "ApplySplit.h"
#include "Simplify.h"
#include "Substitute.h"
namespace Halide{
namespace Internal {
using std::map;
using std::string;
using std::vector;
vector<ApplySplitResult> apply_split(const Split &split, bool is_update, string prefix,
                                     map<string, Expr> &dim_extent_alignment) {
    vector<ApplySplitResult> result;
    Expr outer = Variable::make(Int(32), prefix + split.outer);
    Expr outer_max = Variable::make(Int(32), prefix + split.outer + ".loop_max");
    if (split.is_split()) {
        Expr inner = Variable::make(Int(32), prefix + split.inner);
        Expr old_max = Variable::make(Int(32), prefix + split.old_var + ".loop_max");
        Expr old_min = Variable::make(Int(32), prefix + split.old_var + ".loop_min");
        Expr old_extent = Variable::make(Int(32), prefix + split.old_var + ".loop_extent");
        dim_extent_alignment[split.inner] = split.factor;
        Expr base = outer * split.factor + old_min;
        string base_name = prefix + split.inner + ".base";
        Expr base_var = Variable::make(Int(32), base_name);
        string old_var_name = prefix + split.old_var;
        Expr old_var = Variable::make(Int(32), old_var_name);
        map<string, Expr>::iterator iter = dim_extent_alignment.find(split.old_var);
        TailStrategy tail = split.tail;
        internal_assert(tail != TailStrategy::Auto)
            << "An explicit tail strategy should exist at this point\n";
        if ((iter != dim_extent_alignment.end()) &&
            is_zero(simplify(iter->second % split.factor))) {
            
            
            
            dim_extent_alignment[split.outer] = iter->second / split.factor;
        } else if (is_negative_const(split.factor) || is_zero(split.factor)) {
            user_error << "Can't split " << split.old_var << " by " << split.factor
                       << ". Split factors must be strictly positive\n";
        } else if (is_one(split.factor)) {
            
            
        } else if (tail == TailStrategy::GuardWithIf) {
            
            
            
            
            
            
            
            Expr rebased = outer * split.factor + inner;
            string rebased_var_name = prefix + split.old_var + ".rebased";
            Expr rebased_var = Variable::make(Int(32), rebased_var_name);
            result.push_back(ApplySplitResult(
                prefix + split.old_var, rebased_var + old_min, ApplySplitResult::Substitution));
            
            
            Expr cond = likely(rebased_var < old_extent);
            result.push_back(ApplySplitResult(cond));
            result.push_back(ApplySplitResult(rebased_var_name, rebased, ApplySplitResult::LetStmt));
        } else if (tail == TailStrategy::ShiftInwards) {
            
            
            
            
            
            base = likely_if_innermost(base);
            base = Min::make(base, old_max + (1 - split.factor));
        } else {
            internal_assert(tail == TailStrategy::RoundUp);
        }
        
        result.push_back(ApplySplitResult(old_var_name, base_var + inner, ApplySplitResult::Substitution));
        
        result.push_back(ApplySplitResult(old_var_name, base_var + inner, ApplySplitResult::LetStmt));
        result.push_back(ApplySplitResult(base_name, base, ApplySplitResult::LetStmt));
    } else if (split.is_fuse()) {
        
        Expr fused = Variable::make(Int(32), prefix + split.old_var);
        Expr inner_min = Variable::make(Int(32), prefix + split.inner + ".loop_min");
        Expr outer_min = Variable::make(Int(32), prefix + split.outer + ".loop_min");
        Expr inner_extent = Variable::make(Int(32), prefix + split.inner + ".loop_extent");
        
        
        
        
        
        Expr factor = max(inner_extent, 1);
        Expr inner = fused % factor + inner_min;
        Expr outer = fused / factor + outer_min;
        result.push_back(ApplySplitResult(prefix + split.inner, inner, ApplySplitResult::Substitution));
        result.push_back(ApplySplitResult(prefix + split.outer, outer, ApplySplitResult::Substitution));
        result.push_back(ApplySplitResult(prefix + split.inner, inner, ApplySplitResult::LetStmt));
        result.push_back(ApplySplitResult(prefix + split.outer, outer, ApplySplitResult::LetStmt));
        
        
        map<string, Expr>::iterator inner_dim = dim_extent_alignment.find(split.inner);
        map<string, Expr>::iterator outer_dim = dim_extent_alignment.find(split.outer);
        if (inner_dim != dim_extent_alignment.end() &&
            outer_dim != dim_extent_alignment.end()) {
            dim_extent_alignment[split.old_var] = inner_dim->second*outer_dim->second;
        }
    } else {
        
        result.push_back(ApplySplitResult(prefix + split.old_var, outer, ApplySplitResult::Substitution));
        result.push_back(ApplySplitResult(prefix + split.old_var, outer, ApplySplitResult::LetStmt));
    }
    return result;
}
vector<std::pair<string, Expr>> compute_loop_bounds_after_split(const Split &split, string prefix) {
    
    
    
    vector<std::pair<string, Expr>> let_stmts;
    Expr old_var_extent = Variable::make(Int(32), prefix + split.old_var + ".loop_extent");
    Expr old_var_max = Variable::make(Int(32), prefix + split.old_var + ".loop_max");
    Expr old_var_min = Variable::make(Int(32), prefix + split.old_var + ".loop_min");
    if (split.is_split()) {
        Expr inner_extent = split.factor;
        Expr outer_extent = (old_var_max - old_var_min + split.factor)/split.factor;
        let_stmts.push_back({ prefix + split.inner + ".loop_min", 0 });
        let_stmts.push_back({ prefix + split.inner + ".loop_max", inner_extent-1 });
        let_stmts.push_back({ prefix + split.inner + ".loop_extent", inner_extent });
        let_stmts.push_back({ prefix + split.outer + ".loop_min", 0 });
        let_stmts.push_back({ prefix + split.outer + ".loop_max", outer_extent-1 });
        let_stmts.push_back({ prefix + split.outer + ".loop_extent", outer_extent });
    } else if (split.is_fuse()) {
        
        Expr inner_extent = Variable::make(Int(32), prefix + split.inner + ".loop_extent");
        Expr outer_extent = Variable::make(Int(32), prefix + split.outer + ".loop_extent");
        Expr fused_extent = inner_extent * outer_extent;
        let_stmts.push_back({ prefix + split.old_var + ".loop_min", 0 });
        let_stmts.push_back({ prefix + split.old_var + ".loop_max", fused_extent - 1 });
        let_stmts.push_back({ prefix + split.old_var + ".loop_extent", fused_extent });
    } else if (split.is_rename()) {
        let_stmts.push_back({ prefix + split.outer + ".loop_min", old_var_min });
        let_stmts.push_back({ prefix + split.outer + ".loop_max", old_var_max });
        let_stmts.push_back({ prefix + split.outer + ".loop_extent", old_var_extent });
    }
    
    return let_stmts;
}
}
}