irnode.c 51.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
#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"
Sebastian Hack's avatar
Sebastian Hack committed
30
#include "iredges_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
31

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

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

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

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

Michael Beck's avatar
Michael Beck committed
56
/*
57
 * Calculates the negated (Complement(R)) pnc condition.
Michael Beck's avatar
Michael Beck committed
58
 */
59
60
61
62
63
64
65
66
int get_negated_pnc(int pnc, ir_mode *mode) {
  pnc ^= pn_Cmp_True;

  /* do NOT add the Uo bit for non-floating point values */
  if (! mode_is_float(mode))
    pnc &= ~pn_Cmp_Uo;

  return pnc;
Christian Schäfer's avatar
Christian Schäfer committed
67
68
}

69
/* Calculates the inversed (R^-1) pnc condition, i.e., "<" --> ">" */
Michael Beck's avatar
Michael Beck committed
70
int
71
get_inversed_pnc(int pnc) {
Michael Beck's avatar
Michael Beck committed
72
73
74
75
76
77
78
79
80
  int code    = pnc & ~(pn_Cmp_Lt|pn_Cmp_Gt);
  int lesser  = pnc & pn_Cmp_Lt;
  int greater = pnc & pn_Cmp_Gt;

  code |= (lesser ? pn_Cmp_Gt : 0) | (greater ? pn_Cmp_Lt : 0);

  return code;
}

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
  } else {
    res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1));
    memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
  }
Sebastian Hack's avatar
Sebastian Hack committed
150

Christian Schäfer's avatar
Christian Schäfer committed
151
  res->in[0] = block;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
152
  set_irn_dbg_info(res, db);
153
  res->out = NULL;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
154
155
156
157
158

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

159
160
161
162
#if FIRM_EDGES_INPLACE
  {
    int i, n;
    int not_a_block = is_no_Block(res);
Sebastian Hack's avatar
Sebastian Hack committed
163

164
    INIT_LIST_HEAD(&res->edge_info.outs_head);
Sebastian Hack's avatar
Sebastian Hack committed
165

166
167
168
    for (i = 0, n = arity + not_a_block; i < n; ++i)
      edges_notify_edge(res, i - not_a_block, res->in[i], NULL, irg);
  }
Sebastian Hack's avatar
Sebastian Hack committed
169
170
171
#endif

  hook_new_node(irg, res);
Michael Beck's avatar
Michael Beck committed
172

Christian Schäfer's avatar
Christian Schäfer committed
173
174
175
  return res;
}

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

Sebastian Felis's avatar
Sebastian Felis committed
178
int
179
(is_ir_node)(const void *thing) {
180
  return _is_ir_node(thing);
Sebastian Felis's avatar
Sebastian Felis committed
181
182
}

183
int
184
(get_irn_intra_arity)(const ir_node *node) {
185
  return _get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
186
187
}

188
int
189
(get_irn_inter_arity)(const ir_node *node) {
190
  return _get_irn_inter_arity(node);
191
192
}

193
int (*_get_irn_arity)(const ir_node *node) = _get_irn_intra_arity;
194

195
int
196
(get_irn_arity)(const ir_node *node) {
197
  return _get_irn_arity(node);
198
199
}

200
201
202
203
204
205
/* 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. */
206
ir_node **
207
get_irn_in (const ir_node *node) {
208
  assert(node);
209
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
210
211
212
213
214
215
216
217
218
    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
219
220
}

221
void
222
set_irn_in (ir_node *node, int arity, ir_node **in) {
223
  ir_node *** arr;
224
  assert(node);
225
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    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;
241
  }
242
  fix_backedges(current_ir_graph->obst, node);
243
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
244
245
}

246
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
247
(get_irn_intra_n)(const ir_node *node, int n) {
248
  return _get_irn_intra_n (node, n);
249
250
}

251
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
252
(get_irn_inter_n)(const ir_node *node, int n) {
253
  return _get_irn_inter_n (node, n);
254
255
}

256
ir_node *(*_get_irn_n)(const ir_node *node, int n) = _get_irn_intra_n;
257

258
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
259
(get_irn_n)(const ir_node *node, int n) {
260
  return _get_irn_n(node, n);
Christian Schäfer's avatar
Christian Schäfer committed
261
262
}

