iropt: cmp(~x & 1, 0) => !cmp(x & 1, 0)
[libfirm] / include / libfirm / lowering.h
1 /*
2  * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Lowering of high level constructs.
23  * @author  Michael Beck
24  * @version $Id$
25  */
26 #ifndef FIRM_LOWERING_H
27 #define FIRM_LOWERING_H
28
29 #include <stddef.h>
30
31 #include "firm_types.h"
32
33 #include "begin.h"
34
35 /**
36  * Lower small CopyB nodes to Load/Store nodes, preserve medium-sized CopyB
37  * nodes and replace large CopyBs by a call to memcpy, depending on the given
38  * parameters.
39  *
40  * Small CopyB nodes (size <= max_small_size) are turned into a series of
41  * loads and stores.
42  * Medium-sized CopyB nodes (max_small_size < size < min_large_size) are
43  * left untouched.
44  * Large CopyB nodes (size >= min_large_size) are turned into a memcpy call.
45  *
46  * @param irg                 The graph to be lowered.
47  * @param max_small_size      The maximum number of bytes for a CopyB node so
48  *                            that it is still considered 'small'.
49  * @param min_large_size      The minimum number of bytes for a CopyB node so
50  *                            that it is regarded as 'large'.
51  * @param allow_misalignments Backend can handle misaligned loads and stores.
52  */
53 FIRM_API void lower_CopyB(ir_graph *irg, unsigned max_small_size,
54                           unsigned min_large_size, int allow_misalignments);
55
56 /**
57  * Lowers all Switches (Cond nodes with non-boolean mode) depending on spare_size.
58  * They will either remain the same or be converted into if-cascades.
59  *
60  * @param irg        The ir graph to be lowered.
61  * @param small_switch  If switch has <= cases then change it to an if-cascade.
62  * @param spare_size Allowed spare size for table switches in machine words.
63  *                   (Default in edgfe: 128)
64  * @param allow_out_of_bounds   backend can handle out-of-bounds values
65  *                              (values bigger than minimum and maximum proj
66  *                               number)
67  */
68 FIRM_API void lower_switch(ir_graph *irg, unsigned small_switch,
69                            unsigned spare_size, int allow_out_of_bounds);
70
71 /**
72  * Replaces SymConsts by a real constant if possible.
73  * Replace Sel nodes by address computation.  Also resolves array access.
74  * Handle bit fields by added And/Or calculations.
75  *
76  * @param irg               the graph to lower
77  *
78  * @note: There is NO lowering ob objects oriented types. This is highly compiler
79  *        and ABI specific and should be placed directly in the compiler.
80  */
81 FIRM_API void lower_highlevel_graph(ir_graph *irg);
82
83 /**
84  * Creates an ir_graph pass for lower_highlevel_graph().
85  *
86  * @param name              the name of this pass or NULL
87  *
88  * @return  the newly created ir_graph pass
89  */
90 FIRM_API ir_graph_pass_t *lower_highlevel_graph_pass(const char *name);
91
92 /**
93  * Replaces SymConsts by a real constant if possible.
94  * Replace Sel nodes by address computation.  Also resolves array access.
95  * Handle bit fields by added And/Or calculations.
96  * Lowers all graphs.
97  *
98  * @note There is NO lowering of objects oriented types. This is highly compiler
99  *       and ABI specific and should be placed directly in the compiler.
100  */
101 FIRM_API void lower_highlevel(void);
102
103 /**
104  * does the same as lower_highlevel for all nodes on the const code irg
105  */
106 FIRM_API void lower_const_code(void);
107
108 /**
109  * Creates an ir_prog pass for lower_const_code().
110  *
111  * @param name     the name of this pass or NULL
112  *
113  * @return  the newly created ir_prog pass
114  */
115 FIRM_API ir_prog_pass_t *lower_const_code_pass(const char *name);
116
117 /**
118  * Used as callback, whenever a lowerable mux is found. The return value
119  * indicates, whether the mux should be lowered. This may be used, to lower
120  * floating point muxes, while keeping mux nodes for integers, for example.
121  *
122  * @param mux  The mux node that may be lowered.
123  * @return     A non-zero value indicates that the mux should be lowered.
124  */
125 typedef int lower_mux_callback(ir_node* mux);
126
127 /**
128  * Lowers all mux nodes in the given graph. A callback function may be
129  * given, to select the mux nodes to lower.
130  *
131  * @param irg      The graph to lower mux nodes in.
132  * @param cb_func  The callback function for mux selection. Can be NULL,
133  *                 to lower all mux nodes.
134  */
135 FIRM_API void lower_mux(ir_graph *irg, lower_mux_callback *cb_func);
136
137 /**
138  * Creates an ir_graph pass for lower_mux().
139  *
140  * @param name     the name of this pass or NULL
141  * @param cb_func  The callback function for mux selection. Can be NULL,
142  *                 to lower all mux nodes.
143  *
144  * @return  the newly created ir_graph pass
145  */
146 FIRM_API ir_graph_pass_t *lower_mux_pass(const char *name,
147                                          lower_mux_callback *cb_func);
148
149 /**
150  * An intrinsic mapper function.
151  *
152  * @param node   the IR-node that will be mapped
153  * @param ctx    a context
154  *
155  * @return  non-zero if the call was mapped
156  */
157 typedef int (*i_mapper_func)(ir_node *node, void *ctx);
158
159 enum ikind {
160         INTRINSIC_CALL  = 0,  /**< the record represents an intrinsic call */
161         INTRINSIC_INSTR       /**< the record represents an intrinsic instruction */
162 };
163
164 /**
165  * An intrinsic call record.
166  */
167 typedef struct i_call_record {
168         enum ikind    kind;       /**< must be INTRINSIC_CALL */
169         ir_entity     *i_ent;     /**< the entity representing an intrinsic call */
170         i_mapper_func i_mapper;   /**< the mapper function to call */
171         void          *ctx;       /**< mapper context */
172         void          *link;      /**< used in the construction algorithm, must be NULL */
173 } i_call_record;
174
175 /**
176  * An intrinsic instruction record.
177  */
178 typedef struct i_instr_record {
179         enum ikind    kind;       /**< must be INTRINSIC_INSTR */
180         ir_op         *op;        /**< the opcode that must be mapped. */
181         i_mapper_func i_mapper;   /**< the mapper function to call */
182         void          *ctx;       /**< mapper context */
183         void          *link;      /**< used in the construction algorithm, must be NULL */
184 } i_instr_record;
185
186 /**
187  * An intrinsic record.
188  */
189 typedef union i_record {
190         i_call_record  i_call;
191         i_instr_record i_instr;
192 } i_record;
193
194 /**
195  * Go through all graphs and map calls to intrinsic functions and instructions.
196  *
197  * Every call or instruction is reported to its mapper function,
198  * which is responsible for rebuilding the graph.
199  *
200  * current_ir_graph is always set.
201  *
202  * @param list             an array of intrinsic map records
203  * @param length           the length of the array
204  * @param part_block_used  set to true if part_block() must be using during lowering
205  *
206  * @return number of found intrinsics.
207  */
208 FIRM_API size_t lower_intrinsics(i_record *list, size_t length,
209                                    int part_block_used);
210
211 /**
212  * Creates an irprog pass for lower_intrinsics.
213  *
214  * @param name             the name of this pass or NULL
215  * @param list             an array of intrinsic map records
216  * @param length           the length of the array
217  * @param part_block_used  set to true if part_block() must be using during lowering
218  */
219 FIRM_API ir_prog_pass_t *lower_intrinsics_pass(const char *name, i_record *list,
220                                                size_t length, int part_block_used);
221
222 /**
223  * A mapper for the integer/float absolute value: type abs(type v).
224  * Replaces the call by a Abs node.
225  *
226  * @return always 1
227  */
228 FIRM_API int i_mapper_abs(ir_node *call, void *ctx);
229
230 /**
231  * A mapper for the integer byte swap value: type bswap(type v).
232  * Replaces the call by a builtin[ir_bk_bswap] node.
233  *
234  * @return always 1
235  */
236 FIRM_API int i_mapper_bswap(ir_node *call, void *ctx);
237
238 /**
239  * A mapper for the floating point sqrt(v): floattype sqrt(floattype v);
240  *
241  * @return 1 if the sqrt call was removed, 0 else.
242  */
243 FIRM_API int i_mapper_sqrt(ir_node *call, void *ctx);
244
245 /**
246  * A mapper for the floating point cbrt(v): floattype sqrt(floattype v);
247  *
248  * @return 1 if the cbrt call was removed, 0 else.
249  */
250 FIRM_API int i_mapper_cbrt(ir_node *call, void *ctx);
251
252 /**
253  * A mapper for the floating point pow(a, b): floattype pow(floattype a, floattype b);
254  *
255  * @return 1 if the pow call was removed, 0 else.
256  */
257 FIRM_API int i_mapper_pow(ir_node *call, void *ctx);
258
259 /**
260  * A mapper for the floating point exp(a): floattype exp(floattype a);
261  *
262  * @return 1 if the exp call was removed, 0 else.
263  */
264 FIRM_API int i_mapper_exp(ir_node *call, void *ctx);
265
266 #define i_mapper_exp2   i_mapper_exp
267 #define i_mapper_exp10  i_mapper_exp
268
269 /**
270  * A mapper for the floating point log(a): floattype log(floattype a);
271  *
272  * @return 1 if the log call was removed, 0 else.
273  */
274 FIRM_API int i_mapper_log(ir_node *call, void *ctx);
275
276 #define i_mapper_log2   i_mapper_log
277 #define i_mapper_log10  i_mapper_log
278
279 /**
280  * A mapper for the floating point sin(a): floattype sin(floattype a);
281  *
282  * @return 1 if the sin call was removed, 0 else.
283  */
284 FIRM_API int i_mapper_sin(ir_node *call, void *ctx);
285
286 /**
287  * A mapper for the floating point sin(a): floattype cos(floattype a);
288  *
289  * @return 1 if the cos call was removed, 0 else.
290  */
291 FIRM_API int i_mapper_cos(ir_node *call, void *ctx);
292
293 /**
294  * A mapper for the floating point tan(a): floattype tan(floattype a);
295  *
296  * @return 1 if the tan call was removed, 0 else.
297  */
298 FIRM_API int i_mapper_tan(ir_node *call, void *ctx);
299
300 /**
301  * A mapper for the floating point asin(a): floattype asin(floattype a);
302  *
303  * @return 1 if the asin call was removed, 0 else.
304  */
305 FIRM_API int i_mapper_asin(ir_node *call, void *ctx);
306
307 /**
308  * A mapper for the floating point acos(a): floattype acos(floattype a);
309  *
310  * @return 1 if the tan call was removed, 0 else.
311  */
312 FIRM_API int i_mapper_acos(ir_node *call, void *ctx);
313
314 /**
315  * A mapper for the floating point atan(a): floattype atan(floattype a);
316  *
317  * @return 1 if the atan call was removed, 0 else.
318  */
319 FIRM_API int i_mapper_atan(ir_node *call, void *ctx);
320
321 /**
322  * A mapper for the floating point sinh(a): floattype sinh(floattype a);
323  *
324  * @return 1 if the sinh call was removed, 0 else.
325  */
326 FIRM_API int i_mapper_sinh(ir_node *call, void *ctx);
327
328 /**
329  * A mapper for the floating point cosh(a): floattype cosh(floattype a);
330  *
331  * @return 1 if the cosh call was removed, 0 else.
332  */
333 FIRM_API int i_mapper_cosh(ir_node *call, void *ctx);
334
335 /**
336  * A mapper for the floating point tanh(a): floattype tanh(floattype a);
337  *
338  * @return 1 if the tanh call was removed, 0 else.
339  */
340 FIRM_API int i_mapper_tanh(ir_node *call, void *ctx);
341
342 /**
343  * A mapper for the strcmp-Function: inttype strcmp(char pointer a, char pointer b);
344  *
345  * @return 1 if the strcmp call was removed, 0 else.
346  */
347 FIRM_API int i_mapper_strcmp(ir_node *call, void *ctx);
348
349 /**
350  * A mapper for the strncmp-Function: inttype strncmp(char pointer a, char pointer b, inttype len);
351  *
352  * @return 1 if the strncmp call was removed, 0 else.
353  */
354 FIRM_API int i_mapper_strncmp(ir_node *call, void *ctx);
355
356 /**
357  * A mapper for the strcpy-Function: char pointer strcpy(char pointer a, char pointer b);
358  *
359  * @return 1 if the strcpy call was removed, 0 else.
360  */
361 FIRM_API int i_mapper_strcpy(ir_node *call, void *ctx);
362
363 /**
364  * A mapper for the strlen-Function: inttype strlen(char pointer a);
365  *
366  * @return 1 if the strlen call was removed, 0 else.
367  */
368 FIRM_API int i_mapper_strlen(ir_node *call, void *ctx);
369
370 /**
371  * A mapper for the memcpy-Function: void pointer memcpy(void pointer d, void pointer s, inttype c);
372  *
373  * @return 1 if the memcpy call was removed, 0 else.
374  */
375 FIRM_API int i_mapper_memcpy(ir_node *call, void *ctx);
376
377 /**
378  * A mapper for the mempcpy-Function: void pointer mempcpy(void pointer d, void pointer s, inttype c);
379  *
380  * @return 1 if the mempcpy call was removed, 0 else.
381  */
382 FIRM_API int i_mapper_mempcpy(ir_node *call, void *ctx);
383
384 /**
385  * A mapper for the memmove-Function: void pointer memmove(void pointer d, void pointer s, inttype c);
386  *
387  * @return 1 if the memmove call was removed, 0 else.
388  */
389 FIRM_API int i_mapper_memmove(ir_node *call, void *ctx);
390
391 /**
392  * A mapper for the memset-Function: void pointer memset(void pointer d, inttype C, inttype len);
393  *
394  * @return 1 if the memset call was removed, 0 else.
395  */
396 FIRM_API int i_mapper_memset(ir_node *call, void *ctx);
397
398 /**
399  * A mapper for the strncmp-Function: inttype memcmp(void pointer a, void pointer b, inttype len);
400  *
401  * @return 1 if the strncmp call was removed, 0 else.
402  */
403 FIRM_API int i_mapper_memcmp(ir_node *call, void *ctx);
404
405 /**
406  * A mapper for the alloca() function: pointer alloca(inttype size)
407  * Replaces the call by a Alloca(stack_alloc) node.
408  *
409  * @return always 1
410  */
411 FIRM_API int i_mapper_alloca(ir_node *call, void *ctx);
412
413 /**
414  * A runtime routine description.
415  */
416 typedef struct runtime_rt {
417         ir_entity *ent;            /**< The entity representing the runtime routine. */
418         ir_mode   *mode;           /**< The operation mode of the mapped instruction. */
419         ir_mode   *res_mode;       /**< The result mode of the mapped instruction or NULL. */
420         long      mem_proj_nr;     /**< if >= 0, create a memory ProjM() */
421         long      regular_proj_nr; /**< if >= 0, create a regular ProjX() */
422         long      exc_proj_nr;     /**< if >= 0, create a exception ProjX() */
423         long      res_proj_nr;     /**< if >= 0, first result projection number */
424 } runtime_rt;
425
426 /**
427  * A mapper for mapping unsupported instructions to runtime calls.
428  * Maps a op(arg_0, ..., arg_n) into a call to a runtime function
429  * rt(arg_0, ..., arg_n).
430  *
431  * The mapping is only done, if the modes of all arguments matches the
432  * modes of rt's argument.
433  * Further, if op has a memory input, the generated Call uses it, else
434  * it gets a NoMem.
435  * The pinned state of the Call will be set to the pinned state of op.
436  *
437  * Note that i_mapper_RuntimeCall() must be used with a i_instr_record.
438  *
439  * @return 1 if an op was mapped, 0 else
440  *
441  * Some examples:
442  *
443  * - Maps signed Div nodes to calls to rt_Div():
444    @code
445   runtime_rt rt_Div = {
446     ent("int rt_Div(int, int)"),
447     mode_T,
448     mode_Is,
449     pn_Div_M,
450     pn_Div_X_regular,
451     pn_Div_X_except,
452     pn_Div_M,
453     pn_Div_res
454   };
455   i_instr_record map_Div = {
456     INTRINSIC_INSTR,
457     op_Div,
458     i_mapper_RuntimeCall,
459     &rt_Div,
460     NULL
461   };
462   @endcode
463  *
464  * - Maps ConvD(F) to calls to rt_Float2Div():
465   @code
466   runtime_rt rt_Float2Double = {
467     ent("double rt_Float2Div(float)"),
468     get_type_mode("double"),
469     NULL,
470     -1,
471     -1,
472     -1,
473     -1,
474     -1
475   };
476   i_instr_record map_Float2Double = {
477     INTRINSIC_INSTR,
478     op_Conv,
479     i_mapper_RuntimeCall,
480     &rt_Float2Double,
481     NULL
482   };
483   @endcode
484  */
485 FIRM_API int i_mapper_RuntimeCall(ir_node *node, runtime_rt *rt);
486
487 #include "end.h"
488
489 #endif