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
58
/**
 * Calculates the negated pnc condition.
 */
Christian Schäfer's avatar
Christian Schäfer committed
59
60
61
int
get_negated_pnc(int pnc) {
  switch (pnc) {
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  case pn_Cmp_False: return pn_Cmp_True;  break;
  case pn_Cmp_Eq:    return pn_Cmp_Ne;    break;
  case pn_Cmp_Lt:    return pn_Cmp_Uge;   break;
  case pn_Cmp_Le:    return pn_Cmp_Ug;    break;
  case pn_Cmp_Gt:    return pn_Cmp_Ule;   break;
  case pn_Cmp_Ge:    return pn_Cmp_Ul;    break;
  case pn_Cmp_Lg:    return pn_Cmp_Ue;    break;
  case pn_Cmp_Leg:   return pn_Cmp_Uo;    break;
  case pn_Cmp_Uo:    return pn_Cmp_Leg;   break;
  case pn_Cmp_Ue:    return pn_Cmp_Lg;    break;
  case pn_Cmp_Ul:    return pn_Cmp_Ge;    break;
  case pn_Cmp_Ule:   return pn_Cmp_Gt;    break;
  case pn_Cmp_Ug:    return pn_Cmp_Le;    break;
  case pn_Cmp_Uge:   return pn_Cmp_Lt;    break;
  case pn_Cmp_Ne:    return pn_Cmp_Eq;    break;
  case pn_Cmp_True:  return pn_Cmp_False; break;
Christian Schäfer's avatar
Christian Schäfer committed
78
79
80
81
  }
  return 99; /* to shut up gcc */
}

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

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

91
92
93
94
95
96
97
98
99
100
/**
 * 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.
 */
101
unsigned firm_add_node_size = 0;
102
103


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

108
109
  if (forbid_new_data)
    return 0;
110

111
  return firm_add_node_size += size;
112
113
114
}


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

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

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

Michael Beck's avatar
Michael Beck committed
140
141
142
  res->kind    = k_ir_node;
  res->op      = op;
  res->mode    = mode;
143
  res->visited = 0;
Michael Beck's avatar
Michael Beck committed
144
  res->link    = NULL;
Christian Schäfer's avatar
Christian Schäfer committed
145
  if (arity < 0) {
146
    res->in = NEW_ARR_F (ir_node *, 1);  /* 1: space for block */
Christian Schäfer's avatar
Christian Schäfer committed
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);
  }
Sebastian Hack's avatar
Sebastian Hack committed
151

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

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

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

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

167
168
169
    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
170
171
172
#endif

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

293
294
  /* 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
295

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
411
412
413
414
415
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;

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

#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;
}
438
439
440
441
442
443
#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
444
445
446
#endif /* DO_HEAPANALYSIS */


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

458
const_attr
Christian Schäfer's avatar
Christian Schäfer committed
459
460
461
462
463
464
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

465
long
Christian Schäfer's avatar
Christian Schäfer committed
466
467
468
469
470
471
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

472
alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
473
474
475
476
477
478
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

479
free_attr
Christian Schäfer's avatar
Christian Schäfer committed
480
481
482
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
483
  return node->attr.f;
Christian Schäfer's avatar
Christian Schäfer committed
484
485
}

486
symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
487
488
489
490
491
492
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

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

500
sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
501
502
503
504
505
506
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

507
int
Christian Schäfer's avatar
Christian Schäfer committed
508
509
510
511
512
513
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

514
block_attr
Christian Schäfer's avatar
Christian Schäfer committed
515
516
517
518
519
520
get_irn_block_attr (ir_node *node)
{
  assert (node->op == op_Block);
  return node->attr.block;
}

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

Christian Schäfer's avatar
Christian Schäfer committed
543
544
545
546
/** manipulate fields of individual nodes **/

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

