irnode.c 52.7 KB
Newer Older
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1
2
3
4
5
6
7
8
9
10
11
/*
 * Project:     libFIRM
 * File name:   ir/ir/irnode.c
 * Purpose:     Representation of an intermediate operation.
 * Author:      Martin Trapp, Christian Schaefer
 * Modified by: Goetz Lindenmaier
 * Created:
 * CVS-ID:      $Id$
 * Copyright:   (c) 1998-2003 Universitt Karlsruhe
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */
Boris Boesler's avatar
Boris Boesler committed
12

Boris Boesler's avatar
added    
Boris Boesler committed
13
#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);
165
166
167
    if(!not_a_block)
      INIT_LIST_HEAD(&res->attr.block.succ_head);

Sebastian Hack's avatar
Sebastian Hack committed
168

169
170
171
    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
172
173
174
#endif

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

Christian Schäfer's avatar
Christian Schäfer committed
176
177
178
  return res;
}

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

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

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

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

196
int (*_get_irn_arity)(const ir_node *node) = _get_irn_intra_arity;
197

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

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

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

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

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

259
ir_node *(*_get_irn_n)(const ir_node *node, int n) = _get_irn_intra_n;
260

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

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

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

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

295
296
  /* 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
297

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

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

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

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

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

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

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

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

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

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

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

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

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

383
void
384
(mark_irn_visited)(ir_node *node) {
385
  _mark_irn_visited(node);
386
387
}

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

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

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

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

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

413
414
415
416
417
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
418
419
420
421
422
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;

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

#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;
}
445
446
447
448
449
450
#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
451
452
453
#endif /* DO_HEAPANALYSIS */


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

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

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

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

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

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

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

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

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

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

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

Christian Schäfer's avatar
Christian Schäfer committed
550
551
552
553
/** manipulate fields of individual nodes **/

/* this works for all except Block */
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
554
get_nodes_block (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
555
  assert (!(node->op == op_Block));
556
	assert (is_irn_pinned_in_irg(node) && "block info may be incorrect");
Christian Schäfer's avatar
Christian Schäfer committed
557
558
559
  return get_irn_n(node, -1);
}

560
void
561
set_nodes_block (ir_node *node, ir_node *block) {
Christian Schäfer's avatar
Christian Schäfer committed
562
563
564
565
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

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
598
599
600
601
/* 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;
}

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

613
int
614
615
(get_Block_n_cfgpreds)(ir_node *node) {
  return get_Block_n_cfgpreds(node);
Christian Schäfer's avatar
Christian Schäfer committed
616
617
}

618
ir_node *
619
620
(get_Block_cfgpred)(ir_node *node, int pos) {
  return get_Block_cfgpred(node, pos);
Christian Schäfer's avatar
Christian Schäfer committed
621
622
}

623
void
Christian Schäfer's avatar
Christian Schäfer committed
624
625
626
627
628
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

629
630
631
632
633
ir_node  *
(get_Block_cfgpred_block)(ir_node *node, int pos) {
  return _get_Block_cfgpred_block(node, pos);
}

634
bool
Christian Schäfer's avatar
Christian Schäfer committed
635
636
637
638
639
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

640
void
Christian Schäfer's avatar
Christian Schäfer committed
641
642
643
644
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
645

646
unsigned long
Michael Beck's avatar
Michael Beck committed
647
648
(get_Block_block_visited)(ir_node *node) {
  return _get_Block_block_visited(node);
Christian Schäfer's avatar
Christian Schäfer committed
649
650
}

651
void
Michael Beck's avatar
Michael Beck committed
652
653
(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
654
655
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
656
/* For this current_ir_graph must be set. */
657
void
Michael Beck's avatar
Michael Beck committed
658
659
(mark_Block_block_visited)(ir_node *node) {
  _mark_Block_block_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
660
661
}

662
int
Michael Beck's avatar
Michael Beck committed
663
664
(Block_not_block_visited)(ir_node *node) {
  return _Block_not_block_visited(node);
665
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
666

667
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
668
669
670
671
672
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

673
void
Christian Schäfer's avatar
Christian Schäfer committed
674
675
676
677
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;
}
678

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

714
715
716
717
718
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];
}

719
720
721
722
723
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

724
ir_node *(set_Block_dead)(ir_node *block) {
725
  return _set_Block_dead(block);
726
727
728
}

int (is_Block_dead)(const ir_node *block) {
729
  return _is_Block_dead(block);
730
731
}

