irnode.c 48.1 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
#ifdef HAVE_CONFIG_H
Michael Beck's avatar
Michael Beck committed
14
15
16
17
18
# include "config.h"
#endif

#ifdef HAVE_STRING_H
# include <string.h>
Boris Boesler's avatar
added    
Boris Boesler committed
19
20
#endif

21
#include "ident.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
22
#include "irnode_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
23
#include "irgraph_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
24
#include "irmode_t.h"
25
#include "typegmod.h"
26
#include "irbackedge_t.h"
27
#include "irdump.h"
28
#include "irop_t.h"
29
#include "irprog_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
30

31
#include "irhooks.h"
Michael Beck's avatar
Michael Beck committed
32

Götz Lindenmaier's avatar
Götz Lindenmaier committed
33
34
/* some constants fixing the positions of nodes predecessors
   in the in array */
Michael Beck's avatar
Michael Beck committed
35
36
37
38
39
#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
40

41
42
43
44
45
46
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
47

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

Michael Beck's avatar
Michael Beck committed
55
56
57
/**
 * Calculates the negated pnc condition.
 */
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
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 */
}

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

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

90
91
92
93
94
95
96
97
98
99
/**
 * Indicates, whether additional data can be registered to ir nodes.
 * If set to 1, this is not possible anymore.
 */
static int forbid_new_data = 0;

/**
 * The amount of additional space for custom data to be allocated upon
 * creating a new node.
 */
100
unsigned firm_add_node_size = 0;
101
102


103
104
105
/* register new space for every node */
unsigned register_additional_node_data(unsigned size) {
  assert(!forbid_new_data && "Too late to register additional node data");
106

107
108
  if (forbid_new_data)
    return 0;
109

110
  return firm_add_node_size += size;
111
112
113
}


Christian Schäfer's avatar
Christian Schäfer committed
114
void
115
init_irnode(void) {
116
117
	/* Forbid the addition of new data to an ir node. */
	forbid_new_data = 1;
Christian Schäfer's avatar
Christian Schäfer committed
118
119
}

120
121
122
123
124
125
/*
 * 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.
 */
126
ir_node *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
127
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
128
         int arity, ir_node **in)
Christian Schäfer's avatar
Christian Schäfer committed
129
130
{
  ir_node *res;
131
  size_t node_size = offsetof(ir_node, attr) + op->attr_size + firm_add_node_size;
132
	char *p;
Christian Schäfer's avatar
Christian Schäfer committed
133

134
  assert(irg && op && mode);
135
136
  p = obstack_alloc (irg->obst, node_size);
  memset(p, 0, node_size);
137
	res = (ir_node *) (p + firm_add_node_size);
Christian Schäfer's avatar
Christian Schäfer committed
138

Michael Beck's avatar
Michael Beck committed
139
140
141
  res->kind    = k_ir_node;
  res->op      = op;
  res->mode    = mode;
142
  res->visited = 0;
Michael Beck's avatar
Michael Beck committed
143
  res->link    = NULL;
Christian Schäfer's avatar
Christian Schäfer committed
144
  if (arity < 0) {
145
    res->in = NEW_ARR_F (ir_node *, 1);  /* 1: space for block */
Christian Schäfer's avatar
Christian Schäfer committed
146
147
148
149
150
  } 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
151
  set_irn_dbg_info(res, db);
152
  res->out = NULL;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
153
154
155
156
157

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

158
  hook_new_node(res);
Michael Beck's avatar
Michael Beck committed
159

Christian Schäfer's avatar
Christian Schäfer committed
160
161
162
  return res;
}

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

Sebastian Felis's avatar
Sebastian Felis committed
165
int
166
(is_ir_node)(const void *thing) {
167
  return _is_ir_node(thing);
Sebastian Felis's avatar
Sebastian Felis committed
168
169
}

170
int
171
(get_irn_intra_arity)(const ir_node *node) {
172
  return _get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
173
174
}

175
int
176
(get_irn_inter_arity)(const ir_node *node) {
177
  return _get_irn_inter_arity(node);
178
179
}

180
int (*_get_irn_arity)(const ir_node *node) = _get_irn_intra_arity;
181

182
int
183
(get_irn_arity)(const ir_node *node) {
184
  return _get_irn_arity(node);
185
186
}

187
188
189
190
191
192
/* 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. */
193
ir_node **
194
get_irn_in (const ir_node *node) {
195
  assert(node);
196
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
197
198
199
200
201
202
203
204
205
    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
206
207
}

