diff options
Diffstat (limited to 'chill/include')
-rw-r--r-- | chill/include/chill_error.hh | 6 | ||||
-rw-r--r-- | chill/include/chilldebug.h | 6 | ||||
-rw-r--r-- | chill/include/chillmodule.hh | 15 | ||||
-rw-r--r-- | chill/include/dep.hh | 12 | ||||
-rw-r--r-- | chill/include/graph.hh | 7 | ||||
-rw-r--r-- | chill/include/ir_code.hh | 72 | ||||
-rw-r--r-- | chill/include/ir_rose.hh | 27 | ||||
-rw-r--r-- | chill/include/ir_rose_utils.hh | 6 | ||||
-rw-r--r-- | chill/include/irtools.hh | 13 | ||||
-rw-r--r-- | chill/include/loop.hh | 65 | ||||
-rw-r--r-- | chill/include/omegatools.hh | 103 |
11 files changed, 158 insertions, 174 deletions
diff --git a/chill/include/chill_error.hh b/chill/include/chill_error.hh index dc7432f..ca0936e 100644 --- a/chill/include/chill_error.hh +++ b/chill/include/chill_error.hh @@ -1,17 +1,17 @@ #ifndef CHILL_ERROR_HH #define CHILL_ERROR_HH -// for loop transformation problem +//! for loop transformation problem struct loop_error: public std::runtime_error { loop_error(const std::string &msg): std::runtime_error(msg){} }; -// for generic compiler intermediate code handling problem +//! for generic compiler intermediate code handling problem struct ir_error: public std::runtime_error { ir_error(const std::string &msg): std::runtime_error(msg){} }; -// specific for expression to preburger math translation problem +//! for specific for expression to preburger math translation problem struct ir_exp_error: public ir_error { ir_exp_error(const std::string &msg): ir_error(msg){} }; diff --git a/chill/include/chilldebug.h b/chill/include/chilldebug.h index 4abbb82..865f1f6 100644 --- a/chill/include/chilldebug.h +++ b/chill/include/chilldebug.h @@ -3,9 +3,13 @@ // enable the next line to get lots of output //#define DEBUGCHILL +#ifndef DEBUGCHILL_H +#define DEBUGCHILL_H #ifdef DEBUGCHILL #define DEBUG_PRINT(args...) fprintf(stderr, args ) #else -#define DEBUG_PRINT(args...) /* Don't do anything */ +#define DEBUG_PRINT(args...) do {} while(0) /* Don't do anything */ +#endif + #endif diff --git a/chill/include/chillmodule.hh b/chill/include/chillmodule.hh index 2cb6587..a99db0c 100644 --- a/chill/include/chillmodule.hh +++ b/chill/include/chillmodule.hh @@ -1,19 +1,12 @@ -#ifndef BASIC_CHILLMODULE_HH -#define BASIC_CHILLMODULE_HH -// TODO Python.h defines these and something else does too -#undef _POSIX_C_SOURCE -#undef _XOPEN_SOURCE +#ifndef CHILLMODULE_HH +#define CHILLMODULE_HH #include <Python.h> -// a C routine that will be called from python -//static PyObject * chill_print_code(PyObject *self, PyObject *args); - -//static PyMethodDef ChillMethods[] ; - void finalize_loop(int loop_num_start, int loop_num_end); int get_loop_num_start(); int get_loop_num_end(); -PyMODINIT_FUNC initchill() ; // pass C methods to python +//! pass C methods to python +PyMODINIT_FUNC initchill(); #endif diff --git a/chill/include/dep.hh b/chill/include/dep.hh index 1fa1280..f1cc864 100644 --- a/chill/include/dep.hh +++ b/chill/include/dep.hh @@ -14,9 +14,9 @@ typedef std::vector<DependenceVector> DependenceList; struct DependenceVector { DependenceType type; IR_Symbol *sym; - - bool is_reduction; // used to identify a class of flow dependence - // that can be broken + + bool is_reduction; //!< used to identify a class of flow dependence + //!< that can be broken std::vector<omega::coef_t> lbounds; std::vector<omega::coef_t> ubounds; @@ -29,7 +29,6 @@ struct DependenceVector { quasi = false; is_scalar_dependence = false; } - // DependenceVector(int size); DependenceVector(const DependenceVector &that); ~DependenceVector() {delete sym;} DependenceVector &operator=(const DependenceVector &that); @@ -40,7 +39,7 @@ struct DependenceVector { bool has_been_carried_at(int dim) const; bool has_been_carried_before(int dim) const; - // the following functions will be cleaned up or removed later + // TODO the following functions will be cleaned up or removed later bool isZero() const; bool isPositive() const; bool isNegative() const; @@ -55,7 +54,6 @@ struct DependenceVector { std::vector<DependenceVector> normalize() const; std::vector<DependenceVector> permute(const std::vector<int> &pi) const; DependenceVector reverse() const; - // std::vector<DependenceVector> matrix(const std::vector<std::vector<int> > &M) const; DependenceType getType() const; friend std::ostream& operator<<(std::ostream &os, const DependenceVector &d); }; @@ -72,10 +70,8 @@ public: DependenceGraph() { num_dim_ = 0; } ~DependenceGraph() {} int num_dim() const { return num_dim_; } -// DependenceGraph permute(const std::vector<int> &pi) const; DependenceGraph permute(const std::vector<int> &pi, const std::set<int> &active = std::set<int>()) const; - // DependenceGraph matrix(const std::vector<std::vector<int> > &M) const; DependenceGraph subspace(int dim) const; bool isPositive() const; bool hasPositive(int dim) const; diff --git a/chill/include/graph.hh b/chill/include/graph.hh index f8471df..b67183b 100644 --- a/chill/include/graph.hh +++ b/chill/include/graph.hh @@ -62,7 +62,11 @@ struct Graph { bool hasEdge(int v1, int v2) const; std::vector<EdgeType> getEdge(int v1, int v2) const; + //! Topological sort + /*! This topological sort does handle SCC in graph. */ std::vector<std::set<int> > topoSort() const; + //! Topological sort + /*! This topological sort does not handle SCC in graph. */ std::vector<std::set<int> > packed_topoSort() const; void dump() { @@ -76,7 +80,6 @@ template<typename VertexType, typename EdgeType> std::ostream& operator<<(std::ostream &os, const Graph<VertexType, EdgeType> &g) { for (int i = 0; i < g.vertex.size(); i++) for (typename Graph<VertexType,EdgeType>::EdgeList::const_iterator j = g.vertex[i].second.begin(); j != g.vertex[i].second.end(); j++) { - // os << i+1 << "->" << j->first+1 << ":"; os << "s" << i << "->" << "s" << j->first << ":"; for (typename std::vector<EdgeType>::const_iterator k = j->second.begin(); k != j->second.end(); k++) os << " " << *k; @@ -175,7 +178,6 @@ std::vector<EdgeType> Graph<VertexType,EdgeType>::getEdge(int v1, int v2) const return vertex[v1].second.find(v2)->second; } -// This topological sort does handle SCC in graph. template<typename VertexType, typename EdgeType> std::vector<std::set<int> > Graph<VertexType, EdgeType>::topoSort() const { const int n = vertex.size(); @@ -250,7 +252,6 @@ std::vector<std::set<int> > Graph<VertexType, EdgeType>::topoSort() const { return result; } -// This topological sort does not handle SCC in graph. template<typename VertexType, typename EdgeType> std::vector<std::set<int> > Graph<VertexType, EdgeType>::packed_topoSort() const { const int n = vertex.size(); diff --git a/chill/include/ir_code.hh b/chill/include/ir_code.hh index 1f853fa..b6ebfcd 100644 --- a/chill/include/ir_code.hh +++ b/chill/include/ir_code.hh @@ -46,8 +46,8 @@ enum IR_ARRAY_LAYOUT_TYPE {IR_ARRAY_LAYOUT_ROW_MAJOR, class IR_Code; -// Base abstract class for scalar and array symbols. This is a place -// holder for related declaration in IR code. +//! Base abstract class for scalar and array symbols. +/*! This is a place holder for related declaration in IR code.*/ struct IR_Symbol { const IR_Code *ir_; @@ -75,8 +75,8 @@ struct IR_ArraySymbol: public IR_Symbol { }; -// Base abstract class for scalar and array references. This is a -// place holder for related code in IR code. +//! Base abstract class for scalar and array references. +/*! This is a place holder for related code in IR code. */ struct IR_Ref { const IR_Code *ir_; @@ -87,7 +87,8 @@ struct IR_Ref { virtual bool operator==(const IR_Ref &that) const = 0; virtual bool operator!=(const IR_Ref &that) const {return !(*this == that);} virtual omega::CG_outputRepr *convert() = 0; - virtual IR_Ref *clone() const = 0; /* shallow copy */ + //! shallow copy + virtual IR_Ref *clone() const = 0; }; @@ -155,20 +156,23 @@ struct IR_ArrayRef: public IR_Ref { struct IR_Block; -// Base abstract class for code structures. This is a place holder -// for the actual structure in the IR code. However, in cases that -// original source code may be transformed during loop initialization -// such as converting a while loop to a for loop or reconstructing the -// loop from low level IR code, the helper loop class (NOT -// IMPLEMENTED) must contain the transformed code that needs to be -// freed when out of service. +//! Base abstract class for code structures. +/*! + * This is a place holder for the actual structure in the IR code. + * However, in cases that original source code may be transformed during + * loop initialization such as converting a while loop to a for loop or + * reconstructing the loop from low level IR code, the helper loop class (NOT + * IMPLEMENTED) must contain the transformed code that needs to be + * freed when out of service. + */ struct IR_Control { const IR_Code *ir_; virtual ~IR_Control() {/* ir_ is not the responsibility of this object */} virtual IR_CONTROL_TYPE type() const = 0; virtual IR_Block *convert() = 0; - virtual IR_Control *clone() const = 0; /* shallow copy */ + //! shallow copy + virtual IR_Control *clone() const = 0; }; @@ -208,7 +212,7 @@ struct IR_While: public IR_Control { }; -// Abstract class for compiler IR. +//! Abstract class for compiler IR. class IR_Code { protected: omega::CG_outputBuilder *ocg_; @@ -217,10 +221,14 @@ protected: public: IR_Code() {ocg_ = NULL; init_code_ = cleanup_code_ = NULL;} - virtual ~IR_Code() { delete ocg_; delete init_code_; delete cleanup_code_; } /* the content of init and cleanup code have already been released in derived classes */ + virtual ~IR_Code() { delete ocg_; delete init_code_; delete cleanup_code_; } + /* the content of init and cleanup code have already been released in derived classes */ - // memory_type is for differentiating the location of where the new memory is allocated. - // this is useful for processors with heterogeneous memory hierarchy. + /*! + * \param memory_type is for differentiating the location of + * where the new memory is allocated. this is useful for + * processors with heterogeneous memory hierarchy. + */ virtual IR_ScalarSymbol *CreateScalarSymbol(const IR_Symbol *sym, int memory_type) = 0; virtual IR_ArraySymbol *CreateArraySymbol(const IR_Symbol *sym, std::vector<omega::CG_outputRepr *> &size, int memory_type) = 0; @@ -228,19 +236,28 @@ public: virtual IR_ArrayRef *CreateArrayRef(const IR_ArraySymbol *sym, std::vector<omega::CG_outputRepr *> &index) = 0; virtual int ArrayIndexStartAt() {return 0;} - // Array references should be returned in their accessing order. - // e.g. s1: A[i] = A[i-1] - // s2: B[C[i]] = D[i] + E[i] - // return A[i-1], A[i], D[i], E[i], C[i], B[C[i]] in this order. + /*! + * Array references should be returned in their accessing order. + * + * ~~~ + * e.g. s1: A[i] = A[i-1] + * s2: B[C[i]] = D[i] + E[i] + * return A[i-1], A[i], D[i], E[i], C[i], B[C[i]] in this order. + * ~~~ + */ virtual std::vector<IR_ArrayRef *> FindArrayRef(const omega::CG_outputRepr *repr) const = 0; virtual std::vector<IR_ScalarRef *> FindScalarRef(const omega::CG_outputRepr *repr) const = 0; - // If there is no sub structure interesting inside the block, return empty, - // so we know when to stop looking inside. + /*! + * If there is no sub structure interesting inside the block, return empty, + * so we know when to stop looking inside. + */ virtual std::vector<IR_Control *> FindOneLevelControlStructure(const IR_Block *block) const = 0; - // All controls must be in the same block, at the same level and in - // contiguous lexical order as appeared in parameter vector. + /*! + * All controls must be in the same block, at the same level and in + * contiguous lexical order as appeared in parameter vector. + */ virtual IR_Block *MergeNeighboringControlStructures(const std::vector<IR_Control *> &controls) const = 0; virtual IR_Block *GetCode() const = 0; @@ -252,12 +269,9 @@ public: virtual std::vector<omega::CG_outputRepr *> QueryExpOperand(const omega::CG_outputRepr *repr) const = 0; virtual IR_Ref *Repr2Ref(const omega::CG_outputRepr *repr) const = 0; - //--------------------------------------------------------------------------- - // CC Omega code builder interface here - //--------------------------------------------------------------------------- + //! Codegen Omega code builder interface omega::CG_outputBuilder *builder() const {return ocg_;} }; #endif - diff --git a/chill/include/ir_rose.hh b/chill/include/ir_rose.hh index 0c0417a..9e94dea 100644 --- a/chill/include/ir_rose.hh +++ b/chill/include/ir_rose.hh @@ -236,28 +236,6 @@ public: std::map<SgVarRefExp*, IR_ScalarRef*> &read_scalars_1, std::map<SgVarRefExp*, IR_ScalarRef*> &write_scalars_1, std::set<std::string> &indices, std::vector<std::string> &index); - // std::set<std::string> &def_vars); - /*void findDefinitions(SgStatementPtrList &list_1, - std::set<VirtualCFG::CFGNode> &reaching_defs_1, - std::map<SgVarRefExp*, IR_ScalarRef*> &write_scalars_1, - std::set<std::string> &def_vars); - */ - /* void checkDependency(SgStatementPtrList &output_list_1, - std::vector<DependenceVector> &dvs1, - std::map<SgVarRefExp*, IR_ScalarRef*> &read_scalars_1, - std::map<SgVarRefExp*, IR_ScalarRef*> &write_scalars_1, - std::vector<std::string> &index, int i, int j); - void checkSelfDependency(SgStatementPtrList &output_list_1, - std::vector<DependenceVector> &dvs1, - std::map<SgVarRefExp*, IR_ScalarRef*> &read_scalars_1, - std::map<SgVarRefExp*, IR_ScalarRef*> &write_scalars_1, - std::vector<std::string> &index, int i, int j); - void checkWriteDependency(SgStatementPtrList &output_list_1, - std::vector<DependenceVector> &dvs1, - std::map<SgVarRefExp*, IR_ScalarRef*> &read_scalars_1, - std::map<SgVarRefExp*, IR_ScalarRef*> &write_scalars_1, - std::vector<std::string> &index, int i, int j); - */ std::vector<IR_ArrayRef *> FindArrayRef( const omega::CG_outputRepr *repr) const; std::vector<IR_ScalarRef *> FindScalarRef( @@ -276,11 +254,6 @@ public: std::vector<omega::CG_outputRepr *> QueryExpOperand( const omega::CG_outputRepr *repr) const; IR_Ref *Repr2Ref(const omega::CG_outputRepr *) const; - /* std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > - FindScalarDeps(const omega::CG_outputRepr *repr1, - const omega::CG_outputRepr *repr2, std::vector<std::string> index, - int i, int j); - */ void finalizeRose(); friend class IR_roseArraySymbol; friend class IR_roseArrayRef; diff --git a/chill/include/ir_rose_utils.hh b/chill/include/ir_rose_utils.hh index 9e98aee..d6749de 100644 --- a/chill/include/ir_rose_utils.hh +++ b/chill/include/ir_rose_utils.hh @@ -2,15 +2,11 @@ #define IR_ROSE_UTILS_HH #include <vector> #include <rose.h> -#include "sageBuilder.h" - - +#include <sageBuilder.h> std::vector<SgForStatement *> find_deepest_loops(SgNode *tnl); std::vector<SgForStatement *> find_loops(SgNode *tnl); - - SgNode* loop_body_at_level(SgNode* tnl, int level); SgNode* loop_body_at_level(SgForStatement* loop, int level); void swap_node_for_node_list(SgNode* tn, SgNode* new_tnl); diff --git a/chill/include/irtools.hh b/chill/include/irtools.hh index 8dc8e28..205efe1 100644 --- a/chill/include/irtools.hh +++ b/chill/include/irtools.hh @@ -7,15 +7,18 @@ #include "ir_code.hh" #include "dep.hh" -// IR tree is used to initialize a loop. For a loop node, payload is -// its mapped iteration space dimension. For a simple block node, -// payload is its mapped statement number. Normal if-else is splitted -// into two nodes where the one with odd payload represents then-part and -// the one with even payload represents else-part. +//! It is used to initialize a loop. struct ir_tree_node { IR_Control *content; ir_tree_node *parent; std::vector<ir_tree_node *> children; +/*! + * * For a loop node, payload is its mapped iteration space dimension. + * * For a simple block node, payload is its mapped statement number. + * * Normal if-else is splitted into two nodes + * * the one with odd payload represents then-part and + * * the one with even payload represents else-part. + */ int payload; ~ir_tree_node() { diff --git a/chill/include/loop.hh b/chill/include/loop.hh index f227bb5..2c50d6b 100644 --- a/chill/include/loop.hh +++ b/chill/include/loop.hh @@ -17,17 +17,21 @@ enum TilingMethodType { StridedTile, CountedTile }; enum LoopLevelType { LoopLevelOriginal, LoopLevelTile, LoopLevelUnknown }; -// Describes properties of each loop level of a statement. "payload" -// for LoopLevelOriginal means iteration space dimension, for -// LoopLevelTile means tiled loop level. Special value -1 for -// LoopLevelTile means purely derived loop. For dependence dimension -// payloads, the values must be in an increasing order. -// "parallel_level" will be used by code generation to support -// multi-level parallelization (default 0 means sequential loop under -// the current parallelization level). +//! Describes properties of each loop level of a statement. struct LoopLevel { LoopLevelType type; +/*! + * For LoopLevelOriginal means iteration space dimension + * For LoopLevelTile means tiled loop level. Special value -1 for + * LoopLevelTile means purely derived loop. For dependence dimension + * payloads, the values must be in an increasing order. + */ int payload; +/*! + * Used by code generation to support + * multi-level parallelization (default 0 means sequential loop under + * the current parallelization level). + */ int parallel_level; }; @@ -107,14 +111,16 @@ public: std::vector<std::set <int > > sort_by_same_loops(std::set<int > active, int level); // - // legacy unimodular transformations for perfectly nested loops - // e.g. M*(i,j)^T = (i',j')^T or M*(i,j,1)^T = (i',j')^T - // + //! legacy unimodular transformations for perfectly nested loops + /*! + * e.g. \f$M*(i,j)^T = (i',j')^T or M*(i,j,1)^T = (i',j')^T\f$ + */ bool nonsingular(const std::vector<std::vector<int> > &M); - // - // high-level loop transformations - // + /*! + * \defgroup hltrans High-level loop transformations + * @{ + */ void permute(const std::set<int> &active, const std::vector<int> &pi); void permute(int stmt_num, int level, const std::vector<int> &pi); void permute(const std::vector<int> &pi); @@ -129,8 +135,6 @@ public: bool datacopy_privatized(int stmt_num, int level, const std::string &array_name, const std::vector<int> &privatized_levels, bool allow_extra_read = false, int fastest_changing_dimension = -1, int padding_stride = 1, int padding_alignment = 1, int memory_type = 0); bool datacopy_privatized(const std::vector<std::pair<int, std::vector<int> > > &array_ref_nums, int level, const std::vector<int> &privatized_levels, bool allow_extra_read = false, int fastest_changing_dimension = -1, int padding_stride = 1, int padding_alignment = 1, int memory_type = 0); bool datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_ArrayRef *> > > &stmt_refs, int level, const std::vector<int> &privatized_levels, bool allow_extra_read, int fastest_changing_dimension, int padding_stride, int padding_alignment, int memory_type = 0); - //std::set<int> scalar_replacement_inner(int stmt_num); - Graph<std::set<int>, bool> construct_induced_graph_at_level(std::vector<std::set<int> > s, DependenceGraph dep, int dep_dim); @@ -142,26 +146,35 @@ public: void scale(const std::set<int> &stmt_nums, int level, int scale_amount); void reverse(const std::set<int> &stmt_nums, int level); void peel(int stmt_num, int level, int peel_amount = 1); - // - // more fancy loop transformations - // + /*! + * \defgroup hlfancy fancy loop transformations + * @{ + */ void modular_shift(int stmt_num, int level, int shift_amount) {} void diagonal_map(int stmt_num, const std::pair<int, int> &levels, int offset) {} void modular_partition(int stmt_num, int level, int stride) {} + /*! @} */ - // - // derived loop transformations - // + /*! + * \defgroup hlderived derived loop transformations + * @{ + */ + void shift_to(int stmt_num, int level, int absolute_position); std::set<int> unroll_extra(int stmt_num, int level, int unroll_amount, int cleanup_split_level = 0); bool is_dependence_valid_based_on_lex_order(int i, int j, const DependenceVector &dv, bool before); - // - // other public operations - // + /*! @} */ + + /*! + * \defgroup hlother other public operations + * @{ + */ void pragma(int stmt_num, int level, const std::string &pragmaText); void prefetch(int stmt_num, int level, const std::string &arrName, int hint); - //void prefetch(int stmt_num, int level, const std::string &arrName, const std::string &indexName, int offset, int hint); + /*! @} */ + + /*! @} */ }; diff --git a/chill/include/omegatools.hh b/chill/include/omegatools.hh index 206079c..f77a376 100644 --- a/chill/include/omegatools.hh +++ b/chill/include/omegatools.hh @@ -8,90 +8,81 @@ std::string tmp_e(); +//! Convert expression tree to omega relation. +/*! + * \param destroy shallow deallocation of "repr", not freeing the actual code inside. + */ void exp2formula(IR_Code *ir, omega::Relation &r, omega::F_And *f_root, std::vector<omega::Free_Var_Decl *> &freevars, omega::CG_outputRepr *repr, omega::Variable_ID lhs, char side, IR_CONDITION_TYPE rel, bool destroy); + +//! Build dependence relation for two array references. omega::Relation arrays2relation(IR_Code *ir, std::vector<omega::Free_Var_Decl*> &freevars, const IR_ArrayRef *ref_src, const omega::Relation &IS_w, const IR_ArrayRef *ref_dst, const omega::Relation &IS_r); +//! Convert array dependence relation into set of dependence vectors +/*! + * assuming ref_w is lexicographically before ref_r in the source code. + */ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relation2dependences( const IR_ArrayRef *ref_src, const IR_ArrayRef *ref_dst, const omega::Relation &r); +//! Convert a boolean expression to omega relation. +/*! + * \param destroy shallow deallocation of "repr", not freeing the actual code inside. + */ void exp2constraint(IR_Code *ir, omega::Relation &r, omega::F_And *f_root, std::vector<omega::Free_Var_Decl *> &freevars, omega::CG_outputRepr *repr, bool destroy); -// suif legacy code -// void suif2formula(Relation &r, F_And *f_root, -// std::vector<Free_Var_Decl*> &freevars, -// operand op, Variable_ID lhs, -// char side, char rel); -// void suif2formula(Relation &r, F_And *f_root, -// std::vector<Free_Var_Decl*> &freevars, -// instruction *ins, Variable_ID lhs, -// char side, char rel); -// void add_loop_stride_constraints(omega::Relation &r, omega::F_And *f_root, -// std::vector<omega::Free_Var_Decl*> &freevars, -// tree_for *tnf, char side); -// void add_loop_bound_constraints(IR_Code *ir, omega::Relation &r, omega::F_And *f_root, -// std::vector<omega::Free_Var_Decl*> &freevars, -// tree_for *tnf, -// char upper_or_lower, char side, IR_CONDITION_TYPE rel); -// Relation loop_iteration_space(std::vector<Free_Var_Decl*> &freevars, -// tree_node *tn, std::vector<tree_for*> &loops); - -// Relation arrays2relation(std::vector<Free_Var_Decl*> &freevars, -// in_array *ia_w, const Relation &IS1, -// in_array *ia_r, const Relation &IS2); -// std::vector<DependenceVector> relation2dependences(IR_Code *ir, in_array *ia_w, -// in_array *ia_r, const Relation &r); - -// end of suif legacy code - bool is_single_iteration(const omega::Relation &r, int dim); +//! Set/get the value of a variable which is know to be constant. void assign_const(omega::Relation &r, int dim, int val); + int get_const(const omega::Relation &r, int dim, omega::Var_Kind type); + +//! Find the position index variable in a Relation by name. omega::Variable_ID find_index(omega::Relation &r, const std::string &s, char side); + +//! Generate mapping relation for permuation. omega::Relation permute_relation(const std::vector<int> &pi); + omega::Relation get_loop_bound(const omega::Relation &r, int dim); + +//! Determine whether the loop (starting from 0) in the iteration space has only one iteration. bool is_single_loop_iteration(const omega::Relation &r, int level, const omega::Relation &known); +//! Get the bound for a specific loop. omega::Relation get_loop_bound(const omega::Relation &r, int level, const omega::Relation &known); omega::Relation get_max_loop_bound(const std::vector<omega::Relation> &r, int dim); omega::Relation get_min_loop_bound(const std::vector<omega::Relation> &r, int dim); + +//! Add strident to a loop. +/*! + * Issues: + * + * * Don't work with relations with multiple disjuncts. + * * Omega's dealing with max lower bound is awkward. + */ void add_loop_stride(omega::Relation &r, const omega::Relation &bound, int dim, int stride); bool is_inner_loop_depend_on_level(const omega::Relation &r, int level, const omega::Relation &known); -// void adjust_loop_bound(omega::Relation &r, int dim, int adjustment, std::vector<omega::Free_Var_Decl *> globals = std::vector<omega::Free_Var_Decl *>()); +/*! + * Suppose loop dim is i. Replace i with i+adjustment in loop bounds. + * + * ~~~ + * do i = 1, n + * do j = i, n + * ~~~ + * + * after call with dim = 0 and adjustment = 1: + * + * ~~~ + * do i = 1, n + * do j = i+1, n + * ~~~ + */ omega::Relation adjust_loop_bound(const omega::Relation &r, int level, int adjustment); -// void adjust_loop_bound(Relation &r, int dim, int adjustment); -// void adjust_loop_bound(Relation &r, int dim, Free_Var_Decl *global_var, int adjustment); -// boolean is_private_statement(const omega::Relation &r, int dim); - -// coef_t mod(const Relation &r, Variable_ID v, int dividend); - enum LexicalOrderType {LEX_MATCH, LEX_BEFORE, LEX_AFTER, LEX_UNKNOWN}; -// template <typename T> -// LexicalOrderType lexical_order(const std::vector<T> &a, const std::vector<T> &b) { -// int size = min(a.size(), b.size()); -// for (int i = 0; i < size; i++) { -// if (a[i] < b[i]) -// return LEX_BEFORE; -// else if (b[i] < a[i]) -// return LEX_AFTER; -// } -// if (a.size() < b.size()) -// return LEX_BEFORE; -// else if (b.size() < a.size()) -// return LEX_AFTER; -// else -// return LEX_MATCH; -// } - -// struct LoopException { -// std::string descr; -// LoopException(const std::string &s): descr(s) {}; -// }; - #endif |