irnode_t.h 24.4 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
  struct ir_node **graph_arr; /**< array to store all parameters */
54
  /* Attributes holding analyses information */
Michael Beck's avatar
Michael Beck committed
55
  struct dom_info dom;        /**< Datastructure that holds information about dominators.
56
57
58
59
60
61
                 @@@ @todo
                 Eventually overlay with graph_arr as only valid
                 in different phases.  Eventually inline the whole
                 datastructure. */
  /*   exc_t exc;  */            /**< role of this block for exception handling */
  /*   ir_node *handler_entry; */    /**< handler entry block iff this block is part of a region */
Michael Beck's avatar
Michael Beck committed
62
  ir_node ** in_cg;           /**< array with predecessors in
63
64
                   * interprocedural_view, if they differ
                   * from intraprocedural predecessors */
Michael Beck's avatar
Michael Beck committed
65
  int *backedge;              /**< Field n set to true if pred n is backedge.
66
                     @@@ @todo Ev. replace by bitfield! */
Michael Beck's avatar
Michael Beck committed
67
  int *cg_backedge;           /**< Field n set to true if pred n is interprocedural backedge.
68
                     @@@ @todo Ev. replace by bitfield! */
69
70
  ir_extblk *extblk;          /**< the extended basic block this block belongs to */

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

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

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

Michael Beck's avatar
Michael Beck committed
81
/** Cond attributes */
82
typedef struct {
83
84
85
  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. */
86
87
} cond_attr;

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

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

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

Michael Beck's avatar
Michael Beck committed
105
/** Exception attributes */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
106
typedef struct {
Michael Beck's avatar
Michael Beck committed
107
108
109
  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
110
#if PRECISE_EXC_CONTEXT
Michael Beck's avatar
Michael Beck committed
111
  struct ir_node **frag_arr;    /**< For Phi node construction in case of exception */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
112
#endif
Michael Beck's avatar
Michael Beck committed
113
114
} except_attr;

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

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

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

Michael Beck's avatar
Michael Beck committed
135
/** InstOf attributes */
Michael Beck's avatar
Michael Beck committed
136
typedef struct {
Michael Beck's avatar
Michael Beck committed
137
  ir_type *ent;
138
139
140
  int dfn;
} io_attr;

Michael Beck's avatar
Michael Beck committed
141
/** Filter attributes */
142
typedef struct {
Michael Beck's avatar
Michael Beck committed
143
144
145
  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.
146
                     @todo Ev. replace by bitfield! */
147
148
} filter_attr;

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

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

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

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

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

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

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

Sebastian Hack's avatar
Sebastian Hack committed
185
186
187
188
/**
 * Edge info to put into an irn.
 */
typedef struct _irn_edge_info_t {
Michael Beck's avatar
Michael Beck committed
189
190
  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
191
192
193
} irn_edge_info_t;


Michael Beck's avatar
Michael Beck committed
194
/** Some IR-nodes just have one attribute, these are stored here,
Götz Lindenmaier's avatar
Götz Lindenmaier committed
195
196
   some have more. Their name is 'irnodename_attr' */
typedef union {
197
  start_attr     start; /**< For Start */
Michael Beck's avatar
Michael Beck committed
198
199
  block_attr     block; /**< For Block: Fields needed to construct it */
  cond_attr      c;     /**< For Cond. */
200
  const_attr     con;   /**< For Const: contains the value of the constant and a type */
Michael Beck's avatar
Michael Beck committed
201
202
203
204
  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
205
206
  alloc_attr     a;    /**< For Alloc. */
  free_attr      f;    /**< For Free. */
Michael Beck's avatar
Michael Beck committed
207
  io_attr        io;    /**< For InstOf */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
208
  cast_attr      cast;  /**< For Cast. */
209
210
  load_attr      load;  /**< For Load. */
  store_attr     store;  /**< For Store. */
Michael Beck's avatar
Michael Beck committed
211
  int            phi0_pos;  /**< For Phi. Used to remember the value defined by
212
213
214
215
216
                   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
217
  int *phi_backedge;    /**< For Phi after construction.
Götz Lindenmaier's avatar
Götz Lindenmaier committed
218
219
			   Field n set to true if pred n is backedge.
			   @todo Ev. replace by bitfield! */
Michael Beck's avatar
Michael Beck committed
220
  long           proj;          /**< For Proj: contains the result position to project */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
221
  confirm_attr   confirm_cmp;   /**< For Confirm: compare operation */
Michael Beck's avatar
Michael Beck committed
222
223
224
225
  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 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
226
227
228
} attr;