552
void
553
set_nodes_block (ir_node *node, ir_node *block) {
Christian Schäfer's avatar
Christian Schäfer committed
554
555
556
557
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

558
559
560
561
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
/* 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;
}

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


606
int
Christian Schäfer's avatar
Christian Schäfer committed
607
608
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
609
  return get_irn_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
610
611
}

612
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
613
get_Block_cfgpred (ir_node *node, int pos) {
614
  assert(-1 <= pos && pos < get_irn_arity(node));
615
  assert(node->op == op_Block);
Christian Schäfer's avatar
Christian Schäfer committed
616
617
618
  return get_irn_n(node, pos);
}

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;
}
636
unsigned long
637
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
638
  assert (node->op == op_Block);
639
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
640
641
}

642
void
643
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
644
  assert (node->op == op_Block);
645
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
646
647
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
648
/* For this current_ir_graph must be set. */
649
void
650
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
651
652
653
654
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

655
int
656
Block_not_block_visited(ir_node *node) {
657
658
659
  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
660

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

667
void
Christian Schäfer's avatar
Christian Schäfer committed
668
669
670
671
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;
}
672

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

708
709
710
711
712
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];
}

713
714
715
716
717
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

718
ir_node *(set_Block_dead)(ir_node *block) {
719
  return _set_Block_dead(block);
720
721
722
}

int (is_Block_dead)(const ir_node *block) {
723
  return _is_Block_dead(block);
724
725
}

726
void
727
728
729
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
730
  assert(0 && " Why set irg? -- use set_irn_irg");
731
732
}

733
int
734
735
736
737
738
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

739
ir_node *
740
741
742
743
744
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

745
void
746
747
748
749
750
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

751
void
752
753
754
755
756
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);
}

757
void
758
free_End (ir_node *end) {
759
  assert (end->op == op_End);
760
  end->kind = k_BAD;
761
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
762
  end->in = NULL;   /* @@@ make sure we get an error if we use the
Florian Liekweg's avatar
Florian Liekweg committed
763
               in array afterwards ... */
764
765
}

766

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

804
void
Christian Schäfer's avatar
Christian Schäfer committed
805
806
807
808
809
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

810
cond_kind
811
812
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
813
  return node->attr.c.kind;
814
815
}

816
void
817
818
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
819
  node->attr.c.kind = kind;
820
821
}

822
823
824
825
826
827
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

828
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
829
get_Return_mem (ir_node *node) {
830
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
831
832
833
  return get_irn_n(node, 0);
}

834
void
Christian Schäfer's avatar
Christian Schäfer committed
835
836
837
838
839
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

840
int
841
get_Return_n_ress (ir_node *node) {
842
843
844
845
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

846
ir_node **
847
848
849
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
850
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
851
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
852
853
  else
    return NULL;
854
855
}

Christian Schäfer's avatar
Christian Schäfer committed
856
/*
857
void
Christian Schäfer's avatar
Christian Schäfer committed
858
859
860
861
862
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

863
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
864
865
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
866
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
867
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
868
869
}

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

876
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
877
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
878
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
879
880
881
  return get_irn_n(node, 0);
}

882
void
Christian Schäfer's avatar
Christian Schäfer committed
883
884
885
886
887
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

888
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
889
890
891
892
893
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

894
void
Christian Schäfer's avatar
Christian Schäfer committed
895
896
897
898
899
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
900
901
tarval *(get_Const_tarval)(ir_node *node) {
	return _get_Const_tarval(node);
Christian Schäfer's avatar
Christian Schäfer committed
902
903
}

904
void
Christian Schäfer's avatar
Christian Schäfer committed
905
906
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
907
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
908
909
}

Sebastian Hack's avatar
Sebastian Hack committed
910
911
912
913
914
cnst_classify_t (classify_Const)(ir_node *node)
{
	return _classify_Const(node);
}

915
916
917
918

/* 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. */
919
type *
920
921
922
923
924
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

925
void
926
927
set_Const_type (ir_node *node, type *tp) {
  assert (node->op == op_Const);
928
  if (tp != firm_unknown_type) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
929
    assert (is_atomic_type(tp));
930
931
932
933
934
935
    assert (get_type_mode(tp) == get_irn_mode(node));
  }
  node->attr.con.tp = tp;
}


936
symconst_kind
937
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
938
939
940
941
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

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

948
type *
Christian Schäfer's avatar
Christian Schäfer committed
949
950
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
951
952
953
          && (   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
954
955
}

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

964
ident *
Beyhan's avatar
Beyhan committed
965
get_SymConst_name (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
966
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
967
968
          && (get_SymConst_kind(node) == symconst_addr_name));
  return node->attr.i.sym.ident_p;
Christian Schäfer's avatar
Christian Schäfer committed
969
970
}