263
void
264
set_irn_n (ir_node *node, int n, ir_node *in) {
Sebastian Hack's avatar
Sebastian Hack committed
265
266
267
  assert(node && node->kind == k_ir_node);
  assert(-1 <= n);
  assert(n < get_irn_arity(node));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
268
  assert(in && in->kind == k_ir_node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
269

270
271
272
273
274
275
276
  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;
  }
277
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
278
279
280
281
282
283
284
285
286
287
    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 */
  }
Sebastian Hack's avatar
Sebastian Hack committed
288

289
290
  /* Call the hook */
  hook_set_irn_n(node, n, in, node->in[n + 1]);
Sebastian Hack's avatar
Sebastian Hack committed
291

292
293
  /* Here, we rely on src and tgt being in the current ir graph */
  edges_notify_edge(node, n, in, node->in[n + 1], current_ir_graph);
Sebastian Hack's avatar
Sebastian Hack committed
294

295
  node->in[n + 1] = in;
Christian Schäfer's avatar
Christian Schäfer committed
296
297
}

298
ir_mode *
299
(get_irn_mode)(const ir_node *node) {
300
  return _get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
301
302
}

303
void
304
(set_irn_mode)(ir_node *node, ir_mode *mode)
Till Riedel's avatar
Till Riedel committed
305
{
306
  _set_irn_mode(node, mode);
Till Riedel's avatar
Till Riedel committed
307
308
}

309
modecode
310
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
311
312
313
314
315
{
  assert (node);
  return node->mode->code;
}

316
/** Gets the string representation of the mode .*/
317
const char *
318
319
320
321
322
get_irn_modename (const ir_node *node)
{
  assert(node);
  return get_mode_name(node->mode);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
323

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

331
ir_op *
332
(get_irn_op)(const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
333
{
334
  return _get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
335
336
337
}

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

345
opcode
346
(get_irn_opcode)(const ir_node *node)
347
{
348
  return _get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
349
350
}

351
const char *
352
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
353
354
{
  assert(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
355
356
357
  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";
358
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
359
360
}

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

368
unsigned long
369
(get_irn_visited)(const ir_node *node)
370
{
371
  return _get_irn_visited(node);
372
373
}

374
void
375
(set_irn_visited)(ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
376
{
377
  _set_irn_visited(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
378
}
379

380
void
381
(mark_irn_visited)(ir_node *node) {
382
  _mark_irn_visited(node);
383
384
}

385
int
386
(irn_not_visited)(const ir_node *node) {
387
  return _irn_not_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
388
389
}

390
int
391
(irn_visited)(const ir_node *node) {
392
  return _irn_visited(node);
393
394
}

395
void
396
(set_irn_link)(ir_node *node, void *link) {
397
  _set_irn_link(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
398
399
}

400
void *
401
(get_irn_link)(const ir_node *node) {
402
  return _get_irn_link(node);
Christian Schäfer's avatar
Christian Schäfer committed
403
404
}

405
406
op_pin_state
(get_irn_pinned)(const ir_node *node) {
407
  return _get_irn_pinned(node);
408
409
}

410
411
412
413
414
op_pin_state
(is_irn_pinned_in_irg) (const ir_node *node) {
  return _is_irn_pinned_in_irg(node);
}

Michael Beck's avatar
Michael Beck committed
415
416
417
418
419
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;

420
  assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned);
Michael Beck's avatar
Michael Beck committed
421
422
423
424
  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
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

#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;
}
442
443
444
445
446
447
#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
448
449
450
#endif /* DO_HEAPANALYSIS */


Götz Lindenmaier's avatar
Götz Lindenmaier committed
451
/* Outputs a unique number for this node */
452
long
453
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
454
  assert(node);
455
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
456
  return node->node_nr;
457
#else
458
  return (long)node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
459
#endif
460
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
461

462
const_attr
Christian Schäfer's avatar
Christian Schäfer committed
463
464
465
466
467
468
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

469
long
Christian Schäfer's avatar
Christian Schäfer committed
470
471
472
473
474
475
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

476
alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
477
478
479
480
481
482
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

483
free_attr
Christian Schäfer's avatar
Christian Schäfer committed
484
485
486
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
487
  return node->attr.f;
Christian Schäfer's avatar
Christian Schäfer committed
488
489
}

490
symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
491
492
493
494
495
496
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

497
type *
Christian Schäfer's avatar
Christian Schäfer committed
498
499
500
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
501
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
502
503
}

504
sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
505
506
507
508
509
510
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

511
int
Christian Schäfer's avatar
Christian Schäfer committed
512
513
514
515
516
517
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

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

525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
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 ||
543
          node->op == op_DivMod || node->op == op_Mod || node->op == op_Call || node->op == op_Alloc);
544
545
546
  return node->attr.except;
}

