• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2009 VMware, Inc.
4  * All Rights Reserved.
5  *
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:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
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.
25  *
26  **************************************************************************/
27 
28 /**
29  * LLVM control flow build helpers.
30  *
31  * @author Jose Fonseca <jfonseca@vmware.com>
32  */
33 
34 #include "util/u_debug.h"
35 #include "util/u_memory.h"
36 
37 #include "lp_bld_init.h"
38 #include "lp_bld_type.h"
39 #include "lp_bld_flow.h"
40 
41 
42 /**
43  * Insert a new block, right where builder is pointing to.
44  *
45  * This is useful important not only for aesthetic reasons, but also for
46  * performance reasons, as frequently run blocks should be laid out next to
47  * each other and fall-throughs maximized.
48  *
49  * See also llvm/lib/Transforms/Scalar/BasicBlockPlacement.cpp.
50  *
51  * Note: this function has no dependencies on the flow code and could
52  * be used elsewhere.
53  */
54 LLVMBasicBlockRef
lp_build_insert_new_block(struct gallivm_state * gallivm,const char * name)55 lp_build_insert_new_block(struct gallivm_state *gallivm, const char *name)
56 {
57    LLVMBasicBlockRef current_block;
58    LLVMBasicBlockRef next_block;
59    LLVMBasicBlockRef new_block;
60 
61    /* get current basic block */
62    current_block = LLVMGetInsertBlock(gallivm->builder);
63 
64    /* check if there's another block after this one */
65    next_block = LLVMGetNextBasicBlock(current_block);
66    if (next_block) {
67       /* insert the new block before the next block */
68       new_block = LLVMInsertBasicBlockInContext(gallivm->context, next_block, name);
69    }
70    else {
71       /* append new block after current block */
72       LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
73       new_block = LLVMAppendBasicBlockInContext(gallivm->context, function, name);
74    }
75 
76    return new_block;
77 }
78 
79 
80 /**
81  * Begin a "skip" block.  Inside this block we can test a condition and
82  * skip to the end of the block if the condition is false.
83  */
84 void
lp_build_flow_skip_begin(struct lp_build_skip_context * skip,struct gallivm_state * gallivm)85 lp_build_flow_skip_begin(struct lp_build_skip_context *skip,
86                          struct gallivm_state *gallivm)
87 {
88    skip->gallivm = gallivm;
89    /* create new basic block */
90    skip->block = lp_build_insert_new_block(gallivm, "skip");
91 }
92 
93 
94 /**
95  * Insert code to test a condition and branch to the end of the current
96  * skip block if the condition is true.
97  */
98 void
lp_build_flow_skip_cond_break(struct lp_build_skip_context * skip,LLVMValueRef cond)99 lp_build_flow_skip_cond_break(struct lp_build_skip_context *skip,
100                               LLVMValueRef cond)
101 {
102    LLVMBasicBlockRef new_block;
103 
104    new_block = lp_build_insert_new_block(skip->gallivm, "");
105 
106    /* if cond is true, goto skip->block, else goto new_block */
107    LLVMBuildCondBr(skip->gallivm->builder, cond, skip->block, new_block);
108 
109    LLVMPositionBuilderAtEnd(skip->gallivm->builder, new_block);
110 }
111 
112 
113 void
lp_build_flow_skip_end(struct lp_build_skip_context * skip)114 lp_build_flow_skip_end(struct lp_build_skip_context *skip)
115 {
116    /* goto block */
117    LLVMBuildBr(skip->gallivm->builder, skip->block);
118    LLVMPositionBuilderAtEnd(skip->gallivm->builder, skip->block);
119 }
120 
121 
122 /**
123  * Check if the mask predicate is zero.  If so, jump to the end of the block.
124  */
125 void
lp_build_mask_check(struct lp_build_mask_context * mask)126 lp_build_mask_check(struct lp_build_mask_context *mask)
127 {
128    LLVMBuilderRef builder = mask->skip.gallivm->builder;
129    LLVMValueRef value;
130    LLVMValueRef cond;
131 
132    value = lp_build_mask_value(mask);
133 
134    /*
135     * XXX this doesn't quite generate the most efficient code possible, if
136     * the masks are vectors which have all bits set to the same value
137     * in each element.
138     * movmskps/pmovmskb would be more efficient to get the required value
139     * into ordinary reg (certainly with 8 floats).
140     * Not sure if llvm could figure that out on its own.
141     */
142 
143    /* cond = (mask == 0) */
144    cond = LLVMBuildICmp(builder,
145                         LLVMIntEQ,
146                         LLVMBuildBitCast(builder, value, mask->reg_type, ""),
147                         LLVMConstNull(mask->reg_type),
148                         "");
149 
150    /* if cond, goto end of block */
151    lp_build_flow_skip_cond_break(&mask->skip, cond);
152 }
153 
154 
155 /**
156  * Begin a section of code which is predicated on a mask.
157  * \param mask  the mask context, initialized here
158  * \param flow  the flow context
159  * \param type  the type of the mask
160  * \param value  storage for the mask
161  */
162 void
lp_build_mask_begin(struct lp_build_mask_context * mask,struct gallivm_state * gallivm,struct lp_type type,LLVMValueRef value)163 lp_build_mask_begin(struct lp_build_mask_context *mask,
164                     struct gallivm_state *gallivm,
165                     struct lp_type type,
166                     LLVMValueRef value)
167 {
168    memset(mask, 0, sizeof *mask);
169 
170    mask->reg_type = LLVMIntTypeInContext(gallivm->context, type.width * type.length);
171    mask->var = lp_build_alloca(gallivm,
172                                lp_build_int_vec_type(gallivm, type),
173                                "execution_mask");
174 
175    LLVMBuildStore(gallivm->builder, value, mask->var);
176 
177    lp_build_flow_skip_begin(&mask->skip, gallivm);
178 }
179 
180 
181 LLVMValueRef
lp_build_mask_value(struct lp_build_mask_context * mask)182 lp_build_mask_value(struct lp_build_mask_context *mask)
183 {
184    return LLVMBuildLoad(mask->skip.gallivm->builder, mask->var, "");
185 }
186 
187 
188 /**
189  * Update boolean mask with given value (bitwise AND).
190  * Typically used to update the quad's pixel alive/killed mask
191  * after depth testing, alpha testing, TGSI_OPCODE_KILL_IF, etc.
192  */
193 void
lp_build_mask_update(struct lp_build_mask_context * mask,LLVMValueRef value)194 lp_build_mask_update(struct lp_build_mask_context *mask,
195                      LLVMValueRef value)
196 {
197    value = LLVMBuildAnd(mask->skip.gallivm->builder,
198                         lp_build_mask_value(mask),
199                         value, "");
200    LLVMBuildStore(mask->skip.gallivm->builder, value, mask->var);
201 }
202 
203 /*
204  * Update boolean mask with given value.
205  * Used for per-sample shading to force per-sample execution masks.
206  */
207 void
lp_build_mask_force(struct lp_build_mask_context * mask,LLVMValueRef value)208 lp_build_mask_force(struct lp_build_mask_context *mask,
209                     LLVMValueRef value)
210 {
211    LLVMBuildStore(mask->skip.gallivm->builder, value, mask->var);
212 }
213 
214 /**
215  * End section of code which is predicated on a mask.
216  */
217 LLVMValueRef
lp_build_mask_end(struct lp_build_mask_context * mask)218 lp_build_mask_end(struct lp_build_mask_context *mask)
219 {
220    lp_build_flow_skip_end(&mask->skip);
221    return lp_build_mask_value(mask);
222 }
223 
224 
225 
226 void
lp_build_loop_begin(struct lp_build_loop_state * state,struct gallivm_state * gallivm,LLVMValueRef start)227 lp_build_loop_begin(struct lp_build_loop_state *state,
228                     struct gallivm_state *gallivm,
229                     LLVMValueRef start)
230 
231 {
232    LLVMBuilderRef builder = gallivm->builder;
233 
234    state->block = lp_build_insert_new_block(gallivm, "loop_begin");
235 
236    state->counter_var = lp_build_alloca(gallivm, LLVMTypeOf(start), "loop_counter");
237    state->gallivm = gallivm;
238 
239    LLVMBuildStore(builder, start, state->counter_var);
240 
241    LLVMBuildBr(builder, state->block);
242 
243    LLVMPositionBuilderAtEnd(builder, state->block);
244 
245    state->counter = LLVMBuildLoad(builder, state->counter_var, "");
246 }
247 
248 
249 void
lp_build_loop_end_cond(struct lp_build_loop_state * state,LLVMValueRef end,LLVMValueRef step,LLVMIntPredicate llvm_cond)250 lp_build_loop_end_cond(struct lp_build_loop_state *state,
251                        LLVMValueRef end,
252                        LLVMValueRef step,
253                        LLVMIntPredicate llvm_cond)
254 {
255    LLVMBuilderRef builder = state->gallivm->builder;
256    LLVMValueRef next;
257    LLVMValueRef cond;
258    LLVMBasicBlockRef after_block;
259 
260    if (!step)
261       step = LLVMConstInt(LLVMTypeOf(end), 1, 0);
262 
263    next = LLVMBuildAdd(builder, state->counter, step, "");
264 
265    LLVMBuildStore(builder, next, state->counter_var);
266 
267    cond = LLVMBuildICmp(builder, llvm_cond, next, end, "");
268 
269    after_block = lp_build_insert_new_block(state->gallivm, "loop_end");
270 
271    LLVMBuildCondBr(builder, cond, after_block, state->block);
272 
273    LLVMPositionBuilderAtEnd(builder, after_block);
274 
275    state->counter = LLVMBuildLoad(builder, state->counter_var, "");
276 }
277 
278 void
lp_build_loop_force_set_counter(struct lp_build_loop_state * state,LLVMValueRef end)279 lp_build_loop_force_set_counter(struct lp_build_loop_state *state,
280                           LLVMValueRef end)
281 {
282    LLVMBuilderRef builder = state->gallivm->builder;
283    LLVMBuildStore(builder, end, state->counter_var);
284 }
285 
286 void
lp_build_loop_force_reload_counter(struct lp_build_loop_state * state)287 lp_build_loop_force_reload_counter(struct lp_build_loop_state *state)
288 {
289    LLVMBuilderRef builder = state->gallivm->builder;
290    state->counter = LLVMBuildLoad(builder, state->counter_var, "");
291 }
292 
293 void
lp_build_loop_end(struct lp_build_loop_state * state,LLVMValueRef end,LLVMValueRef step)294 lp_build_loop_end(struct lp_build_loop_state *state,
295                   LLVMValueRef end,
296                   LLVMValueRef step)
297 {
298    lp_build_loop_end_cond(state, end, step, LLVMIntNE);
299 }
300 
301 /**
302  * Creates a c-style for loop,
303  * contrasts lp_build_loop as this checks condition on entry
304  * e.g. for(i = start; i cmp_op end; i += step)
305  * \param state      the for loop state, initialized here
306  * \param gallivm    the gallivm state
307  * \param start      starting value of iterator
308  * \param cmp_op     comparison operator used for comparing current value with end value
309  * \param end        value used to compare against iterator
310  * \param step       value added to iterator at end of each loop
311  */
312 void
lp_build_for_loop_begin(struct lp_build_for_loop_state * state,struct gallivm_state * gallivm,LLVMValueRef start,LLVMIntPredicate cmp_op,LLVMValueRef end,LLVMValueRef step)313 lp_build_for_loop_begin(struct lp_build_for_loop_state *state,
314                         struct gallivm_state *gallivm,
315                         LLVMValueRef start,
316                         LLVMIntPredicate cmp_op,
317                         LLVMValueRef end,
318                         LLVMValueRef step)
319 {
320    LLVMBuilderRef builder = gallivm->builder;
321 
322    assert(LLVMTypeOf(start) == LLVMTypeOf(end));
323    assert(LLVMTypeOf(start) == LLVMTypeOf(step));
324 
325    state->begin = lp_build_insert_new_block(gallivm, "loop_begin");
326    state->step  = step;
327    state->counter_var = lp_build_alloca(gallivm, LLVMTypeOf(start), "loop_counter");
328    state->gallivm = gallivm;
329    state->cond = cmp_op;
330    state->end = end;
331 
332    LLVMBuildStore(builder, start, state->counter_var);
333    LLVMBuildBr(builder, state->begin);
334 
335    LLVMPositionBuilderAtEnd(builder, state->begin);
336    state->counter = LLVMBuildLoad(builder, state->counter_var, "");
337 
338    state->body = lp_build_insert_new_block(gallivm, "loop_body");
339    LLVMPositionBuilderAtEnd(builder, state->body);
340 }
341 
342 /**
343  * End the for loop.
344  */
345 void
lp_build_for_loop_end(struct lp_build_for_loop_state * state)346 lp_build_for_loop_end(struct lp_build_for_loop_state *state)
347 {
348    LLVMValueRef next, cond;
349    LLVMBuilderRef builder = state->gallivm->builder;
350 
351    next = LLVMBuildAdd(builder, state->counter, state->step, "");
352    LLVMBuildStore(builder, next, state->counter_var);
353    LLVMBuildBr(builder, state->begin);
354 
355    state->exit = lp_build_insert_new_block(state->gallivm, "loop_exit");
356 
357    /*
358     * We build the comparison for the begin block here,
359     * if we build it earlier the output llvm ir is not human readable
360     * as the code produced is not in the standard begin -> body -> end order.
361     */
362    LLVMPositionBuilderAtEnd(builder, state->begin);
363    cond = LLVMBuildICmp(builder, state->cond, state->counter, state->end, "");
364    LLVMBuildCondBr(builder, cond, state->body, state->exit);
365 
366    LLVMPositionBuilderAtEnd(builder, state->exit);
367 }
368 
369 
370 /*
371   Example of if/then/else building:
372 
373      int x;
374      if (cond) {
375         x = 1 + 2;
376      }
377      else {
378         x = 2 + 3;
379      }
380 
381   Is built with:
382 
383      // x needs an alloca variable
384      x = lp_build_alloca(builder, type, "x");
385 
386 
387      lp_build_if(ctx, builder, cond);
388         LLVMBuildStore(LLVMBuildAdd(1, 2), x);
389      lp_build_else(ctx);
390         LLVMBuildStore(LLVMBuildAdd(2, 3). x);
391      lp_build_endif(ctx);
392 
393  */
394 
395 
396 
397 /**
398  * Begin an if/else/endif construct.
399  */
400 void
lp_build_if(struct lp_build_if_state * ifthen,struct gallivm_state * gallivm,LLVMValueRef condition)401 lp_build_if(struct lp_build_if_state *ifthen,
402             struct gallivm_state *gallivm,
403             LLVMValueRef condition)
404 {
405    LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder);
406 
407    memset(ifthen, 0, sizeof *ifthen);
408    ifthen->gallivm = gallivm;
409    ifthen->condition = condition;
410    ifthen->entry_block = block;
411 
412    /* create endif/merge basic block for the phi functions */
413    ifthen->merge_block = lp_build_insert_new_block(gallivm, "endif-block");
414 
415    /* create/insert true_block before merge_block */
416    ifthen->true_block =
417       LLVMInsertBasicBlockInContext(gallivm->context,
418                                     ifthen->merge_block,
419                                     "if-true-block");
420 
421    /* successive code goes into the true block */
422    LLVMPositionBuilderAtEnd(gallivm->builder, ifthen->true_block);
423 }
424 
425 
426 /**
427  * Begin else-part of a conditional
428  */
429 void
lp_build_else(struct lp_build_if_state * ifthen)430 lp_build_else(struct lp_build_if_state *ifthen)
431 {
432    LLVMBuilderRef builder = ifthen->gallivm->builder;
433 
434    /* Append an unconditional Br(anch) instruction on the true_block */
435    LLVMBuildBr(builder, ifthen->merge_block);
436 
437    /* create/insert false_block before the merge block */
438    ifthen->false_block =
439       LLVMInsertBasicBlockInContext(ifthen->gallivm->context,
440                                     ifthen->merge_block,
441                                     "if-false-block");
442 
443    /* successive code goes into the else block */
444    LLVMPositionBuilderAtEnd(builder, ifthen->false_block);
445 }
446 
447 
448 /**
449  * End a conditional.
450  */
451 void
lp_build_endif(struct lp_build_if_state * ifthen)452 lp_build_endif(struct lp_build_if_state *ifthen)
453 {
454    LLVMBuilderRef builder = ifthen->gallivm->builder;
455 
456    /* Insert branch to the merge block from current block */
457    LLVMBuildBr(builder, ifthen->merge_block);
458 
459    /*
460     * Now patch in the various branch instructions.
461     */
462 
463    /* Insert the conditional branch instruction at the end of entry_block */
464    LLVMPositionBuilderAtEnd(builder, ifthen->entry_block);
465    if (ifthen->false_block) {
466       /* we have an else clause */
467       LLVMBuildCondBr(builder, ifthen->condition,
468                       ifthen->true_block, ifthen->false_block);
469    }
470    else {
471       /* no else clause */
472       LLVMBuildCondBr(builder, ifthen->condition,
473                       ifthen->true_block, ifthen->merge_block);
474    }
475 
476    /* Resume building code at end of the ifthen->merge_block */
477    LLVMPositionBuilderAtEnd(builder, ifthen->merge_block);
478 }
479 
480 
481 static LLVMBuilderRef
create_builder_at_entry(struct gallivm_state * gallivm)482 create_builder_at_entry(struct gallivm_state *gallivm)
483 {
484    LLVMBuilderRef builder = gallivm->builder;
485    LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
486    LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
487    LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
488    LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
489    LLVMBuilderRef first_builder = LLVMCreateBuilderInContext(gallivm->context);
490 
491    if (first_instr) {
492       LLVMPositionBuilderBefore(first_builder, first_instr);
493    } else {
494       LLVMPositionBuilderAtEnd(first_builder, first_block);
495    }
496 
497    return first_builder;
498 }
499 
500 
501 /**
502  * Allocate a scalar (or vector) variable.
503  *
504  * Although not strictly part of control flow, control flow has deep impact in
505  * how variables should be allocated.
506  *
507  * The mem2reg optimization pass is the recommended way to dealing with mutable
508  * variables, and SSA. It looks for allocas and if it can handle them, it
509  * promotes them, but only looks for alloca instructions in the entry block of
510  * the function. Being in the entry block guarantees that the alloca is only
511  * executed once, which makes analysis simpler.
512  *
513  * See also:
514  * - http://www.llvm.org/docs/tutorial/OCamlLangImpl7.html#memory
515  */
516 LLVMValueRef
lp_build_alloca(struct gallivm_state * gallivm,LLVMTypeRef type,const char * name)517 lp_build_alloca(struct gallivm_state *gallivm,
518                 LLVMTypeRef type,
519                 const char *name)
520 {
521    LLVMBuilderRef builder = gallivm->builder;
522    LLVMBuilderRef first_builder = create_builder_at_entry(gallivm);
523    LLVMValueRef res;
524 
525    res = LLVMBuildAlloca(first_builder, type, name);
526    LLVMBuildStore(builder, LLVMConstNull(type), res);
527 
528    LLVMDisposeBuilder(first_builder);
529 
530    return res;
531 }
532 
533 
534 /**
535  * Like lp_build_alloca, but do not zero-initialize the variable.
536  */
537 LLVMValueRef
lp_build_alloca_undef(struct gallivm_state * gallivm,LLVMTypeRef type,const char * name)538 lp_build_alloca_undef(struct gallivm_state *gallivm,
539                       LLVMTypeRef type,
540                       const char *name)
541 {
542    LLVMBuilderRef first_builder = create_builder_at_entry(gallivm);
543    LLVMValueRef res;
544 
545    res = LLVMBuildAlloca(first_builder, type, name);
546 
547    LLVMDisposeBuilder(first_builder);
548 
549    return res;
550 }
551 
552 
553 /**
554  * Allocate an array of scalars/vectors.
555  *
556  * mem2reg pass is not capable of promoting structs or arrays to registers, but
557  * we still put it in the first block anyway as failure to put allocas in the
558  * first block may prevent the X86 backend from successfully align the stack as
559  * required.
560  *
561  * Also the scalarrepl pass is supposedly more powerful and can promote
562  * arrays in many cases.
563  *
564  * See also:
565  * - http://www.llvm.org/docs/tutorial/OCamlLangImpl7.html#memory
566  */
567 LLVMValueRef
lp_build_array_alloca(struct gallivm_state * gallivm,LLVMTypeRef type,LLVMValueRef count,const char * name)568 lp_build_array_alloca(struct gallivm_state *gallivm,
569                       LLVMTypeRef type,
570                       LLVMValueRef count,
571                       const char *name)
572 {
573    LLVMBuilderRef first_builder = create_builder_at_entry(gallivm);
574    LLVMValueRef res;
575 
576    res = LLVMBuildArrayAlloca(first_builder, type, count, name);
577 
578    LLVMDisposeBuilder(first_builder);
579 
580    return res;
581 }
582