lp_bld_flow.c revision 3469715a8a171512cf9b528702e70393f01c6041
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/**************************************************************************
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2009 VMware, Inc.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All Rights Reserved.
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy of this software and associated documentation files (the
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "Software"), to deal in the Software without restriction, including
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * without limitation the rights to use, copy, modify, merge, publish,
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * distribute, sub license, and/or sell copies of the Software, and to
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * permit persons to whom the Software is furnished to do so, subject to
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the following conditions:
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * The above copyright notice and this permission notice (including the
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * next paragraph) shall be included in all copies or substantial portions
16bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch * of the Software.
17bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch *
18bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) **************************************************************************/
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LLVM control flow build helpers.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @author Jose Fonseca <jfonseca@vmware.com>
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "util/u_debug.h"
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "util/u_memory.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "lp_bld_init.h"
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "lp_bld_type.h"
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "lp_bld_flow.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/**
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Insert a new block, right where builder is pointing to.
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is useful important not only for aesthetic reasons, but also for
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * performance reasons, as frequently run blocks should be laid out next to
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * each other and fall-throughs maximized.
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * See also llvm/lib/Transforms/Scalar/BasicBlockPlacement.cpp.
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Note: this function has no dependencies on the flow code and could
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be used elsewhere.
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)LLVMBasicBlockRef
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_insert_new_block(struct gallivm_state *gallivm, const char *name)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   LLVMBasicBlockRef current_block;
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   LLVMBasicBlockRef next_block;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   LLVMBasicBlockRef new_block;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* get current basic block */
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   current_block = LLVMGetInsertBlock(gallivm->builder);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* check if there's another block after this one */
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   next_block = LLVMGetNextBasicBlock(current_block);
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)   if (next_block) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* insert the new block before the next block */
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_block = LLVMInsertBasicBlockInContext(gallivm->context, next_block, name);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   }
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   else {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      /* append new block after current block */
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new_block = LLVMAppendBasicBlockInContext(gallivm->context, function, name);
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   return new_block;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)/**
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Begin a "skip" block.  Inside this block we can test a condition and
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * skip to the end of the block if the condition is false.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_flow_skip_begin(struct lp_build_skip_context *skip,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         struct gallivm_state *gallivm)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   skip->gallivm = gallivm;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* create new basic block */
90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch   skip->block = lp_build_insert_new_block(gallivm, "skip");
91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/**
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Insert code to test a condition and branch to the end of the current
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * skip block if the condition is true.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_flow_skip_cond_break(struct lp_build_skip_context *skip,
1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                              LLVMValueRef cond)
1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles){
1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)   LLVMBasicBlockRef new_block;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   new_block = lp_build_insert_new_block(skip->gallivm, "");
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   /* if cond is true, goto skip->block, else goto new_block */
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   LLVMBuildCondBr(skip->gallivm->builder, cond, skip->block, new_block);
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
109bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch   LLVMPositionBuilderAtEnd(skip->gallivm->builder, new_block);
110bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void
1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)lp_build_flow_skip_end(struct lp_build_skip_context *skip)
115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch{
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* goto block */
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMBuildBr(skip->gallivm->builder, skip->block);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   LLVMPositionBuilderAtEnd(skip->gallivm->builder, skip->block);
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Check if the mask predicate is zero.  If so, jump to the end of the block.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)lp_build_mask_check(struct lp_build_mask_context *mask)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   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 */
162void
163lp_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
181LLVMValueRef
182lp_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_KIL, etc.
192 */
193void
194lp_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/**
205 * End section of code which is predicated on a mask.
206 */
207LLVMValueRef
208lp_build_mask_end(struct lp_build_mask_context *mask)
209{
210   lp_build_flow_skip_end(&mask->skip);
211   return lp_build_mask_value(mask);
212}
213
214
215
216void
217lp_build_loop_begin(struct lp_build_loop_state *state,
218                    struct gallivm_state *gallivm,
219                    LLVMValueRef start)
220
221{
222   LLVMBuilderRef builder = gallivm->builder;
223
224   state->block = lp_build_insert_new_block(gallivm, "loop_begin");
225
226   state->counter_var = lp_build_alloca(gallivm, LLVMTypeOf(start), "loop_counter");
227   state->gallivm = gallivm;
228
229   LLVMBuildStore(builder, start, state->counter_var);
230
231   LLVMBuildBr(builder, state->block);
232
233   LLVMPositionBuilderAtEnd(builder, state->block);
234
235   state->counter = LLVMBuildLoad(builder, state->counter_var, "");
236}
237
238
239void
240lp_build_loop_end_cond(struct lp_build_loop_state *state,
241                       LLVMValueRef end,
242                       LLVMValueRef step,
243                       LLVMIntPredicate llvm_cond)
244{
245   LLVMBuilderRef builder = state->gallivm->builder;
246   LLVMValueRef next;
247   LLVMValueRef cond;
248   LLVMBasicBlockRef after_block;
249
250   if (!step)
251      step = LLVMConstInt(LLVMTypeOf(end), 1, 0);
252
253   next = LLVMBuildAdd(builder, state->counter, step, "");
254
255   LLVMBuildStore(builder, next, state->counter_var);
256
257   cond = LLVMBuildICmp(builder, llvm_cond, next, end, "");
258
259   after_block = lp_build_insert_new_block(state->gallivm, "loop_end");
260
261   LLVMBuildCondBr(builder, cond, after_block, state->block);
262
263   LLVMPositionBuilderAtEnd(builder, after_block);
264
265   state->counter = LLVMBuildLoad(builder, state->counter_var, "");
266}
267
268
269void
270lp_build_loop_end(struct lp_build_loop_state *state,
271                  LLVMValueRef end,
272                  LLVMValueRef step)
273{
274   lp_build_loop_end_cond(state, end, step, LLVMIntNE);
275}
276
277/**
278 * Creates a c-style for loop,
279 * contrasts lp_build_loop as this checks condition on entry
280 * e.g. for(i = start; i cmp_op end; i += step)
281 * \param state      the for loop state, initialized here
282 * \param gallivm    the gallivm state
283 * \param start      starting value of iterator
284 * \param cmp_op     comparison operator used for comparing current value with end value
285 * \param end        value used to compare against iterator
286 * \param step       value added to iterator at end of each loop
287 */
288void
289lp_build_for_loop_begin(struct lp_build_for_loop_state *state,
290                        struct gallivm_state *gallivm,
291                        LLVMValueRef start,
292                        LLVMIntPredicate cmp_op,
293                        LLVMValueRef end,
294                        LLVMValueRef step)
295{
296   LLVMBuilderRef builder = gallivm->builder;
297
298   assert(LLVMTypeOf(start) == LLVMTypeOf(end));
299   assert(LLVMTypeOf(start) == LLVMTypeOf(step));
300
301   state->begin = lp_build_insert_new_block(gallivm, "loop_begin");
302   state->step  = step;
303   state->counter_var = lp_build_alloca(gallivm, LLVMTypeOf(start), "loop_counter");
304   state->gallivm = gallivm;
305   state->cond = cmp_op;
306   state->end = end;
307
308   LLVMBuildStore(builder, start, state->counter_var);
309   LLVMBuildBr(builder, state->begin);
310
311   LLVMPositionBuilderAtEnd(builder, state->begin);
312   state->counter = LLVMBuildLoad(builder, state->counter_var, "");
313
314   state->body = lp_build_insert_new_block(gallivm, "loop_body");
315   LLVMPositionBuilderAtEnd(builder, state->body);
316}
317
318/**
319 * End the for loop.
320 */
321void
322lp_build_for_loop_end(struct lp_build_for_loop_state *state)
323{
324   LLVMValueRef next, cond;
325   LLVMBuilderRef builder = state->gallivm->builder;
326
327   next = LLVMBuildAdd(builder, state->counter, state->step, "");
328   LLVMBuildStore(builder, next, state->counter_var);
329   LLVMBuildBr(builder, state->begin);
330
331   state->exit = lp_build_insert_new_block(state->gallivm, "loop_exit");
332
333   /*
334    * We build the comparison for the begin block here,
335    * if we build it earlier the output llvm ir is not human readable
336    * as the code produced is not in the standard begin -> body -> end order.
337    */
338   LLVMPositionBuilderAtEnd(builder, state->begin);
339   cond = LLVMBuildICmp(builder, state->cond, state->counter, state->end, "");
340   LLVMBuildCondBr(builder, cond, state->body, state->exit);
341
342   LLVMPositionBuilderAtEnd(builder, state->exit);
343}
344
345
346/*
347  Example of if/then/else building:
348
349     int x;
350     if (cond) {
351        x = 1 + 2;
352     }
353     else {
354        x = 2 + 3;
355     }
356
357  Is built with:
358
359     // x needs an alloca variable
360     x = lp_build_alloca(builder, type, "x");
361
362
363     lp_build_if(ctx, builder, cond);
364        LLVMBuildStore(LLVMBuildAdd(1, 2), x);
365     lp_build_else(ctx);
366        LLVMBuildStore(LLVMBuildAdd(2, 3). x);
367     lp_build_endif(ctx);
368
369 */
370
371
372
373/**
374 * Begin an if/else/endif construct.
375 */
376void
377lp_build_if(struct lp_build_if_state *ifthen,
378            struct gallivm_state *gallivm,
379            LLVMValueRef condition)
380{
381   LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder);
382
383   memset(ifthen, 0, sizeof *ifthen);
384   ifthen->gallivm = gallivm;
385   ifthen->condition = condition;
386   ifthen->entry_block = block;
387
388   /* create endif/merge basic block for the phi functions */
389   ifthen->merge_block = lp_build_insert_new_block(gallivm, "endif-block");
390
391   /* create/insert true_block before merge_block */
392   ifthen->true_block =
393      LLVMInsertBasicBlockInContext(gallivm->context,
394                                    ifthen->merge_block,
395                                    "if-true-block");
396
397   /* successive code goes into the true block */
398   LLVMPositionBuilderAtEnd(gallivm->builder, ifthen->true_block);
399}
400
401
402/**
403 * Begin else-part of a conditional
404 */
405void
406lp_build_else(struct lp_build_if_state *ifthen)
407{
408   LLVMBuilderRef builder = ifthen->gallivm->builder;
409
410   /* Append an unconditional Br(anch) instruction on the true_block */
411   LLVMBuildBr(builder, ifthen->merge_block);
412
413   /* create/insert false_block before the merge block */
414   ifthen->false_block =
415      LLVMInsertBasicBlockInContext(ifthen->gallivm->context,
416                                    ifthen->merge_block,
417                                    "if-false-block");
418
419   /* successive code goes into the else block */
420   LLVMPositionBuilderAtEnd(builder, ifthen->false_block);
421}
422
423
424/**
425 * End a conditional.
426 */
427void
428lp_build_endif(struct lp_build_if_state *ifthen)
429{
430   LLVMBuilderRef builder = ifthen->gallivm->builder;
431
432   /* Insert branch to the merge block from current block */
433   LLVMBuildBr(builder, ifthen->merge_block);
434
435   /*
436    * Now patch in the various branch instructions.
437    */
438
439   /* Insert the conditional branch instruction at the end of entry_block */
440   LLVMPositionBuilderAtEnd(builder, ifthen->entry_block);
441   if (ifthen->false_block) {
442      /* we have an else clause */
443      LLVMBuildCondBr(builder, ifthen->condition,
444                      ifthen->true_block, ifthen->false_block);
445   }
446   else {
447      /* no else clause */
448      LLVMBuildCondBr(builder, ifthen->condition,
449                      ifthen->true_block, ifthen->merge_block);
450   }
451
452   /* Resume building code at end of the ifthen->merge_block */
453   LLVMPositionBuilderAtEnd(builder, ifthen->merge_block);
454}
455
456
457/**
458 * Allocate a scalar (or vector) variable.
459 *
460 * Although not strictly part of control flow, control flow has deep impact in
461 * how variables should be allocated.
462 *
463 * The mem2reg optimization pass is the recommended way to dealing with mutable
464 * variables, and SSA. It looks for allocas and if it can handle them, it
465 * promotes them, but only looks for alloca instructions in the entry block of
466 * the function. Being in the entry block guarantees that the alloca is only
467 * executed once, which makes analysis simpler.
468 *
469 * See also:
470 * - http://www.llvm.org/docs/tutorial/OCamlLangImpl7.html#memory
471 */
472LLVMValueRef
473lp_build_alloca(struct gallivm_state *gallivm,
474                LLVMTypeRef type,
475                const char *name)
476{
477   LLVMBuilderRef builder = gallivm->builder;
478   LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
479   LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
480   LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
481   LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
482   LLVMBuilderRef first_builder = LLVMCreateBuilderInContext(gallivm->context);
483   LLVMValueRef res;
484
485   if (first_instr) {
486      LLVMPositionBuilderBefore(first_builder, first_instr);
487   } else {
488      LLVMPositionBuilderAtEnd(first_builder, first_block);
489   }
490
491   res = LLVMBuildAlloca(first_builder, type, name);
492   LLVMBuildStore(builder, LLVMConstNull(type), res);
493
494   LLVMDisposeBuilder(first_builder);
495
496   return res;
497}
498
499
500/**
501 * Allocate an array of scalars/vectors.
502 *
503 * mem2reg pass is not capable of promoting structs or arrays to registers, but
504 * we still put it in the first block anyway as failure to put allocas in the
505 * first block may prevent the X86 backend from successfully align the stack as
506 * required.
507 *
508 * Also the scalarrepl pass is supposedly more powerful and can promote
509 * arrays in many cases.
510 *
511 * See also:
512 * - http://www.llvm.org/docs/tutorial/OCamlLangImpl7.html#memory
513 */
514LLVMValueRef
515lp_build_array_alloca(struct gallivm_state *gallivm,
516                      LLVMTypeRef type,
517                      LLVMValueRef count,
518                      const char *name)
519{
520   LLVMBuilderRef builder = gallivm->builder;
521   LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
522   LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
523   LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
524   LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
525   LLVMBuilderRef first_builder = LLVMCreateBuilderInContext(gallivm->context);
526   LLVMValueRef res;
527
528   if (first_instr) {
529      LLVMPositionBuilderBefore(first_builder, first_instr);
530   } else {
531      LLVMPositionBuilderAtEnd(first_builder, first_block);
532   }
533
534   res = LLVMBuildArrayAlloca(first_builder, type, count, name);
535
536   LLVMDisposeBuilder(first_builder);
537
538   return res;
539}
540