2 * Copyright 2010-2011 INRIA Saclay
4 * Use of this software is governed by the GNU LGPLv2.1 license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
13 void print_cloog_macros(FILE *dst
)
16 "#define floord(n,d) (((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))\n");
18 "#define ceild(n,d) (((n)<0) ? -((-(n))/(d)) : ((n)+(d)-1)/(d))\n");
19 fprintf(dst
, "#define max(x,y) ((x) > (y) ? (x) : (y))\n");
20 fprintf(dst
, "#define min(x,y) ((x) < (y) ? (x) : (y))\n");
23 static void print_expr(struct clast_expr
*e
, FILE *dst
);
24 static void print_stmt(struct gpucode_info
*info
, struct clast_stmt
*s
);
26 void print_indent(FILE *dst
, int indent
)
28 fprintf(dst
, "%*s", indent
, "");
31 static void print_name(struct clast_name
*n
, FILE *dst
)
33 fprintf(dst
, "%s", n
->name
);
36 static void print_term(struct clast_term
*t
, FILE *dst
)
39 cloog_int_print(dst
, t
->val
);
41 if (!cloog_int_is_one(t
->val
)) {
42 cloog_int_print(dst
, t
->val
);
45 if (t
->var
->type
== clast_expr_red
)
47 print_expr(t
->var
, dst
);
48 if (t
->var
->type
== clast_expr_red
)
53 static void print_bin(struct clast_binary
*b
, FILE *dst
)
55 const char *s1
, *s2
, *s3
;
58 s1
= "(", s2
= ")%", s3
= "";
61 s1
= "(", s2
= ")/(", s3
= ")";
64 s1
= "ceild(", s2
= ", ", s3
= ")";
67 s1
= "floord(", s2
= ", ", s3
= ")";
72 fprintf(dst
, "%s", s1
);
73 print_expr(b
->LHS
, dst
);
74 fprintf(dst
, "%s", s2
);
75 cloog_int_print(dst
, b
->RHS
);
76 fprintf(dst
, "%s", s3
);
79 static void print_red(struct clast_reduction
*r
, FILE *dst
)
82 const char *s1
, *s2
, *s3
;
85 print_expr(r
->elts
[0], dst
);
91 s1
= "", s2
= " + ", s3
= "";
94 s1
= "max(", s2
= ", ", s3
= ")";
97 s1
= "min(", s2
= ", ", s3
= ")";
103 for (i
= 1; i
< r
->n
; ++i
)
104 fprintf(dst
, "%s", s1
);
105 print_expr(r
->elts
[0], dst
);
106 for (i
= 1; i
< r
->n
; ++i
) {
107 if (r
->type
== clast_red_sum
&& r
->elts
[i
]->type
== clast_expr_term
&&
108 cloog_int_is_neg(((struct clast_term
*) r
->elts
[i
])->val
)) {
109 struct clast_term
*t
= (struct clast_term
*) r
->elts
[i
];
110 cloog_int_neg(t
->val
, t
->val
);
112 print_expr(r
->elts
[i
], dst
);
113 cloog_int_neg(t
->val
, t
->val
);
115 fprintf(dst
, "%s", s2
);
116 print_expr(r
->elts
[i
], dst
);
118 fprintf(dst
, "%s", s3
);
122 static void print_expr(struct clast_expr
*e
, FILE *dst
)
125 case clast_expr_name
:
126 print_name((struct clast_name
*) e
, dst
);
128 case clast_expr_term
:
129 print_term((struct clast_term
*) e
, dst
);
132 print_red((struct clast_reduction
*) e
, dst
);
135 print_bin((struct clast_binary
*) e
, dst
);
142 static void print_ass(struct clast_assignment
*a
, FILE *dst
, int indent
,
145 print_indent(dst
, indent
);
147 fprintf(dst
, "int ");
148 fprintf(dst
, "%s = ", a
->LHS
);
149 print_expr(a
->RHS
, dst
);
153 static void print_guard(struct gpucode_info
*info
, struct clast_guard
*g
)
158 print_indent(info
->dst
, info
->indent
);
159 fprintf(info
->dst
, "if (");
160 for (i
= 0; i
< n
; ++i
) {
162 fprintf(info
->dst
," && ");
163 fprintf(info
->dst
,"(");
164 print_expr(g
->eq
[i
].LHS
, info
->dst
);
165 if (g
->eq
[i
].sign
== 0)
166 fprintf(info
->dst
," == ");
167 else if (g
->eq
[i
].sign
> 0)
168 fprintf(info
->dst
," >= ");
170 fprintf(info
->dst
," <= ");
171 print_expr(g
->eq
[i
].RHS
, info
->dst
);
172 fprintf(info
->dst
,")");
174 fprintf(info
->dst
, ") {\n");
176 print_stmt(info
, g
->then
);
178 print_indent(info
->dst
, info
->indent
);
179 fprintf(info
->dst
, "}\n");
182 static void print_for(struct gpucode_info
*info
, struct clast_for
*f
)
184 assert(f
->LB
&& f
->UB
);
185 print_indent(info
->dst
, info
->indent
);
186 fprintf(info
->dst
, "for (int %s = ", f
->iterator
);
187 print_expr(f
->LB
, info
->dst
);
188 fprintf(info
->dst
, "; %s <= ", f
->iterator
);
189 print_expr(f
->UB
, info
->dst
);
190 fprintf(info
->dst
, "; %s", f
->iterator
);
191 if (cloog_int_is_one(f
->stride
))
192 fprintf(info
->dst
, "++");
194 fprintf(info
->dst
, " += ");
195 cloog_int_print(info
->dst
, f
->stride
);
197 fprintf(info
->dst
, ") {\n");
199 if (info
->print_for_head
)
200 info
->print_for_head(info
, f
);
201 print_stmt(info
, f
->body
);
202 if (info
->print_for_foot
)
203 info
->print_for_foot(info
, f
);
205 print_indent(info
->dst
, info
->indent
);
206 fprintf(info
->dst
, "}\n");
209 static void print_user_stmt(struct clast_user_stmt
*u
, FILE *dst
, int indent
)
211 struct clast_stmt
*t
;
213 print_indent(dst
, indent
);
214 fprintf(dst
, "%s", u
->statement
->name
);
216 for (t
= u
->substitutions
; t
; t
= t
->next
) {
217 assert(CLAST_STMT_IS_A(t
, stmt_ass
));
218 print_expr(((struct clast_assignment
*) t
)->RHS
, dst
);
222 fprintf(dst
, ");\n");
225 static void print_stmt(struct gpucode_info
*info
, struct clast_stmt
*s
)
229 for ( ; s
; s
= s
->next
) {
230 if (CLAST_STMT_IS_A(s
, stmt_root
))
232 if (CLAST_STMT_IS_A(s
, stmt_ass
)) {
233 print_ass((struct clast_assignment
*) s
, info
->dst
, info
->indent
,
236 } else if (CLAST_STMT_IS_A(s
, stmt_user
)) {
237 if (info
->print_user_stmt_list
) {
238 info
->print_user_stmt_list(info
, (struct clast_user_stmt
*) s
);
240 } else if (info
->print_user_stmt
)
241 info
->print_user_stmt(info
, (struct clast_user_stmt
*) s
);
243 print_user_stmt((struct clast_user_stmt
*) s
, info
->dst
,
245 } else if (CLAST_STMT_IS_A(s
, stmt_for
)) {
246 print_for(info
, (struct clast_for
*) s
);
247 } else if (CLAST_STMT_IS_A(s
, stmt_guard
)) {
248 print_guard(info
, (struct clast_guard
*) s
);
255 void gpu_print_host_stmt(struct gpucode_info
*info
, struct clast_stmt
*s
)
260 __isl_give isl_set
*extract_host_domain(struct clast_user_stmt
*u
)
262 return isl_set_from_cloog_domain(cloog_domain_copy(u
->domain
));
265 /* Extract the set of scattering dimension values for which the given
266 * sequence of user statements is executed.
267 * In principle, this set should be the same for each of the user
268 * statements in the sequence, but we compute the union just to be safe.
270 __isl_give isl_set
*extract_entire_host_domain(struct clast_user_stmt
*u
)
272 struct clast_stmt
*s
;
273 isl_set
*host_domain
= NULL
;
275 for (s
= &u
->stmt
; s
; s
= s
->next
) {
278 assert(CLAST_STMT_IS_A(s
, stmt_user
));
279 u
= (struct clast_user_stmt
*) s
;
281 set_i
= extract_host_domain(u
);
286 host_domain
= isl_set_union(host_domain
, set_i
);
290 return isl_set_coalesce(host_domain
);