• 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_type = lp_build_int_vec_type(gallivm, type);
172    mask->var = lp_build_alloca(gallivm,
173                                mask->var_type,
174                                "execution_mask");
175 
176    LLVMBuildStore(gallivm->builder, value, mask->var);
177 
178    lp_build_flow_skip_begin(&mask->skip, gallivm);
179 }
180 
181 
182 LLVMValueRef
lp_build_mask_value(struct lp_build_mask_context * mask)183 lp_build_mask_value(struct lp_build_mask_context *mask)
184 {
185    return LLVMBuildLoad2(mask->skip.gallivm->builder, mask->var_type, mask->var, "");
186 }
187 
188 
189 /**
190  * Update boolean mask with given value (bitwise AND).
191  * Typically used to update the quad's pixel alive/killed mask
192  * after depth testing, alpha testing, TGSI_OPCODE_KILL_IF, etc.
193  */
194 void
lp_build_mask_update(struct lp_build_mask_context * mask,LLVMValueRef value)195 lp_build_mask_update(struct lp_build_mask_context *mask,
196                      LLVMValueRef value)
197 {
198    value = LLVMBuildAnd(mask->skip.gallivm->builder,
199                         lp_build_mask_value(mask),
200                         value, "");
201    LLVMBuildStore(mask->skip.gallivm->builder, value, mask->var);
202 }
203 
204 /*
205  * Update boolean mask with given value.
206  * Used for per-sample shading to force per-sample execution masks.
207  */
208 void
lp_build_mask_force(struct lp_build_mask_context * mask,LLVMValueRef value)209 lp_build_mask_force(struct lp_build_mask_context *mask,
210                     LLVMValueRef value)
211 {
212    LLVMBuildStore(mask->skip.gallivm->builder, value, mask->var);
213 }
214 
215 /**
216  * End section of code which is predicated on a mask.
217  */
218 LLVMValueRef
lp_build_mask_end(struct lp_build_mask_context * mask)219 lp_build_mask_end(struct lp_build_mask_context *mask)
220 {
221    lp_build_flow_skip_end(&mask->skip);
222    return lp_build_mask_value(mask);
223 }
224 
225 
226 
227 void
lp_build_loop_begin(struct lp_build_loop_state * state,struct gallivm_state * gallivm,LLVMValueRef start)228 lp_build_loop_begin(struct lp_build_loop_state *state,
229                     struct gallivm_state *gallivm,
230                     LLVMValueRef start)
231 
232 {
233    LLVMBuilderRef builder = gallivm->builder;
234 
235    state->block = lp_build_insert_new_block(gallivm, "loop_begin");
236 
237    state->counter_type = LLVMTypeOf(start);
238    state->counter_var = lp_build_alloca(gallivm, state->counter_type, "loop_counter");
239    state->gallivm = gallivm;
240 
241    LLVMBuildStore(builder, start, state->counter_var);
242 
243    LLVMBuildBr(builder, state->block);
244 
245    LLVMPositionBuilderAtEnd(builder, state->block);
246 
247    state->counter = LLVMBuildLoad2(builder, state->counter_type, state->counter_var, "");
248 }
249 
250 
251 void
lp_build_loop_end_cond(struct lp_build_loop_state * state,LLVMValueRef end,LLVMValueRef step,LLVMIntPredicate llvm_cond)252 lp_build_loop_end_cond(struct lp_build_loop_state *state,
253                        LLVMValueRef end,
254                        LLVMValueRef step,
255                        LLVMIntPredicate llvm_cond)
256 {
257    LLVMBuilderRef builder = state->gallivm->builder;
258    LLVMValueRef next;
259    LLVMValueRef cond;
260    LLVMBasicBlockRef after_block;
261 
262    if (!step)
263       step = LLVMConstInt(LLVMTypeOf(end), 1, 0);
264 
265    next = LLVMBuildAdd(builder, state->counter, step, "");
266 
267    LLVMBuildStore(builder, next, state->counter_var);
268 
269    cond = LLVMBuildICmp(builder, llvm_cond, next, end, "");
270 
271    after_block = lp_build_insert_new_block(state->gallivm, "loop_end");
272 
273    LLVMBuildCondBr(builder, cond, after_block, state->block);
274 
275    LLVMPositionBuilderAtEnd(builder, after_block);
276 
277    state->counter = LLVMBuildLoad2(builder, state->counter_type, state->counter_var, "");
278 }
279 
280 void
lp_build_loop_force_set_counter(struct lp_build_loop_state * state,LLVMValueRef end)281 lp_build_loop_force_set_counter(struct lp_build_loop_state *state,
282                           LLVMValueRef end)
283 {
284    LLVMBuilderRef builder = state->gallivm->builder;
285    LLVMBuildStore(builder, end, state->counter_var);
286 }
287 
288 void
lp_build_loop_force_reload_counter(struct lp_build_loop_state * state)289 lp_build_loop_force_reload_counter(struct lp_build_loop_state *state)
290 {
291    LLVMBuilderRef builder = state->gallivm->builder;
292    state->counter = LLVMBuildLoad2(builder, state->counter_type, state->counter_var, "");
293 }
294 
295 void
lp_build_loop_end(struct lp_build_loop_state * state,LLVMValueRef end,LLVMValueRef step)296 lp_build_loop_end(struct lp_build_loop_state *state,
297                   LLVMValueRef end,
298                   LLVMValueRef step)
299 {
300    lp_build_loop_end_cond(state, end, step, LLVMIntNE);
301 }
302 
303 /**
304  * Creates a c-style for loop,
305  * contrasts lp_build_loop as this checks condition on entry
306  * e.g. for(i = start; i cmp_op end; i += step)
307  * \param state      the for loop state, initialized here
308  * \param gallivm    the gallivm state
309  * \param start      starting value of iterator
310  * \param cmp_op     comparison operator used for comparing current value with end value
311  * \param end        value used to compare against iterator
312  * \param step       value added to iterator at end of each loop
313  */
314 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)315 lp_build_for_loop_begin(struct lp_build_for_loop_state *state,
316                         struct gallivm_state *gallivm,
317                         LLVMValueRef start,
318                         LLVMIntPredicate cmp_op,
319                         LLVMValueRef end,
320                         LLVMValueRef step)
321 {
322    LLVMBuilderRef builder = gallivm->builder;
323 
324    assert(LLVMTypeOf(start) == LLVMTypeOf(end));
325    assert(LLVMTypeOf(start) == LLVMTypeOf(step));
326 
327    state->begin = lp_build_insert_new_block(gallivm, "loop_begin");
328    state->step  = step;
329    state->counter_type = LLVMTypeOf(start);
330    state->counter_var = lp_build_alloca(gallivm, state->counter_type, "loop_counter");
331    state->gallivm = gallivm;
332    state->cond = cmp_op;
333    state->end = end;
334 
335    LLVMBuildStore(builder, start, state->counter_var);
336    LLVMBuildBr(builder, state->begin);
337 
338    LLVMPositionBuilderAtEnd(builder, state->begin);
339    state->counter = LLVMBuildLoad2(builder, state->counter_type, state->counter_var, "");
340 
341    state->body = lp_build_insert_new_block(gallivm, "loop_body");
342    LLVMPositionBuilderAtEnd(builder, state->body);
343 }
344 
345 /**
346  * End the for loop.
347  */
348 void
lp_build_for_loop_end(struct lp_build_for_loop_state * state)349 lp_build_for_loop_end(struct lp_build_for_loop_state *state)
350 {
351    LLVMValueRef next, cond;
352    LLVMBuilderRef builder = state->gallivm->builder;
353 
354    next = LLVMBuildAdd(builder, state->counter, state->step, "");
355    LLVMBuildStore(builder, next, state->counter_var);
356    LLVMBuildBr(builder, state->begin);
357 
358    state->exit = lp_build_insert_new_block(state->gallivm, "loop_exit");
359 
360    /*
361     * We build the comparison for the begin block here,
362     * if we build it earlier the output llvm ir is not human readable
363     * as the code produced is not in the standard begin -> body -> end order.
364     */
365    LLVMPositionBuilderAtEnd(builder, state->begin);
366    cond = LLVMBuildICmp(builder, state->cond, state->counter, state->end, "");
367    LLVMBuildCondBr(builder, cond, state->body, state->exit);
368 
369    LLVMPositionBuilderAtEnd(builder, state->exit);
370 }
371 
372 
373 /*
374   Example of if/then/else building:
375 
376      int x;
377      if (cond) {
378         x = 1 + 2;
379      }
380      else {
381         x = 2 + 3;
382      }
383 
384   Is built with:
385 
386      // x needs an alloca variable
387      x = lp_build_alloca(builder, type, "x");
388 
389 
390      lp_build_if(ctx, builder, cond);
391         LLVMBuildStore(LLVMBuildAdd(1, 2), x);
392      lp_build_else(ctx);
393         LLVMBuildStore(LLVMBuildAdd(2, 3). x);
394      lp_build_endif(ctx);
395 
396  */
397 
398 
399 
400 /**
401  * Begin an if/else/endif construct.
402  */
403 void
lp_build_if(struct lp_build_if_state * ifthen,struct gallivm_state * gallivm,LLVMValueRef condition)404 lp_build_if(struct lp_build_if_state *ifthen,
405             struct gallivm_state *gallivm,
406             LLVMValueRef condition)
407 {
408    LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder);
409 
410    memset(ifthen, 0, sizeof *ifthen);
411    ifthen->gallivm = gallivm;
412    ifthen->condition = condition;
413    ifthen->entry_block = block;
414 
415    /* create endif/merge basic block for the phi functions */
416    ifthen->merge_block = lp_build_insert_new_block(gallivm, "endif-block");
417 
418    /* create/insert true_block before merge_block */
419    ifthen->true_block =
420       LLVMInsertBasicBlockInContext(gallivm->context,
421                                     ifthen->merge_block,
422                                     "if-true-block");
423 
424    /* successive code goes into the true block */
425    LLVMPositionBuilderAtEnd(gallivm->builder, ifthen->true_block);
426 }
427 
428 
429 /**
430  * Begin else-part of a conditional
431  */
432 void
lp_build_else(struct lp_build_if_state * ifthen)433 lp_build_else(struct lp_build_if_state *ifthen)
434 {
435    LLVMBuilderRef builder = ifthen->gallivm->builder;
436 
437    /* Append an unconditional Br(anch) instruction on the true_block */
438    LLVMBuildBr(builder, ifthen->merge_block);
439 
440    /* create/insert false_block before the merge block */
441    ifthen->false_block =
442       LLVMInsertBasicBlockInContext(ifthen->gallivm->context,
443                                     ifthen->merge_block,
444                                     "if-false-block");
445 
446    /* successive code goes into the else block */
447    LLVMPositionBuilderAtEnd(builder, ifthen->false_block);
448 }
449 
450 
451 /**
452  * End a conditional.
453  */
454 void
lp_build_endif(struct lp_build_if_state * ifthen)455 lp_build_endif(struct lp_build_if_state *ifthen)
456 {
457    LLVMBuilderRef builder = ifthen->gallivm->builder;
458 
459    /* Insert branch to the merge block from current block */
460    LLVMBuildBr(builder, ifthen->merge_block);
461 
462    /*
463     * Now patch in the various branch instructions.
464     */
465 
466    /* Insert the conditional branch instruction at the end of entry_block */
467    LLVMPositionBuilderAtEnd(builder, ifthen->entry_block);
468    if (ifthen->false_block) {
469       /* we have an else clause */
470       LLVMBuildCondBr(builder, ifthen->condition,
471                       ifthen->true_block, ifthen->false_block);
472    }
473    else {
474       /* no else clause */
475       LLVMBuildCondBr(builder, ifthen->condition,
476                       ifthen->true_block, ifthen->merge_block);
477    }
478 
479    /* Resume building code at end of the ifthen->merge_block */
480    LLVMPositionBuilderAtEnd(builder, ifthen->merge_block);
481 }
482 
483 
484 static LLVMBuilderRef
create_builder_at_entry(struct gallivm_state * gallivm)485 create_builder_at_entry(struct gallivm_state *gallivm)
486 {
487    LLVMBuilderRef builder = gallivm->builder;
488    LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
489    LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
490    LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
491    LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
492    LLVMBuilderRef first_builder = LLVMCreateBuilderInContext(gallivm->context);
493 
494    if (first_instr) {
495       LLVMPositionBuilderBefore(first_builder, first_instr);
496    } else {
497       LLVMPositionBuilderAtEnd(first_builder, first_block);
498    }
499 
500    return first_builder;
501 }
502 
503 
504 /**
505  * Allocate a scalar (or vector) variable.
506  *
507  * Although not strictly part of control flow, control flow has deep impact in
508  * how variables should be allocated.
509  *
510  * The mem2reg optimization pass is the recommended way to dealing with mutable
511  * variables, and SSA. It looks for allocas and if it can handle them, it
512  * promotes them, but only looks for alloca instructions in the entry block of
513  * the function. Being in the entry block guarantees that the alloca is only
514  * executed once, which makes analysis simpler.
515  *
516  * See also:
517  * - http://www.llvm.org/docs/tutorial/OCamlLangImpl7.html#memory
518  */
519 LLVMValueRef
lp_build_alloca(struct gallivm_state * gallivm,LLVMTypeRef type,const char * name)520 lp_build_alloca(struct gallivm_state *gallivm,
521                 LLVMTypeRef type,
522                 const char *name)
523 {
524    LLVMBuilderRef builder = gallivm->builder;
525    LLVMBuilderRef first_builder = create_builder_at_entry(gallivm);
526    LLVMValueRef res;
527 
528    res = LLVMBuildAlloca(first_builder, type, name);
529    LLVMBuildStore(builder, LLVMConstNull(type), res);
530 
531    LLVMDisposeBuilder(first_builder);
532 
533    return res;
534 }
535 
536 
537 /**
538  * Like lp_build_alloca, but do not zero-initialize the variable.
539  */
540 LLVMValueRef
lp_build_alloca_undef(struct gallivm_state * gallivm,LLVMTypeRef type,const char * name)541 lp_build_alloca_undef(struct gallivm_state *gallivm,
542                       LLVMTypeRef type,
543                       const char *name)
544 {
545    LLVMBuilderRef first_builder = create_builder_at_entry(gallivm);
546    LLVMValueRef res;
547 
548    res = LLVMBuildAlloca(first_builder, type, name);
549 
550    LLVMDisposeBuilder(first_builder);
551 
552    return res;
553 }
554 
555 
556 /**
557  * Allocate an array of scalars/vectors.
558  *
559  * mem2reg pass is not capable of promoting structs or arrays to registers, but
560  * we still put it in the first block anyway as failure to put allocas in the
561  * first block may prevent the X86 backend from successfully align the stack as
562  * required.
563  *
564  * Also the scalarrepl pass is supposedly more powerful and can promote
565  * arrays in many cases.
566  *
567  * See also:
568  * - http://www.llvm.org/docs/tutorial/OCamlLangImpl7.html#memory
569  */
570 LLVMValueRef
lp_build_array_alloca(struct gallivm_state * gallivm,LLVMTypeRef type,LLVMValueRef count,const char * name)571 lp_build_array_alloca(struct gallivm_state *gallivm,
572                       LLVMTypeRef type,
573                       LLVMValueRef count,
574                       const char *name)
575 {
576    LLVMBuilderRef first_builder = create_builder_at_entry(gallivm);
577    LLVMValueRef res;
578 
579    res = LLVMBuildArrayAlloca(first_builder, type, count, name);
580 
581    LLVMDisposeBuilder(first_builder);
582 
583    return res;
584 }
585