irnode.c 47.8 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
/* some constants fixing the positions of nodes predecessors
   in the in array */
Michael Beck's avatar
Michael Beck committed
32
33
34
35
36
#define CALL_PARAM_OFFSET     2
#define FUNCCALL_PARAM_OFFSET 1
#define SEL_INDEX_OFFSET      2
#define RETURN_RESULT_OFFSET  1  /* mem is not a result */
#define END_KEEPALIVE_OFFSET  0
Götz Lindenmaier's avatar
Götz Lindenmaier committed
37

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

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

Michael Beck's avatar
Michael Beck committed
52
53
54
/**
 * Calculates the negated pnc condition.
 */
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
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 */
}

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

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

void
init_irnode (void)
{
}

92
93
94
95
96
97
/*
 * 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.
 */
98
ir_node *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
99
new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode,
Florian Liekweg's avatar
Florian Liekweg committed
100
         int arity, ir_node **in)
Christian Schäfer's avatar
Christian Schäfer committed
101
102
103
104
{
  ir_node *res;
  int node_size = offsetof (ir_node, attr) +  op->attr_size;

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

  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

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

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

Götz Lindenmaier's avatar
Götz Lindenmaier committed
133
134
135
/* Copies all attributes stored in the old node to the new node.
   Assumes both have the same opcode and sufficient size. */
void
136
137
138
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
139
}
Christian Schäfer's avatar
Christian Schäfer committed
140

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

301
const char *
302
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
303
304
{
  assert(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
305
306
307
  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";
308
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
309
310
}

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

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

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

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

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

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

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

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

Götz Lindenmaier's avatar
Götz Lindenmaier committed
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374

#ifdef DO_HEAPANALYSIS
/* Access the abstract interpretation information of a node.
   Returns NULL if no such information is available. */
struct abstval *get_irn_abst_value(ir_node *n) {
  return n->av;
}
/* Set the abstract interpretation information of a node. */
void set_irn_abst_value(ir_node *n, struct abstval *os) {
  n->av = os;
}
struct section *firm_get_irn_section(ir_node *n) {
  return n->sec;
}
void firm_set_irn_section(ir_node *n, struct section *s) {
  n->sec = s;
}
#endif /* DO_HEAPANALYSIS */


Götz Lindenmaier's avatar
Götz Lindenmaier committed
375
/* Outputs a unique number for this node */
376
long
377
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
378
  assert(node);
379
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
380
  return node->node_nr;
381
#else
382
  return (long)&node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
383
#endif
384
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
385

386
const_attr
Christian Schäfer's avatar
Christian Schäfer committed
387
388
389
390
391
392
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

393
long
Christian Schäfer's avatar
Christian Schäfer committed
394
395
396
397
398
399
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

400
alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
401
402
403
404
405
406
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

407
type *
Christian Schäfer's avatar
Christian Schäfer committed
408
409
410
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
411
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
412
413
}

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

421
type *
Christian Schäfer's avatar
Christian Schäfer committed
422
423
424
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
425
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
426
427
}

428
type *
Michael Beck's avatar
Michael Beck committed
429
430
431
432
433
434
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);
}

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

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

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

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