Michael Beck's avatar
Michael Beck committed
229
230
/** 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
231
struct ir_node {
Michael Beck's avatar
Michael Beck committed
232
233
234
235
236
  /* ------- 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
237
  unsigned long visited;   /**< visited counter for walks of the graph */
Michael Beck's avatar
Michael Beck committed
238
  void *link;              /**< to attach additional information to the node, e.g.
Götz Lindenmaier's avatar
Götz Lindenmaier committed
239
                              used while construction to link Phi0 nodes and
Götz Lindenmaier's avatar
Götz Lindenmaier committed
240
241
			      during optimization to link to nodes that
			      shall replace a node. */
Michael Beck's avatar
Michael Beck committed
242
  /* ------- Fields for optimizations / analysis information ------- */
Sebastian Hack's avatar
Sebastian Hack committed
243
  struct ir_node **out;    /**< @deprecated array of out edges. */
Michael Beck's avatar
Michael Beck committed
244
245
  struct dbg_info* dbi;    /**< A pointer to information for debug support. */
  /* ------- For debugging ------- */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
246
#ifdef DEBUG_libfirm
Sebastian Hack's avatar
Sebastian Hack committed
247
	int out_valid;
Michael Beck's avatar
Michael Beck committed
248
  int node_nr;             /**< a unique node number for each node to make output
Götz Lindenmaier's avatar
Götz Lindenmaier committed
249
			      readable. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
250
#endif
Götz Lindenmaier's avatar
Götz Lindenmaier committed
251
252
  /* ------- 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
253
#ifdef  DO_HEAPANALYSIS
Michael Beck's avatar
Michael Beck committed
254
  struct abstval *av;      /**< the abstract value of this node */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
255
  struct section *sec;
Sebastian Hack's avatar
Sebastian Hack committed
256
#endif
257
#if FIRM_EDGES_INPLACE
Michael Beck's avatar
Michael Beck committed
258
  irn_edge_info_t edge_info;  /**< everlasting out edges */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
259
#endif
Götz Lindenmaier's avatar
Götz Lindenmaier committed
260
  /* ------- Opcode depending fields -------- */
Michael Beck's avatar
Michael Beck committed
261
262
  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
263
264
};

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

Michael Beck's avatar
Michael Beck committed
266
/** Returns the array with the ins.  The content of the array may not be
267
   changed.  */