208
void
209
set_irn_in (ir_node *node, int arity, ir_node **in) {
210
  ir_node *** arr;
211
  assert(node);
212
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    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;
228
  }
229
  fix_backedges(current_ir_graph->obst, node);
230
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
231
232
}

233
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
234
(get_irn_intra_n)(const ir_node *node, int n) {
235
  return _get_irn_intra_n (node, n);
236
237
}

238
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
239
(get_irn_inter_n)(const ir_node *node, int n) {
240
  return _get_irn_inter_n (node, n);
241
242
}

243
ir_node *(*_get_irn_n)(const ir_node *node, int n) = _get_irn_intra_n;
244

245
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
246
(get_irn_n)(const ir_node *node, int n) {
247
  return _get_irn_n(node, n);
Christian Schäfer's avatar
Christian Schäfer committed
248
249
}

250
void
251
set_irn_n (ir_node *node, int n, ir_node *in) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
252
253
  assert(node && node->kind == k_ir_node && -1 <= n && n < get_irn_arity(node));
  assert(in && in->kind == k_ir_node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
254

255
256
257
258
259
260
261
  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;
  }
262
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
263
264
265
266
267
268
269
270
271
272
273
    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
274
275
}

276
ir_mode *
277
(get_irn_mode)(const ir_node *node) {
278
  return _get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
279
280
}

281
void
282
(set_irn_mode)(ir_node *node, ir_mode *mode)
Till Riedel's avatar
Till Riedel committed
283
{
284
  _set_irn_mode(node, mode);
Till Riedel's avatar
Till Riedel committed
285
286
}

287
modecode
288
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
289
290
291
292
293
{
  assert (node);
  return node->mode->code;
}

