irnode.c 54.9 KB
Newer Older
Christian Schäfer's avatar
Christian Schäfer committed
1
2
3
4
/* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
** All rights reserved.
**
** Authors: Martin Trapp, Christian Schaefer, Goetz Lindenmaier
Götz Lindenmaier's avatar
Götz Lindenmaier committed
5
**
Christian Schäfer's avatar
Christian Schäfer committed
6
7
*/

Boris Boesler's avatar
Boris Boesler committed
8
9
/* $Id$ */

Boris Boesler's avatar
added    
Boris Boesler committed
10
11
12
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
13
#include <string.h>
Boris Boesler's avatar
added    
Boris Boesler committed
14

Götz Lindenmaier's avatar
Götz Lindenmaier committed
15
#include "irnode_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
16
17
#include "irgraph_t.h"
#include "ident_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
18
#include "irmode_t.h"
19
#include "typegmod_t.h"
Christian Schäfer's avatar
Christian Schäfer committed
20
#include "array.h"
21
#include "irbackedge_t.h"
22
#include "irdump.h"
Christian Schäfer's avatar
Christian Schäfer committed
23

Götz Lindenmaier's avatar
Götz Lindenmaier committed
24
#ifdef DEBUG_libfirm
25
#include "irprog_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
26
27
#endif

Götz Lindenmaier's avatar
Götz Lindenmaier committed
28
29
30
31
32
/* some constants fixing the positions of nodes predecessors
   in the in array */
#define CALL_PARAM_OFFSET 2
#define SEL_INDEX_OFFSET 2
#define RETURN_RESULT_OFFSET 1  /* mem is not a result */
33
#define END_KEEPALIVE_OFFSET 0
Götz Lindenmaier's avatar
Götz Lindenmaier committed
34

35
/* Declarations for inlineing */
36
37
38
39
40
41
42
43
44
45
46
INLINE ir_node ** get_irn_in (ir_node *node);
INLINE ir_mode *get_irn_mode (ir_node *node);
INLINE ir_op *get_irn_op (ir_node *node);
INLINE opcode get_irn_opcode (ir_node *node);
INLINE ident *get_irn_opident (ir_node *node);
INLINE type *get_SymConst_type (ir_node *node);
INLINE ir_node *skip_nop (ir_node *node);
INLINE ir_node *skip_nop (ir_node *node);
INLINE int is_Proj (ir_node *node);


Christian Schäfer's avatar
Christian Schäfer committed
47
48
49
50
51
static char *pnc_name_arr [] = {"False", "Eq", "Lt", "Le",
				"Gt", "Ge", "Lg", "Leg", "Uo",
				"Ue", "Ul", "Ule", "Ug", "Uge",
				"Ne", "True" };

52
INLINE char *get_pnc_string(int pnc) {
Christian Schäfer's avatar
Christian Schäfer committed
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  return pnc_name_arr[pnc];
}


int
get_negated_pnc(int pnc) {
  switch (pnc) {
  case False: return True;  break;
  case Eq:    return Ne;    break;
  case Lt:    return Uge;   break;
  case Le:    return Ug;    break;
  case Gt:    return Ule;   break;
  case Ge:    return Ul;    break;
  case Lg:    return Ue;    break;
  case Leg:   return Uo;    break;
  case Uo:    return Leg;   break;
  case Ue:    return Lg;    break;
  case Ul:    return Ge;    break;
  case Ule:   return Gt;    break;
  case Ug:    return Le;    break;
  case Uge:   return Lt;    break;
  case Ne:    return Eq;    break;
  case True:  return False; break;
  }
  return 99; /* to shut up gcc */
}

static char *pns_name_arr [] = {"initial_exec", "global_store",
				"frame_base", "globals", "args"};

static char *symconst_name_arr [] = {"type_tag", "size", "linkage_ptr_info"};

void
init_irnode (void)
{
}

