irnode.c 46.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.h"
23
#include "irbackedge_t.h"
24
#include "irdump.h"
25
#include "irop_t.h"
26
#include "irprog_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
27

Michael Beck's avatar
Michael Beck committed
28
29
#include "firmstat.h"

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

37
38
39
40
41
42
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
43

Michael Beck's avatar
Michael Beck committed
44
45
46
/**
 * returns the pnc name from an pnc constant
 */
47
const char *get_pnc_string(int pnc) {
Christian Schäfer's avatar
Christian Schäfer committed
48
49
50
  return pnc_name_arr[pnc];
}

Michael Beck's avatar
Michael Beck committed
51
52
53
/**
 * Calculates the negated pnc condition.
 */
Christian Schäfer's avatar
Christian Schäfer committed
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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 */
}

77
const char *pns_name_arr [] = {
78
79
80
  "initial_exec", "global_store",
  "frame_base", "globals", "args"
};
Christian Schäfer's avatar
Christian Schäfer committed
81

82
const char *symconst_name_arr [] = {
Beyhan's avatar
Beyhan committed
83
  "type_tag", "size", "addr_name", "addr_ent"
84
};
Christian Schäfer's avatar
Christian Schäfer committed
85
86
87
88
89
90

void
init_irnode (void)
{
}

91
92
93
94
95
96
/*
 * irnode constructor.
 * Create a new irnode in irg, with an op, mode, arity and
 * some incoming irnodes.
 * If arity is negative, a node with a dynamic array is created.
 */
97
ir_node *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
98
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
99
100
101
102
103
	     int arity, ir_node **in)
{
  ir_node *res;
  int node_size = offsetof (ir_node, attr) +  op->attr_size;

104
  assert(irg && op && mode);
Christian Schäfer's avatar
Christian Schäfer committed
105
  res = (ir_node *) obstack_alloc (irg->obst, node_size);
106
  memset((void *)res, 0, node_size);
Christian Schäfer's avatar
Christian Schäfer committed
107
108
109
110

  res->kind = k_ir_node;
  res->op = op;
  res->mode = mode;
111
  res->visited = 0;
Christian Schäfer's avatar
Christian Schäfer committed
112
113
  res->link = NULL;
  if (arity < 0) {
114
    res->in = NEW_ARR_F (ir_node *, 1);  /* 1: space for block */
Christian Schäfer's avatar
Christian Schäfer committed
115
116
117
118
119
  } 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
120
  set_irn_dbg_info(res, db);
121
  res->out = NULL;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
122
123
124
125
126

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

Michael Beck's avatar
Michael Beck committed
127
128
  stat_new_node(res);

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

Götz Lindenmaier's avatar
Götz Lindenmaier committed
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
135
136
137
copy_attrs (const ir_node *old_node, ir_node *new_node) {
  assert(get_irn_op(old_node) == get_irn_op(new_node));
  memcpy(&new_node->attr, &old_node->attr, get_op_attr_size(get_irn_op(old_node)));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
138
}
Christian Schäfer's avatar
Christian Schäfer committed
139

Michael Beck's avatar
Michael Beck committed
140
/*-- getting some parameters from ir_nodes --*/
Christian Schäfer's avatar
Christian Schäfer committed
141

Sebastian Felis's avatar
Sebastian Felis committed
142
int
143
144
(is_ir_node)(const void *thing) {
  return __is_ir_node(thing);
Sebastian Felis's avatar
Sebastian Felis committed
145
146
}

147
int
148
149
(get_irn_intra_arity)(const ir_node *node) {
  return __get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
150
151
}

152
int
153
154
(get_irn_inter_arity)(const ir_node *node) {
  return __get_irn_inter_arity(node);
155
156
}

157
int
158
159
(get_irn_arity)(const ir_node *node) {
  return __get_irn_arity(node);
160
161
}

162
163
164
165
166
167
/* 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. */
168
ir_node **
169
get_irn_in (const ir_node *node) {
170
171
172
173
174
175
176
177
178
179
180
  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
181
182
}

183
void
184
set_irn_in (ir_node *node, int arity, ir_node **in) {
185
  ir_node *** arr;
186
  assert(node);
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
  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;
203
  }
204
  fix_backedges(current_ir_graph->obst, node);
205
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
206
207
}

