1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
4 * Copyright 2007-2008 VMware, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
29 #include "util/u_memory.h"
30 #include "lp_bld_type.h"
31 #include "lp_bld_init.h"
32 #include "lp_bld_flow.h"
33 #include "lp_bld_ir_common.h"
34 #include "lp_bld_logic.h"
37 * Return the context for the current function.
38 * (always 'main', if shader doesn't do any function calls)
40 static inline struct function_ctx
*
41 func_ctx(struct lp_exec_mask
*mask
)
43 assert(mask
->function_stack_size
> 0);
44 assert(mask
->function_stack_size
<= LP_MAX_NUM_FUNCS
);
45 return &mask
->function_stack
[mask
->function_stack_size
- 1];
49 * Returns true if we're in a loop.
50 * It's global, meaning that it returns true even if there's
51 * no loop inside the current function, but we were inside
52 * a loop inside another function, from which this one was called.
55 mask_has_loop(struct lp_exec_mask
*mask
)
58 for (i
= mask
->function_stack_size
- 1; i
>= 0; --i
) {
59 const struct function_ctx
*ctx
= &mask
->function_stack
[i
];
60 if (ctx
->loop_stack_size
> 0)
67 * Returns true if we're inside a switch statement.
68 * It's global, meaning that it returns true even if there's
69 * no switch in the current function, but we were inside
70 * a switch inside another function, from which this one was called.
73 mask_has_switch(struct lp_exec_mask
*mask
)
76 for (i
= mask
->function_stack_size
- 1; i
>= 0; --i
) {
77 const struct function_ctx
*ctx
= &mask
->function_stack
[i
];
78 if (ctx
->switch_stack_size
> 0)
85 * Returns true if we're inside a conditional.
86 * It's global, meaning that it returns true even if there's
87 * no conditional in the current function, but we were inside
88 * a conditional inside another function, from which this one was called.
91 mask_has_cond(struct lp_exec_mask
*mask
)
94 for (i
= mask
->function_stack_size
- 1; i
>= 0; --i
) {
95 const struct function_ctx
*ctx
= &mask
->function_stack
[i
];
96 if (ctx
->cond_stack_size
> 0)
102 void lp_exec_mask_update(struct lp_exec_mask
*mask
)
104 LLVMBuilderRef builder
= mask
->bld
->gallivm
->builder
;
105 boolean has_loop_mask
= mask_has_loop(mask
);
106 boolean has_cond_mask
= mask_has_cond(mask
);
107 boolean has_switch_mask
= mask_has_switch(mask
);
108 boolean has_ret_mask
= mask
->function_stack_size
> 1 ||
112 /*for loops we need to update the entire mask at runtime */
114 assert(mask
->break_mask
);
115 tmp
= LLVMBuildAnd(builder
,
119 mask
->exec_mask
= LLVMBuildAnd(builder
,
124 mask
->exec_mask
= mask
->cond_mask
;
126 if (has_switch_mask
) {
127 mask
->exec_mask
= LLVMBuildAnd(builder
,
134 mask
->exec_mask
= LLVMBuildAnd(builder
,
140 mask
->has_mask
= (has_cond_mask
||
147 * Initialize a function context at the specified index.
150 lp_exec_mask_function_init(struct lp_exec_mask
*mask
, int function_idx
)
152 LLVMTypeRef int_type
= LLVMInt32TypeInContext(mask
->bld
->gallivm
->context
);
153 LLVMBuilderRef builder
= mask
->bld
->gallivm
->builder
;
154 struct function_ctx
*ctx
= &mask
->function_stack
[function_idx
];
156 ctx
->cond_stack_size
= 0;
157 ctx
->loop_stack_size
= 0;
158 ctx
->bgnloop_stack_size
= 0;
159 ctx
->switch_stack_size
= 0;
161 if (function_idx
== 0) {
162 ctx
->ret_mask
= mask
->ret_mask
;
165 ctx
->loop_limiter
= lp_build_alloca(mask
->bld
->gallivm
,
166 int_type
, "looplimiter");
169 LLVMConstInt(int_type
, LP_MAX_TGSI_LOOP_ITERATIONS
, false),
173 void lp_exec_mask_init(struct lp_exec_mask
*mask
, struct lp_build_context
*bld
)
176 mask
->has_mask
= FALSE
;
177 mask
->ret_in_main
= FALSE
;
178 /* For the main function */
179 mask
->function_stack_size
= 1;
181 mask
->int_vec_type
= lp_build_int_vec_type(bld
->gallivm
, mask
->bld
->type
);
182 mask
->exec_mask
= mask
->ret_mask
= mask
->break_mask
= mask
->cont_mask
=
183 mask
->cond_mask
= mask
->switch_mask
=
184 LLVMConstAllOnes(mask
->int_vec_type
);
186 mask
->function_stack
= CALLOC(LP_MAX_NUM_FUNCS
,
187 sizeof(mask
->function_stack
[0]));
188 lp_exec_mask_function_init(mask
, 0);
192 lp_exec_mask_fini(struct lp_exec_mask
*mask
)
194 FREE(mask
->function_stack
);
197 /* stores val into an address pointed to by dst_ptr.
198 * mask->exec_mask is used to figure out which bits of val
199 * should be stored into the address
200 * (0 means don't store this bit, 1 means do store).
202 void lp_exec_mask_store(struct lp_exec_mask
*mask
,
203 struct lp_build_context
*bld_store
,
205 LLVMValueRef dst_ptr
)
207 LLVMBuilderRef builder
= mask
->bld
->gallivm
->builder
;
208 LLVMValueRef exec_mask
= mask
->has_mask
? mask
->exec_mask
: NULL
;
210 assert(lp_check_value(bld_store
->type
, val
));
211 assert(LLVMGetTypeKind(LLVMTypeOf(dst_ptr
)) == LLVMPointerTypeKind
);
212 assert(LLVMGetElementType(LLVMTypeOf(dst_ptr
)) == LLVMTypeOf(val
) ||
213 LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(dst_ptr
))) == LLVMArrayTypeKind
);
216 LLVMValueRef res
, dst
;
218 dst
= LLVMBuildLoad(builder
, dst_ptr
, "");
219 res
= lp_build_select(bld_store
, exec_mask
, val
, dst
);
220 LLVMBuildStore(builder
, res
, dst_ptr
);
222 LLVMBuildStore(builder
, val
, dst_ptr
);
225 void lp_exec_bgnloop_post_phi(struct lp_exec_mask
*mask
)
227 LLVMBuilderRef builder
= mask
->bld
->gallivm
->builder
;
228 struct function_ctx
*ctx
= func_ctx(mask
);
230 if (ctx
->loop_stack_size
!= ctx
->bgnloop_stack_size
) {
231 mask
->break_mask
= LLVMBuildLoad(builder
, ctx
->break_var
, "");
232 lp_exec_mask_update(mask
);
233 ctx
->bgnloop_stack_size
= ctx
->loop_stack_size
;
237 void lp_exec_bgnloop(struct lp_exec_mask
*mask
, bool load
)
239 LLVMBuilderRef builder
= mask
->bld
->gallivm
->builder
;
240 struct function_ctx
*ctx
= func_ctx(mask
);
242 if (ctx
->loop_stack_size
>= LP_MAX_TGSI_NESTING
) {
243 ++ctx
->loop_stack_size
;
247 ctx
->break_type_stack
[ctx
->loop_stack_size
+ ctx
->switch_stack_size
] =
249 ctx
->break_type
= LP_EXEC_MASK_BREAK_TYPE_LOOP
;
251 ctx
->loop_stack
[ctx
->loop_stack_size
].loop_block
= ctx
->loop_block
;
252 ctx
->loop_stack
[ctx
->loop_stack_size
].cont_mask
= mask
->cont_mask
;
253 ctx
->loop_stack
[ctx
->loop_stack_size
].break_mask
= mask
->break_mask
;
254 ctx
->loop_stack
[ctx
->loop_stack_size
].break_var
= ctx
->break_var
;
255 ++ctx
->loop_stack_size
;
257 ctx
->break_var
= lp_build_alloca(mask
->bld
->gallivm
, mask
->int_vec_type
, "");
258 LLVMBuildStore(builder
, mask
->break_mask
, ctx
->break_var
);
260 ctx
->loop_block
= lp_build_insert_new_block(mask
->bld
->gallivm
, "bgnloop");
262 LLVMBuildBr(builder
, ctx
->loop_block
);
263 LLVMPositionBuilderAtEnd(builder
, ctx
->loop_block
);
266 lp_exec_bgnloop_post_phi(mask
);
270 void lp_exec_endloop(struct gallivm_state
*gallivm
,
271 struct lp_exec_mask
*mask
)
273 LLVMBuilderRef builder
= mask
->bld
->gallivm
->builder
;
274 struct function_ctx
*ctx
= func_ctx(mask
);
275 LLVMBasicBlockRef endloop
;
276 LLVMTypeRef int_type
= LLVMInt32TypeInContext(mask
->bld
->gallivm
->context
);
277 LLVMTypeRef reg_type
= LLVMIntTypeInContext(gallivm
->context
,
278 mask
->bld
->type
.width
*
279 mask
->bld
->type
.length
);
280 LLVMValueRef i1cond
, i2cond
, icond
, limiter
;
282 assert(mask
->break_mask
);
284 assert(ctx
->loop_stack_size
);
285 if (ctx
->loop_stack_size
> LP_MAX_TGSI_NESTING
) {
286 --ctx
->loop_stack_size
;
287 --ctx
->bgnloop_stack_size
;
292 * Restore the cont_mask, but don't pop
294 mask
->cont_mask
= ctx
->loop_stack
[ctx
->loop_stack_size
- 1].cont_mask
;
295 lp_exec_mask_update(mask
);
298 * Unlike the continue mask, the break_mask must be preserved across loop
301 LLVMBuildStore(builder
, mask
->break_mask
, ctx
->break_var
);
303 /* Decrement the loop limiter */
304 limiter
= LLVMBuildLoad(builder
, ctx
->loop_limiter
, "");
306 limiter
= LLVMBuildSub(
309 LLVMConstInt(int_type
, 1, false),
312 LLVMBuildStore(builder
, limiter
, ctx
->loop_limiter
);
314 /* i1cond = (mask != 0) */
315 i1cond
= LLVMBuildICmp(
318 LLVMBuildBitCast(builder
, mask
->exec_mask
, reg_type
, ""),
319 LLVMConstNull(reg_type
), "i1cond");
321 /* i2cond = (looplimiter > 0) */
322 i2cond
= LLVMBuildICmp(
326 LLVMConstNull(int_type
), "i2cond");
328 /* if( i1cond && i2cond ) */
329 icond
= LLVMBuildAnd(builder
, i1cond
, i2cond
, "");
331 endloop
= lp_build_insert_new_block(mask
->bld
->gallivm
, "endloop");
333 LLVMBuildCondBr(builder
,
334 icond
, ctx
->loop_block
, endloop
);
336 LLVMPositionBuilderAtEnd(builder
, endloop
);
338 assert(ctx
->loop_stack_size
);
339 --ctx
->loop_stack_size
;
340 --ctx
->bgnloop_stack_size
;
341 mask
->cont_mask
= ctx
->loop_stack
[ctx
->loop_stack_size
].cont_mask
;
342 mask
->break_mask
= ctx
->loop_stack
[ctx
->loop_stack_size
].break_mask
;
343 ctx
->loop_block
= ctx
->loop_stack
[ctx
->loop_stack_size
].loop_block
;
344 ctx
->break_var
= ctx
->loop_stack
[ctx
->loop_stack_size
].break_var
;
345 ctx
->break_type
= ctx
->break_type_stack
[ctx
->loop_stack_size
+
346 ctx
->switch_stack_size
];
348 lp_exec_mask_update(mask
);
351 void lp_exec_mask_cond_push(struct lp_exec_mask
*mask
,
354 LLVMBuilderRef builder
= mask
->bld
->gallivm
->builder
;
355 struct function_ctx
*ctx
= func_ctx(mask
);
357 if (ctx
->cond_stack_size
>= LP_MAX_TGSI_NESTING
) {
358 ctx
->cond_stack_size
++;
361 if (ctx
->cond_stack_size
== 0 && mask
->function_stack_size
== 1) {
362 assert(mask
->cond_mask
== LLVMConstAllOnes(mask
->int_vec_type
));
364 ctx
->cond_stack
[ctx
->cond_stack_size
++] = mask
->cond_mask
;
365 assert(LLVMTypeOf(val
) == mask
->int_vec_type
);
366 mask
->cond_mask
= LLVMBuildAnd(builder
,
370 lp_exec_mask_update(mask
);
373 void lp_exec_mask_cond_invert(struct lp_exec_mask
*mask
)
375 LLVMBuilderRef builder
= mask
->bld
->gallivm
->builder
;
376 struct function_ctx
*ctx
= func_ctx(mask
);
377 LLVMValueRef prev_mask
;
378 LLVMValueRef inv_mask
;
380 assert(ctx
->cond_stack_size
);
381 if (ctx
->cond_stack_size
>= LP_MAX_TGSI_NESTING
)
383 prev_mask
= ctx
->cond_stack
[ctx
->cond_stack_size
- 1];
384 if (ctx
->cond_stack_size
== 1 && mask
->function_stack_size
== 1) {
385 assert(prev_mask
== LLVMConstAllOnes(mask
->int_vec_type
));
388 inv_mask
= LLVMBuildNot(builder
, mask
->cond_mask
, "");
390 mask
->cond_mask
= LLVMBuildAnd(builder
,
393 lp_exec_mask_update(mask
);
396 void lp_exec_mask_cond_pop(struct lp_exec_mask
*mask
)
398 struct function_ctx
*ctx
= func_ctx(mask
);
399 assert(ctx
->cond_stack_size
);
400 --ctx
->cond_stack_size
;
401 if (ctx
->cond_stack_size
>= LP_MAX_TGSI_NESTING
)
403 mask
->cond_mask
= ctx
->cond_stack
[ctx
->cond_stack_size
];
404 lp_exec_mask_update(mask
);
408 void lp_exec_continue(struct lp_exec_mask
*mask
)
410 LLVMBuilderRef builder
= mask
->bld
->gallivm
->builder
;
411 LLVMValueRef exec_mask
= LLVMBuildNot(builder
,
415 mask
->cont_mask
= LLVMBuildAnd(builder
,
419 lp_exec_mask_update(mask
);
422 void lp_exec_break(struct lp_exec_mask
*mask
, int *pc
,
425 LLVMBuilderRef builder
= mask
->bld
->gallivm
->builder
;
426 struct function_ctx
*ctx
= func_ctx(mask
);
428 if (ctx
->break_type
== LP_EXEC_MASK_BREAK_TYPE_LOOP
) {
429 LLVMValueRef exec_mask
= LLVMBuildNot(builder
,
433 mask
->break_mask
= LLVMBuildAnd(builder
,
435 exec_mask
, "break_full");
438 if (ctx
->switch_in_default
) {
440 * stop default execution but only if this is an unconditional switch.
441 * (The condition here is not perfect since dead code after break is
442 * allowed but should be sufficient since false negatives are just
443 * unoptimized - so we don't have to pre-evaluate that).
445 if(break_always
&& ctx
->switch_pc
) {
447 *pc
= ctx
->switch_pc
;
453 mask
->switch_mask
= LLVMConstNull(mask
->bld
->int_vec_type
);
456 LLVMValueRef exec_mask
= LLVMBuildNot(builder
,
459 mask
->switch_mask
= LLVMBuildAnd(builder
,
461 exec_mask
, "break_switch");
465 lp_exec_mask_update(mask
);