irnode_t.h 28.5 KB
Newer Older
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1
2
3
4
5
/*
 * Project:     libFIRM
 * File name:   ir/ir/irnode_t.h
 * Purpose:     Representation of an intermediate operation -- private header.
 * Author:      Martin Trapp, Christian Schaefer
6
 * Modified by: Goetz Lindenmaier, Michael Beck
Götz Lindenmaier's avatar
Götz Lindenmaier committed
7
8
9
10
11
12
 * 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
/**
 * @file irnode_t.h
 *
 * Declarations of an ir node.
 *
 * @author Martin Trapp, Christian Schaefer
 */
20
21
#ifndef _IRNODE_T_H_
#define _IRNODE_T_H_
Götz Lindenmaier's avatar
Götz Lindenmaier committed
22

23
24
25
26
27
28
29
30
31
32
#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
33

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

Sebastian Hack's avatar
Sebastian Hack committed
41

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

Michael Beck's avatar
Michael Beck committed
44
/** Block attributes */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
45
typedef struct {
46
47
  /* General attributes */
  ir_graph *irg;
Michael Beck's avatar
Michael Beck committed
48
  unsigned long block_visited;  /**< for the walker that walks over all blocks. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
49
  /* Attributes private to construction: */
50
51
  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
52
  ir_node **graph_arr;        /**< array to store all parameters */
53
  /* Attributes holding analyses information */
Michael Beck's avatar
Michael Beck committed
54
55
56
57
58
59
  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
60
  ir_node ** in_cg;           /**< array with predecessors in
Michael Beck's avatar
Michael Beck committed
61
62
                               * interprocedural_view, if they differ
                               * from intraprocedural predecessors */
Michael Beck's avatar
Michael Beck committed
63
  int *backedge;              /**< Field n set to true if pred n is backedge.
Michael Beck's avatar
Michael Beck committed
64
                                   @@@ @todo Ev. replace by bit field! */
Michael Beck's avatar
Michael Beck committed
65
  int *cg_backedge;           /**< Field n set to true if pred n is interprocedural backedge.
Michael Beck's avatar
Michael Beck committed
66
                                   @@@ @todo Ev. replace by bit field! */
67
68
  ir_extblk *extblk;          /**< the extended basic block this block belongs to */

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

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

73
/** Cond attributes. */
74
typedef struct {
75
76
77
  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. */
78
79
} cond_attr;

80
/** Const attributes. */
81
typedef struct {
Michael Beck's avatar
Michael Beck committed
82
83
  tarval  *tv;       /**< the target value */
  ir_type *tp;       /**< the source type, for analyses. default: type_unknown. */
84
85
} const_attr;

86
/** SymConst attributes. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
87
typedef struct {
Beyhan's avatar
Beyhan committed
88
  symconst_symbol sym;  // old tori
Götz Lindenmaier's avatar
Götz Lindenmaier committed
89
  symconst_kind num;
Michael Beck's avatar
Michael Beck committed
90
  ir_type *tp;       /**< the source type, for analyses. default: type_unknown. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
91
92
} symconst_attr;

93
/** Sel attributes. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
94
typedef struct {
Michael Beck's avatar
Michael Beck committed
95
  entity *ent;          /**< entity to select */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
96
97
} sel_attr;

98
/** Exception attributes. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
99
typedef struct {
100
101
102
  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
103
#if PRECISE_EXC_CONTEXT
Michael Beck's avatar
Michael Beck committed
104
  struct ir_node **frag_arr;    /**< For Phi node construction in case of exception */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
105
#endif
Michael Beck's avatar
Michael Beck committed
106
107
} except_attr;

108
/** Call attributes. */
Michael Beck's avatar
Michael Beck committed
109
110
typedef struct {
  except_attr    exc;           /**< the exception attribute. MUST be the first one. */
Michael Beck's avatar
Michael Beck committed
111
  ir_type *cld_tp;              /**< type of called procedure */
Michael Beck's avatar
Michael Beck committed
112
  entity ** callee_arr;         /**< result of callee analysis */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
113
114
} call_attr;

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

122
/** Free attributes. */
Michael Beck's avatar
Michael Beck committed
123
typedef struct {
Michael Beck's avatar
Michael Beck committed
124
  ir_type *type;                /**< Type of the allocated object.  */
Michael Beck's avatar
Michael Beck committed
125
126
127
  where_alloc where;            /**< stack, heap or other managed part of memory */
} free_attr;

