irnode.c 55.7 KB
Newer Older
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1
2
3
4
5
6
7
8
9
10
11
/*
 * Project:     libFIRM
 * File name:   ir/ir/irnode.c
 * Purpose:     Representation of an intermediate operation.
 * Author:      Martin Trapp, Christian Schaefer
 * Modified by: Goetz Lindenmaier
 * Created:
 * CVS-ID:      $Id$
 * Copyright:   (c) 1998-2003 Universitt Karlsruhe
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */
Boris Boesler's avatar
Boris Boesler committed
12

Boris Boesler's avatar
added    
Boris Boesler committed
13
14
15
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
16
#include <string.h>
Boris Boesler's avatar
added    
Boris Boesler committed
17

18
#include "ident.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
19
#include "irnode_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
20
#include "irgraph_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
21
#include "irmode_t.h"
22
#include "typegmod_t.h"
Christian Schäfer's avatar
Christian Schäfer committed
23
#include "array.h"
24
#include "irbackedge_t.h"
25
#include "irdump.h"
26
#include "irflag.h"
Christian Schäfer's avatar
Christian Schäfer committed
27

Götz Lindenmaier's avatar
Götz Lindenmaier committed
28
#ifdef DEBUG_libfirm
29
#include "irprog_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
30
31
#endif

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

39
/* Declarations for inlineing */
40
41
42
43
44
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);
45
46
INLINE type *get_SymConst_type (ir_node *node);
INLINE ir_node *skip_nop (ir_node *node);
47
INLINE int is_Proj (const ir_node *node);
48
49


50
51
52
53
54
55
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
56

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

85
const char *pns_name_arr [] = {
86
87
88
  "initial_exec", "global_store",
  "frame_base", "globals", "args"
};
Christian Schäfer's avatar
Christian Schäfer committed
89

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

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

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

Christian Schäfer's avatar
Christian Schäfer committed
131
132
133
  return res;
}

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

/** getting some parameters from ir_nodes **/

Sebastian Felis's avatar
Sebastian Felis committed
144
145
146
147
148
149
150
151
152
int
is_ir_node (void *thing) {
  assert(thing);
  if (get_kind(thing) == k_ir_node)
    return 1;
  else
    return 0;
}

Christian Schäfer's avatar
Christian Schäfer committed
153
/* returns the number of predecessors without the block predecessor. */
154
INLINE int
155
get_irn_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
156
  assert(node);
157
158
159
160
161
162
163
164
165
166
  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
167
168
}

169
170
171
172
173
174
/* 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. */
175
INLINE ir_node **
176
get_irn_in (const ir_node *node) {
177
178
179
180
181
182
183
184
185
186
187
  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
188
189
}

190
INLINE void
191
set_irn_in (ir_node *node, int arity, ir_node **in) {
192
  ir_node *** arr;
193
  assert(node);
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  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;
210
  }
211
  fix_backedges(current_ir_graph->obst, node);
212
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
213
214
}

Christian Schäfer's avatar
Christian Schäfer committed
215
216
217
/* 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
218
219
   i < get_irn_arity.
   If it is a block, the entry -1 is NULL. */
220
INLINE ir_node *
221
get_irn_n (ir_node *node, int n) {
222
  /* debug @@@
223
224
225
  if (-1 > n || get_irn_arity(node) <= n) {
    printf("pos: %d, arity: %d ", n, get_irn_arity(node));
    DDMN(node);
226
    } */
227
  assert(node); assert(-1 <= n && n < get_irn_arity(node));
228
229
230
231
232
233
234
235
236
237
  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
238
239
}

240
INLINE void
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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
262
263
}

264
INLINE ir_mode *
265
get_irn_mode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
266
267
268
269
270
{
  assert (node);
  return node->mode;
}

Till Riedel's avatar
Till Riedel committed
271
272
273
274
275
276
277
278
INLINE void
set_irn_mode (ir_node *node, ir_mode *mode)
{
  assert (node);
  node->mode=mode;
  return;
}

279
INLINE modecode
280
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
281
282
283
284
285
{
  assert (node);
  return node->mode->code;
}

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

287
INLINE ident *
288
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
289
290
{
  assert(node);
291
  return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
292
293
}