208
ir_node *
209
210
(get_irn_intra_n)(ir_node *node, int n) {
  return __get_irn_intra_n (node, n);
211
212
}

213
ir_node *
214
215
(get_irn_inter_n)(ir_node *node, int n) {
  return __get_irn_inter_n (node, n);
216
217
}

218
ir_node *
219
220
(get_irn_n)(ir_node *node, int n) {
  return __get_irn_n (node, n);
Christian Schäfer's avatar
Christian Schäfer committed
221
222
}

223
void
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
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
245
246
}

247
ir_mode *
248
249
(get_irn_mode)(const ir_node *node) {
  return __get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
250
251
}

252
void
253
(set_irn_mode)(ir_node *node, ir_mode *mode)
Till Riedel's avatar
Till Riedel committed
254
{
255
  __set_irn_mode(node, mode);
Till Riedel's avatar
Till Riedel committed
256
257
}

258
modecode
259
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
260
261
262
263
264
{
  assert (node);
  return node->mode->code;
}

265
/** Gets the string representation of the mode .*/
266
const char *
267
268
269
270
271
get_irn_modename (const ir_node *node)
{
  assert(node);
  return get_mode_name(node->mode);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
272

273
ident *
274
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
275
276
{
  assert(node);
277
  return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
278
279
}

280
ir_op *
281
(get_irn_op)(const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
282
{
283
  return __get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
284
285
286
}

/* should be private to the library: */
287
void
Christian Schäfer's avatar
Christian Schäfer committed
288
289
290
291
292
293
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

294
opcode
295
(get_irn_opcode)(const ir_node *node)
296
{
297
  return __get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
298
299
}

300
const char *
301
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
302
303
{
  assert(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
304
305
306
  if ((get_irn_op((ir_node *)node) == op_Phi) &&
      (get_irg_phase_state(get_irn_irg((ir_node *)node)) == phase_building) &&
      (get_irn_arity((ir_node *)node) == 0)) return "Phi0";
307
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
308
309
}

310
ident *
311
get_irn_opident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
312
313
314
{
  assert(node);
  return node->op->name;
315
316
}

317
unsigned long
318
(get_irn_visited)(const ir_node *node)
319
{
320
  return __get_irn_visited(node);
321
322
}

323
void
324
(set_irn_visited)(ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
325
{
326
  __set_irn_visited(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
327
}
328

329
void
330
331
(mark_irn_visited)(ir_node *node) {
  __mark_irn_visited(node);
332
333
}

334
int
335
336
(irn_not_visited)(const ir_node *node) {
  return __irn_not_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
337
338
}

339
int
340
341
(irn_visited)(const ir_node *node) {
  return __irn_visited(node);
342
343
}

344
void
345
346
(set_irn_link)(ir_node *node, void *link) {
  __set_irn_link(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
347
348
}

349
void *
350
351
(get_irn_link)(const ir_node *node) {
  return __get_irn_link(node);
Christian Schäfer's avatar
Christian Schäfer committed
352
353
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
354
/* Outputs a unique number for this node */
355
long
356
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
357
  assert(node);
358
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
359
  return node->node_nr;
360
#else
361
  return (long)&node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
362
#endif
363
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
364

365
const_attr
Christian Schäfer's avatar
Christian Schäfer committed
366
367
368
369
370
371
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

372
long
Christian Schäfer's avatar
Christian Schäfer committed
373
374
375
376
377
378
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

379
alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
380
381
382
383
384
385
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

386
type *
Christian Schäfer's avatar
Christian Schäfer committed
387
388
389
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
390
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
391
392
}

393
symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
394
395
396
397
398
399
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

400
type *
Christian Schäfer's avatar
Christian Schäfer committed
401
402
403
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
404
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
405
406
}

407
type *
Michael Beck's avatar
Michael Beck committed
408
409
410
411
412
413
get_irn_funccall_attr (ir_node *node)
{
  assert (node->op == op_FuncCall);
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
}

414
sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
415
416
417
418
419
420
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

421
int
Christian Schäfer's avatar
Christian Schäfer committed
422
423
424
425
426
427
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

428
block_attr
Christian Schäfer's avatar
Christian Schäfer committed
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
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);
}

444
void
Christian Schäfer's avatar
Christian Schäfer committed
445
446
447
448
449
set_nodes_Block (ir_node *node, ir_node *block) {
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
/* Test whether arbitrary node is frame pointer, i.e. Proj(pn_Start_P_frame_base)
 * from Start.  If so returns frame type, else Null. */
type *is_frame_pointer(ir_node *n) {
  if ((get_irn_op(n) == op_Proj) &&
      (get_Proj_proj(n) == pn_Start_P_frame_base)) {
    ir_node *start = get_Proj_pred(n);
    if (get_irn_op(start) == op_Start) {
      return get_irg_frame_type(get_irn_irg(start));
    }
  }
  return NULL;
}

/* Test whether arbitrary node is globals pointer, i.e. Proj(pn_Start_P_globals)
 * from Start.  If so returns global type, else Null. */
type *is_globals_pointer(ir_node *n) {
  if ((get_irn_op(n) == op_Proj) &&
      (get_Proj_proj(n) == pn_Start_P_globals)) {
    ir_node *start = get_Proj_pred(n);
    if (get_irn_op(start) == op_Start) {
      return get_glob_type();
    }
  }
  return NULL;
}

/* Test whether arbitrary node is value arg base, i.e. Proj(pn_Start_P_value_arg_base)
 * from Start.  If so returns 1, else 0. */
int is_value_arg_pointer(ir_node *n) {
  if ((get_irn_op(n) == op_Proj) &&
      (get_Proj_proj(n) == pn_Start_P_value_arg_base) &&
      (get_irn_op(get_Proj_pred(n)) == op_Start))
    return 1;
  return 0;
}

486
/* Returns an array with the predecessors of the Block. Depending on
487
   the implementation of the graph data structure this can be a copy of
488
489
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
490
ir_node **
491
492
493
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
494
  return (ir_node **)&(get_irn_in(node)[1]);
495
496
497
}


498
int
Christian Schäfer's avatar
Christian Schäfer committed
499
500
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
501
  return get_irn_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
502
503
}

504
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
505
get_Block_cfgpred (ir_node *node, int pos) {
506
  assert(node);
Christian Schäfer's avatar
Christian Schäfer committed
507
  assert (node->op == op_Block);
508
  assert(-1 <= pos && pos < get_irn_arity(node));
Christian Schäfer's avatar
Christian Schäfer committed
509
510
511
  return get_irn_n(node, pos);
}

512
void
Christian Schäfer's avatar
Christian Schäfer committed
513
514
515
516
517
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

518
bool
Christian Schäfer's avatar
Christian Schäfer committed
519
520
521
522
523
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

524
void
Christian Schäfer's avatar
Christian Schäfer committed
525
526
527
528
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
529
unsigned long
530
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
531
  assert (node->op == op_Block);
532
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
533
534
}

535
void
536
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
537
  assert (node->op == op_Block);
538
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
539
540
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
541
/* For this current_ir_graph must be set. */
542
void
543
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
544
545
546
547
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

548
int
549
Block_not_block_visited(ir_node *node) {
550
551
552
  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
553

554
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
555
556
557
558
559
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

560
void
Christian Schäfer's avatar
Christian Schäfer committed
561
562
563
564
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;
}
565

566
/* handler handling for Blocks * /
567
568
void
set_Block_handler (ir_node *block, ir_node *handler)  {
569
570
571
572
573
  assert ((block->op == op_Block));
  assert ((handler->op == op_Block));
  block->attr.block.handler_entry = handler;
}

574
575
ir_node *
get_Block_handler (ir_node *block) {
576
577
578
579
  assert ((block->op == op_Block));
  return (block->attr.block.handler_entry);
}

580
/ * handler handling for Nodes * /
581
582
void
set_Node_handler (ir_node *node, ir_node *handler) {
583
584
585
  set_Block_handler (get_nodes_Block (node), handler);
}

586
587
ir_node *
get_Node_handler (ir_node *node) {
588
589
590
  return (get_Block_handler (get_nodes_Block (node)));
}

591
/ * exc_t handling for Blocks * /
592
void set_Block_exc (ir_node *block, exc_t exc) {
593
  assert ((block->op == op_Block));
594
595
596
  block->attr.block.exc = exc;
}

597
exc_t get_Block_exc (ir_node *block) {
598
  assert ((block->op == op_Block));
599
600
601
  return (block->attr.block.exc);
}

602
/ * exc_t handling for Nodes * /
603
void set_Node_exc (ir_node *node, exc_t exc) {
604
605
606
  set_Block_exc (get_nodes_Block (node), exc);
}

607
exc_t get_Node_exc (ir_node *node) {
608
609
  return (get_Block_exc (get_nodes_Block (node)));
}
610
*/
611

612
613
614
615
616
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;
617
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
618
619
620
621
622
623
624
625
    {
      /* 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;
    }
626
627
628
629
630
  }
  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
631
632
633
  assert(node->op == op_Block &&
	 node->attr.block.in_cg &&
	 0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
634
635
636
637
638
639
640
641
642
  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) {
643
644
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
645
646
}

647
648
649
650
651
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];
}

652
653
654
655
656
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

657
/* Start references the irg it is in. */
658
ir_graph *
659
get_Start_irg(ir_node *node) {
660
  return get_irn_irg(node);
661
662
}

663
void
664
665
666
set_Start_irg(ir_node *node, ir_graph *irg) {
  assert(node->op == op_Start);
  assert(is_ir_graph(irg));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
667
  assert(0 && " Why set irg? -- use set_irn_irg");
668
669
}

670
int
671
672
673
674
675
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

676
ir_node *
677
678
679
680
681
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

682
void
683
684
685
686
687
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

688
void
689
690
691
692
693
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);
}

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

703
704
ir_graph *get_EndReg_irg (ir_node *end) {
  return get_irn_irg(end);
705
706
}

707
708
ir_graph *get_EndExcept_irg  (ir_node *end) {
  return get_irn_irg(end);
709
710
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
711
712
713
714
715
716
717
718
719
/*
> 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
720
 - determining the biggest case constant to know the proj number for
Götz Lindenmaier's avatar
Götz Lindenmaier committed
721
722
723
724
725
726
727
728
729
730
731
732
   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.,
733
libFIRM can implement a routine that transforms between the two
Götz Lindenmaier's avatar
Götz Lindenmaier committed
734
735
736
737
738
739
740
741
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).
*/
742
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
743
744
745
746
747
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

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

754
cond_kind
755
756
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
757
  return node->attr.c.kind;
758
759
}

760
void
761
762
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
763
  node->attr.c.kind = kind;
764
765
}

766
767
768
769
770
771
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

772
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
773
get_Return_mem (ir_node *node) {
774
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
775
776
777
  return get_irn_n(node, 0);
}

778
void
Christian Schäfer's avatar
Christian Schäfer committed
779
780
781
782
783
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

784
int
785
get_Return_n_ress (ir_node *node) {
786
787
788
789
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

790
ir_node **
791
792
793
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
794
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
795
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
796
797
  else
    return NULL;
798
799
}

Christian Schäfer's avatar
Christian Schäfer committed
800
/*
801
void
Christian Schäfer's avatar
Christian Schäfer committed
802
803
804
805
806
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

807
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
808
809
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
810
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
811
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
812
813
}

814
void
Christian Schäfer's avatar
Christian Schäfer committed
815
set_Return_res (ir_node *node, int pos, ir_node *res){
816
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
817
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
818
819
}

820
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
821
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
822
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
823
824
825
  return get_irn_n(node, 0);
}

826
void
Christian Schäfer's avatar
Christian Schäfer committed
827
828
829
830
831
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

832
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
833
834
835
836
837
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

838
void
Christian Schäfer's avatar
Christian Schäfer committed
839
840
841
842
843
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

844
tarval *get_Const_tarval (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
845
  assert (node->op == op_Const);
846
  return node->attr.con.tv;
Christian Schäfer's avatar
Christian Schäfer committed
847
848
}

849
void
Christian Schäfer's avatar
Christian Schäfer committed
850
851
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
852
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
853
854
}

855
856
857
858

/* The source language type.  Must be an atomic type.  Mode of type must
   be mode of node. For tarvals from entities type must be pointer to
   entity type. */
859
type *
860
861
862
863
864
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

865
void
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
set_Const_type (ir_node *node, type *tp) {
  assert (node->op == op_Const);
  if (tp != unknown_type) {
    assert (is_atomic_type(tp));
    assert (get_type_mode(tp) == get_irn_mode(node));
    assert (!tarval_is_entity(get_Const_tarval(node)) ||
	    (is_pointer_type(tp) &&
	     (get_pointer_points_to_type(tp) ==
	      get_entity_type(get_tarval_entity(get_Const_tarval(node))))));
  }

  node->attr.con.tp = tp;
}


881
symconst_kind
882
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
883
884
885
886
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

887
void
Christian Schäfer's avatar
Christian Schäfer committed
888
889
890
891
892
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

893
type *
Christian Schäfer's avatar
Christian Schäfer committed
894
895
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
896
897
898
          && (   get_SymConst_kind(node) == symconst_type_tag
              || get_SymConst_kind(node) == symconst_size));
  return node->attr.i.sym.type_p = skip_tid(node->attr.i.sym.type_p);
Christian Schäfer's avatar
Christian Schäfer committed
899
900
}

