xref: /llvm-project/polly/lib/External/isl/isl_scheduler.h (revision a749e09e184b2b0b6dde71af01c82dd427b3e3e2)
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