/* irnode constructor                                             */
/* create a new irnode in irg, with an op, mode, arity and        */
/* some incoming irnodes                                          */
/* this constructor is used in every specified irnode constructor */
94
INLINE ir_node *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
95
new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode,
Christian Schäfer's avatar
Christian Schäfer committed
96
97
98
99
100
101
102
103
104
105
	     int arity, ir_node **in)
{
  ir_node *res;
  int node_size = offsetof (ir_node, attr) +  op->attr_size;

  res = (ir_node *) obstack_alloc (irg->obst, node_size);

  res->kind = k_ir_node;
  res->op = op;
  res->mode = mode;
106
  res->visited = 0;
Christian Schäfer's avatar
Christian Schäfer committed
107
108
  res->link = NULL;
  if (arity < 0) {
109
    res->in = NEW_ARR_F (ir_node *, 1);  /* 1: space for block */
Christian Schäfer's avatar
Christian Schäfer committed
110
111
112
113
114
  } else {
    res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1));
    memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
  }
  res->in[0] = block;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
115
  set_irn_dbg_info(res, db);
116
  res->out = NULL;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
117
118
119
120
121

#ifdef DEBUG_libfirm
  res->node_nr = get_irp_new_node_nr();
#endif

Christian Schäfer's avatar
Christian Schäfer committed
122
123
124
  return res;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
125
126
127
128
/* Copies all attributes stored in the old node to the new node.
   Assumes both have the same opcode and sufficient size. */
void
copy_attrs (ir_node *old, ir_node *new) {
129
  assert (get_irn_op(old) == get_irn_op(new));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
130
131
  memcpy (&new->attr, &old->attr, get_op_attr_size(get_irn_op(old)));
}
Christian Schäfer's avatar
Christian Schäfer committed
132
133
134
135
136
137
138
139
140
141
142
143
144

/* IR-Nodes with attributes */
int
ir_node_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
{
  int printed = 0;
  ir_node *np = XP_GETARG (ir_node *, 0);

  if (!np) {
    XPS ("<null ir_node>");
    return printed;
  }

Götz Lindenmaier's avatar
Götz Lindenmaier committed
145
  XPF1 ("%I", get_irn_opident(np));
Christian Schäfer's avatar
Christian Schäfer committed
146
147
148
149
150
151
152
153

  switch (get_irn_opcode (np)) {	/* node label */
  case iro_Const:
    XPF1 ("%I", get_irn_mode(np)->name);
    XPS (" : ");
    XPF1 ("%v", get_irn_const_attr);
    break;
  case iro_Proj:
154
    if (get_irn_mode (np) == mode_b) {
Christian Schäfer's avatar
Christian Schäfer committed
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
      XPC (" ");
      XP (pnc_name_arr[get_irn_proj_attr(np)]);
    } else if (get_irn_opcode (get_irn_in (np)[1]) == iro_Start) {
      XPC (" ");
      XP (pns_name_arr[get_irn_proj_attr(np)]);
    } else {
      XPF1 ("%I", get_irn_mode(np)->name);
      XPC (" ");
      XPF1 ("%d", get_irn_proj_attr(np));
    }
    break;
  case iro_SymConst:
    XPF1 ("%I", get_irn_mode(np)->name);
    XPC  (" ");
    XP   (symconst_name_arr[get_irn_symconst_attr(np).num]);
170
    XPF1 (" %#N", get_type_ident(get_SymConst_type(np)));
Christian Schäfer's avatar
Christian Schäfer committed
171
172
173
174
175
176
177
178
    break;
  case iro_Start:		/* don't dump mode of these */
  case iro_Cond:
  case iro_Block:
  case iro_Call:
  case iro_Jmp:
  case iro_Return:
  case iro_End:
179
180
181
182
  case iro_Break:
  case iro_EndReg:
  case iro_EndExcept:
  case iro_CallBegin:
Christian Schäfer's avatar
Christian Schäfer committed
183
184
185
186
187
188
189
190
191
192
193
    break;
  default:
    XPF1 ("%I", get_irn_mode(np)->name);
  }

  return printed;
}

/** getting some parameters from ir_nodes **/

