irnode_t.h 22 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 {
Michael Beck's avatar
Michael Beck committed
83
84
  cond_kind kind;    /**< flavor of Cond */
  long default_proj; /**< for optimization: biggest Proj number, i.e. the one
Michael Beck's avatar
Michael Beck committed
85
                          used for default. */
86
87
} cond_attr;

88
89
90
91
92
93
/** Const attributes */
typedef struct {
  tarval *tv;        /**< the target value */
  type   *tp;        /**< the source type, for analyses. default: type_unknown. */
} 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;
Beyhan's avatar
Beyhan committed
97
  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
115
116
117
118
} except_attr;

typedef struct {
  except_attr    exc;           /**< the exception attribute. MUST be the first one. */
  type *cld_tp;                 /**< type of called procedure */
  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
124
125
  except_attr    exc;           /**< the exception attribute. MUST be the first one. */
  type *type;                   /**< Type of the allocated object.  */
  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
130
131
132
133
/** Free attributes */
typedef struct {
  type *type;                   /**< Type of the allocated object.  */
  where_alloc where;            /**< stack, heap or other managed part of memory */
} free_attr;

Michael Beck's avatar
Michael Beck committed
134
/** InstOf attributes */
135
136
137
138
139
140
typedef struct
{
  type *ent;
  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
161
162
163
/** Cast attributes */
typedef struct {
  type *totype;
} 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 */
168
169
170
171
172
  ent_volatility volatility;	/**< the volatility of a Load/Store operation */
} 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. */
174
175
176
  ent_volatility volatility;	/**< the volatility of a Store operation */
} 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

Sebastian Hack's avatar
Sebastian Hack committed
179
180
181
182
/**
 * Edge info to put into an irn.
 */
typedef struct _irn_edge_info_t {
Michael Beck's avatar
Michael Beck committed
183
184
  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
185
186
187
} irn_edge_info_t;


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


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

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

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

Michael Beck's avatar
Michael Beck committed
263
/** @{ */
Michael Beck's avatar
Michael Beck committed
264
/** access attributes directly */
265
266
267
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
268
free_attr     get_irn_free_attr     (ir_node *node);
269
270
271
272
273
274
275
276
277
symconst_attr get_irn_symconst_attr (ir_node *node);
type         *get_irn_call_attr     (ir_node *node);
type         *get_irn_funccall_attr (ir_node *node);
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
278
/** @} */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
279

280
/**
281
282
283
284
 * The amount of additional space for custom data to be allocated upon creating a new node.
 */
extern unsigned firm_add_node_size;

285
286
287
/** Set the get_type operation of an ir_op. */
ir_op *firm_set_default_get_type(ir_op *op);

Michael Beck's avatar
Michael Beck committed
288
/*-------------------------------------------------------------------*/
Götz Lindenmaier's avatar
Götz Lindenmaier committed
289
290
/*  These function are most used in libfirm.  Give them as static    */
/*  functions so they can be inlined.                                */
Michael Beck's avatar
Michael Beck committed
291
/*-------------------------------------------------------------------*/
Götz Lindenmaier's avatar
Götz Lindenmaier committed
292

293
294
295
296
297
/**
 * Checks whether a pointer points to a ir node.
 * Intern version for libFirm.
 */
static INLINE int
298
_is_ir_node (const void *thing) {
299
300
  return (get_kind(thing) == k_ir_node);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
301

302
303
304
305
306
/**
 * Gets the op of a node.
 * Intern version for libFirm.
 */
static INLINE ir_op *
307
_get_irn_op (const ir_node *node) {
308
309
310
311
  assert (node);
  return node->op;
}

312
313
314
315
/** 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) {
316
  ir_op *op = _get_irn_op(old_node);
317
318
319
320
321

  /* must always exist */
  op->copy_attr(old_node, new_node);
}

322
323
324
325
326
/**
 * Gets the opcode of a node.
 * Intern version for libFirm.
 */
