irnode_t.h 25.6 KB
Newer Older
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1
2
3
4
5
6
7
8
9
10
11
12
/*
 * Project:     libFIRM
 * File name:   ir/ir/irnode_t.h
 * Purpose:     Representation of an intermediate operation -- private header.
 * Author:      Martin Trapp, Christian Schaefer
 * Modified by: Goetz Lindenmaier
 * Created:
 * CVS-ID:      $Id$
 * Copyright:   (c) 1998-2003 Universität Karlsruhe
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */

Michael Beck's avatar
Michael Beck committed
13
14
15
16
17
18
19
20
/**
 * @file irnode_t.h
 *
 * Declarations of an ir node.
 *
 * @author Martin Trapp, Christian Schaefer
 */

Götz Lindenmaier's avatar
Götz Lindenmaier committed
21
22
23
# ifndef _IRNODE_T_H_
# define _IRNODE_T_H_

24
25
26
27
28
29
30
31
32
33
#include "firm_config.h"
#include "irnode.h"
#include "irop_t.h"
#include "irgraph_t.h"
#include "irflag_t.h"
#include "firm_common_t.h"
#include "irdom_t.h" /* For size of struct dom_info. */
#include "dbginfo.h"
#include "irloop.h"
#include "array.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
34

Beyhan's avatar
Beyhan committed
35
#include "set.h"
Sebastian Hack's avatar
Sebastian Hack committed
36
#include "list.h"
Beyhan's avatar
Beyhan committed
37
38
#include "entity_t.h"
#include "type_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
39
#include "tv_t.h"
40
#include "irextbb_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
41

Sebastian Hack's avatar
Sebastian Hack committed
42

Götz Lindenmaier's avatar
Götz Lindenmaier committed
43
/** ir node attributes **/
Götz Lindenmaier's avatar
Götz Lindenmaier committed
44

Michael Beck's avatar
Michael Beck committed
45
/** Block attributes */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
46
typedef struct {
47
48
  /* General attributes */
  ir_graph *irg;
Michael Beck's avatar
Michael Beck committed
49
  unsigned long block_visited;  /**< for the walker that walks over all blocks. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
50
  /* Attributes private to construction: */
51
52
  unsigned matured:1;         /**< if set, all in-nodes of the block are fixed */
  unsigned dead:1;            /**< if set, the block is dead (and could be replace by a Bad */
Michael Beck's avatar
Michael Beck committed
53
  ir_node **graph_arr;        /**< array to store all parameters */
54
  /* Attributes holding analyses information */
Michael Beck's avatar
Michael Beck committed
55
56
57
58
59
60
  dom_info dom;               /**< Datastructure that holds information about dominators.
                                   @@@ @todo
                                   Eventually overlay with graph_arr as only valid
                                   in different phases.  Eventually inline the whole
                                   datastructure. */
  dom_info pdom;              /**< Datastructure that holds information about post-dominators. */
Michael Beck's avatar
Michael Beck committed
61
  ir_node ** in_cg;           /**< array with predecessors in
Michael Beck's avatar
Michael Beck committed
62
63
                               * interprocedural_view, if they differ
                               * from intraprocedural predecessors */
Michael Beck's avatar
Michael Beck committed
64
  int *backedge;              /**< Field n set to true if pred n is backedge.
Michael Beck's avatar
Michael Beck committed
65
                                   @@@ @todo Ev. replace by bit field! */
Michael Beck's avatar
Michael Beck committed
66
  int *cg_backedge;           /**< Field n set to true if pred n is interprocedural backedge.
Michael Beck's avatar
Michael Beck committed
67
                                   @@@ @todo Ev. replace by bit field! */
68
69
  ir_extblk *extblk;          /**< the extended basic block this block belongs to */

70
71
  struct list_head succ_head; /**< A list head for all successor edges of a block. */

Götz Lindenmaier's avatar
Götz Lindenmaier committed
72
73
} block_attr;

74
75
/** Start attributes */
typedef struct {
76
  char dummy;
77
  /*   ir_graph *irg;   @@@ now in block */
78
79
} start_attr;

Michael Beck's avatar
Michael Beck committed
80
/** Cond attributes */
81
typedef struct {
82
83
84
  cond_kind kind;           /**< flavor of Cond */
  long default_proj;        /**< only for non-binary Conds: biggest Proj number, i.e. the one used for default. */
  cond_jmp_predicate pred;  /**< only for binary Conds: The jump predication. */
85
86
} cond_attr;

87
88
/** Const attributes */
typedef struct {
Michael Beck's avatar
Michael Beck committed
89
90
  tarval  *tv;       /**< the target value */
  ir_type *tp;       /**< the source type, for analyses. default: type_unknown. */
91
92
} const_attr;

