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
," && ");
164 fprintf(info
->dst
,"(");
165 print_expr(g
->eq
[i
].LHS
, info
->dst
);
166 if (g
->eq
[i
].sign
== 0)
167 fprintf(info
->dst
," == ");
168 else if (g
->eq
[i
].sign
> 0)
169 fprintf(info
->dst
," >= ");
171 fprintf(info
->dst
," <= ");
172 print_expr(g
->eq
[i
].RHS
, info
->dst
);
174 fprintf(info
->dst
,")");
176 fprintf(info
->dst
, ") {\n");
178 print_stmt(info
, g
->then
);
180 print_indent(info
->dst
, info
->indent
);
181 fprintf(info
->dst
, "}\n");
184 static void print_for(struct gpucode_info
*info
, struct clast_for
*f
)
186 assert(f
->LB
&& f
->UB
);
187 print_indent(info
->dst
, info
->indent
);
188 fprintf(info
->dst
, "for (int %s = ", f
->iterator
);
189 print_expr(f
->LB
, info
->dst
);
190 fprintf(info
->dst
, "; %s <= ", f
->iterator
);
191 print_expr(f
->UB
, info
->dst
);
192 fprintf(info
->dst
, "; %s", f
->iterator
);
193 if (cloog_int_is_one(f
->stride
))
194 fprintf(info
->dst
, "++");
196 fprintf(info
->dst
, " += ");
197 cloog_int_print(info
->dst
, f
->stride
);
199 fprintf(info
->dst
, ") {\n");
201 if (info
->print_for_head
)
202 info
->print_for_head(info
, f
);
203 print_stmt(info
, f
->body
);
204 if (info
->print_for_foot
)
205 info
->print_for_foot(info
, f
);
207 print_indent(info
->dst
, info
->indent
);
208 fprintf(info
->dst
, "}\n");
211 static void print_user_stmt(struct clast_user_stmt
*u
, FILE *dst
, int indent
)
213 struct clast_stmt
*t
;
215 print_indent(dst
, indent
);
216 fprintf(dst
, "%s", u
->statement
->name
);
218 for (t
= u
->substitutions
; t
; t
= t
->next
) {
219 assert(CLAST_STMT_IS_A(t
, stmt_ass
));
220 print_expr(((struct clast_assignment
*) t
)->RHS
, dst
);
224 fprintf(dst
, ");\n");
227 static void print_stmt(struct gpucode_info
*info
, struct clast_stmt
*s
)
231 for ( ; s
; s
= s
->next
) {
232 if (CLAST_STMT_IS_A(s
, stmt_root
))
234 if (CLAST_STMT_IS_A(s
, stmt_ass
)) {
235 print_ass((struct clast_assignment
*) s
, info
->dst
, info
->indent
,
238 } else if (CLAST_STMT_IS_A(s
, stmt_user
)) {
239 if (info
->print_user_stmt_list
) {
240 info
->print_user_stmt_list(info
, (struct clast_user_stmt
*) s
);
242 } else if (info
->print_user_stmt
)
243 info
->print_user_stmt(info
, (struct clast_user_stmt
*) s
);
245 print_user_stmt((struct clast_user_stmt
*) s
, info
->dst
,
247 } else if (CLAST_STMT_IS_A(s
, stmt_for
)) {
248 print_for(info
, (struct clast_for
*) s
);
249 } else if (CLAST_STMT_IS_A(s
, stmt_guard
)) {
250 print_guard(info
, (struct clast_guard
*) s
);
257 void gpu_print_host_stmt(struct gpucode_info
*info
, struct clast_stmt
*s
)
262 __isl_give isl_set
*extract_host_domain(struct clast_user_stmt
*u
)
264 return isl_set_from_cloog_domain(cloog_domain_copy(u
->domain
));
267 /* Extract the set of scattering dimension values for which the given
268 * sequence of user statements is executed.
269 * In principle, this set should be the same for each of the user
270 * statements in the sequence, but we compute the union just to be safe.
272 __isl_give isl_set
*extract_entire_host_domain(struct clast_user_stmt
*u
)
274 struct clast_stmt
*s
;
275 isl_set
*host_domain
= NULL
;
277 for (s
= &u
->stmt
; s
; s
= s
->next
) {
280 assert(CLAST_STMT_IS_A(s
, stmt_user
));
281 u
= (struct clast_user_stmt
*) s
;
283 set_i
= extract_host_domain(u
);
288 host_domain
= isl_set_union(host_domain
, set_i
);
292 return isl_set_coalesce(host_domain
);