128
/** InstOf attributes. */
Michael Beck's avatar
Michael Beck committed
129
typedef struct {
130
131
  except_attr    exc;           /**< the exception attribute. MUST be the first one. */
  ir_type *type;                /**< the type of which the object pointer must be */
132
133
} io_attr;

134
/** Filter attributes. */
135
typedef struct {
Michael Beck's avatar
Michael Beck committed
136
137
138
  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.
139
                     @todo Ev. replace by bitfield! */
140
141
} filter_attr;

142
/** EndReg/EndExcept attributes. */
143
typedef struct {
144
  char dummy;
145
146
} end_attr;

147
/** CallBegin attributes. */
148
typedef struct {
149
  ir_node * call;               /**< Associated Call-operation. */
150
151
} callbegin_attr;

152
/** Cast attributes. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
153
typedef struct {
154
  ir_type *totype;              /**< Type of the casted node. */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
155
156
} cast_attr;

157
/** Load attributes. */
158
typedef struct {
159
160
161
  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. */
162
163
} load_attr;

164
/** Store attributes. */
165
typedef struct {
Michael Beck's avatar
Michael Beck committed
166
  except_attr    exc;           /**< the exception attribute. MUST be the first one. */
Michael Beck's avatar
Michael Beck committed
167
  ent_volatility volatility;	  /**< the volatility of a Store operation */
168
169
} store_attr;

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

172
/** CopyB attribute. */
Michael Beck's avatar
Michael Beck committed
173
typedef struct {
174
175
  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
176
177
} copyb_attr;

178
/** Bound attribute. */
Michael Beck's avatar
Michael Beck committed
179
typedef struct {
180
  except_attr    exc;           /**< The exception attribute. MUST be the first one. */
Michael Beck's avatar
Michael Beck committed
181
182
} bound_attr;

183
184
185
186
187
/** Conv attribute. */
typedef struct {
  char           strict;        /**< If set, this is a strict Conv that cannot be removed. */
} conv_attr;

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


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


Michael Beck's avatar
Michael Beck committed
233
234
/** 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
235
struct ir_node {
Michael Beck's avatar
Michael Beck committed
236
237
238
239
  /* ------- 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. */
240
241
242
243
  struct ir_node **in;     /**< The array of predecessors / operands. */
  unsigned long visited;   /**< Visited counter for walks of the graph. */
  unsigned node_idx;       /**< The node index of this node in its graph. */
  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
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
252
  int out_valid;
253
254
  long node_nr;            /**< A unique node number for each node to make output
                                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 */
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
Michael Beck's avatar
Michael Beck committed
262
  irn_edge_info_t edge_info;  /**< everlasting out edges */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
263
  /* ------- Opcode depending fields -------- */
Michael Beck's avatar
Michael Beck committed
264
265
  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
266
267
};

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

269
270
271
272
273
274
/**
 * 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().
 */
275
ir_node     **get_irn_in            (const ir_node *node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
276

Michael Beck's avatar
Michael Beck committed
277
/** @{ */
Michael Beck's avatar
Michael Beck committed
278
/** access attributes directly */
279
280
281
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
282
free_attr     get_irn_free_attr     (ir_node *node);
283
symconst_attr get_irn_symconst_attr (ir_node *node);
Michael Beck's avatar
Michael Beck committed
284
285
ir_type      *get_irn_call_attr     (ir_node *node);
ir_type      *get_irn_funccall_attr (ir_node *node);
286
287
288
289
290
291
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
292
/** @} */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
293

294
/**
295
296
297
298
 * 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
299
300
301
302
303
304
305
306
307
308
/**
 * 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);
309

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

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

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

356
static INLINE void
357
358
_set_irn_op(ir_node *node, ir_op *op) {
  assert(node);
359
360
361
  node->op = op;
}

362
363
364
365
/** 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) {
366
  ir_op *op = _get_irn_op(old_node);
367
368

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

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

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

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

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

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

422
  assert(node); assert(-1 <= n && n < _get_irn_intra_arity(node));
423

Michael Beck's avatar
Michael Beck committed
424
425
426
427
  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
428
429
}

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

Götz Lindenmaier's avatar
Götz Lindenmaier committed
437
  /* handle Filter and Block specially */
438
  if (_get_irn_op(node) == op_Filter) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
439
    assert(node->attr.filter.in_cg);
440
    return (node->attr.filter.in_cg[n + 1] = skip_Id(node->attr.filter.in_cg[n + 1]));
441
  } else if (_get_irn_op(node) == op_Block && node->attr.block.in_cg) {
442
    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
443
444
  }