901
void
902
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
903
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
904
905
906
          && (   get_SymConst_kind(node) == symconst_type_tag
              || get_SymConst_kind(node) == symconst_size));
  node->attr.i.sym.type_p = tp;
Christian Schäfer's avatar
Christian Schäfer committed
907
908
}

909
ident *
Beyhan's avatar
Beyhan committed
910
get_SymConst_name (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
911
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
912
913
          && (get_SymConst_kind(node) == symconst_addr_name));
  return node->attr.i.sym.ident_p;
Christian Schäfer's avatar
Christian Schäfer committed
914
915
}

916
void
Beyhan's avatar
Beyhan committed
917
set_SymConst_name (ir_node *node, ident *name) {
Christian Schäfer's avatar
Christian Schäfer committed
918
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
919
920
          && (get_SymConst_kind(node) == symconst_addr_name));
  node->attr.i.sym.ident_p = name;
Christian Schäfer's avatar
Christian Schäfer committed
921
922
}

Beyhan's avatar
Beyhan committed
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938

/* Only to access SymConst of kind symconst_addr_ent.  Else assertion: */
entity   *get_SymConst_entity (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == symconst_addr_ent));
  return node->attr.i.sym.entity_p;
}

void     set_SymConst_entity (ir_node *node, entity *ent) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == symconst_addr_ent));
  node->attr.i.sym.entity_p  = ent;
}