Christian Schäfer's avatar
Christian Schäfer committed
547
548
549
550
/** manipulate fields of individual nodes **/

/* this works for all except Block */
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
551
get_nodes_block (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
552
553
554
555
  assert (!(node->op == op_Block));
  return get_irn_n(node, -1);
}

556
void
557
set_nodes_block (ir_node *node, ir_node *block) {
Christian Schäfer's avatar
Christian Schäfer committed
558
559
560
561
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
/* 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;
}

598
/* Returns an array with the predecessors of the Block. Depending on
599
   the implementation of the graph data structure this can be a copy of
600
601
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
602
ir_node **
603
604
605
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
606
  return (ir_node **)&(get_irn_in(node)[1]);
607
608
}

609
int
610
611
(get_Block_n_cfgpreds)(ir_node *node) {
  return get_Block_n_cfgpreds(node);
Christian Schäfer's avatar
Christian Schäfer committed
612
613
}

614
ir_node *
615
616
(get_Block_cfgpred)(ir_node *node, int pos) {
  return get_Block_cfgpred(node, pos);
Christian Schäfer's avatar
Christian Schäfer committed
617
618
}

619
void
Christian Schäfer's avatar
Christian Schäfer committed
620
621
622
623
624
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

625
bool
Christian Schäfer's avatar
Christian Schäfer committed
626
627
628
629
630
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

631
void
Christian Schäfer's avatar
Christian Schäfer committed
632
633
634
635
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
Michael Beck's avatar
Michael Beck committed
636

637
unsigned long
Michael Beck's avatar
Michael Beck committed
638
639
(get_Block_block_visited)(ir_node *node) {
  return _get_Block_block_visited(node);
Christian Schäfer's avatar
Christian Schäfer committed
640
641
}

642
void
Michael Beck's avatar
Michael Beck committed
643
644
(set_Block_block_visited)(ir_node *node, unsigned long visit) {
  _set_Block_block_visited(node, visit);
Christian Schäfer's avatar
Christian Schäfer committed
645
646
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
647
/* For this current_ir_graph must be set. */
648
void
Michael Beck's avatar
Michael Beck committed
649
650
(mark_Block_block_visited)(ir_node *node) {
  _mark_Block_block_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
651
652
}

653
int
Michael Beck's avatar
Michael Beck committed
654
655
(Block_not_block_visited)(ir_node *node) {
  return _Block_not_block_visited(node);
656
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
657

658
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
659
660
661
662
663
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

664
void
Christian Schäfer's avatar
Christian Schäfer committed
665
666
667
668
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;
}
669

670
671
672
673
674
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;
675
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
676
677
    {
      /* Fix backedge array.  fix_backedges operates depending on
Florian Liekweg's avatar
Florian Liekweg committed
678
     interprocedural_view. */
679
680
      int ipv = get_interprocedural_view();
      set_interprocedural_view(true);
681
      fix_backedges(current_ir_graph->obst, node);
682
      set_interprocedural_view(ipv);
683
    }
684
685
686
687
688
  }
  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
689
  assert(node->op == op_Block &&
Florian Liekweg's avatar
Florian Liekweg committed
690
691
     node->attr.block.in_cg &&
     0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
692
693
694
695
696
697
698
699
700
  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) {
701
702
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
703
704
}

705
706
707
708
709
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];
}

710
711
712
713
714
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

715
ir_node *(set_Block_dead)(ir_node *block) {
716
  return _set_Block_dead(block);
717
718
719
}

int (is_Block_dead)(const ir_node *block) {
720
  return _is_Block_dead(block);
721
722
}

723
724
725
726
727
728
729
730
731
732
ir_extblk *get_Block_extbb(const ir_node *block) {
  assert(is_Block(block));
  return block->attr.block.extblk;
}