294
INLINE ir_op *
295
get_irn_op (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
296
297
298
299
300
301
{
  assert (node);
  return node->op;
}

/* should be private to the library: */
302
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
303
304
305
306
307
308
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

309
INLINE opcode
310
get_irn_opcode (const ir_node *node)
311
312
{
  assert (node);
Boris Boesler's avatar
Boris Boesler committed
313
314
  assert (k_ir_node == get_kind(node));
  assert (node -> op);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
315
316
317
  return node->op->code;
}

318
INLINE const char *
319
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
320
321
{
  assert(node);
322
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
323
324
}

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

332
INLINE unsigned long
333
get_irn_visited (const ir_node *node)
334
335
336
337
338
{
  assert (node);
  return node->visited;
}

339
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
340
set_irn_visited (ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
341
342
{
  assert (node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
343
  node->visited = visited;
Christian Schäfer's avatar
Christian Schäfer committed
344
}
345

346
INLINE void
347
348
349
350
351
mark_irn_visited (ir_node *node) {
  assert (node);
  node->visited = current_ir_graph->visited;
}

352
INLINE int
353
irn_not_visited  (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
354
355
356
357
  assert (node);
  return (node->visited < current_ir_graph->visited);
}

358
INLINE int
359
irn_visited  (const ir_node *node) {
360
361
362
363
  assert (node);
  return (node->visited >= current_ir_graph->visited);
}

364
INLINE void
365
set_irn_link (ir_node *node, void *link) {
Christian Schäfer's avatar
Christian Schäfer committed
366
  assert (node);
367
368
369
370
  /* 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
371
372
373
  node->link = link;
}

374
INLINE void *
375
get_irn_link (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
376
377
378
379
  assert (node);
  return node->link;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
380
/* Outputs a unique number for this node */
381
INLINE long
382
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
383
  assert(node);
384
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
385
  return node->node_nr;
386
387
#else
  return 0;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
388
#endif
389
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
390

391
INLINE tarval *
Christian Schäfer's avatar
Christian Schäfer committed
392
393
394
395
396
397
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

398
INLINE long
Christian Schäfer's avatar
Christian Schäfer committed
399
400
401
402
403
404
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

405
INLINE alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
406
407
408
409
410
411
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

412
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
413
414
415
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
416
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
417
418
}

419
INLINE symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
420
421
422
423
424
425
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

426
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
427
428
429
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
430
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
431
432
}

433
INLINE sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
434
435
436
437
438
439
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

440
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
441
442
443
444
445
446
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

447
INLINE block_attr
Christian Schäfer's avatar
Christian Schäfer committed
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
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);
}

463
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
464
465
466
467
468
set_nodes_Block (ir_node *node, ir_node *block) {
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

469
470
471
472
/* 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. */
473
INLINE ir_node **
474
475
476
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
477
  return (ir_node **)&(get_irn_in(node)[1]);
478
479
480
}


481
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
482
483
484
485
486
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
  return (get_irn_arity(node));
}

487
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
488
489
get_Block_cfgpred (ir_node *node, int pos) {
  assert (node->op == op_Block);
490
  /* debug @@@
491
492
493
494
  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);
495
    } */
496
  assert(node); assert(-1 <= pos && pos < get_irn_arity(node));
Christian Schäfer's avatar
Christian Schäfer committed
497
498
499
  return get_irn_n(node, pos);
}

500
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
501
502
503
504
505
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

506
INLINE bool
Christian Schäfer's avatar
Christian Schäfer committed
507
508
509
510
511
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

512
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
513
514
515
516
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
517
INLINE unsigned long
518
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
519
  assert (node->op == op_Block);
520
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
521
522
}

523
INLINE void
524
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
525
  assert (node->op == op_Block);
526
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
527
528
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
529
/* For this current_ir_graph must be set. */
530
531
INLINE void
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
532
533
534
535
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

536
537
INLINE int
Block_not_block_visited(ir_node *node) {
538
539
540
  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
541

542
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
543
544
545
546
547
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

548
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
549
550
551
552
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;
}
553