Götz Lindenmaier's avatar
Götz Lindenmaier committed
93
typedef struct {
Beyhan's avatar
Beyhan committed
94
  symconst_symbol sym;  // old tori
Götz Lindenmaier's avatar
Götz Lindenmaier committed
95
  symconst_kind num;
Michael Beck's avatar
Michael Beck committed
96
  ir_type *tp;       /**< the source type, for analyses. default: type_unknown. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
97
98
} symconst_attr;

Michael Beck's avatar
Michael Beck committed
99
/** Sel attributes */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
100
typedef struct {
Michael Beck's avatar
Michael Beck committed
101
  entity *ent;          /**< entity to select */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
102
103
} sel_attr;

Michael Beck's avatar
Michael Beck committed
104
/** Exception attributes */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
105
typedef struct {
Michael Beck's avatar
Michael Beck committed
106
107
108
  op_pin_state   pin_state;     /**< the pin state for operations that might generate a exception:
                                     If it's know that no exception will be generated, could be set to
                                     op_pin_state_floats. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
109
#if PRECISE_EXC_CONTEXT
Michael Beck's avatar
Michael Beck committed
110
  struct ir_node **frag_arr;    /**< For Phi node construction in case of exception */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
111
#endif
Michael Beck's avatar
Michael Beck committed
112
113
} except_attr;

Michael Beck's avatar
Michael Beck committed
114
/** Call attributes */
Michael Beck's avatar
Michael Beck committed
115
116
typedef struct {
  except_attr    exc;           /**< the exception attribute. MUST be the first one. */
Michael Beck's avatar
Michael Beck committed
117
  ir_type *cld_tp;              /**< type of called procedure */
Michael Beck's avatar
Michael Beck committed
118
  entity ** callee_arr;         /**< result of callee analysis */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
119
120
} call_attr;

Michael Beck's avatar
Michael Beck committed
121
/** Alloc attributes */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
122
typedef struct {
Michael Beck's avatar
Michael Beck committed
123
  except_attr    exc;           /**< the exception attribute. MUST be the first one. */
Michael Beck's avatar
Michael Beck committed
124
  ir_type *type;                /**< Type of the allocated object.  */
Michael Beck's avatar
Michael Beck committed
125
  where_alloc where;            /**< stack, heap or other managed part of memory */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
126
127
} alloc_attr;

Michael Beck's avatar
Michael Beck committed
128
129
/** Free attributes */
typedef struct {
Michael Beck's avatar
Michael Beck committed
130
  ir_type *type;                /**< Type of the allocated object.  */
Michael Beck's avatar
Michael Beck committed
131
132
133
  where_alloc where;            /**< stack, heap or other managed part of memory */
} free_attr;

Michael Beck's avatar
Michael Beck committed
134
/** InstOf attributes */
Michael Beck's avatar
Michael Beck committed
135
typedef struct {
136
137
  except_attr    exc;           /**< the exception attribute. MUST be the first one. */
  ir_type *type;                /**< the type of which the object pointer must be */
138
139
} io_attr;

Michael Beck's avatar
Michael Beck committed
140
/** Filter attributes */
141
typedef struct {
Michael Beck's avatar
Michael Beck committed
142
143
144
  long proj;                 /**< contains the result position to project (Proj) */
  ir_node ** in_cg;          /**< array with interprocedural predecessors (Phi) */
  int *backedge;              /**< Field n set to true if pred n is backedge.
145
                     @todo Ev. replace by bitfield! */
146
147
} filter_attr;

Michael Beck's avatar
Michael Beck committed
148
/** EndReg/EndExcept attributes */
149
typedef struct {
150
  char dummy;
151
152
} end_attr;

Michael Beck's avatar
Michael Beck committed
153
/** CallBegin attributes */
154
typedef struct {
155
  ir_node * call;               /**< Associated Call-operation. */
156
157
} callbegin_attr;

Götz Lindenmaier's avatar
Götz Lindenmaier committed
158
159
/** Cast attributes */
typedef struct {
160
  ir_type *totype;              /**< Type of the casted node. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
161
162
} cast_attr;

163
164
/** Load attributes */
typedef struct {
165
166
167
  except_attr    exc;           /**< The exception attribute. MUST be the first one. */
  ir_mode        *load_mode;    /**< The mode of this Load operation. */
  ent_volatility volatility;	  /**< The volatility of a Load/Store operation. */
168
169
170
171
} load_attr;

/** Store attributes */
typedef struct {
Michael Beck's avatar
Michael Beck committed
172
  except_attr    exc;           /**< the exception attribute. MUST be the first one. */
Michael Beck's avatar
Michael Beck committed
173
  ent_volatility volatility;	  /**< the volatility of a Store operation */
174
175
} store_attr;

Michael Beck's avatar
Michael Beck committed
176
typedef pn_Cmp confirm_attr;    /**< Attribute to hold compare operation */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
177

Michael Beck's avatar
Michael Beck committed
178
/** CopyB attribute */
Michael Beck's avatar
Michael Beck committed
179
typedef struct {
180
181
  except_attr    exc;           /**< The exception attribute. MUST be the first one. */
  ir_type        *data_type;    /**< Type of the copied entity. */
Michael Beck's avatar
Michael Beck committed
182
183
} copyb_attr;

Michael Beck's avatar
Michael Beck committed
184
185
/** Bound attribute */
typedef struct {
186
  except_attr    exc;           /**< The exception attribute. MUST be the first one. */
Michael Beck's avatar
Michael Beck committed
187
188
} bound_attr;

Sebastian Hack's avatar
Sebastian Hack committed
189
190
191
192
/**
 * Edge info to put into an irn.
 */
typedef struct _irn_edge_info_t {
193
194
  struct list_head outs_head;  /**< The list of all outs. */
  int out_count;               /**< Number of outs in the list. */
Sebastian Hack's avatar
Sebastian Hack committed
195
196
197
} irn_edge_info_t;


Michael Beck's avatar
Michael Beck committed
198
/** Some IR-nodes just have one attribute, these are stored here,
Götz Lindenmaier's avatar
Götz Lindenmaier committed
199
200
   some have more. Their name is 'irnodename_attr' */
typedef union {
201
  start_attr     start; /**< For Start */
Michael Beck's avatar
Michael Beck committed
202
203
  block_attr     block; /**< For Block: Fields needed to construct it */
  cond_attr      c;     /**< For Cond. */
204
  const_attr     con;   /**< For Const: contains the value of the constant and a type */
Michael Beck's avatar
Michael Beck committed
205
206
207
208
  symconst_attr  i;     /**< For SymConst. */
  sel_attr       s;     /**< For Sel. */
  call_attr      call;  /**< For Call: pointer to the type of the method to call */
  callbegin_attr callbegin; /**< For CallBegin */
Michael Beck's avatar
Michael Beck committed
209
210
  alloc_attr     a;    /**< For Alloc. */
  free_attr      f;    /**< For Free. */
Michael Beck's avatar
Michael Beck committed
211
  io_attr        io;    /**< For InstOf */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
212
  cast_attr      cast;  /**< For Cast. */
213
214
  load_attr      load;  /**< For Load. */
  store_attr     store;  /**< For Store. */
Michael Beck's avatar
Michael Beck committed
215
  int            phi0_pos;  /**< For Phi. Used to remember the value defined by
216
217
218
219
220
                   this Phi node.  Needed when the Phi is completed
                   to call get_r_internal_value to find the
                   predecessors. If this attribute is set, the Phi
                   node takes the role of the obsolete Phi0 node,
                   therefore the name. */
Michael Beck's avatar
Michael Beck committed
221
  int *phi_backedge;    /**< For Phi after construction.
Götz Lindenmaier's avatar
Götz Lindenmaier committed
222
223
			   Field n set to true if pred n is backedge.
			   @todo Ev. replace by bitfield! */
Michael Beck's avatar
Michael Beck committed
224
  long           proj;          /**< For Proj: contains the result position to project */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
225
  confirm_attr   confirm_cmp;   /**< For Confirm: compare operation */
Michael Beck's avatar
Michael Beck committed
226
227
228
229
  filter_attr    filter;        /**< For Filter */
  end_attr       end;           /**< For EndReg, EndExcept */
  except_attr    except;        /**< For Phi node construction in case of exceptions */
  copyb_attr     copyb;         /**< For CopyB operation */
Michael Beck's avatar
Michael Beck committed
230
  bound_attr     bound;         /**< For Bound operation */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
231
232
233
} attr;


Michael Beck's avatar
Michael Beck committed
234
235
/** common structure of an irnode
    if the node has some attributes, they are stored in attr */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
236
struct ir_node {
Michael Beck's avatar
Michael Beck committed
237
238
239
240
241
  /* ------- Basics of the representation  ------- */
  firm_kind kind;          /**< distinguishes this node from others */
  ir_op *op;               /**< Opcode of this node. */
  ir_mode *mode;           /**< Mode of this node. */
  struct ir_node **in;     /**< array with predecessors / operands */
Michael Beck's avatar
Michael Beck committed
242
  unsigned long visited;   /**< visited counter for walks of the graph */
Michael Beck's avatar
Michael Beck committed
243
  void *link;              /**< to attach additional information to the node, e.g.
Götz Lindenmaier's avatar
Götz Lindenmaier committed
244
                              used while construction to link Phi0 nodes and
Götz Lindenmaier's avatar
Götz Lindenmaier committed
245
246
			      during optimization to link to nodes that
			      shall replace a node. */
Michael Beck's avatar
Michael Beck committed
247
  /* ------- Fields for optimizations / analysis information ------- */
Sebastian Hack's avatar
Sebastian Hack committed
248
  struct ir_node **out;    /**< @deprecated array of out edges. */
Michael Beck's avatar
Michael Beck committed
249
250
  struct dbg_info* dbi;    /**< A pointer to information for debug support. */
  /* ------- For debugging ------- */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
251
#ifdef DEBUG_libfirm
Sebastian Hack's avatar
Sebastian Hack committed
252
	int out_valid;
Michael Beck's avatar
Michael Beck committed
253
  long node_nr;            /**< a unique node number for each node to make output
Götz Lindenmaier's avatar
Götz Lindenmaier committed
254
			      readable. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
255
#endif
Götz Lindenmaier's avatar
Götz Lindenmaier committed
256
257
  /* ------- For analyses -------- */
  ir_loop *loop;           /**< the loop the node is in. Access routines in irloop.h */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
258
#ifdef  DO_HEAPANALYSIS
Michael Beck's avatar
Michael Beck committed
259
  struct abstval *av;      /**< the abstract value of this node */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
260
  struct section *sec;
Sebastian Hack's avatar
Sebastian Hack committed
261
#endif
262
#if FIRM_EDGES_INPLACE
Michael Beck's avatar
Michael Beck committed
263
  irn_edge_info_t edge_info;  /**< everlasting out edges */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
264
#endif
Götz Lindenmaier's avatar
Götz Lindenmaier committed
265
  /* ------- Opcode depending fields -------- */
Michael Beck's avatar
Michael Beck committed
266
267
  attr attr;               /**< attribute of this node. Depends on opcode.
                              Must be last field of struct ir_node. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
268
269
};

Götz Lindenmaier's avatar
Götz Lindenmaier committed
270

271
272
273
274
275
276
/**
 * Returns the array with the ins.  The content of the array may not be
 * changed.
 * Note that this function returns the whole in array including the
 * block predecessor. So, it is NOT symmetric with set_irn_in().
 */
277
ir_node     **get_irn_in            (const ir_node *node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
278

Michael Beck's avatar
Michael Beck committed
279
/** @{ */
Michael Beck's avatar
Michael Beck committed
280
/** access attributes directly */
281
282
283
const_attr    get_irn_const_attr    (ir_node *node);
long          get_irn_proj_attr     (ir_node *node);
alloc_attr    get_irn_alloc_attr    (ir_node *node);
Michael Beck's avatar
Michael Beck committed
284
free_attr     get_irn_free_attr     (ir_node *node);
285
symconst_attr get_irn_symconst_attr (ir_node *node);
Michael Beck's avatar
Michael Beck committed
286
287
ir_type      *get_irn_call_attr     (ir_node *node);
ir_type      *get_irn_funccall_attr (ir_node *node);
288
289
290
291
292
293
sel_attr      get_irn_sel_attr      (ir_node *node);
int           get_irn_phi_attr      (ir_node *node);
block_attr    get_irn_block_attr    (ir_node *node);
load_attr     get_irn_load_attr     (ir_node *node);
store_attr    get_irn_store_attr    (ir_node *node);
except_attr   get_irn_except_attr   (ir_node *node);
Michael Beck's avatar
Michael Beck committed
294
/** @} */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
295

296
/**
297
298
299
300
 * The amount of additional space for custom data to be allocated upon creating a new node.
 */
extern unsigned firm_add_node_size;

Michael Beck's avatar
Michael Beck committed
301
302
303
304
305
306
307
308
309
310
/**
 * Sets the get_type operation for an ir_op_ops.
 *
 * @param code   the opcode for the default operation
 * @param ops    the operations initialized
 *
 * @return
 *    The operations.
 */
ir_op_ops *firm_set_default_get_type(opcode code, ir_op_ops *ops);
311

Michael Beck's avatar
Michael Beck committed
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
/**
 * Sets the get_type_attr operation for an ir_op_ops.
 *
 * @param code   the opcode for the default operation
 * @param ops    the operations initialized
 *
 * @return
 *    The operations.
 */
ir_op_ops *firm_set_default_get_type_attr(opcode code, ir_op_ops *ops);

/**
 * Sets the get_entity_attr operation for an ir_op_ops.
 *
 * @param code   the opcode for the default operation
 * @param ops    the operations initialized
 *
 * @return
 *    The operations.
 */
ir_op_ops *firm_set_default_get_entity_attr(opcode code, ir_op_ops *ops);

Michael Beck's avatar
Michael Beck committed
334
/*-------------------------------------------------------------------*/
Götz Lindenmaier's avatar
Götz Lindenmaier committed
335
336
/*  These function are most used in libfirm.  Give them as static    */
/*  functions so they can be inlined.                                */
Michael Beck's avatar
Michael Beck committed
337
/*-------------------------------------------------------------------*/
Götz Lindenmaier's avatar
Götz Lindenmaier committed
338

339
340
341
342
343
/**
 * Checks whether a pointer points to a ir node.
 * Intern version for libFirm.
 */
static INLINE int
344
_is_ir_node (const void *thing) {
345
346
  return (get_kind(thing) == k_ir_node);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
347

348
349
350
351
352
/**
 * Gets the op of a node.
 * Intern version for libFirm.
 */
static INLINE ir_op *
353
_get_irn_op (const ir_node *node) {
354
355
356
357
  assert (node);
  return node->op;
}

358
359
360
361
/** Copies all attributes stored in the old node  to the new node.
    Assumes both have the same opcode and sufficient size. */
static INLINE void
copy_node_attr(const ir_node *old_node, ir_node *new_node) {
362
  ir_op *op = _get_irn_op(old_node);
363
364

  /* must always exist */
Michael Beck's avatar
Michael Beck committed
365
  op->ops.copy_attr(old_node, new_node);
366
367
}

368
369
370
371
372
/**
 * Gets the opcode of a node.
 * Intern version for libFirm.
 */
static INLINE opcode
373
_get_irn_opcode (const ir_node *node) {
374
  assert (k_ir_node == get_kind(node));
375
  assert (node->op);
376
377
  return node->op->code;
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
378

Michael Beck's avatar
Michael Beck committed
379
380
381
382
/**
 * Returns the number of predecessors without the block predecessor.
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
383
static INLINE int
384
_get_irn_intra_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
385
386
387
388
  assert(node);
  return ARR_LEN(node->in) - 1;
}

Michael Beck's avatar
Michael Beck committed
389
390
391
392
/**
 * Returns the number of predecessors without the block predecessor.
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
393
static INLINE int
394
_get_irn_inter_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
395
  assert(node);
Michael Beck's avatar
Michael Beck committed
396
  if (_get_irn_op(node) == op_Filter) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
397
398
    assert(node->attr.filter.in_cg);
    return ARR_LEN(node->attr.filter.in_cg) - 1;
Michael Beck's avatar
Michael Beck committed
399
  } else if (_get_irn_op(node) == op_Block && node->attr.block.in_cg) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
400
401
    return ARR_LEN(node->attr.block.in_cg) - 1;
  }
402
  return _get_irn_intra_arity(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
403
404
}

Michael Beck's avatar
Michael Beck committed
405
406
407
408
/**
 * Returns the number of predecessors without the block predecessor.
 * Intern version for libFirm.
 */
409
extern int (*_get_irn_arity)(const ir_node *node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
410

Michael Beck's avatar
Michael Beck committed
411
412
413
/**
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
414
static INLINE ir_node *
415
_get_irn_intra_n (const ir_node *node, int n) {
Michael Beck's avatar
Michael Beck committed
416
417
  ir_node *nn;

418
  assert(node); assert(-1 <= n && n < _get_irn_intra_arity(node));
419

Michael Beck's avatar
Michael Beck committed
420
421
422
423
  nn = node->in[n + 1];
  if (!nn || (nn->op != op_Id)) return nn;

  return (node->in[n + 1] = skip_Id(nn));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
424
425
}

Michael Beck's avatar
Michael Beck committed
426
427
428
/**
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
429
static INLINE ir_node*
430
431
_get_irn_inter_n (const ir_node *node, int n) {
  assert(node); assert(-1 <= n && n < _get_irn_inter_arity(node));
432

Götz Lindenmaier's avatar
Götz Lindenmaier committed
433
  /* handle Filter and Block specially */
434
  if (_get_irn_op(node) == op_Filter) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
435
    assert(node->attr.filter.in_cg);
436
    return (node->attr.filter.in_cg[n + 1] = skip_Id(node->attr.filter.in_cg[n + 1]));
437
  } else if (_get_irn_op(node) == op_Block && node->attr.block.in_cg) {
438
    return (node->attr.block.in_cg[n + 1] = skip_Id(node->attr.block.in_cg[n + 1]));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
439
440
  }

441
  return _get_irn_intra_n (node, n);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
442
443
}

Michael Beck's avatar
Michael Beck committed
444
445
/**
 * Access to the predecessors of a node.
446
 * To iterate over the operands iterate from 0 to i < get_irn_arity(),
Michael Beck's avatar
Michael Beck committed
447
448
449
450
451
 * to iterate including the Block predecessor iterate from i = -1 to
 * i < get_irn_arity.
 * If it is a block, the entry -1 is NULL.
 * Intern version for libFirm.
 */
452
extern ir_node *(*_get_irn_n)(const ir_node *node, int n);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
453

Michael Beck's avatar
Michael Beck committed
454
455
456
457
/**
 * Gets the mode of a node.
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
458
static INLINE ir_mode *
459
_get_irn_mode (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
460
461
462
463
464
{
  assert (node);
  return node->mode;
}

Michael Beck's avatar
Michael Beck committed
465
/**
466
467
468
469
 * Sets the mode of a node.
 * Intern version of libFirm.
 */
static INLINE void
470
_set_irn_mode (ir_node *node, ir_mode *mode)
471
472
473
474
475
476
477
{
  assert (node);
  node->mode = mode;
}

/**
 * Gets the visited counter of a node.
Michael Beck's avatar
Michael Beck committed
478
479
 * Intern version for libFirm.
 */
480
static INLINE unsigned long
481
_get_irn_visited (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
482
483
{
  assert (node);
484
  return node->visited;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
485
486
}

Michael Beck's avatar
Michael Beck committed
487
/**
488
 * Sets the visited counter of a node.
Michael Beck's avatar
Michael Beck committed
489
490
 * Intern version for libFirm.
 */
491
static INLINE void
492
_set_irn_visited (ir_node *node, unsigned long visited)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
493
{
494
495
496
497
498
499
500
501
502
  assert (node);
  node->visited = visited;
}

/**
 * Mark a node as visited in a graph.
 * Intern version for libFirm.
 */
static INLINE void
503
_mark_irn_visited (ir_node *node) {
504
505
506
507
508
509
510
511
512
  assert (node);
  node->visited = current_ir_graph->visited;
}

/**
 * Returns non-zero if a node of was visited.
 * Intern version for libFirm.
 */
static INLINE int
513
_irn_visited(const ir_node *node) {
514
515
  assert (node);
  return (node->visited >= current_ir_graph->visited);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
516
517
}

518
519
520
521
522
/**
 * Returns non-zero if a node of was NOT visited.
 * Intern version for libFirm.
 */
static INLINE int
523
_irn_not_visited(const ir_node *node) {
524
525
526
527
528
529
530
531
532
  assert (node);
  return (node->visited < current_ir_graph->visited);
}

/**
 * Sets the link of a node.
 * Intern version of libFirm.
 */
static INLINE void
533
_set_irn_link(ir_node *node, void *link) {
534
535
536
  assert (node);
  /* Link field is used for Phi construction and various optimizations
     in iropt. */
537
  assert(get_irg_phase_state(get_irn_irg(node)) != phase_building);
538
539
540
541
542
543
544
545
546

  node->link = link;
}

/**
 * Returns the link of a node.
 * Intern version of libFirm.
 */
static INLINE void *
547
548
_get_irn_link(const ir_node *node) {
  assert (node && _is_ir_node(node));
549
550
  return node->link;
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
551

Michael Beck's avatar
Michael Beck committed
552
/**
553
554
555
 * Returns whether the node _always_ must be pinned.
 * I.e., the node is not floating after global cse.
 *
Michael Beck's avatar
Michael Beck committed
556
557
558
 * Intern version of libFirm.
 */
static INLINE op_pin_state
559
560
561
_get_irn_pinned(const ir_node *node) {
  op_pin_state state;
  assert(node && _is_ir_node(node));
562
  /* Check opcode */
563
  state = _get_op_pinned(_get_irn_op(node));
564

565
  if (state >= op_pin_state_exc_pinned)
Michael Beck's avatar
Michael Beck committed
566
567
568
569
    return get_opt_fragile_ops() ? node->attr.except.pin_state : op_pin_state_pinned;
  return state;
}

570
571
static INLINE op_pin_state
_is_irn_pinned_in_irg(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
572
573
  if (get_irg_pinned(get_irn_irg(node)) == op_pin_state_floats)
    return get_irn_pinned(node);
574
575
576
  return op_pin_state_pinned;
}

Michael Beck's avatar
Michael Beck committed
577
static INLINE int
578
579
_is_unop(const ir_node *node) {
  assert(node && _is_ir_node(node));
Michael Beck's avatar
Michael Beck committed
580
581
582
583
  return (node->op->opar == oparity_unary);
}

static INLINE int
584
585
_is_binop(const ir_node *node) {
  assert(node && _is_ir_node(node));
Michael Beck's avatar
Michael Beck committed
586
587
588
589
  return (node->op->opar == oparity_binary);
}

static INLINE int
590
_is_Bad(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
591
  assert(node);
592
  return (node && _get_irn_op(node) == op_Bad);
Michael Beck's avatar
Michael Beck committed
593
594
}

Sebastian Hack's avatar
Sebastian Hack committed
595
596
static INLINE int
_is_Const(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
597
  assert(node);
Sebastian Hack's avatar
Sebastian Hack committed
598
599
600
  return (node && _get_irn_op(node) == op_Const);
}

Michael Beck's avatar
Michael Beck committed
601
602
603
604
605
606
static INLINE int
_is_Unknown (const ir_node *node) {
  assert(node);
  return (node && _get_irn_op(node) == op_Unknown);
}

607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
static INLINE int
_is_Return (const ir_node *node) {
  assert(node);
  return (node && _get_irn_op(node) == op_Return);
}

static INLINE int
_is_Call (const ir_node *node) {
  assert(node);
  return (node && _get_irn_op(node) == op_Call);
}

static INLINE int
_is_Sel (const ir_node *node) {
  assert(node);
  return (node && _get_irn_op(node) == op_Sel);
}

Michael Beck's avatar
Michael Beck committed
625
static INLINE int
626
627
628
_is_no_Block(const ir_node *node) {
  assert(node && _is_ir_node(node));
  return (_get_irn_op(node) != op_Block);
Michael Beck's avatar
Michael Beck committed
629
630
631
}

static INLINE int
632
633
634
_is_Block(const ir_node *node) {
  assert(node && _is_ir_node(node));
  return (_get_irn_op(node) == op_Block);
Michael Beck's avatar
Michael Beck committed
635
636
}

637
638
639
640
641
642
643
644
645
646
647
648
649
static INLINE int
_get_Block_n_cfgpreds (ir_node *node) {
  assert(_is_Block(node));
  return _get_irn_arity(node);
}

static INLINE ir_node *
_get_Block_cfgpred (ir_node *node, int pos) {
  assert(0 <= pos && pos < get_irn_arity(node));
  assert(_is_Block(node));
  return _get_irn_n(node, pos);
}

650
651
/* Get the predecessor block.
 *
652
 *  Returns the block corresponding to the predecessor pos.
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
 *
 *  There are several ambiguities we resolve with this function:
 *  - The direct predecessor can be a Proj, which is not pinned.
 *    We walk from the predecessor to the next pinned node
 *    (skip_Proj) and return the block that node is in.
 *  - If we encounter the Bad node, this function does not return
 *    Start, but the Bad node.
 */
static INLINE ir_node  *
_get_Block_cfgpred_block(ir_node *node, int pos) {
  ir_node *res = skip_Proj(get_Block_cfgpred(node, pos));
  if (!is_Bad(res))
    res = get_nodes_block(res);
  return res;
}

Michael Beck's avatar
Michael Beck committed
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
static INLINE unsigned long
_get_Block_block_visited (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.block_visited;
}

static INLINE void
_set_Block_block_visited (ir_node *node, unsigned long visit) {
  assert (node->op == op_Block);
  node->attr.block.block_visited = visit;
}

/* For this current_ir_graph must be set. */
static INLINE void
_mark_Block_block_visited (ir_node *node) {
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

static INLINE int
_Block_not_block_visited(ir_node *node) {
  assert (node->op == op_Block);
  return (node->attr.block.block_visited < get_irg_block_visited(current_ir_graph));
}

694
static INLINE ir_node *
695
696
_set_Block_dead(ir_node *block) {
  assert(_get_irn_op(block) == op_Block);
697
698
699
700
701
  block->attr.block.dead = 1;
  return block;
}

static INLINE int
702
703
_is_Block_dead(const ir_node *block) {
  ir_op * op = _get_irn_op(block);
704
705
706
707
708
709
710
711
712

  if (op == op_Bad)
    return 1;
  else {
    assert(op == op_Block);
    return block->attr.block.dead;
  }
}

Sebastian Hack's avatar
Sebastian Hack committed
713
static INLINE tarval *_get_Const_tarval (ir_node *node) {
714
  assert (_get_irn_op(node) == op_Const);
Sebastian Hack's avatar
Sebastian Hack committed
715
716
717
  return node->attr.con.tv;
}

718
719
static INLINE cnst_classify_t _classify_Const(ir_node *node) {
  ir_op *op;
Sebastian Hack's avatar
Sebastian Hack committed
720
721
  assert(_is_ir_node(node));

722
  op = _get_irn_op(node);
Sebastian Hack's avatar
Sebastian Hack committed
723

724
725
726
727
  if(op == op_Const)
    return classify_tarval(_get_Const_tarval(node));
  else if(op == op_SymConst)
    return CNST_SYMCONST;
Sebastian Hack's avatar
Sebastian Hack committed
728

729
  return CNST_NO_CONST;
Sebastian Hack's avatar
Sebastian Hack committed
730
731
}

Michael Beck's avatar
Michael Beck committed
732
733
734
735
static INLINE int _is_irn_forking(const ir_node *node) {
  return is_op_forking(_get_irn_op(node));
}

Michael Beck's avatar
Michael Beck committed
736
static INLINE ir_type *_get_irn_type(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
737
  return _get_irn_op(node)->ops.get_type(node);
738
}
Sebastian Hack's avatar
Sebastian Hack committed
739

Michael Beck's avatar
Michael Beck committed
740
static INLINE ir_type *_get_irn_type_attr(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
741
742
743
  return _get_irn_op(node)->ops.get_type_attr(node);
}

Michael Beck's avatar
Michael Beck committed
744
static INLINE entity *_get_irn_entity_attr(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
745
746
747
  return _get_irn_op(node)->ops.get_entity_attr(node);
}

Michael Beck's avatar
Michael Beck committed
748
749
750
751
static INLINE int _is_irn_constlike(const ir_node *node) {
  return is_op_constlike(_get_irn_op(node));
}

Michael Beck's avatar
Michael Beck committed
752
753
754
755
static INLINE int _is_irn_keep(const ir_node *node) {
  return is_op_keep(_get_irn_op(node));
}

756
757
758
759
760
761
762
763
764
765
static INLINE cond_jmp_predicate _get_Cond_jmp_pred(ir_node *node) {
  assert (_get_irn_op(node) == op_Cond);
  return node->attr.c.pred;
}

static INLINE void _set_Cond_jmp_pred(ir_node *node, cond_jmp_predicate pred) {
  assert (_get_irn_op(node) == op_Cond);
  node->attr.c.pred = pred;
}

766
/* this section MUST contain all inline functions */
Michael Beck's avatar
Michael Beck committed
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
#define is_ir_node(thing)                     _is_ir_node(thing)
#define get_irn_intra_arity(node)             _get_irn_intra_arity(node)
#define get_irn_inter_arity(node)             _get_irn_inter_arity(node)
#define get_irn_arity(node)                   _get_irn_arity(node)
#define get_irn_intra_n(node, n)              _get_irn_intra_n(node, n)
#define get_irn_inter_n(node, n)              _get_irn_inter_n(node, n)
#define get_irn_n(node, n)                    _get_irn_n(node, n)
#define get_irn_mode(node)                    _get_irn_mode(node)
#define set_irn_mode(node, mode)              _set_irn_mode(node, mode)
#define get_irn_op(node)                      _get_irn_op(node)
#define get_irn_opcode(node)                  _get_irn_opcode(node)
#define get_irn_visited(node)                 _get_irn_visited(node)
#define set_irn_visited(node, v)              _set_irn_visited(node, v)
#define mark_irn_visited(node)                _mark_irn_visited(node)
#define irn_visited(node)                     _irn_visited(node)
#define irn_not_visited(node)                 _irn_not_visited(node)
#define set_irn_link(node, link)              _set_irn_link(node, link)
#define get_irn_link(node)                    _get_irn_link(node)
785
786
#define get_irn_pinned(node)                  _get_irn_pinned(node)
#define is_irn_pinned_in_irg(node)            _is_irn_pinned_in_irg(node)
Michael Beck's avatar
Michael Beck committed
787
788
#define is_unop(node)                         _is_unop(node)
#define is_binop(node)                        _is_binop(node)
Sebastian Hack's avatar
Sebastian Hack committed
789
#define is_Const(node)                        _is_Const(node)
Michael Beck's avatar
Michael Beck committed
790
#define is_Unknown(node)                      _is_Unknown(node)
791
792
793
#define is_Return(node)                       _is_Return(node)
#define is_Call(node)                         _is_Call(node)
#define is_Sel(node)                          _is_Sel(node)
Michael Beck's avatar
Michael Beck committed
794
795
796
#define is_Bad(node)                          _is_Bad(node)
#define is_no_Block(node)                     _is_no_Block(node)
#define is_Block(node)                        _is_Block(node)
797
798
#define get_Block_n_cfgpreds(node)            _get_Block_n_cfgpreds(node)
#define get_Block_cfgpred(node, pos)          _get_Block_cfgpred(node, pos)
799
#define get_Block_cfgpred_block(node, pos)    _get_Block_cfgpred_block(node, pos)
Michael Beck's avatar
Michael Beck committed
800
801
802
803
804
805
806
807
#define get_Block_block_visited(node)         _get_Block_block_visited(node)
#define set_Block_block_visited(node, visit)  _set_Block_block_visited(node, visit)
#define mark_Block_block_visited(node)        _mark_Block_block_visited(node)
#define Block_not_block_visited(node)         _Block_not_block_visited(node)
#define set_Block_dead(block)                 _set_Block_dead(block)
#define is_Block_dead(block)                  _is_Block_dead(block)
#define get_Const_tarval(node)                _get_Const_tarval(node)
#define classify_Const(node)                  _classify_Const(node)
Michael Beck's avatar
Michael Beck committed
808
#define is_irn_forking(node)                  _is_irn_forking(node)
Michael Beck's avatar
Michael Beck committed
809
#define get_irn_type(node)                    _get_irn_type(node)
Michael Beck's avatar
Michael Beck committed
810
811
#define get_irn_type_attr(node)               _get_irn_type_attr(node)
#define get_irn_entity_attr(node)             _get_irn_entity_attr(node)
Michael Beck's avatar
Michael Beck committed
812
#define is_irn_constlike(node)                _is_irn_constlike(node)
Michael Beck's avatar
Michael Beck committed
813
#define is_irn_keep(node)                     _is_irn_keep(node)
814
815
#define get_Cond_jmp_pred(node)               _get_Cond_jmp_pred(node)
#define set_Cond_jmp_pred(node, pred)         _set_Cond_jmp_pred(node, pred)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
816

Götz Lindenmaier's avatar
Götz Lindenmaier committed
817
# endif /* _IRNODE_T_H_ */