Home | History | Annotate | Download | only in gallivm
      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 (at) vmware.com>
     32  */
     33 
     34 #ifndef LP_BLD_FLOW_H
     35 #define LP_BLD_FLOW_H
     36 
     37 
     38 #include "gallivm/lp_bld.h"
     39 
     40 #ifdef __cplusplus
     41 extern "C" {
     42 #endif
     43 
     44 struct lp_type;
     45 
     46 
     47 /**
     48  * Early exit. Useful to skip to the end of a function or block when
     49  * the execution mask becomes zero or when there is an error condition.
     50  */
     51 struct lp_build_skip_context
     52 {
     53    struct gallivm_state *gallivm;
     54 
     55    /** Block to skip to */
     56    LLVMBasicBlockRef block;
     57 };
     58 
     59 void
     60 lp_build_flow_skip_begin(struct lp_build_skip_context *ctx,
     61                          struct gallivm_state *gallivm);
     62 
     63 void
     64 lp_build_flow_skip_cond_break(struct lp_build_skip_context *ctx,
     65                               LLVMValueRef cond);
     66 
     67 void
     68 lp_build_flow_skip_end(struct lp_build_skip_context *ctx);
     69 
     70 
     71 struct lp_build_mask_context
     72 {
     73    struct lp_build_skip_context skip;
     74 
     75    LLVMTypeRef reg_type;
     76 
     77    LLVMValueRef var;
     78 };
     79 
     80 
     81 void
     82 lp_build_mask_begin(struct lp_build_mask_context *mask,
     83                     struct gallivm_state *gallivm,
     84                     struct lp_type type,
     85                     LLVMValueRef value);
     86 
     87 LLVMValueRef
     88 lp_build_mask_value(struct lp_build_mask_context *mask);
     89 
     90 /**
     91  * Bitwise AND the mask with the given value, if a previous mask was set.
     92  */
     93 void
     94 lp_build_mask_update(struct lp_build_mask_context *mask,
     95                      LLVMValueRef value);
     96 
     97 void
     98 lp_build_mask_check(struct lp_build_mask_context *mask);
     99 
    100 LLVMValueRef
    101 lp_build_mask_end(struct lp_build_mask_context *mask);
    102 
    103 
    104 /**
    105  * LLVM's IR doesn't represent for-loops directly. Furthermore it
    106  * it requires creating code blocks, branches, phi variables, so it
    107  * requires a fair amount of code.
    108  *
    109  * @sa http://www.llvm.org/docs/tutorial/LangImpl5.html#for
    110  */
    111 struct lp_build_loop_state
    112 {
    113    LLVMBasicBlockRef block;
    114    LLVMValueRef counter_var;
    115    LLVMValueRef counter;
    116    struct gallivm_state *gallivm;
    117 };
    118 
    119 
    120 void
    121 lp_build_loop_begin(struct lp_build_loop_state *state,
    122                     struct gallivm_state *gallivm,
    123                     LLVMValueRef start);
    124 
    125 void
    126 lp_build_loop_end(struct lp_build_loop_state *state,
    127                   LLVMValueRef end,
    128                   LLVMValueRef step);
    129 
    130 void
    131 lp_build_loop_end_cond(struct lp_build_loop_state *state,
    132                        LLVMValueRef end,
    133                        LLVMValueRef step,
    134                        LLVMIntPredicate cond);
    135 
    136 
    137 /**
    138  * Implementation of simple C-style for loops
    139  */
    140 struct lp_build_for_loop_state
    141 {
    142    LLVMBasicBlockRef begin;
    143    LLVMBasicBlockRef body;
    144    LLVMBasicBlockRef exit;
    145    LLVMValueRef counter_var;
    146    LLVMValueRef counter;
    147    LLVMValueRef step;
    148    LLVMIntPredicate cond;
    149    LLVMValueRef end;
    150    struct gallivm_state *gallivm;
    151 };
    152 
    153 void
    154 lp_build_for_loop_begin(struct lp_build_for_loop_state *state,
    155                         struct gallivm_state *gallivm,
    156                         LLVMValueRef start,
    157                         LLVMIntPredicate llvm_cond,
    158                         LLVMValueRef end,
    159                         LLVMValueRef step);
    160 
    161 void
    162 lp_build_for_loop_end(struct lp_build_for_loop_state *state);
    163 
    164 
    165 /**
    166  * if/else/endif.
    167  */
    168 struct lp_build_if_state
    169 {
    170    struct gallivm_state *gallivm;
    171    LLVMValueRef condition;
    172    LLVMBasicBlockRef entry_block;
    173    LLVMBasicBlockRef true_block;
    174    LLVMBasicBlockRef false_block;
    175    LLVMBasicBlockRef merge_block;
    176 };
    177 
    178 
    179 void
    180 lp_build_if(struct lp_build_if_state *ctx,
    181             struct gallivm_state *gallivm,
    182             LLVMValueRef condition);
    183 
    184 void
    185 lp_build_else(struct lp_build_if_state *ctx);
    186 
    187 void
    188 lp_build_endif(struct lp_build_if_state *ctx);
    189 
    190 LLVMBasicBlockRef
    191 lp_build_insert_new_block(struct gallivm_state *gallivm, const char *name);
    192 
    193 LLVMValueRef
    194 lp_build_alloca(struct gallivm_state *gallivm,
    195                 LLVMTypeRef type,
    196                 const char *name);
    197 
    198 LLVMValueRef
    199 lp_build_alloca_undef(struct gallivm_state *gallivm,
    200                       LLVMTypeRef type,
    201                       const char *name);
    202 
    203 LLVMValueRef
    204 lp_build_array_alloca(struct gallivm_state *gallivm,
    205                       LLVMTypeRef type,
    206                       LLVMValueRef count,
    207                       const char *name);
    208 
    209 #ifdef __cplusplus
    210 }
    211 #endif
    212 
    213 #endif /* !LP_BLD_FLOW_H */
    214