554
/* handler handling for Blocks */
555
556
void
set_Block_handler (ir_node *block, ir_node *handler)  {
557
558
559
560
561
  assert ((block->op == op_Block));
  assert ((handler->op == op_Block));
  block->attr.block.handler_entry = handler;
}

562
563
ir_node *
get_Block_handler (ir_node *block) {
564
565
566
567
568
  assert ((block->op == op_Block));
  return (block->attr.block.handler_entry);
}

/* handler handling for Nodes */
569
570
void
set_Node_handler (ir_node *node, ir_node *handler) {
571
572
573
  set_Block_handler (get_nodes_Block (node), handler);
}

574
575
ir_node *
get_Node_handler (ir_node *node) {
576
577
578
579
  return (get_Block_handler (get_nodes_Block (node)));
}

/* exc_t handling for Blocks */
580
void set_Block_exc (ir_node *block, exc_t exc) {
581
  assert ((block->op == op_Block));
582
583
584
  block->attr.block.exc = exc;
}

585
exc_t get_Block_exc (ir_node *block) {
586
587
  assert ((block->op == op_Block));

588
589
590
  return (block->attr.block.exc);
}

591
/* exc_t handling for Nodes */
592
void set_Node_exc (ir_node *node, exc_t exc) {
593
594
595
  set_Block_exc (get_nodes_Block (node), exc);
}

596
exc_t get_Node_exc (ir_node *node) {
597
598
599
  return (get_Block_exc (get_nodes_Block (node)));
}

600
601
602
603
604
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;
605
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
606
607
608
609
610
611
612
613
    {
      /* 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;
    }
614
615
616
617
618
  }
  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
619
620
621
  assert(node->op == op_Block &&
	 node->attr.block.in_cg &&
	 0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
622
623
624
625
626
627
628
629
630
  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) {
631
632
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
633
634
}

635
636
637
638
639
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];
}

640
641
642
643
644
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

645
646
647
648
649
650
651
652
653
654
655
656
657
658
/* Start references the irg it is in. */
INLINE ir_graph *
get_Start_irg(ir_node *node) {
  assert(node->op == op_Start);
  return node->attr.start.irg;
}

INLINE void
set_Start_irg(ir_node *node, ir_graph *irg) {
  assert(node->op == op_Start);
  assert(is_ir_graph(irg));
  node->attr.start.irg = irg;
}

659
INLINE int
660
661
662
663
664
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

665
INLINE ir_node *
666
667
668
669
670
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

671
INLINE void
672
673
674
675
676
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

677
INLINE void
678
679
680
681
682
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);
}

683
INLINE void
684
free_End (ir_node *end) {
685
  assert (end->op == op_End);
686
  /* DEL_ARR_F(end->in);   GL @@@ tut nicht ! */
687
688
689
690
  end->in = NULL;   /* @@@ make sure we get an error if we use the
		       in array afterwards ... */
}

691
ir_graph *get_EndReg_irg (const ir_node *end) {
692
693
694
695
  assert (end->op == op_EndReg);
  return end->attr.end.irg;
}

696
ir_graph *get_EndExcept_irg  (const ir_node *end) {
697
698
  assert (end->op == op_EndReg);
  return end->attr.end.irg;
699
700
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
/*
> 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).
*/
732
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
733
734
735
736
737
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

738
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
739
740
741
742
743
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

744
INLINE cond_kind
745
746
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
747
  return node->attr.c.kind;
748
749
}

750
INLINE void
751
752
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
753
  node->attr.c.kind = kind;
754
755
}

756
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
757
get_Return_mem (ir_node *node) {
758
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
759
760
761
  return get_irn_n(node, 0);
}

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

768
INLINE int
769
get_Return_n_ress (ir_node *node) {
770
771
772
773
774
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

INLINE ir_node **
775
776
777
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
778
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
779
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
780
781
  else
    return NULL;
782
783
}