static INLINE opcode
327
_get_irn_opcode (const ir_node *node) {
328
  assert (k_ir_node == get_kind(node));
329
  assert (node->op);
330
331
  return node->op->code;
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
332

Michael Beck's avatar
Michael Beck committed
333
334
335
336
/**
 * Returns the number of predecessors without the block predecessor.
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
337
static INLINE int
338
_get_irn_intra_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
339
340
341
342
  assert(node);
  return ARR_LEN(node->in) - 1;
}

Michael Beck's avatar
Michael Beck committed
343
344
345
346
/**
 * Returns the number of predecessors without the block predecessor.
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
347
static INLINE int
348
_get_irn_inter_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
349
  assert(node);
350
  if (_get_irn_opcode(node) == iro_Filter) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
351
352
    assert(node->attr.filter.in_cg);
    return ARR_LEN(node->attr.filter.in_cg) - 1;
353
  } else if (_get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
354
355
    return ARR_LEN(node->attr.block.in_cg) - 1;
  }
356
  return _get_irn_intra_arity(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
357
358
}

Michael Beck's avatar
Michael Beck committed
359
360
361
362
/**
 * Returns the number of predecessors without the block predecessor.
 * Intern version for libFirm.
 */
363
extern int (*_get_irn_arity)(const ir_node *node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
364

Michael Beck's avatar
Michael Beck committed
365
366
367
/**
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
368
static INLINE ir_node *
369
370
_get_irn_intra_n (const ir_node *node, int n) {
  assert(node); assert(-1 <= n && n < _get_irn_intra_arity(node));
371

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

Michael Beck's avatar
Michael Beck committed
375
376
377
/**
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
378
static INLINE ir_node*
379
380
_get_irn_inter_n (const ir_node *node, int n) {
  assert(node); assert(-1 <= n && n < _get_irn_inter_arity(node));
381

Götz Lindenmaier's avatar
Götz Lindenmaier committed
382
  /* handle Filter and Block specially */
383
  if (_get_irn_op(node) == op_Filter) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
384
    assert(node->attr.filter.in_cg);
385
    return (node->attr.filter.in_cg[n + 1] = skip_Id(node->attr.filter.in_cg[n + 1]));
386
  } else if (_get_irn_op(node) == op_Block && node->attr.block.in_cg) {
387
    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
388
389
  }

390
  return _get_irn_intra_n (node, n);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
391
392
}

Michael Beck's avatar
Michael Beck committed
393
394
/**
 * Access to the predecessors of a node.
395
 * To iterate over the operands iterate from 0 to i < get_irn_arity(),
Michael Beck's avatar
Michael Beck committed
396
397
398
399
400
 * 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.
 */
401
extern ir_node *(*_get_irn_n)(const ir_node *node, int n);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
402

Michael Beck's avatar
Michael Beck committed
403
404
405
406
/**
 * Gets the mode of a node.
 * Intern version for libFirm.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
407
static INLINE ir_mode *
408
_get_irn_mode (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
409
410
411
412
413
{
  assert (node);
  return node->mode;
}

Michael Beck's avatar
Michael Beck committed
414
/**
415
416
417
418
 * Sets the mode of a node.
 * Intern version of libFirm.
 */
static INLINE void
419
_set_irn_mode (ir_node *node, ir_mode *mode)
420
421
422
423
424
425
426
{
  assert (node);
  node->mode = mode;
}

/**
 * Gets the visited counter of a node.
Michael Beck's avatar
Michael Beck committed
427
428
 * Intern version for libFirm.
 */
429
static INLINE unsigned long
430
_get_irn_visited (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
431
432
{
  assert (node);
433
  return node->visited;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
434
435
}

Michael Beck's avatar
Michael Beck committed
436
/**
437
 * Sets the visited counter of a node.
Michael Beck's avatar
Michael Beck committed
438
439
 * Intern version for libFirm.
 */
440
static INLINE void
441
_set_irn_visited (ir_node *node, unsigned long visited)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
442
{
443
444
445
446
447
448
449
450
451
  assert (node);
  node->visited = visited;
}

/**
 * Mark a node as visited in a graph.
 * Intern version for libFirm.
 */
static INLINE void
452
_mark_irn_visited (ir_node *node) {
453
454
455
456
457
458
459
460
461
  assert (node);
  node->visited = current_ir_graph->visited;
}

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

467
468
469
470
471
/**
 * Returns non-zero if a node of was NOT visited.
 * Intern version for libFirm.
 */
static INLINE int
472
_irn_not_visited(const ir_node *node) {
473
474
475
476
477
478
479
480
481
  assert (node);
  return (node->visited < current_ir_graph->visited);
}

/**
 * Sets the link of a node.
 * Intern version of libFirm.
 */
static INLINE void
482
_set_irn_link(ir_node *node, void *link) {
483
484
485
486
487
488
489
490
491
492
493
494
495
  assert (node);
  /* Link field is used for Phi construction and various optimizations
     in iropt. */
  assert(get_irg_phase_state(current_ir_graph) != phase_building);

  node->link = link;
}

/**
 * Returns the link of a node.
 * Intern version of libFirm.
 */
static INLINE void *
496
497
_get_irn_link(const ir_node *node) {
  assert (node && _is_ir_node(node));
498
499
  return node->link;
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
500

Michael Beck's avatar
Michael Beck committed
501
/**
502
503
504
 * 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
505
506
507
 * Intern version of libFirm.
 */
static INLINE op_pin_state
508
509
510
_get_irn_pinned(const ir_node *node) {
  op_pin_state state;
  assert(node && _is_ir_node(node));
511
  /* Check opcode */
512
  state = _get_op_pinned(_get_irn_op(node));
513

514
  if (state >= op_pin_state_exc_pinned)
Michael Beck's avatar
Michael Beck committed
515
516
517
518
    return get_opt_fragile_ops() ? node->attr.except.pin_state : op_pin_state_pinned;
  return state;
}

519
520
static INLINE op_pin_state
_is_irn_pinned_in_irg(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
521
522
  if (get_irg_pinned(get_irn_irg(node)) == op_pin_state_floats)
    return get_irn_pinned(node);
523
524
525
  return op_pin_state_pinned;
}

Michael Beck's avatar
Michael Beck committed
526
static INLINE int
527
528
_is_unop(const ir_node *node) {
  assert(node && _is_ir_node(node));
Michael Beck's avatar
Michael Beck committed
529
530
531
532
  return (node->op->opar == oparity_unary);
}

static INLINE int
533
534
_is_binop(const ir_node *node) {
  assert(node && _is_ir_node(node));
Michael Beck's avatar
Michael Beck committed
535
536
537
538
  return (node->op->opar == oparity_binary);
}

static INLINE int
539
_is_Bad(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
540
  assert(node);
541
  return (node && _get_irn_op(node) == op_Bad);
Michael Beck's avatar
Michael Beck committed
542
543
}

Sebastian Hack's avatar
Sebastian Hack committed
544
545
static INLINE int
_is_Const(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
546
  assert(node);
Sebastian Hack's avatar
Sebastian Hack committed
547
548
549
  return (node && _get_irn_op(node) == op_Const);
}

Michael Beck's avatar
Michael Beck committed
550
551
552
553
554
555
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
556
static INLINE int
557
558
559
_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
560
561
562
}

static INLINE int
563
564
565
_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
566
567
}