symconst_symbol
Götz Lindenmaier's avatar
Götz Lindenmaier committed
939
940
get_SymConst_type_or_id (ir_node *node) {
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
941
  return node->attr.i.sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
942
943
}

944
void
Beyhan's avatar
Beyhan committed
945
set_SymConst_type_or_id (ir_node *node, symconst_symbol sym) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
946
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
947
948
  //memcpy (&(node->attr.i.sym), sym, sizeof(type_or_id));
  node->attr.i.sym = sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
949
950
}

951
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
952
953
954
955
956
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

957
void
Christian Schäfer's avatar
Christian Schäfer committed
958
959
960
961
962
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

963
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
964
965
966
967
968
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

969
void
Christian Schäfer's avatar
Christian Schäfer committed
970
971
972
973
974
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

975
int
976
get_Sel_n_indexs (ir_node *node) {
977
978
979
980
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

981
ir_node **
982
983
984
get_Sel_index_arr (ir_node *node)
{
  assert ((node->op == op_Sel));
985
  if (get_Sel_n_indexs(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
986
    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
987
988
  else
    return NULL;
989
990
}

991
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
992
993
get_Sel_index (ir_node *node, int pos) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
994
  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
995
996
}

997
void
Christian Schäfer's avatar
Christian Schäfer committed
998
999
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
1000
  set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
Christian Schäfer's avatar
Christian Schäfer committed
1001
1002
}

1003
entity *
Christian Schäfer's avatar
Christian Schäfer committed
1004
1005
1006
1007
1008
get_Sel_entity (ir_node *node) {
  assert (node->op == op_Sel);
  return node->attr.s.ent;
}

1009
void
Christian Schäfer's avatar
Christian Schäfer committed
1010
1011
1012
1013
1014
set_Sel_entity (ir_node *node, entity *ent) {
  assert (node->op == op_Sel);
  node->attr.s.ent = ent;
}

1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
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 (