471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
/* 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;
}

507
/* Returns an array with the predecessors of the Block. Depending on
508
   the implementation of the graph data structure this can be a copy of
509
510
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
511
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
int
Christian Schäfer's avatar
Christian Schäfer committed
520
521
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
522
  return get_irn_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
523
524
}

525
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
526
get_Block_cfgpred (ir_node *node, int pos) {
527
  assert(node);
Christian Schäfer's avatar
Christian Schäfer committed
528
  assert (node->op == op_Block);
529
  assert(-1 <= pos && pos < get_irn_arity(node));
Christian Schäfer's avatar
Christian Schäfer committed
530
531
532
  return get_irn_n(node, pos);
}

533
void
Christian Schäfer's avatar
Christian Schäfer committed
534
535
536
537
538
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

539
bool
Christian Schäfer's avatar
Christian Schäfer committed
540
541
542
543
544
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

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

556
void
557
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
558
  assert (node->op == op_Block);
559
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
560
561
}

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

569
int
570
Block_not_block_visited(ir_node *node) {
571
572
573
  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
574

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

581
void
Christian Schäfer's avatar
Christian Schäfer committed
582
583
584
585
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;
}
586

587
/* handler handling for Blocks * /
588
589
void
set_Block_handler (ir_node *block, ir_node *handler)  {
590
591
592
593
594
  assert ((block->op == op_Block));
  assert ((handler->op == op_Block));
  block->attr.block.handler_entry = handler;
}

595
596
ir_node *
get_Block_handler (ir_node *block) {
597
598
599
600
  assert ((block->op == op_Block));
  return (block->attr.block.handler_entry);
}

601
/ * handler handling for Nodes * /
602
603
void
set_Node_handler (ir_node *node, ir_node *handler) {
604
605
606
  set_Block_handler (get_nodes_Block (node), handler);
}

607
608
ir_node *
get_Node_handler (ir_node *node) {
609
610
611
  return (get_Block_handler (get_nodes_Block (node)));
}

612
/ * exc_t handling for Blocks * /
613
void set_Block_exc (ir_node *block, exc_t exc) {
614
  assert ((block->op == op_Block));
615
616
617
  block->attr.block.exc = exc;
}

618
exc_t get_Block_exc (ir_node *block) {
619
  assert ((block->op == op_Block));
620
621
622
  return (block->attr.block.exc);
}

623
/ * exc_t handling for Nodes * /
624
void set_Node_exc (ir_node *node, exc_t exc) {
625
626
627
  set_Block_exc (get_nodes_Block (node), exc);
}

628
exc_t get_Node_exc (ir_node *node) {
629
630
  return (get_Block_exc (get_nodes_Block (node)));
}
631
*/
632

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

668
669
670
671
672
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];
}

673
674
675
676
677
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

678
/* Start references the irg it is in. */
679
ir_graph *
680
get_Start_irg(ir_node *node) {
681
  return get_irn_irg(node);
682
683
}

684
void
685
686
687
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
688
  assert(0 && " Why set irg? -- use set_irn_irg");
689
690
}

691
int
692
693
694
695
696
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

697
ir_node *
698
699
700
701
702
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

703
void
704
705
706
707
708
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

709
void
710
711
712
713
714
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);
}

715
void
716
free_End (ir_node *end) {
717
  assert (end->op == op_End);
718
  end->kind = k_BAD;
719
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
720
  end->in = NULL;   /* @@@ make sure we get an error if we use the
Florian Liekweg's avatar
Florian Liekweg committed
721
               in array afterwards ... */
722
723
}

724
725
ir_graph *get_EndReg_irg (ir_node *end) {
  return get_irn_irg(end);
726
727
}

728
729
ir_graph *get_EndExcept_irg  (ir_node *end) {
  return get_irn_irg(end);
730
731
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
732
733
734
735
736
737
738
739
740
/*
> 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
741
 - determining the biggest case constant to know the proj number for
Götz Lindenmaier's avatar
Götz Lindenmaier committed
742
743
744
745
746
747
748
749
750
751
752
753
   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.,
754
libFIRM can implement a routine that transforms between the two
Götz Lindenmaier's avatar
Götz Lindenmaier committed
755
756
757
758
759
760
761
762
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).
*/
763
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
764
765
766
767
768
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

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

775
cond_kind
776
777
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
778
  return node->attr.c.kind;
779
780
}

781
void
782
783
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
784
  node->attr.c.kind = kind;
785
786
}

787
788
789
790
791
792
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

793
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
794
get_Return_mem (ir_node *node) {
795
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
796
797
798
  return get_irn_n(node, 0);
}

799
void
Christian Schäfer's avatar
Christian Schäfer committed
800
801
802
803
804
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

805
int
806
get_Return_n_ress (ir_node *node) {
807
808
809
810
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

811
ir_node **
812
813
814
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
815
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
816
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
817
818
  else
    return NULL;
819
820
}