568
569
570
571
572
573
574
575
576
577
578
579
580
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);
}

581
582
/* Get the predecessor block.
 *
583
 *  Returns the block corresponding to the predecessor pos.
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
 *
 *  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
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
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));
}

625
static INLINE ir_node *
626
627
_set_Block_dead(ir_node *block) {
  assert(_get_irn_op(block) == op_Block);
628
629
630
631
632
  block->attr.block.dead = 1;
  return block;
}

static INLINE int
633
634
_is_Block_dead(const ir_node *block) {
  ir_op * op = _get_irn_op(block);
635
636
637
638
639
640
641
642
643

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

Sebastian Hack's avatar
Sebastian Hack committed
644
static INLINE tarval *_get_Const_tarval (ir_node *node) {
645
  assert (_get_irn_op(node) == op_Const);
Sebastian Hack's avatar
Sebastian Hack committed
646
647
648
  return node->attr.con.tv;
}

649
650
static INLINE cnst_classify_t _classify_Const(ir_node *node) {
  ir_op *op;
Sebastian Hack's avatar
Sebastian Hack committed
651
652
  assert(_is_ir_node(node));

653
  op = _get_irn_op(node);
Sebastian Hack's avatar
Sebastian Hack committed
654

655
656
657
658
  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
659

660
  return CNST_NO_CONST;
Sebastian Hack's avatar
Sebastian Hack committed
661
662
}

663
664
665
static INLINE type *_get_irn_type(ir_node *node) {
  return _get_irn_op(node)->get_type(node);
}
Sebastian Hack's avatar
Sebastian Hack committed
666

667
/* this section MUST contain all inline functions */
Michael Beck's avatar
Michael Beck committed
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
#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)
686
687
#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
688
689
#define is_unop(node)                         _is_unop(node)
#define is_binop(node)                        _is_binop(node)
Sebastian Hack's avatar
Sebastian Hack committed
690
#define is_Const(node)                        _is_Const(node)
Michael Beck's avatar
Michael Beck committed
691
#define is_Unknown(node)                      _is_Unknown(node)
Michael Beck's avatar
Michael Beck committed
692
693
694
#define is_Bad(node)                          _is_Bad(node)
#define is_no_Block(node)                     _is_no_Block(node)
#define is_Block(node)                        _is_Block(node)
695
696
#define get_Block_n_cfgpreds(node)            _get_Block_n_cfgpreds(node)
#define get_Block_cfgpred(node, pos)          _get_Block_cfgpred(node, pos)
697
#define get_Block_cfgpred_block(node, pos)    _get_Block_cfgpred_block(node, pos)
Michael Beck's avatar
Michael Beck committed
698
699
700
701
702
703
704
705
706
#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)
#define get_irn_type(node)                    _get_irn_type(node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
707

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