294
/** Gets the string representation of the mode .*/
295
const char *
296
297
298
299
300
get_irn_modename (const ir_node *node)
{
  assert(node);
  return get_mode_name(node->mode);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
301

302
ident *
303
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
304
305
{
  assert(node);
306
  return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
307
308
}

309
ir_op *
310
(get_irn_op)(const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
311
{
312
  return _get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
313
314
315
}

/* should be private to the library: */
316
void
Christian Schäfer's avatar
Christian Schäfer committed
317
318
319
320
321
322
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

323
opcode
324
(get_irn_opcode)(const ir_node *node)
325
{
326
  return _get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
327
328
}

329
const char *
330
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
331
332
{
  assert(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
333
334
335
  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";
336
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
337
338
}

339
ident *
340
get_irn_opident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
341
342
343
{
  assert(node);
  return node->op->name;
344
345
}

346
unsigned long
347
(get_irn_visited)(const ir_node *node)
348
{
349
  return _get_irn_visited(node);
350
351
}

352
void
353
(set_irn_visited)(ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
354
{
355
  _set_irn_visited(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
356
}
357

358
void
359
(mark_irn_visited)(ir_node *node) {
360
  _mark_irn_visited(node);
361
362
}

363
int
364
(irn_not_visited)(const ir_node *node) {
365
  return _irn_not_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
366
367
}

368
int
369
(irn_visited)(const ir_node *node) {
370
  return _irn_visited(node);
371
372
}

373
void
374
(set_irn_link)(ir_node *node, void *link) {
375
  _set_irn_link(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
376
377
}

378
void *
379
(get_irn_link)(const ir_node *node) {
380
  return _get_irn_link(node);
Christian Schäfer's avatar
Christian Schäfer committed
381
382
}

383
384
op_pin_state
(get_irn_pinned)(const ir_node *node) {
385
  return _get_irn_pinned(node);
386
387
}

Michael Beck's avatar
Michael Beck committed
388
389
390
391
392
void set_irn_pinned(ir_node *node, op_pin_state state) {
  /* due to optimization an opt may be turned into a Tuple */
  if (get_irn_op(node) == op_Tuple)
    return;

393
  assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned);
Michael Beck's avatar
Michael Beck committed
394
395
396
397
  assert(state == op_pin_state_pinned || state == op_pin_state_floats);

  node->attr.except.pin_state = state;
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

#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;
}
415
416
417
418
419
420
#else
/* Dummies needed for firmjni. */
struct abstval *get_irn_abst_value(ir_node *n) { return NULL; }
void set_irn_abst_value(ir_node *n, struct abstval *os) {}
struct section *firm_get_irn_section(ir_node *n) { return NULL; }
void firm_set_irn_section(ir_node *n, struct section *s) {}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
421
422
423
#endif /* DO_HEAPANALYSIS */


Götz Lindenmaier's avatar
Götz Lindenmaier committed
424
/* Outputs a unique number for this node */
425
long
426
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
427
  assert(node);
428
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
429
  return node->node_nr;
430
#else
431
  return (long)node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
432
#endif
433
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
434

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

442
long
Christian Schäfer's avatar
Christian Schäfer committed
443
444
445
446
447
448
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

449
alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
450
451
452
453
454
455
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

456
type *
Christian Schäfer's avatar
Christian Schäfer committed
457
458
459
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
460
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
461
462
}

463
symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
464
465
466
467
468
469
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

470
type *
Christian Schäfer's avatar
Christian Schäfer committed
471
472
473
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
474
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
475
476
}

477
sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
478
479
480
481
482
483
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

484
int
Christian Schäfer's avatar
Christian Schäfer committed
485
486
487
488
489
490
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

491
block_attr
Christian Schäfer's avatar
Christian Schäfer committed
492
493
494
495
496
497
get_irn_block_attr (ir_node *node)
{
  assert (node->op == op_Block);
  return node->attr.block;
}

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
load_attr
get_irn_load_attr (ir_node *node)
{
  assert (node->op == op_Load);
  return node->attr.load;
}

store_attr
get_irn_store_attr (ir_node *node)
{
  assert (node->op == op_Store);
  return node->attr.store;
}

except_attr
get_irn_except_attr (ir_node *node)
{
  assert (node->op == op_Div || node->op == op_Quot ||
516
          node->op == op_DivMod || node->op == op_Mod || node->op == op_Call || node->op == op_Alloc);
517
518
519
  return node->attr.except;
}

Christian Schäfer's avatar
Christian Schäfer committed
520
521
522
523
/** manipulate fields of individual nodes **/

/* this works for all except Block */
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
524
get_nodes_block (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
525
526
527
528
  assert (!(node->op == op_Block));
  return get_irn_n(node, -1);
}

529
void
530
set_nodes_block (ir_node *node, ir_node *block) {
Christian Schäfer's avatar
Christian Schäfer committed
531
532
533
534
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
/* 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;
}

571
/* Returns an array with the predecessors of the Block. Depending on
572
   the implementation of the graph data structure this can be a copy of
573
574
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
575
ir_node **
576
577
578
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
579
  return (ir_node **)&(get_irn_in(node)[1]);
580
581
582
}


583
int
Christian Schäfer's avatar
Christian Schäfer committed
584
585
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
586
  return get_irn_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
587
588
}

589
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
590
get_Block_cfgpred (ir_node *node, int pos) {
591
  assert(-1 <= pos && pos < get_irn_arity(node));
592
  assert(node->op == op_Block);
Christian Schäfer's avatar
Christian Schäfer committed
593
594
595
  return get_irn_n(node, pos);
}

596
void
Christian Schäfer's avatar
Christian Schäfer committed
597
598
599
600
601
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

602
bool
Christian Schäfer's avatar
Christian Schäfer committed
603
604
605
606
607
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

608
void
Christian Schäfer's avatar
Christian Schäfer committed
609
610
611
612
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
613
unsigned long
614
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
615
  assert (node->op == op_Block);
616
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
617
618
}

619
void
620
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
621
  assert (node->op == op_Block);
622
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
623
624
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
625
/* For this current_ir_graph must be set. */
626
void
627
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
628
629
630
631
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

632
int
633
Block_not_block_visited(ir_node *node) {
634
635
636
  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
637

638
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
639
640
641
642
643
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

644
void
Christian Schäfer's avatar
Christian Schäfer committed
645
646
647
648
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;
}
649

650
651
652
653
654
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;
655
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
656
657
    {
      /* Fix backedge array.  fix_backedges operates depending on
Florian Liekweg's avatar
Florian Liekweg committed
658
     interprocedural_view. */
659
660
      int ipv = get_interprocedural_view();
      set_interprocedural_view(true);
661
      fix_backedges(current_ir_graph->obst, node);
662
      set_interprocedural_view(ipv);
663
    }
664
665
666
667
668
  }
  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
669
  assert(node->op == op_Block &&
Florian Liekweg's avatar
Florian Liekweg committed
670
671
     node->attr.block.in_cg &&
     0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
672
673
674
675
676
677
678
679
680
  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) {
681
682
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
683
684
}

685
686
687
688
689
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];
}

690
691
692
693
694
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

695
ir_node *(set_Block_dead)(ir_node *block) {
696
  return _set_Block_dead(block);
697
698
699
}

int (is_Block_dead)(const ir_node *block) {
700
  return _is_Block_dead(block);
701
702
}

703
void
704
705
706
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
707
  assert(0 && " Why set irg? -- use set_irn_irg");
708
709
}