445
  return _get_irn_intra_n(node, n);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
446
447
}

Michael Beck's avatar
Michael Beck committed
448
449
/**
 * Access to the predecessors of a node.
450
 * To iterate over the operands iterate from 0 to i < get_irn_arity(),
Michael Beck's avatar
Michael Beck committed
451
452
453
454
455
 * 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.
 */
456
extern ir_node *(*_get_irn_n)(const ir_node *node, int n);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
457

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

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

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

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

/**
 * Mark a node as visited in a graph.
 * Intern version for libFirm.
 */
static INLINE void
Michael Beck's avatar
Michael Beck committed
503
_mark_irn_visited(ir_node *node) {
504
  assert(node);
505
506
507
508
509
510
511
512
  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
  assert(node);
515
  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
  assert(node);
525
526
527
528
529
530
531
532
  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
  assert(node);
535
536
  /* 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
_get_irn_link(const ir_node *node) {
548
  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)
566
567
    return get_opt_fragile_ops() ? node->attr.except.pin_state : op_pin_state_pinned;
  return state;
Michael Beck's avatar
Michael Beck committed
568
569
}

570
571
static INLINE op_pin_state
_is_irn_pinned_in_irg(const ir_node *node) {
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);
Michael Beck's avatar
Michael Beck committed
592
  return (_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);
Michael Beck's avatar
Michael Beck committed
598
  return (_get_irn_op(node) == op_Const);
Sebastian Hack's avatar
Sebastian Hack committed
599
600
}

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

607
static INLINE int
Michael Beck's avatar
Michael Beck committed
608
_is_Return(const ir_node *node) {
609
  assert(node);
Michael Beck's avatar
Michael Beck committed
610
  return (_get_irn_op(node) == op_Return);
611
612
613
}

static INLINE int
Michael Beck's avatar
Michael Beck committed
614
_is_Call(const ir_node *node) {
615
  assert(node);
Michael Beck's avatar
Michael Beck committed
616
  return (_get_irn_op(node) == op_Call);
617
618
619
}

static INLINE int
Michael Beck's avatar
Michael Beck committed
620
_is_Sel(const ir_node *node) {
621
  assert(node);
Michael Beck's avatar
Michael Beck committed
622
  return (_get_irn_op(node) == op_Sel);
623
624
}

Michael Beck's avatar
Michael Beck committed
625
static INLINE int
Michael Beck's avatar
Michael Beck committed
626
_is_Mux(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
627
628
629
630
631
632
633
634
  assert(node);
  if (node) {
    ir_op *op = _get_irn_op(node);
    return (op == op_Mux || ((op == op_Psi) && _get_irn_arity(node) == 3));
  }
  return 0;
}

Michael Beck's avatar
Michael Beck committed
635
static INLINE int
Michael Beck's avatar
Michael Beck committed
636
_is_Load(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
637
  assert(node);
Michael Beck's avatar
Michael Beck committed
638
  return (_get_irn_op(node) == op_Load);
Michael Beck's avatar
Michael Beck committed
639
640
641
}

static INLINE int
Michael Beck's avatar
Michael Beck committed
642
_is_Sync(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
643
  assert(node);
Michael Beck's avatar
Michael Beck committed
644
  return (_get_irn_op(node) == op_Sync);
Michael Beck's avatar
Michael Beck committed
645
646
647
}

static INLINE int
Michael Beck's avatar
Michael Beck committed
648
_is_Confirm(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
649
  assert(node);
Michael Beck's avatar
Michael Beck committed
650
  return (_get_irn_op(node) == op_Confirm);
Michael Beck's avatar
Michael Beck committed
651
652
}

Michael Beck's avatar
Michael Beck committed
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
static INLINE int
_is_SymConst(const ir_node *node) {
  assert(node);
  return (_get_irn_op(node) == op_SymConst);
}

static INLINE int
_is_Cond(const ir_node *node) {
  assert(node);
  return (_get_irn_op(node) == op_Cond);
}

static INLINE int
_is_Cmp(const ir_node *node) {
  assert(node);
  return (_get_irn_op(node) == op_Cmp);
}

Michael Beck's avatar
Michael Beck committed
671
672
673
674
675
676
static INLINE int
_is_Alloc(const ir_node *node) {
  assert(node);
  return (_get_irn_op(node) == op_Alloc);
}

Michael Beck's avatar
Michael Beck committed
677
static INLINE int
678
679
680
_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
681
682
683
}

static INLINE int
684
685
686
_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
687
688
}

689
static INLINE int
Christoph Mallon's avatar
Christoph Mallon committed
690
_get_Block_n_cfgpreds(const ir_node *node) {
691
692
693
694
695
  assert(_is_Block(node));
  return _get_irn_arity(node);
}

static INLINE ir_node *
Michael Beck's avatar
Michael Beck committed
696
_get_Block_cfgpred(ir_node *node, int pos) {
697
698
699
700
701
  assert(0 <= pos && pos < get_irn_arity(node));
  assert(_is_Block(node));
  return _get_irn_n(node, pos);
}

702
703
/* Get the predecessor block.
 *
704
 *  Returns the block corresponding to the predecessor pos.
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
 *
 *  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
721
static INLINE unsigned long
Michael Beck's avatar
Michael Beck committed
722
_get_Block_block_visited(ir_node *node) {
723
  assert(node->op == op_Block);
Michael Beck's avatar
Michael Beck committed
724
725
726
727
  return node->attr.block.block_visited;
}

static INLINE void
Michael Beck's avatar
Michael Beck committed
728
_set_Block_block_visited(ir_node *node, unsigned long visit) {
729
  assert(node->op == op_Block);
Michael Beck's avatar
Michael Beck committed
730
731
732
733
734
  node->attr.block.block_visited = visit;
}

/* For this current_ir_graph must be set. */
static INLINE void
Michael Beck's avatar
Michael Beck committed
735
_mark_Block_block_visited(ir_node *node) {
736
  assert(node->op == op_Block);
Michael Beck's avatar
Michael Beck committed
737
738
739
740
741
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

static INLINE int
_Block_not_block_visited(ir_node *node) {
742
  assert(node->op == op_Block);
Michael Beck's avatar
Michael Beck committed
743
744
745
  return (node->attr.block.block_visited < get_irg_block_visited(current_ir_graph));
}

746
static INLINE ir_node *
747
748
_set_Block_dead(ir_node *block) {
  assert(_get_irn_op(block) == op_Block);
749
750
751
752
753
  block->attr.block.dead = 1;
  return block;
}

static INLINE int
754
_is_Block_dead(const ir_node *block) {
Michael Beck's avatar
Michael Beck committed
755
  ir_op *op = _get_irn_op(block);
756
757
758
759
760
761
762
763
764

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

765
766
static INLINE tarval *_get_Const_tarval(ir_node *node) {
  assert(_get_irn_op(node) == op_Const);
Sebastian Hack's avatar
Sebastian Hack committed
767
768
769
  return node->attr.con.tv;
}

770
771
static INLINE cnst_classify_t _classify_Const(ir_node *node) {
  ir_op *op;
Sebastian Hack's avatar
Sebastian Hack committed
772
773
  assert(_is_ir_node(node));

774
  op = _get_irn_op(node);
Sebastian Hack's avatar
Sebastian Hack committed
775

Michael Beck's avatar
Michael Beck committed
776
  if (op == op_Const)
777
778
779
    return classify_tarval(_get_Const_tarval(node));
  else if(op == op_SymConst)
    return CNST_SYMCONST;
Sebastian Hack's avatar
Sebastian Hack committed
780

781
  return CNST_NO_CONST;
Sebastian Hack's avatar
Sebastian Hack committed
782
783
}

Michael Beck's avatar
Michael Beck committed
784
785
786
787
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
788
static INLINE ir_type *_get_irn_type(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
789
  return _get_irn_op(node)->ops.get_type(node);
790
}
Sebastian Hack's avatar
Sebastian Hack committed
791

Michael Beck's avatar
Michael Beck committed
792
static INLINE ir_type *_get_irn_type_attr(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
793
794
795
  return _get_irn_op(node)->ops.get_type_attr(node);
}

Michael Beck's avatar
Michael Beck committed
796
static INLINE entity *_get_irn_entity_attr(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
797
798
799
  return _get_irn_op(node)->ops.get_entity_attr(node);
}

Michael Beck's avatar
Michael Beck committed
800
801
802
803
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
804
805
806
807
static INLINE int _is_irn_always_opt(const ir_node *node) {
  return is_op_always_opt(_get_irn_op(node));
}

Michael Beck's avatar
Michael Beck committed
808
809
810
811
static INLINE int _is_irn_keep(const ir_node *node) {
  return is_op_keep(_get_irn_op(node));
}

812
813
814
815
816
817
818
819
820
821
822
823
static INLINE int _is_irn_machine_op(const ir_node *node) {
  return is_op_machine(_get_irn_op(node));
}

static INLINE int _is_irn_machine_operand(const ir_node *node) {
  return is_op_machine_operand(_get_irn_op(node));
}

static INLINE int _is_irn_machine_user(const ir_node *node, unsigned n) {
  return is_op_machine_user(_get_irn_op(node), n);
}

824
static INLINE cond_jmp_predicate _get_Cond_jmp_pred(ir_node *node) {
825
  assert(_get_irn_op(node) == op_Cond);
826
  return node->attr.cond.pred;
827
828
829
}

static INLINE void _set_Cond_jmp_pred(ir_node *node, cond_jmp_predicate pred) {
830
  assert(_get_irn_op(node) == op_Cond);
831
  node->attr.cond.pred = pred;
832
833
}

Michael Beck's avatar
Michael Beck committed
834
835
836
837
838
static INLINE int _get_Psi_n_conds(ir_node *node) {
  assert(_get_irn_op(node) == op_Psi);
  return _get_irn_arity(node) >> 1;
}

839
840
841
842
static INLINE unsigned _get_irn_idx(const ir_node *node) {
  return node->node_idx;
}

843
/* this section MUST contain all inline functions */
Michael Beck's avatar
Michael Beck committed
844
845
846
847
848
849
850
851
852
853
#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)
854
#define set_irn_op(node, op)                  _set_irn_op(node, op)
Michael Beck's avatar
Michael Beck committed
855
856
857
858
859
860
861
862
#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)
863
864
#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
865
866
#define is_unop(node)                         _is_unop(node)
#define is_binop(node)                        _is_binop(node)
Sebastian Hack's avatar
Sebastian Hack committed
867
#define is_Const(node)                        _is_Const(node)
Michael Beck's avatar
Michael Beck committed
868
#define is_Unknown(node)                      _is_Unknown(node)
869
870
871
#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
872
#define is_Mux(node)                          _is_Mux(node)
Michael Beck's avatar
Michael Beck committed
873
874
875
#define is_Load(node)                         _is_Load(node)
#define is_Sync(node)                         _is_Sync(node)
#define is_Confirm(node)                      _is_Confirm(node)
Michael Beck's avatar
Michael Beck committed
876
877
#define is_SymConst(node)                     _is_SymConst(node)
#define is_Cond(node)                         _is_Cond(node)
Michael Beck's avatar
Michael Beck committed
878
879
#define is_Cmp(node)                          _is_Cmp(node)
#define is_Alloc(node)                        _is_Alloc(node)
Michael Beck's avatar
Michael Beck committed
880
881
882
#define is_Bad(node)                          _is_Bad(node)
#define is_no_Block(node)                     _is_no_Block(node)
#define is_Block(node)                        _is_Block(node)
883
884
#define get_Block_n_cfgpreds(node)            _get_Block_n_cfgpreds(node)
#define get_Block_cfgpred(node, pos)          _get_Block_cfgpred(node, pos)
885
#define get_Block_cfgpred_block(node, pos)    _get_Block_cfgpred_block(node, pos)
Michael Beck's avatar
Michael Beck committed
886
887
888
889
890
891
892
893
#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
894
#define is_irn_forking(node)                  _is_irn_forking(node)
Michael Beck's avatar
Michael Beck committed
895
#define get_irn_type(node)                    _get_irn_type(node)
Michael Beck's avatar
Michael Beck committed
896
897
#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
898
#define is_irn_constlike(node)                _is_irn_constlike(node)
Michael Beck's avatar
Michael Beck committed
899
#define is_irn_always_opt(node)               _is_irn_always_opt(node)
Michael Beck's avatar
Michael Beck committed
900
#define is_irn_keep(node)                     _is_irn_keep(node)
901
902
903
#define is_irn_machine_op(node)               _is_irn_machine_op(node)
#define is_irn_machine_operand(node)          _is_irn_machine_operand(node)
#define is_irn_machine_user(node, n)          _is_irn_machine_user(node, n)
904
905
#define get_Cond_jmp_pred(node)               _get_Cond_jmp_pred(node)
#define set_Cond_jmp_pred(node, pred)         _set_Cond_jmp_pred(node, pred)
Michael Beck's avatar
Michael Beck committed
906
#define get_Psi_n_conds(node)                 _get_Psi_n_conds(node)
907
#define get_irn_idx(node)                     _get_irn_idx(node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
908

909
#endif /* _IRNODE_T_H_ */