irnode.c 55.5 KB
Newer Older
Christian Schäfer's avatar
Christian Schäfer committed
1
/* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
Sebastian Felis's avatar
Sebastian Felis committed
2
3
4
5
* All rights reserved.
*
* Authors: Martin Trapp, Christian Schaefer, Goetz Lindenmaier
*
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
#include "irgraph_t.h"
17
#include "xp_help.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"
23
#include "irflag.h"
Christian Schäfer's avatar
Christian Schäfer committed
24

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

Götz Lindenmaier's avatar
Götz Lindenmaier committed
29
30
31
32
33
/* 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 */
34
#define END_KEEPALIVE_OFFSET 0
Götz Lindenmaier's avatar
Götz Lindenmaier committed
35

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


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

54
INLINE const char *get_pnc_string(int pnc) {
Christian Schäfer's avatar
Christian Schäfer committed
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
  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 */
}

82
83
84
85
static const char *pns_name_arr [] = {
  "initial_exec", "global_store",
  "frame_base", "globals", "args"
};
Christian Schäfer's avatar
Christian Schäfer committed
86

87
88
89
static const char *symconst_name_arr [] = {
  "type_tag", "size", "linkage_ptr_info"
};
Christian Schäfer's avatar
Christian Schäfer committed
90
91
92
93
94
95
96
97
98
99

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 */
100
INLINE ir_node *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
101
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
102
103
104
105
106
107
108
109
110
111
	     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;
112
  res->visited = 0;
Christian Schäfer's avatar
Christian Schäfer committed
113
114
  res->link = NULL;
  if (arity < 0) {
115
    res->in = NEW_ARR_F (ir_node *, 1);  /* 1: space for block */
Christian Schäfer's avatar
Christian Schäfer committed
116
117
118
119
120
  } 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
121
  set_irn_dbg_info(res, db);
122
  res->out = NULL;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
123
124
125
126
127

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

Christian Schäfer's avatar
Christian Schäfer committed
128
129
130
  return res;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
131
132
133
134
/* 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) {
135
  assert (get_irn_op(old) == get_irn_op(new));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
136
137
  memcpy (&new->attr, &old->attr, get_op_attr_size(get_irn_op(old)));
}
Christian Schäfer's avatar
Christian Schäfer committed
138
139
140
141
142
143
144
145
146
147
148
149
150

/* 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
151
  XPF1 ("%I", get_irn_opident(np));
Christian Schäfer's avatar
Christian Schäfer committed
152
153
154
155
156
157
158
159

  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:
160
    if (get_irn_mode (np) == mode_b) {
Christian Schäfer's avatar
Christian Schäfer committed
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
      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]);
176
    XPF1 (" %#N", get_type_ident(get_SymConst_type(np)));
Christian Schäfer's avatar
Christian Schäfer committed
177
178
179
180
181
182
183
184
    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:
185
186
187
188
  case iro_Break:
  case iro_EndReg:
  case iro_EndExcept:
  case iro_CallBegin:
Christian Schäfer's avatar
Christian Schäfer committed
189
190
191
192
193
194
195
196
197
198
199
    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. */
200
INLINE int
201
get_irn_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
202
  assert(node);
203
204
205
206
207
208
209
210
211
212
  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
213
214
}

215
216
217
218
219
220
/* 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. */
221
INLINE ir_node **
222
get_irn_in (const ir_node *node) {
223
224
225
226
227
228
229
230
231
232
233
  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
234
235
}

236
INLINE void
237
set_irn_in (ir_node *node, int arity, ir_node **in) {
238
  ir_node *** arr;
239
  assert(node);
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
  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;
256
  }
257
  fix_backedges(current_ir_graph->obst, node);
258
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
259
260
}

Christian Schäfer's avatar
Christian Schäfer committed
261
262
263
/* 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
264
265
   i < get_irn_arity.
   If it is a block, the entry -1 is NULL. */