268
ir_node     **get_irn_in            (const ir_node *node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
269

Michael Beck's avatar
Michael Beck committed
270
/** @{ */
Michael Beck's avatar
Michael Beck committed
271
/** access attributes directly */
272
273
274
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
275
free_attr     get_irn_free_attr     (ir_node *node);
276
symconst_attr get_irn_symconst_attr (ir_node *node);
Michael Beck's avatar
Michael Beck committed
277
278
ir_type      *get_irn_call_attr     (ir_node *node);
ir_type      *get_irn_funccall_attr (ir_node *node);
279
280
281
282
283
284
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
285
/** @} */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
286

287
/**
288
289
290
291
 * 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
292
293
294
295
296
297
298
299
300
301
/**
 * 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);
302

Michael Beck's avatar
Michael Beck committed
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
/**
 * 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
325
/*-------------------------------------------------------------------*/
Götz Lindenmaier's avatar
Götz Lindenmaier committed
326
327
/*  These function are most used in libfirm.  Give them as static    */
/*  functions so they can be inlined.                                */
Michael Beck's avatar
Michael Beck committed
328
/*-------------------------------------------------------------------*/
Götz Lindenmaier's avatar
Götz Lindenmaier committed
329

330
331
332
333
334
/**
 * Checks whether a pointer points to a ir node.
 * Intern version for libFirm.
 */
static INLINE int
335
_is_ir_node (const void *thing) {
336
337
  return (get_kind(thing) == k_ir_node);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
338

339
340
341
342
343
/**
 * Gets the op of a node.
 * Intern version for libFirm.
 */
static INLINE ir_op *
344
_get_irn_op (const ir_node *node) {
345
346
347
348
  assert (node);
  return node->op;
}

349
350
351
352
/** 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) {
353
  ir_op *op = _get_irn_op(old_node);
354
355

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

359
360
361
362
363
/**
 * Gets the opcode of a node.
 * Intern version for libFirm.
 */
static INLINE opcode
364
_get_irn_opcode (const ir_node *node) {
365
  assert (k_ir_node == get_kind(node));
366
  assert (node->op);
367
368
  return node->op->code;
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
369

Michael Beck's avatar
Michael Beck committed
370
371
372
373
/**
 * Returns the number of predecessors without the block predecessor.
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
374
static INLINE int
375
_get_irn_intra_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
376
377
378
379
  assert(node);
  return ARR_LEN(node->in) - 1;
}

Michael Beck's avatar
Michael Beck committed
380
381
382
383
/**
 * Returns the number of predecessors without the block predecessor.
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
384
static INLINE int
385
_get_irn_inter_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
386
  assert(node);
Michael Beck's avatar
Michael Beck committed
387
  if (_get_irn_op(node) == op_Filter) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
388
389
    assert(node->attr.filter.in_cg);
    return ARR_LEN(node->attr.filter.in_cg) - 1;
Michael Beck's avatar
Michael Beck committed
390
  } else if (_get_irn_op(node) == op_Block && node->attr.block.in_cg) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
391
392
    return ARR_LEN(node->attr.block.in_cg) - 1;
  }
393
  return _get_irn_intra_arity(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
394
395
}

Michael Beck's avatar
Michael Beck committed
396
397
398
399
/**
 * Returns the number of predecessors without the block predecessor.
 * Intern version for libFirm.
 */
400
extern int (*_get_irn_arity)(const ir_node *node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
401

Michael Beck's avatar
Michael Beck committed
402
403
404
/**
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
405
static INLINE ir_node *
406
_get_irn_intra_n (const ir_node *node, int n) {
Michael Beck's avatar
Michael Beck committed
407
408
  ir_node *nn;

409
  assert(node); assert(-1 <= n && n < _get_irn_intra_arity(node));
410

Michael Beck's avatar
Michael Beck committed
411
412
413
414
  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
415
416
}

Michael Beck's avatar
Michael Beck committed
417
418
419
/**
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
420
static INLINE ir_node*
421
422
_get_irn_inter_n (const ir_node *node, int n) {
  assert(node); assert(-1 <= n && n < _get_irn_inter_arity(node));
423

Götz Lindenmaier's avatar
Götz Lindenmaier committed
424
  /* handle Filter and Block specially */
425
  if (_get_irn_op(node) == op_Filter) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
426
    assert(node->attr.filter.in_cg);
427
    return (node->attr.filter.in_cg[n + 1] = skip_Id(node->attr.filter.in_cg[n + 1]));
428
  } else if (_get_irn_op(node) == op_Block && node->attr.block.in_cg) {
429
    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
430
431
  }

432
  return _get_irn_intra_n (node, n);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
433
434
}

Michael Beck's avatar
Michael Beck committed
435
436
/**
 * Access to the predecessors of a node.
437
 * To iterate over the operands iterate from 0 to i < get_irn_arity(),
Michael Beck's avatar
Michael Beck committed
438
439
440
441
442
 * 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.
 */
443
extern ir_node *(*_get_irn_n)(const ir_node *node, int n);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
444

Michael Beck's avatar
Michael Beck committed
445
446
447
448
/**
 * Gets the mode of a node.
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
449
static INLINE ir_mode *
450
_get_irn_mode (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
451
452
453
454
455
{
  assert (node);
  return node->mode;
}

Michael Beck's avatar
Michael Beck committed
456
/**
457
458
459
460
 * Sets the mode of a node.
 * Intern version of libFirm.
 */
static INLINE void
461
_set_irn_mode (ir_node *node, ir_mode *mode)
462
463
464
465
466
467
468
{
  assert (node);
  node->mode = mode;
}

/**
 * Gets the visited counter of a node.
Michael Beck's avatar
Michael Beck committed
469
470
 * Intern version for libFirm.
 */
471
static INLINE unsigned long
472
_get_irn_visited (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
473
474
{
  assert (node);
475
  return node->visited;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
476
477
}

Michael Beck's avatar
Michael Beck committed
478
/**
479
 * Sets the visited counter of a node.
Michael Beck's avatar
Michael Beck committed
480
481
 * Intern version for libFirm.
 */
482
static INLINE void
483
_set_irn_visited (ir_node *node, unsigned long visited)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
484
{
485
486
487
488
489
490
491
492
493
  assert (node);
  node->visited = visited;
}

/**
 * Mark a node as visited in a graph.
 * Intern version for libFirm.
 */
static INLINE void
494
_mark_irn_visited (ir_node *node) {
495
496
497
498
499
500
501
502
503
  assert (node);
  node->visited = current_ir_graph->visited;
}

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

509
510
511
512
513
/**
 * Returns non-zero if a node of was NOT visited.
 * Intern version for libFirm.
 */
static INLINE int
514
_irn_not_visited(const ir_node *node) {
515
516
517
518
519
520
521
522
523
  assert (node);
  return (node->visited < current_ir_graph->visited);
}

/**
 * Sets the link of a node.
 * Intern version of libFirm.
 */
static INLINE void
524
_set_irn_link(ir_node *node, void *link) {
525
526
527
  assert (node);
  /* Link field is used for Phi construction and various optimizations
     in iropt. */
528
  assert(get_irg_phase_state(get_irn_irg(node)) != phase_building);
529
530
531
532
533
534
535
536
537

  node->link = link;
}

/**
 * Returns the link of a node.
 * Intern version of libFirm.
 */
static INLINE void *
538
539
_get_irn_link(const ir_node *node) {
  assert (node && _is_ir_node(node));
540
541
  return node->link;
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
542

Michael Beck's avatar
Michael Beck committed
543
/**
544
545
546
 * 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
547
548
549
 * Intern version of libFirm.
 */
static INLINE op_pin_state
550
551
552
_get_irn_pinned(const ir_node *node) {
  op_pin_state state;
  assert(node && _is_ir_node(node));
553
  /* Check opcode */
554
  state = _get_op_pinned(_get_irn_op(node));
555

556
  if (state >= op_pin_state_exc_pinned)
Michael Beck's avatar
Michael Beck committed
557
558
559
560
    return get_opt_fragile_ops() ? node->attr.except.pin_state : op_pin_state_pinned;
  return state;
}

561
562
static INLINE op_pin_state
_is_irn_pinned_in_irg(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
563
564
  if (get_irg_pinned(get_irn_irg(node)) == op_pin_state_floats)
    return get_irn_pinned(node);
565
566
567
  return op_pin_state_pinned;
}

Michael Beck's avatar
Michael Beck committed
568
static INLINE int
569
570
_is_unop(const ir_node *node) {
  assert(node && _is_ir_node(node));
Michael Beck's avatar
Michael Beck committed
571
572
573
574
  return (node->op->opar == oparity_unary);
}

static INLINE int
575
576
_is_binop(const ir_node *node) {
  assert(node && _is_ir_node(node));
Michael Beck's avatar
Michael Beck committed
577
578
579
580
  return (node->op->opar == oparity_binary);
}

static INLINE int
581
_is_Bad(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
582
  assert(node);
583
  return (node && _get_irn_op(node) == op_Bad);
Michael Beck's avatar
Michael Beck committed
584
585
}

Sebastian Hack's avatar
Sebastian Hack committed
586
587
static INLINE int
_is_Const(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
588
  assert(node);
Sebastian Hack's avatar
Sebastian Hack committed
589
590
591
  return (node && _get_irn_op(node) == op_Const);
}

Michael Beck's avatar
Michael Beck committed
592
593
594
595
596
597
static INLINE int
_is_Unknown (const ir_node *node) {
  assert(node);
  return (node && _get_irn_op(node) == op_Unknown);
}

Michael Beck's avatar
Michael Beck committed
598
static INLINE int
599
600
601
_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
602
603
604
}

static INLINE int
605
606
607
_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
608
609
}

610
611
612
613
614
615
616
617
618
619
620
621
622
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);
}