void set_Block_extbb(ir_node *block, ir_extblk *extblk) {
  assert(is_Block(block));
  block->attr.block.extblk = extblk;
}

733
void
734
735
736
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
737
  assert(0 && " Why set irg? -- use set_irn_irg");
738
739
}

740
int
741
742
743
744
745
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

746
ir_node *
747
748
749
750
751
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

752
void
753
754
755
756
757
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

758
void
759
760
761
762
763
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);
}

764
void
765
free_End (ir_node *end) {
766
  assert (end->op == op_End);
767
  end->kind = k_BAD;
768
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
769
  end->in = NULL;   /* @@@ make sure we get an error if we use the
Florian Liekweg's avatar
Florian Liekweg committed
770
               in array afterwards ... */
771
772
}

773

Götz Lindenmaier's avatar
Götz Lindenmaier committed
774
775
776
777
778
779
780
781
782
/*
> 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
783
 - determining the biggest case constant to know the proj number for
Götz Lindenmaier's avatar
Götz Lindenmaier committed
784
785
786
787
788
789
790
791
792
793
794
795
   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.,
796
libFIRM can implement a routine that transforms between the two
Götz Lindenmaier's avatar
Götz Lindenmaier committed
797
798
799
800
801
802
803
804
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).
*/
805
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
806
807
808
809
810
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

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

817
cond_kind
818
819
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
820
  return node->attr.c.kind;
821
822
}

823
void
824
825
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
826
  node->attr.c.kind = kind;
827
828
}

829
830
831
832
833
834
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

835
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
836
get_Return_mem (ir_node *node) {
837
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
838
839
840
  return get_irn_n(node, 0);
}

841
void
Christian Schäfer's avatar
Christian Schäfer committed
842
843
844
845
846
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

847
int
848
get_Return_n_ress (ir_node *node) {
849
850
851
852
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

853
ir_node **
854
855
856
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
857
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
858
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
859
860
  else
    return NULL;
861
862
}

Christian Schäfer's avatar
Christian Schäfer committed
863
/*
864
void
Christian Schäfer's avatar
Christian Schäfer committed
865
866
867
868
869
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

870
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
871
872
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
873
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
874
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
875
876
}

877
void
Christian Schäfer's avatar
Christian Schäfer committed
878
set_Return_res (ir_node *node, int pos, ir_node *res){
879
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
880
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
881
882
}

883
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
884
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
885
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
886
887
888
  return get_irn_n(node, 0);
}

889
void
Christian Schäfer's avatar
Christian Schäfer committed
890
891
892
893
894
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

895
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
896
897
898
899
900
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

901
void
Christian Schäfer's avatar
Christian Schäfer committed
902
903
904
905
906
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

Sebastian Hack's avatar
Sebastian Hack committed
907
908
tarval *(get_Const_tarval)(ir_node *node) {
	return _get_Const_tarval(node);
Christian Schäfer's avatar
Christian Schäfer committed
909
910
}

911
void
Christian Schäfer's avatar
Christian Schäfer committed
912
913
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
914
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
915
916
}

Sebastian Hack's avatar
Sebastian Hack committed
917
918
919
920
921
cnst_classify_t (classify_Const)(ir_node *node)
{
	return _classify_Const(node);
}

922
923
924
925

/* 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. */
926
type *
927
928
929
930
931
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

932
void
933
934
set_Const_type (ir_node *node, type *tp) {
  assert (node->op == op_Const);
935
  if (tp != firm_unknown_type) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
936
    assert (is_atomic_type(tp));
937
938
939
940
941
942
    assert (get_type_mode(tp) == get_irn_mode(node));
  }
  node->attr.con.tp = tp;
}


943
symconst_kind
944
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
945
946
947
948
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

949
void
Christian Schäfer's avatar
Christian Schäfer committed
950
951
952
953
954
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

955
type *
Christian Schäfer's avatar
Christian Schäfer committed
956
957
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
958
959
960
          && (   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
961
962
}

963
void
964
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
965
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
966
967
968
          && (   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
969
970
}

971
ident *
Beyhan's avatar
Beyhan committed
972
get_SymConst_name (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
973
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
974
975
          && (get_SymConst_kind(node) == symconst_addr_name));
  return node->attr.i.sym.ident_p;
Christian Schäfer's avatar