1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 * LLVM control flow build helpers.
31 * @author Jose Fonseca <jfonseca@vmware.com>
34 #include "util/u_debug.h"
35 #include "util/u_memory.h"
37 #include "lp_bld_type.h"
38 #include "lp_bld_flow.h"
41 #define LP_BUILD_FLOW_MAX_VARIABLES 32
42 #define LP_BUILD_FLOW_MAX_DEPTH 32
45 * Enumeration of all possible flow constructs.
47 enum lp_build_flow_construct_kind
{
55 * Variable declaration scope.
57 struct lp_build_flow_scope
59 /** Number of variables declared in this scope */
60 unsigned num_variables
;
65 * Early exit. Useful to skip to the end of a function or block when
66 * the execution mask becomes zero or when there is an error condition.
68 struct lp_build_flow_skip
70 /** Block to skip to */
71 LLVMBasicBlockRef block
;
73 /** Number of variables declared at the beginning */
74 unsigned num_variables
;
76 LLVMValueRef
*phi
; /**< array [num_variables] */
83 struct lp_build_flow_if
85 unsigned num_variables
;
87 LLVMValueRef
*phi
; /**< array [num_variables] */
89 LLVMValueRef condition
;
90 LLVMBasicBlockRef entry_block
, true_block
, false_block
, merge_block
;
95 * Union of all possible flow constructs' data
97 union lp_build_flow_construct_data
99 struct lp_build_flow_scope scope
;
100 struct lp_build_flow_skip skip
;
101 struct lp_build_flow_if ifthen
;
106 * Element of the flow construct stack.
108 struct lp_build_flow_construct
110 enum lp_build_flow_construct_kind kind
;
111 union lp_build_flow_construct_data data
;
116 * All necessary data to generate LLVM control flow constructs.
118 * Besides keeping track of the control flow construct themselves we also
119 * need to keep track of variables in order to generate SSA Phi values.
121 struct lp_build_flow_context
123 LLVMBuilderRef builder
;
126 * Control flow stack.
128 struct lp_build_flow_construct constructs
[LP_BUILD_FLOW_MAX_DEPTH
];
129 unsigned num_constructs
;
134 LLVMValueRef
*variables
[LP_BUILD_FLOW_MAX_VARIABLES
];
135 unsigned num_variables
;
139 struct lp_build_flow_context
*
140 lp_build_flow_create(LLVMBuilderRef builder
)
142 struct lp_build_flow_context
*flow
;
144 flow
= CALLOC_STRUCT(lp_build_flow_context
);
148 flow
->builder
= builder
;
155 lp_build_flow_destroy(struct lp_build_flow_context
*flow
)
157 assert(flow
->num_constructs
== 0);
158 assert(flow
->num_variables
== 0);
164 * Begin/push a new flow control construct, such as a loop, skip block
167 static union lp_build_flow_construct_data
*
168 lp_build_flow_push(struct lp_build_flow_context
*flow
,
169 enum lp_build_flow_construct_kind kind
)
171 assert(flow
->num_constructs
< LP_BUILD_FLOW_MAX_DEPTH
);
172 if(flow
->num_constructs
>= LP_BUILD_FLOW_MAX_DEPTH
)
175 flow
->constructs
[flow
->num_constructs
].kind
= kind
;
176 return &flow
->constructs
[flow
->num_constructs
++].data
;
181 * Return the current/top flow control construct on the stack.
182 * \param kind the expected type of the top-most construct
184 static union lp_build_flow_construct_data
*
185 lp_build_flow_peek(struct lp_build_flow_context
*flow
,
186 enum lp_build_flow_construct_kind kind
)
188 assert(flow
->num_constructs
);
189 if(!flow
->num_constructs
)
192 assert(flow
->constructs
[flow
->num_constructs
- 1].kind
== kind
);
193 if(flow
->constructs
[flow
->num_constructs
- 1].kind
!= kind
)
196 return &flow
->constructs
[flow
->num_constructs
- 1].data
;
201 * End/pop the current/top flow control construct on the stack.
202 * \param kind the expected type of the top-most construct
204 static union lp_build_flow_construct_data
*
205 lp_build_flow_pop(struct lp_build_flow_context
*flow
,
206 enum lp_build_flow_construct_kind kind
)
208 assert(flow
->num_constructs
);
209 if(!flow
->num_constructs
)
212 assert(flow
->constructs
[flow
->num_constructs
- 1].kind
== kind
);
213 if(flow
->constructs
[flow
->num_constructs
- 1].kind
!= kind
)
216 return &flow
->constructs
[--flow
->num_constructs
].data
;
221 * Begin a variable scope.
226 lp_build_flow_scope_begin(struct lp_build_flow_context
*flow
)
228 struct lp_build_flow_scope
*scope
;
230 scope
= &lp_build_flow_push(flow
, LP_BUILD_FLOW_SCOPE
)->scope
;
234 scope
->num_variables
= 0;
239 * Declare a variable.
241 * A variable is a named entity which can have different LLVMValueRef's at
242 * different points of the program. This is relevant for control flow because
243 * when there are multiple branches to a same location we need to replace
244 * the variable's value with a Phi function as explained in
245 * http://en.wikipedia.org/wiki/Static_single_assignment_form .
247 * We keep track of variables by keeping around a pointer to where they're
250 * There are a few cautions to observe:
252 * - Variable's value must not be NULL. If there is no initial value then
253 * LLVMGetUndef() should be used.
255 * - Variable's value must be kept up-to-date. If the variable is going to be
256 * modified by a function then a pointer should be passed so that its value
257 * is accurate. Failure to do this will cause some of the variables'
258 * transient values to be lost, leading to wrong results.
260 * - A program should be written from top to bottom, by always appending
261 * instructions to the bottom with a single LLVMBuilderRef. Inserting and/or
262 * modifying existing statements will most likely lead to wrong results.
266 lp_build_flow_scope_declare(struct lp_build_flow_context
*flow
,
267 LLVMValueRef
*variable
)
269 struct lp_build_flow_scope
*scope
;
271 scope
= &lp_build_flow_peek(flow
, LP_BUILD_FLOW_SCOPE
)->scope
;
279 assert(flow
->num_variables
< LP_BUILD_FLOW_MAX_VARIABLES
);
280 if(flow
->num_variables
>= LP_BUILD_FLOW_MAX_VARIABLES
)
283 flow
->variables
[flow
->num_variables
++] = variable
;
284 ++scope
->num_variables
;
289 lp_build_flow_scope_end(struct lp_build_flow_context
*flow
)
291 struct lp_build_flow_scope
*scope
;
293 scope
= &lp_build_flow_pop(flow
, LP_BUILD_FLOW_SCOPE
)->scope
;
297 assert(flow
->num_variables
>= scope
->num_variables
);
298 if(flow
->num_variables
< scope
->num_variables
) {
299 flow
->num_variables
= 0;
303 flow
->num_variables
-= scope
->num_variables
;
308 * Note: this function has no dependencies on the flow code and could
312 lp_build_insert_new_block(LLVMBuilderRef builder
, const char *name
)
314 LLVMBasicBlockRef current_block
;
315 LLVMBasicBlockRef next_block
;
316 LLVMBasicBlockRef new_block
;
318 /* get current basic block */
319 current_block
= LLVMGetInsertBlock(builder
);
321 /* check if there's another block after this one */
322 next_block
= LLVMGetNextBasicBlock(current_block
);
324 /* insert the new block before the next block */
325 new_block
= LLVMInsertBasicBlock(next_block
, name
);
328 /* append new block after current block */
329 LLVMValueRef function
= LLVMGetBasicBlockParent(current_block
);
330 new_block
= LLVMAppendBasicBlock(function
, name
);
337 static LLVMBasicBlockRef
338 lp_build_flow_insert_block(struct lp_build_flow_context
*flow
)
340 return lp_build_insert_new_block(flow
->builder
, "");
345 * Begin a "skip" block. Inside this block we can test a condition and
346 * skip to the end of the block if the condition is false.
349 lp_build_flow_skip_begin(struct lp_build_flow_context
*flow
)
351 struct lp_build_flow_skip
*skip
;
352 LLVMBuilderRef builder
;
355 skip
= &lp_build_flow_push(flow
, LP_BUILD_FLOW_SKIP
)->skip
;
359 /* create new basic block */
360 skip
->block
= lp_build_flow_insert_block(flow
);
362 skip
->num_variables
= flow
->num_variables
;
363 if(!skip
->num_variables
) {
368 /* Allocate a Phi node for each variable in this skip scope */
369 skip
->phi
= MALLOC(skip
->num_variables
* sizeof *skip
->phi
);
371 skip
->num_variables
= 0;
375 builder
= LLVMCreateBuilder();
376 LLVMPositionBuilderAtEnd(builder
, skip
->block
);
378 /* create a Phi node for each variable */
379 for(i
= 0; i
< skip
->num_variables
; ++i
)
380 skip
->phi
[i
] = LLVMBuildPhi(builder
, LLVMTypeOf(*flow
->variables
[i
]), "");
382 LLVMDisposeBuilder(builder
);
387 * Insert code to test a condition and branch to the end of the current
388 * skip block if the condition is true.
391 lp_build_flow_skip_cond_break(struct lp_build_flow_context
*flow
,
394 struct lp_build_flow_skip
*skip
;
395 LLVMBasicBlockRef current_block
;
396 LLVMBasicBlockRef new_block
;
399 skip
= &lp_build_flow_peek(flow
, LP_BUILD_FLOW_SKIP
)->skip
;
403 current_block
= LLVMGetInsertBlock(flow
->builder
);
405 new_block
= lp_build_flow_insert_block(flow
);
407 /* for each variable, update the Phi node with a (variable, block) pair */
408 for(i
= 0; i
< skip
->num_variables
; ++i
) {
409 assert(*flow
->variables
[i
]);
410 LLVMAddIncoming(skip
->phi
[i
], flow
->variables
[i
], ¤t_block
, 1);
413 /* if cond is true, goto skip->block, else goto new_block */
414 LLVMBuildCondBr(flow
->builder
, cond
, skip
->block
, new_block
);
416 LLVMPositionBuilderAtEnd(flow
->builder
, new_block
);
421 lp_build_flow_skip_end(struct lp_build_flow_context
*flow
)
423 struct lp_build_flow_skip
*skip
;
424 LLVMBasicBlockRef current_block
;
427 skip
= &lp_build_flow_pop(flow
, LP_BUILD_FLOW_SKIP
)->skip
;
431 current_block
= LLVMGetInsertBlock(flow
->builder
);
433 /* add (variable, block) tuples to the phi nodes */
434 for(i
= 0; i
< skip
->num_variables
; ++i
) {
435 assert(*flow
->variables
[i
]);
436 LLVMAddIncoming(skip
->phi
[i
], flow
->variables
[i
], ¤t_block
, 1);
437 *flow
->variables
[i
] = skip
->phi
[i
];
441 LLVMBuildBr(flow
->builder
, skip
->block
);
442 LLVMPositionBuilderAtEnd(flow
->builder
, skip
->block
);
449 * Check if the mask predicate is zero. If so, jump to the end of the block.
452 lp_build_mask_check(struct lp_build_mask_context
*mask
)
454 LLVMBuilderRef builder
= mask
->flow
->builder
;
457 /* cond = (mask == 0) */
458 cond
= LLVMBuildICmp(builder
,
460 LLVMBuildBitCast(builder
, mask
->value
, mask
->reg_type
, ""),
461 LLVMConstNull(mask
->reg_type
),
464 /* if cond, goto end of block */
465 lp_build_flow_skip_cond_break(mask
->flow
, cond
);
470 * Begin a section of code which is predicated on a mask.
471 * \param mask the mask context, initialized here
472 * \param flow the flow context
473 * \param type the type of the mask
474 * \param value storage for the mask
477 lp_build_mask_begin(struct lp_build_mask_context
*mask
,
478 struct lp_build_flow_context
*flow
,
482 memset(mask
, 0, sizeof *mask
);
485 mask
->reg_type
= LLVMIntType(type
.width
* type
.length
);
488 lp_build_flow_scope_begin(flow
);
489 lp_build_flow_scope_declare(flow
, &mask
->value
);
490 lp_build_flow_skip_begin(flow
);
492 lp_build_mask_check(mask
);
497 * Update boolean mask with given value (bitwise AND).
498 * Typically used to update the quad's pixel alive/killed mask
499 * after depth testing, alpha testing, TGSI_OPCODE_KIL, etc.
502 lp_build_mask_update(struct lp_build_mask_context
*mask
,
505 mask
->value
= LLVMBuildAnd( mask
->flow
->builder
, mask
->value
, value
, "");
507 lp_build_mask_check(mask
);
512 * End section of code which is predicated on a mask.
515 lp_build_mask_end(struct lp_build_mask_context
*mask
)
517 lp_build_flow_skip_end(mask
->flow
);
518 lp_build_flow_scope_end(mask
->flow
);
525 lp_build_loop_begin(LLVMBuilderRef builder
,
527 struct lp_build_loop_state
*state
)
529 LLVMBasicBlockRef block
= LLVMGetInsertBlock(builder
);
530 LLVMValueRef function
= LLVMGetBasicBlockParent(block
);
532 state
->block
= LLVMAppendBasicBlock(function
, "loop");
534 LLVMBuildBr(builder
, state
->block
);
536 LLVMPositionBuilderAtEnd(builder
, state
->block
);
538 state
->counter
= LLVMBuildPhi(builder
, LLVMTypeOf(start
), "");
540 LLVMAddIncoming(state
->counter
, &start
, &block
, 1);
546 lp_build_loop_end(LLVMBuilderRef builder
,
549 struct lp_build_loop_state
*state
)
551 LLVMBasicBlockRef block
= LLVMGetInsertBlock(builder
);
552 LLVMValueRef function
= LLVMGetBasicBlockParent(block
);
555 LLVMBasicBlockRef after_block
;
558 step
= LLVMConstInt(LLVMTypeOf(end
), 1, 0);
560 next
= LLVMBuildAdd(builder
, state
->counter
, step
, "");
562 cond
= LLVMBuildICmp(builder
, LLVMIntNE
, next
, end
, "");
564 after_block
= LLVMAppendBasicBlock(function
, "");
566 LLVMBuildCondBr(builder
, cond
, after_block
, state
->block
);
568 LLVMAddIncoming(state
->counter
, &next
, &block
, 1);
570 LLVMPositionBuilderAtEnd(builder
, after_block
);
576 Example of if/then/else building:
588 LLVMValueRef x = LLVMGetUndef(); // or something else
590 flow = lp_build_flow_create(builder);
592 lp_build_flow_scope_begin(flow);
594 // x needs a phi node
595 lp_build_flow_scope_declare(flow, &x);
597 lp_build_if(ctx, flow, builder, cond);
603 lp_build_flow_scope_end(flow);
605 lp_build_flow_destroy(flow);
611 * Begin an if/else/endif construct.
614 lp_build_if(struct lp_build_if_state
*ctx
,
615 struct lp_build_flow_context
*flow
,
616 LLVMBuilderRef builder
,
617 LLVMValueRef condition
)
619 LLVMBasicBlockRef block
= LLVMGetInsertBlock(builder
);
620 struct lp_build_flow_if
*ifthen
;
623 memset(ctx
, 0, sizeof(*ctx
));
624 ctx
->builder
= builder
;
627 /* push/create new scope */
628 ifthen
= &lp_build_flow_push(flow
, LP_BUILD_FLOW_IF
)->ifthen
;
631 ifthen
->num_variables
= flow
->num_variables
;
632 ifthen
->condition
= condition
;
633 ifthen
->entry_block
= block
;
635 /* create a Phi node for each variable in this flow scope */
636 ifthen
->phi
= MALLOC(ifthen
->num_variables
* sizeof(*ifthen
->phi
));
638 ifthen
->num_variables
= 0;
642 /* create endif/merge basic block for the phi functions */
643 ifthen
->merge_block
= lp_build_insert_new_block(builder
, "endif-block");
644 LLVMPositionBuilderAtEnd(builder
, ifthen
->merge_block
);
646 /* create a phi node for each variable */
647 for (i
= 0; i
< flow
->num_variables
; i
++) {
648 ifthen
->phi
[i
] = LLVMBuildPhi(builder
, LLVMTypeOf(*flow
->variables
[i
]), "");
650 /* add add the initial value of the var from the entry block */
651 if (!LLVMIsUndef(*flow
->variables
[i
]))
652 LLVMAddIncoming(ifthen
->phi
[i
], flow
->variables
[i
],
653 &ifthen
->entry_block
, 1);
656 /* create/insert true_block before merge_block */
657 ifthen
->true_block
= LLVMInsertBasicBlock(ifthen
->merge_block
, "if-true-block");
659 /* successive code goes into the true block */
660 LLVMPositionBuilderAtEnd(builder
, ifthen
->true_block
);
665 * Begin else-part of a conditional
668 lp_build_else(struct lp_build_if_state
*ctx
)
670 struct lp_build_flow_context
*flow
= ctx
->flow
;
671 struct lp_build_flow_if
*ifthen
;
674 ifthen
= &lp_build_flow_peek(flow
, LP_BUILD_FLOW_IF
)->ifthen
;
677 /* for each variable, update the Phi node with a (variable, block) pair */
678 LLVMPositionBuilderAtEnd(ctx
->builder
, ifthen
->merge_block
);
679 for (i
= 0; i
< flow
->num_variables
; i
++) {
680 assert(*flow
->variables
[i
]);
681 LLVMAddIncoming(ifthen
->phi
[i
], flow
->variables
[i
], &ifthen
->true_block
, 1);
684 /* create/insert false_block before the merge block */
685 ifthen
->false_block
= LLVMInsertBasicBlock(ifthen
->merge_block
, "if-false-block");
687 /* successive code goes into the else block */
688 LLVMPositionBuilderAtEnd(ctx
->builder
, ifthen
->false_block
);
696 lp_build_endif(struct lp_build_if_state
*ctx
)
698 struct lp_build_flow_context
*flow
= ctx
->flow
;
699 struct lp_build_flow_if
*ifthen
;
700 LLVMBasicBlockRef curBlock
= LLVMGetInsertBlock(ctx
->builder
);
703 ifthen
= &lp_build_flow_pop(flow
, LP_BUILD_FLOW_IF
)->ifthen
;
706 /* Insert branch to the merge block from current block */
707 LLVMBuildBr(ctx
->builder
, ifthen
->merge_block
);
709 if (ifthen
->false_block
) {
710 LLVMPositionBuilderAtEnd(ctx
->builder
, ifthen
->merge_block
);
711 /* for each variable, update the Phi node with a (variable, block) pair */
712 for (i
= 0; i
< flow
->num_variables
; i
++) {
713 assert(*flow
->variables
[i
]);
714 LLVMAddIncoming(ifthen
->phi
[i
], flow
->variables
[i
], &curBlock
, 1);
715 /* replace the variable ref with the phi function */
716 *flow
->variables
[i
] = ifthen
->phi
[i
];
721 LLVMPositionBuilderAtEnd(ctx
->builder
, ifthen
->merge_block
);
722 for (i
= 0; i
< flow
->num_variables
; i
++) {
723 assert(*flow
->variables
[i
]);
724 LLVMAddIncoming(ifthen
->phi
[i
], flow
->variables
[i
], &ifthen
->true_block
, 1);
726 /* replace the variable ref with the phi function */
727 *flow
->variables
[i
] = ifthen
->phi
[i
];
734 *** Now patch in the various branch instructions.
737 /* Insert the conditional branch instruction at the end of entry_block */
738 LLVMPositionBuilderAtEnd(ctx
->builder
, ifthen
->entry_block
);
739 if (ifthen
->false_block
) {
740 /* we have an else clause */
741 LLVMBuildCondBr(ctx
->builder
, ifthen
->condition
,
742 ifthen
->true_block
, ifthen
->false_block
);
746 LLVMBuildCondBr(ctx
->builder
, ifthen
->condition
,
747 ifthen
->true_block
, ifthen
->merge_block
);
750 /* Insert branch from end of true_block to merge_block */
751 if (ifthen
->false_block
) {
752 /* Append an unconditional Br(anch) instruction on the true_block */
753 LLVMPositionBuilderAtEnd(ctx
->builder
, ifthen
->true_block
);
754 LLVMBuildBr(ctx
->builder
, ifthen
->merge_block
);
758 * Note that we've already inserted the branch at the end of
759 * true_block. See the very first LLVMBuildBr() call in this function.
763 /* Resume building code at end of the ifthen->merge_block */
764 LLVMPositionBuilderAtEnd(ctx
->builder
, ifthen
->merge_block
);