/* returns the number of predecessors without the block predecessor. */
194
INLINE int
195
get_irn_arity (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
196
  assert(node);
197
198
199
200
201
202
203
204
205
206
  if (interprocedural_view) { /* handle Filter and Block specially */
    if (get_irn_opcode(node) == iro_Filter) {
      assert(node->attr.filter.in_cg);
      return ARR_LEN(node->attr.filter.in_cg) - 1;
    } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
      return ARR_LEN(node->attr.block.in_cg) - 1;
    }
    /* else fall through */
  }
  return ARR_LEN(node->in) - 1;
Christian Schäfer's avatar
Christian Schäfer committed
207
208
}

209
210
211
212
213
214
/* Returns the array with ins. This array is shifted with respect to the
   array accessed by get_irn_n: The block operand is at position 0 not -1.
   (@@@ This should be changed.)
   The order of the predecessors in this array is not guaranteed, except that
   lists of operands as predecessors of Block or arguments of a Call are
   consecutive. */
215
INLINE ir_node **
216
217
218
219
220
221
222
223
224
225
226
227
get_irn_in (ir_node *node) {
  assert(node);
  if (interprocedural_view) { /* handle Filter and Block specially */
    if (get_irn_opcode(node) == iro_Filter) {
      assert(node->attr.filter.in_cg);
      return node->attr.filter.in_cg;
    } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
      return node->attr.block.in_cg;
    }
    /* else fall through */
  }
  return node->in;
Christian Schäfer's avatar
Christian Schäfer committed
228
229
}

230
INLINE void
231
set_irn_in (ir_node *node, int arity, ir_node **in) {
232
  ir_node *** arr;
233
  assert(node);
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
  if (interprocedural_view) { /* handle Filter and Block specially */
    if (get_irn_opcode(node) == iro_Filter) {
      assert(node->attr.filter.in_cg);
      arr = &node->attr.filter.in_cg;
    } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
      arr = &node->attr.block.in_cg;
    } else {
      arr = &node->in;
    }
  } else {
    arr = &node->in;
  }
  if (arity != ARR_LEN(*arr) - 1) {
    ir_node * block = (*arr)[0];
    *arr = NEW_ARR_D(ir_node *, current_ir_graph->obst, arity + 1);
    (*arr)[0] = block;
250
  }
251
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
252
253
}

Christian Schäfer's avatar
Christian Schäfer committed
254
255
256
/* to iterate through the predecessors without touching the array */
/* To iterate over the operands iterate from 0 to i < get_irn_arity(),
   to iterate includind the Block predecessor iterate from i = -1 to
257
258
   i < get_irn_arity.
   If it is a block, the entry -1 is NULL. */
259
INLINE ir_node *
260
get_irn_n (ir_node *node, int n) {
261
  /* debug @@@
262
263
264
  if (-1 > n || get_irn_arity(node) <= n) {
    printf("pos: %d, arity: %d ", n, get_irn_arity(node));
    DDMN(node);
265
    } */
266
  assert(node); assert(-1 <= n && n < get_irn_arity(node));
267
268
269
270
271
272
273
274
275
276
  if (interprocedural_view) { /* handle Filter and Block specially */
    if (get_irn_opcode(node) == iro_Filter) {
      assert(node->attr.filter.in_cg);
      return (node->attr.filter.in_cg[n + 1] = skip_nop(node->attr.filter.in_cg[n + 1]));
    } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
      return (node->attr.block.in_cg[n + 1] = skip_nop(node->attr.block.in_cg[n + 1]));
    }
    /* else fall through */
  }
  return (node->in[n + 1] = skip_nop(node->in[n + 1]));
Christian Schäfer's avatar
Christian Schäfer committed
277
278
}

279
INLINE void
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
set_irn_n (ir_node *node, int n, ir_node *in) {
  assert(node && -1 <= n && n < get_irn_arity(node));
  if ((n == -1) && (get_irn_opcode(node) == iro_Filter)) {
    /* Change block pred in both views! */
    node->in[n + 1] = in;
    assert(node->attr.filter.in_cg);
    node->attr.filter.in_cg[n + 1] = in;
    return;
  }
  if (interprocedural_view) { /* handle Filter and Block specially */
    if (get_irn_opcode(node) == iro_Filter) {
      assert(node->attr.filter.in_cg);
      node->attr.filter.in_cg[n + 1] = in;
      return;
    } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
      node->attr.block.in_cg[n + 1] = in;
      return;
    }
    /* else fall through */
  }
  node->in[n + 1] = in;