266
INLINE ir_node *
267
get_irn_n (ir_node *node, int n) {
268
  /* debug @@@
269
270
271
  if (-1 > n || get_irn_arity(node) <= n) {
    printf("pos: %d, arity: %d ", n, get_irn_arity(node));
    DDMN(node);
272
    } */
273
  assert(node); assert(-1 <= n && n < get_irn_arity(node));
274
275
276
277
278
279
280
281
282
283
  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
284
285
}

286
INLINE void
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
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
308
309
}

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

317
INLINE modecode
318
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
319
320
321
322
323
{
  assert (node);
  return node->mode->code;
}

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

325
INLINE ident *
326
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
327
328
329
330
331
{
  assert(node);
  return node->mode->name;
}

332
INLINE ir_op *
333
get_irn_op (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
334
335
336
337
338
339
{
  assert (node);
  return node->op;
}

/* should be private to the library: */
340
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
341
342
343
344
345
346
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

347
INLINE opcode
348
get_irn_opcode (const ir_node *node)
349
350
{
  assert (node);
Boris Boesler's avatar
Boris Boesler committed
351
352
  assert (k_ir_node == get_kind(node));
  assert (node -> op);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
353
354
355
  return node->op->code;
}

356
INLINE const char *
357
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
358
359
360
361
362
{
  assert(node);
  return id_to_str(node->op->name);
}

363
INLINE ident *
364
get_irn_opident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
365
366
367
{
  assert(node);
  return node->op->name;
368
369
}

370
INLINE unsigned long
371
get_irn_visited (const ir_node *node)
372
373
374
375
376
{
  assert (node);
  return node->visited;
}

377
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
378
set_irn_visited (ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
379
380
{
  assert (node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
381
  node->visited = visited;
Christian Schäfer's avatar
Christian Schäfer committed
382
}
383

384
INLINE void
385
386
387
388
389
mark_irn_visited (ir_node *node) {
  assert (node);
  node->visited = current_ir_graph->visited;
}

390
INLINE int
391
irn_not_visited  (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
392
393
394
395
  assert (node);
  return (node->visited < current_ir_graph->visited);
}

396
INLINE int
397
irn_visited  (const ir_node *node) {
398
399
400
401
  assert (node);
  return (node->visited >= current_ir_graph->visited);
}

402
INLINE void
403
set_irn_link (ir_node *node, void *link) {
Christian Schäfer's avatar
Christian Schäfer committed
404
  assert (node);
405
406
407
408
  /* 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
409
410
411
  node->link = link;
}

412
INLINE void *
413
get_irn_link (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
414
415
416
417
  assert (node);
  return node->link;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
418
/* Outputs a unique number for this node */
419
INLINE long
420
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
421
  assert(node);
422
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
423
  return node->node_nr;
424
425
#else
  return 0;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
426
#endif
427
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
428

429
INLINE tarval *
Christian Schäfer's avatar
Christian Schäfer committed
430
431
432
433
434
435
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

436
INLINE long
Christian Schäfer's avatar
Christian Schäfer committed
437
438
439
440
441
442
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

443
INLINE alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
444
445
446
447
448
449
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

450
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
451
452
453
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
454
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
455
456
}

457
INLINE symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
458
459
460
461
462
463
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

464
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
465
466
467
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
468
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
469
470
}

471
INLINE sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
472
473
474
475
476
477
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

478
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
479
480
481
482
483
484
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

485
INLINE block_attr
Christian Schäfer's avatar
Christian Schäfer committed
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
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);
}

501
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
502
503
504
505
506
set_nodes_Block (ir_node *node, ir_node *block) {
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

507
508
509
510
/* 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. */
511
INLINE ir_node **
512
513
514
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
515
  return (ir_node **)&(get_irn_in(node)[1]);
516
517
518
}


519
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
520
521
522
523
524
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
  return (get_irn_arity(node));
}