Christian Schäfer's avatar
Christian Schäfer committed
784
/*
785
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
786
787
788
789
790
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

791
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
792
793
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
794
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
795
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
796
797
}

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

804
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
805
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
806
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
807
808
809
  return get_irn_n(node, 0);
}

810
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
811
812
813
814
815
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

816
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
817
818
819
820
821
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

822
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
823
824
825
826
827
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

828
INLINE tarval *get_Const_tarval (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
829
830
831
832
  assert (node->op == op_Const);
  return get_irn_const_attr(node);
}

833
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
834
835
836
837
838
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
  node->attr.con = con;
}

839
INLINE symconst_kind
840
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
841
842
843
844
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

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

851
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
852
853
854
855
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
856
  return node->attr.i.tori.typ = skip_tid(node->attr.i.tori.typ);
Christian Schäfer's avatar
Christian Schäfer committed
857
858
}

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

867
INLINE ident *
Christian Schäfer's avatar
Christian Schäfer committed
868
869
870
871
872
873
get_SymConst_ptrinfo (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == linkage_ptr_info));
  return node->attr.i.tori.ptrinfo;
}

874
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
875
876
877
878
879
880
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;
}

881
INLINE type_or_id_p
Götz Lindenmaier's avatar
Götz Lindenmaier committed
882
883
884
885
886
get_SymConst_type_or_id (ir_node *node) {
  assert (node->op == op_SymConst);
  return &(node->attr.i.tori);
}

887
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
888
889
890
891
892
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));
}

893
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
894
895
896
897
898
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

899
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
900
901
902
903
904
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

905
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
906
907
908
909
910
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

911
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
912
913
914
915
916
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

917
INLINE int
918
get_Sel_n_indexs (ir_node *node) {
919
920
921
922
923
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

INLINE ir_node **
924
925
926
get_Sel_index_arr (ir_node *node)
{
  assert ((node->op == op_Sel));
927
  if (get_Sel_n_indexs(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
928
    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
929
930
  else
    return NULL;
931
932
}

933
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
934
935
get_Sel_index (ir_node *node, int pos) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
936
  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
937
938
}

939
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
940
941
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
942
  set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
Christian Schäfer's avatar
Christian Schäfer committed
943
944
}

945
INLINE entity *
Christian Schäfer's avatar
Christian Schäfer committed
946
947
948
949
950
get_Sel_entity (ir_node *node) {
  assert (node->op == op_Sel);
  return node->attr.s.ent;
}

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

957
958
959
960
961
962
963
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
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);
}

993
994
995
996

/* 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.
Götz Lindenmaier's avatar
Götz Lindenmaier committed
997
   unops are: Minus, Abs, Not, Conv, Cast
998
999
1000
1001
1002
   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
1003
1004
1005
1006
1007
get_Call_mem (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 0);
}

1008
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1009
1010
1011
1012
1013
set_Call_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Call);
  set_irn_n(node, 0, mem);
}

1014
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1015
1016
1017
1018
1019
get_Call_ptr (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 1);
}

1020
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1021
1022
1023
1024
1025
set_Call_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Call);
  set_irn_n(node, 1, ptr);
}

1026
INLINE ir_node **
1027
1028
get_Call_param_arr (ir_node *node) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1029
  return (ir_node **)&get_irn_in(node)[CALL_PARAM_OFFSET + 1];
1030
1031
}

1032
INLINE int
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1033
get_Call_n_params (ir_node *node)  {
Christian Schäfer's avatar
Christian Schäfer committed
1034
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1035
  return (get_irn_arity(node) - CALL_PARAM_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1036
1037
}

1038
INLINE int
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1039
get_Call_arity (ir_node *node) {
1040
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1041
1042
1043
  return get_Call_n_params(node);
}

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

1050
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1051
1052
get_Call_param (ir_node *node, int pos) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1053
  return get_irn_n(node, pos + CALL_PARAM_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1054
1055
}

1056
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1057
1058
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
1059
  set_irn_n(node, pos + CALL_PARAM_OFFSET, param);
Christian Schäfer's avatar
Christian Schäfer committed
1060
1061
}

1062
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
1063
1064
get_Call_type (ir_node *node) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1065
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
1066
1067
}

1068
INLINE void
1069
set_Call_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
1070
  assert (node->op == op_Call);
1071
1072
  assert (is_method_type(tp));
  node->attr.call.cld_tp = tp;
Christian Schäfer's avatar
Christian Schäfer committed
1073
1074
}

1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
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;
}

1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
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;
}

1119
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1120
1121
1122
1123
1124
get_Add_left