732
733
734
735
736
737
738
739
740
741
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;
}

742
void
743
744
745
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
746
  assert(0 && " Why set irg? -- use set_irn_irg");
747
748
}

749
int
750
751
752
753
754
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

755
ir_node *
756
757
758
759
760
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

761
void
762
763
764
765
766
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

767
void
768
769
770
771
772
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);
}

773
void
774
free_End (ir_node *end) {
775
  assert (end->op == op_End);
776
  end->kind = k_BAD;
777
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
778
  end->in = NULL;   /* @@@ make sure we get an error if we use the
Florian Liekweg's avatar
Florian Liekweg committed
779
               in array afterwards ... */
780
781
}

782
783
784
785
786
787
788
789
790
791
792
/* Return the target address of an IJmp */
ir_node *get_IJmp_target(ir_node *ijmp) {
  assert(ijmp->op == op_IJmp);
  return get_irn_n(ijmp, 0);
}

/** Sets the target address of an IJmp */
void set_IJmp_target(ir_node *ijmp, ir_node *tgt) {
  assert(ijmp->op == op_IJmp);
  set_irn_n(ijmp, 0, tgt);
}
793

Götz Lindenmaier's avatar
Götz Lindenmaier committed
794
795
796
797
798
799
800
801
802
/*
> 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
803
 - determining the biggest case constant to know the proj number for
Götz Lindenmaier's avatar
Götz Lindenmaier committed
804
805
806
807
808
809
810
811
812
813
814
815
   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.,
816
libFIRM can implement a routine that transforms between the two
Götz Lindenmaier's avatar
Götz Lindenmaier committed
817
818
819
820
821
822
823
824
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).
*/
825
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
826
827
828
829
830
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

831
void
Christian Schäfer's avatar
Christian Schäfer committed
832
833
834
835
836
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

837
cond_kind
838
839
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
840
  return node->attr.c.kind;
841
842
}

843
void
844
845
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
846
  node->attr.c.kind = kind;
847
848
}

849
850
851
852
853
854
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

855
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
856
get_Return_mem (ir_node *node) {
857
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
858
859
860
  return get_irn_n(node, 0);
}

861
void
Christian Schäfer's avatar
Christian Schäfer committed
862
863
864
865
866
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

867
int
868
get_Return_n_ress (ir_node *node) {
869
870
871
872
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

873
ir_node **
874
875
876
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
877
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
878
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
879
880
  else
    return NULL;
881
882
}

Christian Schäfer's avatar
Christian Schäfer committed
883
/*
884
void
Christian Schäfer's avatar
Christian Schäfer committed
885
886
887
888
889
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

890
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
891
892
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
893
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
894
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
895
896
}

897
void
Christian Schäfer's avatar
Christian Schäfer committed
898
set_Return_res (ir_node *node, int pos, ir_node *res){
899
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
900
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
901
902
}

903
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
904
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
905
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
906
907
908
  return get_irn_n(node, 0);
}

909
void
Christian Schäfer's avatar
Christian Schäfer committed
910
911
912
913
914
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

915
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
916
917
918
919
920
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

921
void
Christian Schäfer's avatar
Christian Schäfer committed
922
923
924
925
926
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
927
928
tarval *(get_Const_tarval)(ir_node *node) {
	return _get_Const_tarval(node);
Christian Schäfer's avatar
Christian Schäfer committed
929
930
}

931
void
Christian Schäfer's avatar
Christian Schäfer committed
932
933
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
934
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
935
936
}

Sebastian Hack's avatar
Sebastian Hack committed
937
938
939
940
941
cnst_classify_t (classify_Const)(ir_node *node)
{
	return _classify_Const(node);
}

942
943
944
945

/* 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. */
946
type *
947
948
949
950
951
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

952
void
953
954
set_Const_type (ir_node *node, type *tp) {
  assert (node->op == op_Const);
955
  if (tp != firm_unknown_type) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
956
    assert (is_atomic_type(tp));
957
958
959
960
961
962
    assert (get_type_mode(tp) == get_irn_mode(node));
  }
  node->attr.con.tp = tp;
}


963
symconst_kind
964
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
965
966
967
968
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

969
void
Christian Schäfer's avatar
Christian Schäfer committed
970
971
972
973
974
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

975
type *
Christian Schäfer's avatar
Christian Schäfer committed
976
977
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
978
979
980
          && (   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
981
982
}

983
void
984
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
985
  assert (   (node->op == op_SymConst</