525
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
526
527
get_Block_cfgpred (ir_node *node, int pos) {
  assert (node->op == op_Block);
528
  /* debug @@@
529
530
531
532
  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);
533
    } */
534
  assert(node); assert(-1 <= pos && pos < get_irn_arity(node));
Christian Schäfer's avatar
Christian Schäfer committed
535
536
537
  return get_irn_n(node, pos);
}

538
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
539
540
541
542
543
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

544
INLINE bool
Christian Schäfer's avatar
Christian Schäfer committed
545
546
547
548
549
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

550
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
551
552
553
554
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
555
INLINE unsigned long
556
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
557
  assert (node->op == op_Block);
558
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
559
560
}

561
INLINE void
562
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
563
  assert (node->op == op_Block);
564
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
565
566
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
567
/* For this current_ir_graph must be set. */
568
569
INLINE void
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
570
571
572
573
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

574
575
INLINE int
Block_not_block_visited(ir_node *node) {
576
577
578
  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
579

580
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
581
582
583
584
585
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

586
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
587
588
589
590
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;
}
591

592
/* handler handling for Blocks */
593
594
void
set_Block_handler (ir_node *block, ir_node *handler)  {
595
596
597
598
599
  assert ((block->op == op_Block));
  assert ((handler->op == op_Block));
  block->attr.block.handler_entry = handler;
}

600
601
ir_node *
get_Block_handler (ir_node *block) {
602
603
604
605
606
  assert ((block->op == op_Block));
  return (block->attr.block.handler_entry);
}

/* handler handling for Nodes */
607
608
void
set_Node_handler (ir_node *node, ir_node *handler) {
609
610
611
  set_Block_handler (get_nodes_Block (node), handler);
}

612
613
ir_node *
get_Node_handler (ir_node *node) {
614
615
616
617
  return (get_Block_handler (get_nodes_Block (node)));
}

/* exc_t handling for Blocks */
618
void set_Block_exc (ir_node *block, exc_t exc) {
619
  assert ((block->op == op_Block));
620
621
622
  block->attr.block.exc = exc;
}

623
exc_t get_Block_exc (ir_node *block) {
624
625
  assert ((block->op == op_Block));

626
627
628
  return (block->attr.block.exc);
}

629
/* exc_t handling for Nodes */
630
void set_Node_exc (ir_node *node, exc_t exc) {
631
632
633
  set_Block_exc (get_nodes_Block (node), exc);
}

634
exc_t get_Node_exc (ir_node *node) {
635
636
637
  return (get_Block_exc (get_nodes_Block (node)));
}

638
639
640
641
642
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;
643
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
644
645
646
647
648
649
650
651
    {
      /* Fix backedge array.  fix_backedges operates depending on
	 interprocedural_view. */
      bool ipv = interprocedural_view;
      interprocedural_view = true;
      fix_backedges(current_ir_graph->obst, node);
      interprocedural_view = ipv;
    }
652
653
654
655
656
  }
  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
657
658
659
  assert(node->op == op_Block &&
	 node->attr.block.in_cg &&
	 0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
660
661
662
663
664
665
666
667
668
  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) {
669
670
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
671
672
}

673
674
675
676
677
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];
}

678
679
680
681
682
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

683
INLINE int
684
685
686
687
688
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

689
INLINE ir_node *
690
691
692
693
694
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

695
INLINE void
696
697
698
699
700
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

701
INLINE void
702
703
704
705
706
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);
}

707
INLINE void
708
free_End (ir_node *end) {
709
  assert (end->op == op_End);
710
  /* DEL_ARR_F(end->in);   GL @@@ tut nicht ! */
711
712
713
714
  end->in = NULL;   /* @@@ make sure we get an error if we use the
		       in array afterwards ... */
}

715
ir_graph *get_EndReg_irg (const ir_node *end) {
716
717
718
719
  assert (end->op == op_EndReg);
  return end->attr.end.irg;
}