Christian Schäfer's avatar
Christian Schäfer committed
301
302
}

303
INLINE ir_mode *
Christian Schäfer's avatar
Christian Schäfer committed
304
305
306
307
308
309
get_irn_mode (ir_node *node)
{
  assert (node);
  return node->mode;
}

310
INLINE modecode
Christian Schäfer's avatar
Christian Schäfer committed
311
312
313
314
315
316
get_irn_modecode (ir_node *node)
{
  assert (node);
  return node->mode->code;
}

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

318
INLINE ident *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
319
get_irn_modeident (ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
320
321
322
323
324
{
  assert(node);
  return node->mode->name;
}

325
INLINE ir_op *
Christian Schäfer's avatar
Christian Schäfer committed
326
327
328
329
330
331
332
get_irn_op (ir_node *node)
{
  assert (node);
  return node->op;
}

/* should be private to the library: */
333
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
334
335
336
337
338
339
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

340
INLINE opcode
Götz Lindenmaier's avatar
Götz Lindenmaier committed
341
get_irn_opcode (ir_node *node)
342
343
{
  assert (node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
344
345
346
  return node->op->code;
}

347
INLINE const char *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
348
get_irn_opname (ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
349
350
351
352
353
{
  assert(node);
  return id_to_str(node->op->name);
}

354
INLINE ident *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
355
get_irn_opident (ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
356
357
358
{
  assert(node);
  return node->op->name;
359
360
}

361
INLINE unsigned long
362
363
364
365
366
367
get_irn_visited (ir_node *node)
{
  assert (node);
  return node->visited;
}

368
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
369
set_irn_visited (ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
370
371
{
  assert (node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
372
  node->visited = visited;
Christian Schäfer's avatar
Christian Schäfer committed
373
}
374

375
INLINE void
376
377
378
379
380
mark_irn_visited (ir_node *node) {
  assert (node);
  node->visited = current_ir_graph->visited;
}

381
INLINE int
Götz Lindenmaier's avatar
Götz Lindenmaier committed
382
383
384
385
386
irn_not_visited  (ir_node *node) {
  assert (node);
  return (node->visited < current_ir_graph->visited);
}

387
388
389
390
391
392
INLINE int
irn_visited  (ir_node *node) {
  assert (node);
  return (node->visited >= current_ir_graph->visited);
}

393
INLINE void
394
set_irn_link (ir_node *node, void *link) {
Christian Schäfer's avatar
Christian Schäfer committed
395
  assert (node);
396
397
398
399
  /* Link field is used for Phi construction and various optimizations
     in iropt. */
  assert(get_irg_phase_state(current_ir_graph) != phase_building);

Christian Schäfer's avatar
Christian Schäfer committed
400
401
402
  node->link = link;
}

403
INLINE void *
Christian Schäfer's avatar
Christian Schäfer committed
404
405
406
407
408
get_irn_link (ir_node *node) {
  assert (node);
  return node->link;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
409
/* Outputs a unique number for this node */
410
INLINE long
Götz Lindenmaier's avatar
Götz Lindenmaier committed
411
412
get_irn_node_nr(ir_node *node) {
  assert(node);
413
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
414
  return node->node_nr;
415
416
#else
  return 0;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
417
#endif
418
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
419

420
INLINE tarval *
Christian Schäfer's avatar
Christian Schäfer committed
421
422
423
424
425
426
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

427
INLINE long
Christian Schäfer's avatar
Christian Schäfer committed
428
429
430
431
432
433
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

434
INLINE alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
435
436
437
438
439
440
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

441
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
442
443
444
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
445
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
446
447
}

448
INLINE symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
449
450
451
452
453
454
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

455
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
456
457
458
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
459
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
460
461
}

462
INLINE sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
463
464
465
466
467
468
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

469
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
470
471
472
473
474
475
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

476
INLINE block_attr
Christian Schäfer's avatar
Christian Schäfer committed
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
get_irn_block_attr (ir_node *node)
{
  assert (node->op == op_Block);
  return node->attr.block;
}

/** manipulate fields of individual nodes **/

/* this works for all except Block */
ir_node *
get_nodes_Block (ir_node *node) {
  assert (!(node->op == op_Block));
  return get_irn_n(node, -1);
}

492
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
493
494
495
496
497
set_nodes_Block (ir_node *node, ir_node *block) {
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

498
499
500
501
/* Returns an array with the predecessors of the Block. Depending on
   the implementation of the graph datastructure this can be a copy of
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
502
INLINE ir_node **
503
504
505
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
506
  return (ir_node **)&(get_irn_in(node)[1]);
507
508
509
}


510
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
511
512
513
514
515
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
  return (get_irn_arity(node));
}

516
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
517
518
get_Block_cfgpred (ir_node *node, int pos) {
  assert (node->op == op_Block);
519
  /* debug @@@
520
521
522
523
  if (-1 > pos || get_irn_arity(node) <= pos) {
    dump_ir_block_graph(current_ir_graph);
    printf("pos: %d, arity: %d ", pos, get_irn_arity(node));
    DDMN(node);
524
    } */
525
  assert(node); assert(-1 <= pos && pos < get_irn_arity(node));
Christian Schäfer's avatar
Christian Schäfer committed
526
527
528
  return get_irn_n(node, pos);
}

529
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
530
531
532
533
534
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

535
INLINE bool
Christian Schäfer's avatar
Christian Schäfer committed
536
537
538
539
540
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

541
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
542
543
544
545
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
546
INLINE unsigned long
547
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
548
  assert (node->op == op_Block);
549
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
550
551
}

552
INLINE void
553
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
554
  assert (node->op == op_Block);
555
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
556
557
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
558
/* For this current_ir_graph must be set. */
559
560
INLINE void
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
561
562
563
564
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

565
566
INLINE int
Block_not_block_visited(ir_node *node) {
567
568
569
  assert (node->op == op_Block);
  return (node->attr.block.block_visited < get_irg_block_visited(current_ir_graph));
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
570

571
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
572
573
574
575
576
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

577
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
578
579
580
581
set_Block_graph_arr (ir_node *node, int pos, ir_node *value) {
  assert (node->op == op_Block);
  node->attr.block.graph_arr[pos+1] = value;
}
582

583
/* handler handling for Blocks */
584
585
void
set_Block_handler (ir_node *block, ir_node *handler)  {
586
587
588
589
590
  assert ((block->op == op_Block));
  assert ((handler->op == op_Block));
  block->attr.block.handler_entry = handler;
}

591
592
ir_node *
get_Block_handler (ir_node *block) {
593
594
595
596
597
  assert ((block->op == op_Block));
  return (block->attr.block.handler_entry);
}

/* handler handling for Nodes */
598
599
void
set_Node_handler (ir_node *node, ir_node *handler) {
600
601
602
  set_Block_handler (get_nodes_Block (node), handler);
}

603
604
ir_node *
get_Node_handler (ir_node *node) {
605
606
607
608
  return (get_Block_handler (get_nodes_Block (node)));
}

/* exc_t handling for Blocks */
609
void set_Block_exc (ir_node *block, exc_t exc) {
610
  assert ((block->op == op_Block));
611
612
613
  block->attr.block.exc = exc;
}

614
exc_t get_Block_exc (ir_node *block) {
615
616
  assert ((block->op == op_Block));

617
618
619
  return (block->attr.block.exc);
}

620
/* exc_t handling for Nodes */
621
void set_Node_exc (ir_node *node, exc_t exc) {
622
623
624
  set_Block_exc (get_nodes_Block (node), exc);
}

625
exc_t get_Node_exc (ir_node *node) {
626
627
628
  return (get_Block_exc (get_nodes_Block (node)));
}

629
630
631
632
633
void set_Block_cg_cfgpred_arr(ir_node * node, int arity, ir_node ** in) {
  assert(node->op == op_Block);
  if (node->attr.block.in_cg == NULL || arity != ARR_LEN(node->attr.block.in_cg) - 1) {
    node->attr.block.in_cg = NEW_ARR_D(ir_node *, current_ir_graph->obst, arity + 1);
    node->attr.block.in_cg[0] = NULL;
634
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
635
636
637
638
639
  }
  memcpy(node->attr.block.in_cg + 1, in, sizeof(ir_node *) * arity);
}

void set_Block_cg_cfgpred(ir_node * node, int pos, ir_node * pred) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
640
641
642
  assert(node->op == op_Block &&
	 node->attr.block.in_cg &&
	 0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
643
644
645
646
647
648
649
650
651
  node->attr.block.in_cg[pos + 1] = pred;
}

ir_node ** get_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? NULL : node->attr.block.in_cg  + 1;
}

int get_Block_cg_n_cfgpreds(ir_node * node) {
652
653
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
654
655
}

656
657
658
659
660
ir_node * get_Block_cg_cfgpred(ir_node * node, int pos) {
  assert(node->op == op_Block && node->attr.block.in_cg);
  return node->attr.block.in_cg[pos + 1];
}

661
662
663
664
665
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

666
INLINE int
667
668
669
670
671
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

672
INLINE ir_node *
673
674
675
676
677
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

678
INLINE void
679
680
681
682
683
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

684
INLINE void
685
686
687
688
689
set_End_keepalive(ir_node *end, int pos, ir_node *ka) {
  assert (end->op == op_End);
  set_irn_n(end, pos + END_KEEPALIVE_OFFSET, ka);
}

690
INLINE void
691
free_End (ir_node *end) {
692
  assert (end->op == op_End);
693
  /* DEL_ARR_F(end->in);   GL @@@ tut nicht ! */
694
695
696
697
698
699
700
701
702
703
704
705
  end->in = NULL;   /* @@@ make sure we get an error if we use the
		       in array afterwards ... */
}

ir_graph *get_EndReg_irg (ir_node *end) {
  assert (end->op == op_EndReg);
  return end->attr.end.irg;
}

ir_graph *get_EndExcept_irg  (ir_node *end) {
  assert (end->op == op_EndReg);
  return end->attr.end.irg;
706
707
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
/*
> Implementing the case construct (which is where the constant Proj node is
> important) involves far more than simply determining the constant values.
> We could argue that this is more properly a function of the translator from
> Firm to the target machine.  That could be done if there was some way of
> projecting "default" out of the Cond node.
I know it's complicated.
Basically there are two proglems:
 - determining the gaps between the projs
 - determining the biggest case constant to konw the proj number for
   the default node.
I see several solutions:
1. Introduce a ProjDefault node.  Solves both problems.
   This means to extend all optimizations executed during construction.
2. Give the Cond node for switch two flavors:
   a) there are no gaps in the projs  (existing flavor)
   b) gaps may exist, default proj is still the Proj with the largest
      projection number.  This covers also the gaps.
3. Fix the semantic of the Cond to that of 2b)

Solution 2 seems to be the best:
Computing the gaps in the Firm representation is not too hard, i.e.,
libfirm can implement a routine that transforms betweeen the two
flavours.  This is also possible for 1) but 2) does not require to
change any existing optimization.
Further it should be far simpler to determine the biggest constant than
to compute all gaps.
I don't want to choose 3) as 2a) seems to have advantages for
dataflow analysis and 3) does not allow to convert the representation to
2a).
*/
739
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
740
741
742
743
744
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

745
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
746
747
748
749
750
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

751
INLINE cond_kind
752
753
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
754
  return node->attr.c.kind;
755
756
}

757
INLINE void
758
759
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
760
  node->attr.c.kind = kind;
761
762
}

763
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
764
get_Return_mem (ir_node *node) {
765
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
766
767
768
  return get_irn_n(node, 0);
}

769
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
770
771
772
773
774
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

775
INLINE int
776
get_Return_n_ress (ir_node *node) {
777
778
779
780
781
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

INLINE ir_node **
782
783
784
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
785
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
786
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
787
788
  else
    return NULL;
789
790
}

Christian Schäfer's avatar
Christian Schäfer committed
791
/*
792
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
793
794
795
796
797
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

798
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
799
800
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
801
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
802
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
803
804
}

805
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
806
set_Return_res (ir_node *node, int pos, ir_node *res){
807
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
808
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
809
810
}

811
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
812
813
814
815
816
get_Raise_mem (ir_node *node) {
  assert (node->op == op_Return);
  return get_irn_n(node, 0);
}

817
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
818
819
820
821
822
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

823
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
824
825
826
827
828
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

829
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
830
831
832
833
834
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

835
INLINE tarval *get_Const_tarval (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
836
837
838
839
  assert (node->op == op_Const);
  return get_irn_const_attr(node);
}

840
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
841
842
843
844
845
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
  node->attr.con = con;
}

846
INLINE symconst_kind
Christian Schäfer's avatar
Christian Schäfer committed
847
848
849
850
851
get_SymConst_kind (ir_node *node) {
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

852
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
853
854
855
856
857
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

858
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
859
860
861
862
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
863
  return node->attr.i.tori.typ = skip_tid(node->attr.i.tori.typ);
Christian Schäfer's avatar
Christian Schäfer committed
864
865
}

866
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
867
868
869
870
871
872
873
set_SymConst_type (ir_node *node, type *type) {
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
  node->attr.i.tori.typ = type;
}

874
INLINE ident *
Christian Schäfer's avatar
Christian Schäfer committed
875
876
877
878
879
880
get_SymConst_ptrinfo (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == linkage_ptr_info));
  return node->attr.i.tori.ptrinfo;
}

881
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
882
883
884
885
886
887
set_SymConst_ptrinfo (ir_node *node, ident *ptrinfo) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == linkage_ptr_info));
  node->attr.i.tori.ptrinfo = ptrinfo;
}

888
INLINE type_or_id_p
Götz Lindenmaier's avatar
Götz Lindenmaier committed
889
890
891
892
893
get_SymConst_type_or_id (ir_node *node) {
  assert (node->op == op_SymConst);
  return &(node->attr.i.tori);
}

894
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
895
896
897
898
899
set_SymConst_type_or_id (ir_node *node, type_or_id_p tori) {
  assert (node->op == op_SymConst);
  memcpy (&(node->attr.i.tori), tori, sizeof(type_or_id));
}

900
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
901
902
903
904
905
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

906
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
907
908
909
910
911
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

912
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
913
914
915
916
917
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

918
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
919
920
921
922
923
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

924
INLINE int
925
get_Sel_n_indexs (ir_node *node) {
926
927
928
929
930
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

INLINE ir_node **
931
932
933
get_Sel_index_arr (ir_node *node)
{
  assert ((node->op == op_Sel));
934
  if (get_Sel_n_indexs(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
935
    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
936
937
  else
    return NULL;
938
939
}

940
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
941
942
get_Sel_index (ir_node *node, int pos) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
943
  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
944
945
}

946
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
947
948
set_Sel_index (ir_node *node, int pos, ir_node *index) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
949
  set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
Christian Schäfer's avatar
Christian Schäfer committed
950
951
}

952
INLINE entity *
Christian Schäfer's avatar
Christian Schäfer committed
953
954
955
956
957
get_Sel_entity (ir_node *node) {
  assert (node->op == op_Sel);
  return node->attr.s.ent;
}

958
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
959
960
961
962
963
set_Sel_entity (ir_node *node, entity *ent) {
  assert (node->op == op_Sel);
  node->attr.s.ent = ent;
}

964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
type *
get_InstOf_ent (ir_node *node) {
  assert (node->op = op_InstOf);
  return (node->attr.io.ent);
}

void
set_InstOf_ent (ir_node *node, type *ent) {
  assert (node->op = op_InstOf);
  node->attr.io.ent = ent;
}

ir_node *
get_InstOf_store (ir_node *node) {
  assert (node->op = op_InstOf);
  return (get_irn_n (node, 0));
}

void
set_InstOf_store (ir_node *node, ir_node *obj) {
  assert (node->op = op_InstOf);
  set_irn_n (node, 0, obj);
}

ir_node *
get_InstOf_obj (ir_node *node) {
  assert (node->op = op_InstOf);
  return (get_irn_n (node, 1));
}

void
set_InstOf_obj (ir_node *node, ir_node *obj) {
  assert (node->op = op_InstOf);
  set_irn_n (node, 1, obj);
}

1000