1*a749e09eSMichael Kruse #ifndef ISL_SCHEDULER_H 2*a749e09eSMichael Kruse #define ISL_SCHEDULER_H 3*a749e09eSMichael Kruse 4*a749e09eSMichael Kruse #include <isl/aff_type.h> 5*a749e09eSMichael Kruse #include <isl/hash.h> 6*a749e09eSMichael Kruse #include <isl/id_type.h> 7*a749e09eSMichael Kruse #include <isl/map_type.h> 8*a749e09eSMichael Kruse #include <isl/map_to_basic_set.h> 9*a749e09eSMichael Kruse #include <isl/mat.h> 10*a749e09eSMichael Kruse #include <isl/space_type.h> 11*a749e09eSMichael Kruse #include <isl/set_type.h> 12*a749e09eSMichael Kruse #include <isl/val_type.h> 13*a749e09eSMichael Kruse #include <isl/vec.h> 14*a749e09eSMichael Kruse #include <isl/union_map_type.h> 15*a749e09eSMichael Kruse 16*a749e09eSMichael Kruse #include "isl_schedule_constraints.h" 17*a749e09eSMichael Kruse #include "isl_tab.h" 18*a749e09eSMichael Kruse 19*a749e09eSMichael Kruse /* Internal information about a node that is used during the construction 20*a749e09eSMichael Kruse * of a schedule. 21*a749e09eSMichael Kruse * space represents the original space in which the domain lives; 22*a749e09eSMichael Kruse * that is, the space is not affected by compression 23*a749e09eSMichael Kruse * sched is a matrix representation of the schedule being constructed 24*a749e09eSMichael Kruse * for this node; if compressed is set, then this schedule is 25*a749e09eSMichael Kruse * defined over the compressed domain space 26*a749e09eSMichael Kruse * sched_map is an isl_map representation of the same (partial) schedule 27*a749e09eSMichael Kruse * sched_map may be NULL; if compressed is set, then this map 28*a749e09eSMichael Kruse * is defined over the uncompressed domain space 29*a749e09eSMichael Kruse * rank is the number of linearly independent rows in the linear part 30*a749e09eSMichael Kruse * of sched 31*a749e09eSMichael Kruse * the rows of "vmap" represent a change of basis for the node 32*a749e09eSMichael Kruse * variables; the first rank rows span the linear part of 33*a749e09eSMichael Kruse * the schedule rows; the remaining rows are linearly independent 34*a749e09eSMichael Kruse * the rows of "indep" represent linear combinations of the schedule 35*a749e09eSMichael Kruse * coefficients that are non-zero when the schedule coefficients are 36*a749e09eSMichael Kruse * linearly independent of previously computed schedule rows. 37*a749e09eSMichael Kruse * start is the first variable in the LP problem in the sequences that 38*a749e09eSMichael Kruse * represents the schedule coefficients of this node 39*a749e09eSMichael Kruse * nvar is the dimension of the (compressed) domain 40*a749e09eSMichael Kruse * nparam is the number of parameters or 0 if we are not constructing 41*a749e09eSMichael Kruse * a parametric schedule 42*a749e09eSMichael Kruse * 43*a749e09eSMichael Kruse * If compressed is set, then hull represents the constraints 44*a749e09eSMichael Kruse * that were used to derive the compression, while compress and 45*a749e09eSMichael Kruse * decompress map the original space to the compressed space and 46*a749e09eSMichael Kruse * vice versa. 47*a749e09eSMichael Kruse * 48*a749e09eSMichael Kruse * scc is the index of SCC (or WCC) this node belongs to 49*a749e09eSMichael Kruse * 50*a749e09eSMichael Kruse * "cluster" is only used inside extract_clusters and identifies 51*a749e09eSMichael Kruse * the cluster of SCCs that the node belongs to. 52*a749e09eSMichael Kruse * 53*a749e09eSMichael Kruse * coincident contains a boolean for each of the rows of the schedule, 54*a749e09eSMichael Kruse * indicating whether the corresponding scheduling dimension satisfies 55*a749e09eSMichael Kruse * the coincidence constraints in the sense that the corresponding 56*a749e09eSMichael Kruse * dependence distances are zero. 57*a749e09eSMichael Kruse * 58*a749e09eSMichael Kruse * If the schedule_treat_coalescing option is set, then 59*a749e09eSMichael Kruse * "sizes" contains the sizes of the (compressed) instance set 60*a749e09eSMichael Kruse * in each direction. If there is no fixed size in a given direction, 61*a749e09eSMichael Kruse * then the corresponding size value is set to infinity. 62*a749e09eSMichael Kruse * If the schedule_treat_coalescing option or the schedule_max_coefficient 63*a749e09eSMichael Kruse * option is set, then "max" contains the maximal values for 64*a749e09eSMichael Kruse * schedule coefficients of the (compressed) variables. If no bound 65*a749e09eSMichael Kruse * needs to be imposed on a particular variable, then the corresponding 66*a749e09eSMichael Kruse * value is negative. 67*a749e09eSMichael Kruse * If not NULL, then "bounds" contains a non-parametric set 68*a749e09eSMichael Kruse * in the compressed space that is bounded by the size in each direction. 69*a749e09eSMichael Kruse */ 70*a749e09eSMichael Kruse struct isl_sched_node { 71*a749e09eSMichael Kruse isl_space *space; 72*a749e09eSMichael Kruse int compressed; 73*a749e09eSMichael Kruse isl_set *hull; 74*a749e09eSMichael Kruse isl_multi_aff *compress; 75*a749e09eSMichael Kruse isl_pw_multi_aff *decompress; 76*a749e09eSMichael Kruse isl_mat *sched; 77*a749e09eSMichael Kruse isl_map *sched_map; 78*a749e09eSMichael Kruse int rank; 79*a749e09eSMichael Kruse isl_mat *indep; 80*a749e09eSMichael Kruse isl_mat *vmap; 81*a749e09eSMichael Kruse int start; 82*a749e09eSMichael Kruse int nvar; 83*a749e09eSMichael Kruse int nparam; 84*a749e09eSMichael Kruse 85*a749e09eSMichael Kruse int scc; 86*a749e09eSMichael Kruse int cluster; 87*a749e09eSMichael Kruse 88*a749e09eSMichael Kruse int *coincident; 89*a749e09eSMichael Kruse 90*a749e09eSMichael Kruse isl_multi_val *sizes; 91*a749e09eSMichael Kruse isl_basic_set *bounds; 92*a749e09eSMichael Kruse isl_vec *max; 93*a749e09eSMichael Kruse }; 94*a749e09eSMichael Kruse 95*a749e09eSMichael Kruse int isl_sched_node_scc_exactly(struct isl_sched_node *node, int scc); 96*a749e09eSMichael Kruse 97*a749e09eSMichael Kruse isl_stat isl_sched_node_update_vmap(struct isl_sched_node *node); 98*a749e09eSMichael Kruse __isl_give isl_multi_aff *isl_sched_node_extract_partial_schedule_multi_aff( 99*a749e09eSMichael Kruse struct isl_sched_node *node, int first, int n); 100*a749e09eSMichael Kruse 101*a749e09eSMichael Kruse /* An edge in the dependence graph. An edge may be used to 102*a749e09eSMichael Kruse * ensure validity of the generated schedule, to minimize the dependence 103*a749e09eSMichael Kruse * distance or both 104*a749e09eSMichael Kruse * 105*a749e09eSMichael Kruse * map is the dependence relation, with i -> j in the map if j depends on i 106*a749e09eSMichael Kruse * tagged_condition and tagged_validity contain the union of all tagged 107*a749e09eSMichael Kruse * condition or conditional validity dependence relations that 108*a749e09eSMichael Kruse * specialize the dependence relation "map"; that is, 109*a749e09eSMichael Kruse * if (i -> a) -> (j -> b) is an element of "tagged_condition" 110*a749e09eSMichael Kruse * or "tagged_validity", then i -> j is an element of "map". 111*a749e09eSMichael Kruse * If these fields are NULL, then they represent the empty relation. 112*a749e09eSMichael Kruse * src is the source node 113*a749e09eSMichael Kruse * dst is the sink node 114*a749e09eSMichael Kruse * 115*a749e09eSMichael Kruse * types is a bit vector containing the types of this edge. 116*a749e09eSMichael Kruse * validity is set if the edge is used to ensure correctness 117*a749e09eSMichael Kruse * coincidence is used to enforce zero dependence distances 118*a749e09eSMichael Kruse * proximity is set if the edge is used to minimize dependence distances 119*a749e09eSMichael Kruse * condition is set if the edge represents a condition 120*a749e09eSMichael Kruse * for a conditional validity schedule constraint 121*a749e09eSMichael Kruse * local can only be set for condition edges and indicates that 122*a749e09eSMichael Kruse * the dependence distance over the edge should be zero 123*a749e09eSMichael Kruse * conditional_validity is set if the edge is used to conditionally 124*a749e09eSMichael Kruse * ensure correctness 125*a749e09eSMichael Kruse * 126*a749e09eSMichael Kruse * For validity edges, start and end mark the sequence of inequality 127*a749e09eSMichael Kruse * constraints in the LP problem that encode the validity constraint 128*a749e09eSMichael Kruse * corresponding to this edge. 129*a749e09eSMichael Kruse * 130*a749e09eSMichael Kruse * During clustering, an edge may be marked "no_merge" if it should 131*a749e09eSMichael Kruse * not be used to merge clusters. 132*a749e09eSMichael Kruse * The weight is also only used during clustering and it is 133*a749e09eSMichael Kruse * an indication of how many schedule dimensions on either side 134*a749e09eSMichael Kruse * of the schedule constraints can be aligned. 135*a749e09eSMichael Kruse * If the weight is negative, then this means that this edge was postponed 136*a749e09eSMichael Kruse * by has_bounded_distances or any_no_merge. The original weight can 137*a749e09eSMichael Kruse * be retrieved by adding 1 + graph->max_weight, with "graph" 138*a749e09eSMichael Kruse * the graph containing this edge. 139*a749e09eSMichael Kruse */ 140*a749e09eSMichael Kruse struct isl_sched_edge { 141*a749e09eSMichael Kruse isl_map *map; 142*a749e09eSMichael Kruse isl_union_map *tagged_condition; 143*a749e09eSMichael Kruse isl_union_map *tagged_validity; 144*a749e09eSMichael Kruse 145*a749e09eSMichael Kruse struct isl_sched_node *src; 146*a749e09eSMichael Kruse struct isl_sched_node *dst; 147*a749e09eSMichael Kruse 148*a749e09eSMichael Kruse unsigned types; 149*a749e09eSMichael Kruse 150*a749e09eSMichael Kruse int start; 151*a749e09eSMichael Kruse int end; 152*a749e09eSMichael Kruse 153*a749e09eSMichael Kruse int no_merge; 154*a749e09eSMichael Kruse int weight; 155*a749e09eSMichael Kruse }; 156*a749e09eSMichael Kruse 157*a749e09eSMichael Kruse int isl_sched_edge_has_type(struct isl_sched_edge *edge, 158*a749e09eSMichael Kruse enum isl_edge_type type); 159*a749e09eSMichael Kruse int isl_sched_edge_is_condition(struct isl_sched_edge *edge); 160*a749e09eSMichael Kruse int isl_sched_edge_is_conditional_validity(struct isl_sched_edge *edge); 161*a749e09eSMichael Kruse int isl_sched_edge_scc_exactly(struct isl_sched_edge *edge, int scc); 162*a749e09eSMichael Kruse int isl_sched_edge_is_proximity(struct isl_sched_edge *edge); 163*a749e09eSMichael Kruse 164*a749e09eSMichael Kruse /* Internal information about the dependence graph used during 165*a749e09eSMichael Kruse * the construction of the schedule. 166*a749e09eSMichael Kruse * 167*a749e09eSMichael Kruse * intra_hmap is a cache, mapping dependence relations to their dual, 168*a749e09eSMichael Kruse * for dependences from a node to itself, possibly without 169*a749e09eSMichael Kruse * coefficients for the parameters 170*a749e09eSMichael Kruse * intra_hmap_param is a cache, mapping dependence relations to their dual, 171*a749e09eSMichael Kruse * for dependences from a node to itself, including coefficients 172*a749e09eSMichael Kruse * for the parameters 173*a749e09eSMichael Kruse * inter_hmap is a cache, mapping dependence relations to their dual, 174*a749e09eSMichael Kruse * for dependences between distinct nodes 175*a749e09eSMichael Kruse * if compression is involved then the key for these maps 176*a749e09eSMichael Kruse * is the original, uncompressed dependence relation, while 177*a749e09eSMichael Kruse * the value is the dual of the compressed dependence relation. 178*a749e09eSMichael Kruse * 179*a749e09eSMichael Kruse * n is the number of nodes 180*a749e09eSMichael Kruse * node is the list of nodes 181*a749e09eSMichael Kruse * maxvar is the maximal number of variables over all nodes 182*a749e09eSMichael Kruse * max_row is the allocated number of rows in the schedule 183*a749e09eSMichael Kruse * n_row is the current (maximal) number of linearly independent 184*a749e09eSMichael Kruse * rows in the node schedules 185*a749e09eSMichael Kruse * n_total_row is the current number of rows in the node schedules 186*a749e09eSMichael Kruse * band_start is the starting row in the node schedules of the current band 187*a749e09eSMichael Kruse * root is set to the original dependence graph from which this graph 188*a749e09eSMichael Kruse * is derived through splitting. If this graph is not the result of 189*a749e09eSMichael Kruse * splitting, then the root field points to the graph itself. 190*a749e09eSMichael Kruse * 191*a749e09eSMichael Kruse * sorted contains a list of node indices sorted according to the 192*a749e09eSMichael Kruse * SCC to which a node belongs 193*a749e09eSMichael Kruse * 194*a749e09eSMichael Kruse * n_edge is the number of edges 195*a749e09eSMichael Kruse * edge is the list of edges 196*a749e09eSMichael Kruse * max_edge contains the maximal number of edges of each type; 197*a749e09eSMichael Kruse * in particular, it contains the number of edges in the inital graph. 198*a749e09eSMichael Kruse * edge_table contains pointers into the edge array, hashed on the source 199*a749e09eSMichael Kruse * and sink spaces; there is one such table for each type; 200*a749e09eSMichael Kruse * a given edge may be referenced from more than one table 201*a749e09eSMichael Kruse * if the corresponding relation appears in more than one of the 202*a749e09eSMichael Kruse * sets of dependences; however, for each type there is only 203*a749e09eSMichael Kruse * a single edge between a given pair of source and sink space 204*a749e09eSMichael Kruse * in the entire graph 205*a749e09eSMichael Kruse * 206*a749e09eSMichael Kruse * node_table contains pointers into the node array, hashed on the space tuples 207*a749e09eSMichael Kruse * 208*a749e09eSMichael Kruse * region contains a list of variable sequences that should be non-trivial 209*a749e09eSMichael Kruse * 210*a749e09eSMichael Kruse * lp contains the (I)LP problem used to obtain new schedule rows 211*a749e09eSMichael Kruse * 212*a749e09eSMichael Kruse * src_scc and dst_scc are the source and sink SCCs of an edge with 213*a749e09eSMichael Kruse * conflicting constraints 214*a749e09eSMichael Kruse * 215*a749e09eSMichael Kruse * scc represents the number of components 216*a749e09eSMichael Kruse * weak is set if the components are weakly connected 217*a749e09eSMichael Kruse * 218*a749e09eSMichael Kruse * max_weight is used during clustering and represents the maximal 219*a749e09eSMichael Kruse * weight of the relevant proximity edges. 220*a749e09eSMichael Kruse */ 221*a749e09eSMichael Kruse struct isl_sched_graph { 222*a749e09eSMichael Kruse isl_map_to_basic_set *intra_hmap; 223*a749e09eSMichael Kruse isl_map_to_basic_set *intra_hmap_param; 224*a749e09eSMichael Kruse isl_map_to_basic_set *inter_hmap; 225*a749e09eSMichael Kruse 226*a749e09eSMichael Kruse struct isl_sched_node *node; 227*a749e09eSMichael Kruse int n; 228*a749e09eSMichael Kruse int maxvar; 229*a749e09eSMichael Kruse int max_row; 230*a749e09eSMichael Kruse int n_row; 231*a749e09eSMichael Kruse 232*a749e09eSMichael Kruse int *sorted; 233*a749e09eSMichael Kruse 234*a749e09eSMichael Kruse int n_total_row; 235*a749e09eSMichael Kruse int band_start; 236*a749e09eSMichael Kruse 237*a749e09eSMichael Kruse struct isl_sched_graph *root; 238*a749e09eSMichael Kruse 239*a749e09eSMichael Kruse struct isl_sched_edge *edge; 240*a749e09eSMichael Kruse int n_edge; 241*a749e09eSMichael Kruse int max_edge[isl_edge_last + 1]; 242*a749e09eSMichael Kruse struct isl_hash_table *edge_table[isl_edge_last + 1]; 243*a749e09eSMichael Kruse 244*a749e09eSMichael Kruse struct isl_hash_table *node_table; 245*a749e09eSMichael Kruse struct isl_trivial_region *region; 246*a749e09eSMichael Kruse 247*a749e09eSMichael Kruse isl_basic_set *lp; 248*a749e09eSMichael Kruse 249*a749e09eSMichael Kruse int src_scc; 250*a749e09eSMichael Kruse int dst_scc; 251*a749e09eSMichael Kruse 252*a749e09eSMichael Kruse int scc; 253*a749e09eSMichael Kruse int weak; 254*a749e09eSMichael Kruse 255*a749e09eSMichael Kruse int max_weight; 256*a749e09eSMichael Kruse }; 257*a749e09eSMichael Kruse 258*a749e09eSMichael Kruse isl_stat isl_sched_graph_init(struct isl_sched_graph *graph, 259*a749e09eSMichael Kruse __isl_keep isl_schedule_constraints *sc); 260*a749e09eSMichael Kruse void isl_sched_graph_free(isl_ctx *ctx, struct isl_sched_graph *graph); 261*a749e09eSMichael Kruse 262*a749e09eSMichael Kruse int isl_sched_graph_is_node(struct isl_sched_graph *graph, 263*a749e09eSMichael Kruse struct isl_sched_node *node); 264*a749e09eSMichael Kruse isl_bool isl_sched_graph_has_validity_edge(struct isl_sched_graph *graph, 265*a749e09eSMichael Kruse struct isl_sched_node *src, struct isl_sched_node *dst); 266*a749e09eSMichael Kruse 267*a749e09eSMichael Kruse struct isl_sched_node *isl_sched_graph_find_node(isl_ctx *ctx, 268*a749e09eSMichael Kruse struct isl_sched_graph *graph, __isl_keep isl_space *space); 269*a749e09eSMichael Kruse 270*a749e09eSMichael Kruse isl_stat isl_sched_graph_detect_ccs(isl_ctx *ctx, struct isl_sched_graph *graph, 271*a749e09eSMichael Kruse isl_bool (*follows)(int i, int j, void *user)); 272*a749e09eSMichael Kruse 273*a749e09eSMichael Kruse __isl_give isl_union_set *isl_sched_graph_extract_scc(isl_ctx *ctx, 274*a749e09eSMichael Kruse struct isl_sched_graph *graph, int scc); 275*a749e09eSMichael Kruse __isl_give isl_union_set_list *isl_sched_graph_extract_sccs(isl_ctx *ctx, 276*a749e09eSMichael Kruse struct isl_sched_graph *graph); 277*a749e09eSMichael Kruse isl_stat isl_sched_graph_extract_sub_graph(isl_ctx *ctx, 278*a749e09eSMichael Kruse struct isl_sched_graph *graph, 279*a749e09eSMichael Kruse int (*node_pred)(struct isl_sched_node *node, int data), 280*a749e09eSMichael Kruse int (*edge_pred)(struct isl_sched_edge *edge, int data), 281*a749e09eSMichael Kruse int data, struct isl_sched_graph *sub); 282*a749e09eSMichael Kruse isl_stat isl_sched_graph_compute_maxvar(struct isl_sched_graph *graph); 283*a749e09eSMichael Kruse isl_stat isl_schedule_node_compute_wcc_band(isl_ctx *ctx, 284*a749e09eSMichael Kruse struct isl_sched_graph *graph); 285*a749e09eSMichael Kruse __isl_give isl_schedule_node *isl_schedule_node_compute_finish_band( 286*a749e09eSMichael Kruse __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, 287*a749e09eSMichael Kruse int initialized); 288*a749e09eSMichael Kruse 289*a749e09eSMichael Kruse #endif 290