Christian Schäfer's avatar
Christian Schäfer committed
821
/*
822
void
Christian Schäfer's avatar
Christian Schäfer committed
823
824
825
826
827
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

828
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
829
830
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
831
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
832
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
833
834
}

835
void
Christian Schäfer's avatar
Christian Schäfer committed
836
set_Return_res (ir_node *node, int pos, ir_node *res){
837
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
838
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
839
840
}

841
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
842
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
843
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
844
845
846
  return get_irn_n(node, 0);
}

847
void
Christian Schäfer's avatar
Christian Schäfer committed
848
849
850
851
852
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

853
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
854
855
856
857
858
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

859
void
Christian Schäfer's avatar
Christian Schäfer committed
860
861
862
863
864
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

865
tarval *get_Const_tarval (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
866
  assert (node->op == op_Const);
867
  return node->attr.con.tv;
Christian Schäfer's avatar
Christian Schäfer committed
868
869
}

870
void
Christian Schäfer's avatar
Christian Schäfer committed
871
872
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
873
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
874
875
}

876
877
878
879

/* 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. */
880
type *
881
882
883
884
885
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

886
void
887
888
889
890
891
892
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)) ||
Florian Liekweg's avatar
Florian Liekweg committed
893
894
895
        (is_pointer_type(tp) &&
         (get_pointer_points_to_type(tp) ==
          get_entity_type(get_tarval_entity(get_Const_tarval(node))))));
896
897
898
899
900
901
  }

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


902
symconst_kind
903
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
904
905
906
907
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

908
void
Christian Schäfer's avatar
Christian Schäfer committed
909
910
911
912
913
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

914
type *
Christian Schäfer's avatar
Christian Schäfer committed
915
916
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
917
918
919
          && (   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
920
921
}

922
void
923
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
924
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
925
926
927
          && (   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
928
929
}

930
ident *
Beyhan's avatar
Beyhan committed
931
get_SymConst_name (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
932
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
933
934
          && (get_SymConst_kind(node) == symconst_addr_name));
  return node->attr.i.sym.ident_p;
Christian Schäfer's avatar
Christian Schäfer committed
935
936
}

937
void
Beyhan's avatar
Beyhan committed
938
set_SymConst_name (ir_node *node, ident *name) {
Christian Schäfer's avatar
Christian Schäfer committed
939
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
940
941
          && (get_SymConst_kind(node) == symconst_addr_name));
  node->attr.i.sym.ident_p = name;
Christian Schäfer's avatar
Christian Schäfer committed
942
943
}

Beyhan's avatar
Beyhan committed
944
945
946
947

/* Only to access SymConst of kind symconst_addr_ent.  Else assertion: */
entity   *get_SymConst_entity (ir_node *node) {
  assert (   (node->op == op_SymConst)
Florian Liekweg's avatar
Florian Liekweg committed
948
          && (get_SymConst_kind (node) == symconst_addr_ent));
Beyhan's avatar
Beyhan committed
949
950
951
952
953
954
955
956
957
958
  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;
}


Michael Beck's avatar
Michael Beck committed
959
960
union symconst_symbol
get_SymConst_symbol (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
961
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
962
  return node->attr.i.sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
963
964
}

965
void
Michael Beck's avatar
Michael Beck committed
966
set_SymConst_symbol (ir_node *node, union symconst_symbol sym) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
967
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
968
969
  //memcpy (&(node->attr.i.sym), sym, sizeof(type_or_id));
  node->attr.i.sym = sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
970
971
}

972
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
973
974
975
976
977
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

978
void
Christian Schäfer's avatar
Christian Schäfer committed
979
980
981
982
983
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

984
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
985
986
987
988
989
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

990
void
Christian Schäfer's avatar
Christian Schäfer committed
991
992
993
994
995
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

996
int
997
get_Sel_n_indexs (ir_node *node) {
998
999
1000
1001
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

1002
ir_node **
1003
1004
1005
get_Sel_index_arr (ir_node *node)
{
  assert ((node->op == op_Sel));
1006
  if (get_Sel_n_indexs(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1007
    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1008
1009
  else
    return NULL;
1010
1011
}

1012
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1013
1014
get_Sel_index (ir_node *node, int pos) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1015
  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1016
1017
}

1018
void
Christian Schäfer's avatar
Christian Schäfer committed
1019
1020
set_Sel_index (ir_node *node, int pos, ir_node *index) {
  assert (