local_optimize() now kills unrteachable code if dominance info is available.
[libfirm] / ir / ir / irreflect.h
1 /**
2  * @file irreflect.h
3  * @date 9.9.2004
4  * @author Sebastian Hack
5  * @brief Reflection for Firm operations.
6  *
7  * $Id$
8  */
9
10 #ifndef _FIRM_REFLECT_H
11 #define _FIRM_REFLECT_H
12
13 #include <limits.h>
14 #include <stdbool.h>
15
16 #include "irop.h"
17 #include "irnode.h"
18
19 #define RFLCT_MC(m) rflct_ms_ ## m
20 typedef enum {
21   RFLCT_MC(None)  = 0,
22   RFLCT_MC(Mem)   = 2,
23   RFLCT_MC(Bool)  = 4,
24   RFLCT_MC(IntS)  = 8,
25   RFLCT_MC(IntU)  = 16,
26   RFLCT_MC(Float) = 32,
27   RFLCT_MC(Ref)   = 64,
28   RFLCT_MC(Char)  = 128,
29   RFLCT_MC(X)     = 256,
30   RFLCT_MC(BB)    = 512,
31   RFLCT_MC(Cf)    = RFLCT_MC(X) | RFLCT_MC(BB),
32
33   RFLCT_MC(Int) = RFLCT_MC(IntS) | RFLCT_MC(IntU),
34   RFLCT_MC(Intb) = RFLCT_MC(Int) | RFLCT_MC(Bool),
35   RFLCT_MC(Num) = RFLCT_MC(Int) | RFLCT_MC(Float),
36   RFLCT_MC(NumP) = RFLCT_MC(Num) | RFLCT_MC(Ref),
37   RFLCT_MC(Data) = RFLCT_MC(NumP) | RFLCT_MC(Char),
38   RFLCT_MC(Datab) = RFLCT_MC(Data) | RFLCT_MC(Bool),
39   RFLCT_MC(DataM) = RFLCT_MC(Data) | RFLCT_MC(Mem),
40   RFLCT_MC(DataMX) = RFLCT_MC(Data) | RFLCT_MC(Mem) | RFLCT_MC(X),
41   RFLCT_MC(Lh) = RFLCT_MC(Mem) | RFLCT_MC(BB),
42
43   RFLCT_MC(Any) = -1
44
45 } rflct_mode_class_t;
46
47 typedef struct _rflct_arg_t {
48   const char *name;  /**< The name of the argument (just a description). */
49
50   bool is_variadic; /**< True, if this argument can have multiple parameters. */
51   rflct_mode_class_t accepted_modes; /**< The set of accepted modes. */
52
53   int mode_equals; /**< If not variadic: You can specify the index of
54                         another argument meaning, that the mode of the
55                         operand binding at this argument must be the same
56                         as the mode of the operand binding to the argument
57                         at index. If you don't want to express such a
58                         dependency, just give -1 here.
59
60                         If variadic: If true, the modes of all
61                         variadic operands binding to this argument
62                         must be the same. If false, they can differ. */
63 } rflct_arg_t;
64
65 typedef struct _rflct_sig_t {
66         int defs; /**< The number of defined arguments in the signature. */
67         int uses; /**< The number of used arguments in the signature. */
68
69         rflct_arg_t *args; /**< The arguments array. */
70 } rflct_sig_t;
71
72 #define RFLCT_ARG_IS_A(arg,modes) (((arg)->accepted_modes & modes) != 0)
73 #define RFLCT_ARG_VALID(arg) ((arg)->name != NULL)
74 #define RFLCT_SIG_VALID(sig) ((sig) != INT_MAX)
75
76 /**
77  * Get the mode class for an IR mode.
78  * @param mode An IR mode.
79  * @return The corresponding smallest reflection mode class.
80  */
81 rflct_mode_class_t rflct_get_mode_class(const ir_mode *mode);
82
83 /**
84  * Get the number of signatures for a Firm opcode.
85  * @param opc The opcode.
86  * @return The number of signatures for this opcode.
87  */
88 int rflct_get_signature_count(opcode opc);
89
90 /**
91  * Try to get the signature, that matches to a given instance
92  * of a Firm node.
93  * @param irn The node.
94  * @return The first matching signature or -1, if no signature matches.
95  */
96 int rflct_get_signature(const ir_node *irn);
97
98 /**
99  * Get the number of in arguments.
100  * An in argument is a use of a value.
101  * @param opc The opcode.
102  * @param sig The signature you are refering to.
103  * @return The number of arguments.
104  */
105 int rflct_get_in_args_count(opcode opc, int sig);
106
107 /**
108  * Get the number of out arguments.
109  * An out argument is a def of a value.
110  * @param opc The opcode.
111  * @param sig The signature you are refering to.
112  * @return The number of arguments.
113  */
114 int rflct_get_out_args_count(opcode opc, int sig);
115
116 #define rflct_get_args_count(opc, sig, use) \
117   ((use) ? rflct_get_in_args_count(opc, sig) : rflct_get_out_args_count(opc, sig))
118
119 /**
120  * Get the array of use args.
121  * The array is terminated with an entry for which
122  * <code>RFLCT_ARG_VALID</code> is 0.
123  * @param opc The opcode.
124  * @param sig The signature you are referring to (Must be between
125  * 0 and the signature count).
126  * @return The array.
127  */
128 const rflct_arg_t *rflct_get_in_args(opcode opc, int sig);
129
130 /**
131  * Get the array of def args.
132  * The array is terminated with an entry for which
133  * <code>RFLCT_ARG_VALID</code> is 0.
134  * @param opc The opcode.
135  * @param sig The signature you are referring to (Must be between
136  * 0 and the signature count).
137  * @return The array.
138  */
139 const rflct_arg_t *rflct_get_out_args(opcode opc, int sig);
140
141 #define rflct_get_args(opc, sig, use) \
142   ((use) ? rflct_get_in_args(opc, sig) : rflct_get_out_args(opc, sig))
143
144 /**
145  * Make a string representation of a signature of an opcode.
146  * @param buf The buffer to put the string to.
147  * @param n The size of buf.
148  * @param opc The opcode.
149  * @param sig The signature.
150  * @return buf.
151  */
152 char *rflct_to_string(char *buf, int n, opcode opc, int sig);
153
154 /**
155  * Get a string representation of a mode class.
156  * @param str The buffer to put the string to.
157  * @param n The size of the buffer.
158  * @param mc The mode class.
159  * @return str.
160  */
161 char *rflct_mode_class_name(char *str, int n, rflct_mode_class_t mc);
162
163 /**
164  * Create a new opcode.
165  * @param opc The Firm opcode.
166  * @param name A name.
167  * @param commutative True, if the opcode is commuatative.
168  */
169 void rflct_new_opcode(opcode opc, const char *name, bool commutative);
170
171 /**
172  * Add a signature to the opcode.
173  * @param opc The opcode.
174  * @param args The signature.
175  * @return true, if the signature was added sucessfully, false if no
176  * more signatures can be added to the opcode.
177  */
178 bool rflct_opcode_add_signature(opcode opc, rflct_sig_t *sig);
179
180 /**
181  * Allocate a new signature.
182  * @param defs Number of def arguments.
183  * @param uses Number of use arguments.
184  * @return An allocated signature.
185  */
186 rflct_sig_t *rflct_signature_allocate(int defs, int uses);
187
188 /**
189  * Set an argument in a signature.
190  * @param sig The signature.
191  * @param is_use true, if the argument is a use, else it is considered a
192  * def.
193  * @param num The index of the argument.
194  * @param name The name of the argument.
195  * @param mc The mode class of the argument.
196  * @param is_variadic true, if the argument is variadic.
197  * @param mode_equals This variable has following meaning: If the
198  * argument is variadic, a 1 indicates that all operands binding to this
199  * argument must have the same mode. A 0 indicates, that their mode must
200  * be of the specified mode class but can differ. If the argument is non
201  * variadic, a positive number indicates, that the mode of the operand
202  * binding to this argument must be the same as the one binding to
203  * argument indexed by mode_equals. If the mode should not be dependent
204  * to another mode, set -1 here.
205  * @return The index of the argument. Only use this index in mode_equals
206  * parameters of other arguments.
207  */
208 int rflct_signature_set_arg(rflct_sig_t *sig, bool is_use, int num,
209                 const char *name, rflct_mode_class_t mc, bool is_variadic, int mode_equals);
210
211 /**
212  * Get the arguments array index for an argument.
213  * @param sig The signature.
214  * @param is_use True, if the argument indicates a use or def argument.
215  * @param num The number of the argument.
216  * @return The index into the arguments array.
217  */
218 int rflct_signature_get_index(const rflct_sig_t *sig, bool is_use, int num);
219
220
221 #endif /* _FIRM_REFLECT_H */