720
ir_graph *get_EndExcept_irg  (const ir_node *end) {
721
722
  assert (end->op == op_EndReg);
  return end->attr.end.irg;
723
724
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
/*
> 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).
*/
756
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
757
758
759
760
761
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

762
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
763
764
765
766
767
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

768
INLINE cond_kind
769
770
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
771
  return node->attr.c.kind;
772
773
}

774
INLINE void
775
776
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
777
  node->attr.c.kind = kind;
778
779
}

780
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
781
get_Return_mem (ir_node *node) {
782
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
783
784
785
  return get_irn_n(node, 0);
}

786
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
787
788
789
790
791
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

792
INLINE int
793
get_Return_n_ress (ir_node *node) {
794
795
796
797
798
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

INLINE ir_node **
799
800
801
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
802
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
803
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
804
805
  else
    return NULL;
806
807
}

Christian Schäfer's avatar
Christian Schäfer committed
808
/*
809
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
810
811
812
813
814
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

815
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
816
817
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
818
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
819
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
820
821
}

822
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
823
set_Return_res (ir_node *node, int pos, ir_node *res){
824
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
825
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
826
827
}

828
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
829
830
831
832
833
get_Raise_mem (ir_node *node) {
  assert (node->op == op_Return);
  return get_irn_n(node, 0);
}

834
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
835
836
837
838
839
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

840
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
841
842
843
844
845
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

846
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
847
848
849
850
851
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

852
INLINE tarval *get_Const_tarval (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
853
854
855
856
  assert (node->op == op_Const);
  return get_irn_const_attr(node);
}

857
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
858
859
860
861
862
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
  node->attr.con = con;
}

863
INLINE symconst_kind
864
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
865
866
867
868
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

869
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
870
871
872
873
874
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

875
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
876
877
878
879
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
880
  return node->attr.i.tori.typ = skip_tid(node->attr.i.tori.typ);
Christian Schäfer's avatar
Christian Schäfer committed
881
882
}

883
INLINE void
884
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
885
886
887
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
888
  node->attr.i.tori.typ = tp;
Christian Schäfer's avatar
Christian Schäfer committed
889
890
}

891
INLINE ident *
Christian Schäfer's avatar
Christian Schäfer committed
892
893
894
895
896
897
get_SymConst_ptrinfo (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == linkage_ptr_info));
  return node->attr.i.tori.ptrinfo;
}

898
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
899
900
901
902
903
904
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;
}

905
INLINE type_or_id_p
Götz Lindenmaier's avatar
Götz Lindenmaier committed
906
907
908
909
910
get_SymConst_type_or_id (ir_node *node) {
  assert (node->op == op_SymConst);
  return &(node->attr.i.tori);
}

911
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
912
913
914
915
916
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));
}

917
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
918
919
920
921
922
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

923
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
924
925
926
927
928
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

929
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
930
931
932
933
934
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

935
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
936
937
938
939
940
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

941
INLINE int
942
get_Sel_n_indexs (ir_node *node) {
943
944
945
946
947
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

INLINE ir_node **
948
949
950
get_Sel_index_arr (ir_node *node)
{
  assert ((node->op == op_Sel));
951
  if (get_Sel_n_indexs(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
952
    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
953
954
  else
    return NULL;
955
956
}

957
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
958
959
get_Sel_index (ir_node *node, int pos) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
960
  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
961
962
}

963
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
964
965
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
966
  set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
Christian Schäfer's avatar
Christian Schäfer committed
967
968
}

969
INLINE entity *
Christian Schäfer's avatar
Christian Schäfer committed
970
971
972
973
974
get_Sel_entity (ir_node *node) {
  assert (node->op == op_Sel);
  return node->attr.s.ent;
}

975
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
976
977
978
979
980
set_Sel_entity (ir_node *node, entity *ent) {
  assert (node->op == op_Sel);
  node->attr.s.ent = ent;
}

981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
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);
}

1017
1018
1019
1020
1021
1022
1023
1024
1025
1026

/* For unary and binary arithmetic operations the access to the
   operands can be factored out.  Left is the first, right the
   second arithmetic value  as listed in tech report 0999-33.
   unops are: Minus, Abs, Not, Conv
   binops are: Add, Sub, Mul, Quot, DivMod, Div, Mod, And, Or, Eor, Shl,
   Shr, Shrs, Rotate, Cmp */


INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1027
1028
1029
1030
1031
get_Call_mem (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 0);
}

1032
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1033
1034
1035
1036
1037
set_Call_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Call);
  set_irn_n(node, 0, mem);
}

1038
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1039
1040
1041
1042
1043
get_Call_ptr (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 1);
}

1044
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1045
1046
1047
1048
1049
set_Call_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Call);
  set_irn_n(node, 1, ptr);
}

1050
INLINE ir_node **
1051
1052
get_Call_param_arr (ir_node *node) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1053
  return (ir_node **)&get_irn_in(node)[CALL_PARAM_OFFSET + 1];
1054
1055
}

1056
INLINE int
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1057
get_Call_n_params (ir_node *node)  {
Christian Schäfer's avatar
Christian Schäfer committed
1058
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1059
  return (get_irn_arity(node) - CALL_PARAM_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1060
1061
}

1062
INLINE int
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1063
get_Call_arity (ir_node *node) {
1064
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1065
1066
1067
  return get_Call_n_params(node);
}

1068
/* INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1069
1070
1071
1072
1073
set_Call_arity (ir_node *node, ir_node *arity) {
  assert (node->op == op_Call);
}
*/

1074
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1075
1076
get_Call_param (ir_node *node, int pos) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1077
  return get_irn_n(node, pos + CALL_PARAM_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1078
1079
}

1080
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1081
1082
set_Call_param (ir_node *node, int pos, ir_node *param) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1083
  set_irn_n(node, pos + CALL_PARAM_OFFSET, param);
Christian Schäfer's avatar
Christian Schäfer committed
1084
1085
}

1086
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
1087
1088
get_Call_type (ir_node *node) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1089
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
1090
1091
}

1092
INLINE void
1093
set_Call_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
1094
  assert (node->op == op_Call);
1095
1096
  assert (is_method_type(tp));
  node->attr.call.cld_tp = tp;
Christian Schäfer's avatar
Christian Schäfer committed
1097
1098
}

1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
int get_Call_n_callees(ir_node * node) {
  assert(node->op == op_Call && node->attr.call.callee_arr);
  return ARR_LEN(node->attr.call.callee_arr);
}

entity * get_Call_callee(ir_node * node, int pos) {
  assert(node->op == op_Call && node->attr.call.callee_arr);
  return node->attr.call.callee_arr[pos];
}

void set_Call_callee_arr(ir_node * node, int n, entity ** arr) {
  assert(node->op == op_Call);
  if (node->attr.call.callee_arr == NULL || get_Call_n_callees(node) != n) {
    node->attr.call.callee_arr = NEW_ARR_D(entity *, current_ir_graph->obst, n);
  }
  memcpy(node->attr.call.callee_arr, arr, n * sizeof(entity *));
}

void remove_Call_callee_arr(ir_node * node) {
  assert(node->op == op_Call);
  node->attr.call.callee_arr = NULL;
}

1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
ir_node * get_CallBegin_ptr (ir_node *node) {
  assert(node->op == op_CallBegin);
  return get_irn_n(node, 0);
}
void set_CallBegin_ptr (ir_node *node, ir_node *ptr) {
  assert(node->op == op_CallBegin);
  set_irn_n(node, 0, ptr);
}
ir_graph * get_CallBegin_irg (ir_node *node) {
  assert(node->op == op_CallBegin);
  return node->attr.callbegin.irg;
}
ir_node * get_CallBegin_call (ir_node *node) {
  assert(node->op == op_CallBegin);
  return node->attr.callbegin.call;
}
void  set_CallBegin_call (ir_node *node, ir_node *call) {
  assert(node->op == op_CallBegin);
  node->attr.callbegin.call = call;
}

1143
INLINE ir_node *