710
int
711
712
713
714
715
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

716
ir_node *
717
718
719
720
721
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

722
void
723
724
725
726
727
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

728
void
729
730
731
732
733
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);
}

734
void
735
free_End (ir_node *end) {
736
  assert (end->op == op_End);
737
  end->kind = k_BAD;
738
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
739
  end->in = NULL;   /* @@@ make sure we get an error if we use the
Florian Liekweg's avatar
Florian Liekweg committed
740
               in array afterwards ... */
741
742
}

743

Götz Lindenmaier's avatar
Götz Lindenmaier committed
744
745
746
747
748
749
750
751
752
/*
> 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
753
 - determining the biggest case constant to know the proj number for
Götz Lindenmaier's avatar
Götz Lindenmaier committed
754
755
756
757
758
759
760
761
762
763
764
765
   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.,
766
libFIRM can implement a routine that transforms between the two
Götz Lindenmaier's avatar
Götz Lindenmaier committed
767
768
769
770
771
772
773
774
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).
*/
775
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
776
777
778
779
780
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

781
void
Christian Schäfer's avatar
Christian Schäfer committed
782
783
784
785
786
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

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

793
void
794
795
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
796
  node->attr.c.kind = kind;
797
798
}

799
800
801
802
803
804
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

805
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
806
get_Return_mem (ir_node *node) {
807
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
808
809
810
  return get_irn_n(node, 0);
}

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

817
int
818
get_Return_n_ress (ir_node *node) {
819
820
821
822
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

823
ir_node **
824
825
826
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
827
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
828
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
829
830
  else
    return NULL;
831
832
}

Christian Schäfer's avatar
Christian Schäfer committed
833
/*
834
void
Christian Schäfer's avatar
Christian Schäfer committed
835
836
837
838
839
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

840
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
841
842
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
843
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
844
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
845
846
}

847
void
Christian Schäfer's avatar
Christian Schäfer committed
848
set_Return_res (ir_node *node, int pos, ir_node *res){
849
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
850
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
851
852
}

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

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

865
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
866
867
868
869
870
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

871
void
Christian Schäfer's avatar
Christian Schäfer committed
872
873
874
875
876
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

877
tarval *get_Const_tarval (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
878
  assert (node->op == op_Const);
879
  return node->attr.con.tv;
Christian Schäfer's avatar
Christian Schäfer committed
880
881
}

882
void
Christian Schäfer's avatar
Christian Schäfer committed
883
884
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
885
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
886
887
}

888
889
890
891

/* 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. */
892
type *
893
894
895
896
897
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

898
void
899
900
set_Const_type (ir_node *node, type *tp) {
  assert (node->op == op_Const);
901
  if (tp != firm_unknown_type) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
902
    assert (is_atomic_type(tp));
903
904
905
906
907
908
    assert (get_type_mode(tp) == get_irn_mode(node));
  }
  node->attr.con.tp = tp;
}


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

915
void
Christian Schäfer's avatar
Christian Schäfer committed
916
917
918
919
920
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

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

929
void
930
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
931
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
932
933
934
          && (   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
935
936
}

937
ident *
Beyhan's avatar
Beyhan committed
938
get_SymConst_name (ir_node *node) {
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));
  return node->attr.i.sym.ident_p;
Christian Schäfer's avatar
Christian Schäfer committed
942
943
}

944
void
Beyhan's avatar
Beyhan committed
945
set_SymConst_name (ir_node *node, ident *name) {
Christian Schäfer's avatar
Christian Schäfer committed
946
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
947
948
          && (get_SymConst_kind(node) == symconst_addr_name));
  node->attr.i.sym.ident_p = name;
Christian Schäfer's avatar
Christian Schäfer committed
949
950
}

Beyhan's avatar
Beyhan committed
951
952
953
954

/* 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
955
          && (get_SymConst_kind (node) == symconst_addr_ent));
Beyhan's avatar
Beyhan committed
956
957
958
959
960
961
962
963
964
  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
965
966
union symconst_symbol
get_SymConst_symbol (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
967
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
968
  return node->attr.i.sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
969
970
}

971
void
Michael Beck's avatar
Michael Beck committed
972
set_SymConst_symbol (ir_node *node, union symconst_symbol sym) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
973
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
974
975
  //memcpy (&(node->attr.i.sym), sym, sizeof(type_or_id));
  node->attr.i.sym = sym;