623
624
/* Get the predecessor block.
 *
625
 *  Returns the block corresponding to the predecessor pos.
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
 *
 *  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
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
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));
}

667
static INLINE ir_node *
668
669
_set_Block_dead(ir_node *block) {
  assert(_get_irn_op(block) == op_Block);
670
671
672
673
674
  block->attr.block.dead = 1;
  return block;
}

static INLINE int
675
676
_is_Block_dead(const ir_node *block) {
  ir_op * op = _get_irn_op(block);
677
678
679
680
681
682
683
684
685

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

Sebastian Hack's avatar
Sebastian Hack committed
686
static INLINE tarval *_get_Const_tarval (ir_node *node) {
687
  assert (_get_irn_op(node) == op_Const);
Sebastian Hack's avatar
Sebastian Hack committed
688
689
690
  return node->attr.con.tv;
}

691
692
static INLINE cnst_classify_t _classify_Const(ir_node *node) {
  ir_op *op;
Sebastian Hack's avatar
Sebastian Hack committed
693
694
  assert(_is_ir_node(node));

695
  op = _get_irn_op(node);
Sebastian Hack's avatar
Sebastian Hack committed
696

697
698
699
700
  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
701

702
  return CNST_NO_CONST;
Sebastian Hack's avatar
Sebastian Hack committed
703
704
}

Michael Beck's avatar
Michael Beck committed
705
706
707
708
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
709
static INLINE ir_type *_get_irn_type(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
710
  return _get_irn_op(node)->ops.get_type(node);
711
}
Sebastian Hack's avatar
Sebastian Hack committed
712

Michael Beck's avatar
Michael Beck committed
713
static INLINE ir_type *_get_irn_type_attr(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
714
715
716
  return _get_irn_op(node)->ops.get_type_attr(node);
}

Michael Beck's avatar
Michael Beck committed
717
static INLINE entity *_get_irn_entity_attr(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
718
719
720
  return _get_irn_op(node)->ops.get_entity_attr(node);
}

Michael Beck's avatar
Michael Beck committed
721
722
723
724
static INLINE int _is_irn_constlike(const ir_node *node) {
  return is_op_constlike(_get_irn_op(node));
}

725
726
727
728
729
730
731
732
733
734
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;
}

735
/* this section MUST contain all inline functions */
Michael Beck's avatar
Michael Beck committed
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
#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)
754
755
#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
756
757
#define is_unop(node)                         _is_unop(node)
#define is_binop(node)                        _is_binop(node)
Sebastian Hack's avatar
Sebastian Hack committed
758
#define is_Const(node)                        _is_Const(node)
Michael Beck's avatar
Michael Beck committed
759
#define is_Unknown(node)                      _is_Unknown(node)
Michael Beck's avatar
Michael Beck committed
760
761
762
#define is_Bad(node)                          _is_Bad(node)
#define is_no_Block(node)                     _is_no_Block(node)
#define is_Block(node)                        _is_Block(node)
763
764
#define get_Block_n_cfgpreds(node)            _get_Block_n_cfgpreds(node)
#define get_Block_cfgpred(node, pos)          _get_Block_cfgpred(node, pos)
765
#define get_Block_cfgpred_block(node, pos)    _get_Block_cfgpred_block(node, pos)
Michael Beck's avatar
Michael Beck committed
766
767
768
769
770
771
772
773
#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
774
#define is_irn_forking(node)                  _is_irn_forking(node)
Michael Beck's avatar
Michael Beck committed
775
#define get_irn_type(node)                    _get_irn_type(node)
Michael Beck's avatar
Michael Beck committed
776
777
#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
778
#define is_irn_constlike(node)                _is_irn_constlike(node)
779
780
#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
781

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