irnode.c 62 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"
33
#include "irtools.h"
Michael Beck's avatar
Michael Beck committed
34

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

43
static const char *pnc_name_arr [] = {
Michael Beck's avatar
Michael Beck committed
44
45
46
47
  "pn_Cmp_False", "pn_Cmp_Eq", "pn_Cmp_Lt", "pn_Cmp_Le",
  "pn_Cmp_Gt", "pn_Cmp_Ge", "pn_Cmp_Lg", "pn_Cmp_Leg",
  "pn_Cmp_Uo", "pn_Cmp_Ue", "pn_Cmp_Ul", "pn_Cmp_Ule",
  "pn_Cmp_Ug", "pn_Cmp_Uge", "pn_Cmp_Ne", "pn_Cmp_True"
48
};
Christian Schäfer's avatar
Christian Schäfer committed
49

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

Michael Beck's avatar
Michael Beck committed
57
/*
58
 * Calculates the negated (Complement(R)) pnc condition.
Michael Beck's avatar
Michael Beck committed
59
 */
60
61
62
63
64
65
66
67
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
68
69
}

70
/* Calculates the inversed (R^-1) pnc condition, i.e., "<" --> ">" */
Michael Beck's avatar
Michael Beck committed
71
int
72
get_inversed_pnc(int pnc) {
Michael Beck's avatar
Michael Beck committed
73
74
75
76
77
78
79
80
81
  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;
}

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

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

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

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

161
162
#if FIRM_EDGES_INPLACE
  {
163
164
    int i;
    int is_bl = is_Block(res);
Sebastian Hack's avatar
Sebastian Hack committed
165

166
    INIT_LIST_HEAD(&res->edge_info.outs_head);
167
    if(is_bl)
168
169
      INIT_LIST_HEAD(&res->attr.block.succ_head);

Sebastian Hack's avatar
Sebastian Hack committed
170

171
172
    for (i = is_bl; i <= arity; ++i)
      edges_notify_edge(res, i - 1, res->in[i], NULL, irg);
173
  }
Sebastian Hack's avatar
Sebastian Hack committed
174
175
176
#endif

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

Christian Schäfer's avatar
Christian Schäfer committed
178
179
180
  return res;
}

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

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

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

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

198
int (*_get_irn_arity)(const ir_node *node) = _get_irn_intra_arity;
199

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

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

226
void
227
set_irn_in (ir_node *node, int arity, ir_node **in) {
228
  int i;
229
  ir_node *** arr;
230
  ir_graph *irg = current_ir_graph;
231
  assert(node);
232
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
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;
  }
244
245
246

	for (i = 0; i < arity; i++) {
		if (i < ARR_LEN(*arr)-1)
247
    	edges_notify_edge(node, i, in[i], (*arr)[i+1], irg);
248
		else
249
	    edges_notify_edge(node, i, in[i], NULL,        irg);
250
251
  }
	for(;i < ARR_LEN(*arr)-1; i++) {
252
		edges_notify_edge(node, i, NULL, (*arr)[i+1], irg);
253
254
255
	}

	if (arity != ARR_LEN(*arr) - 1) {
256
    ir_node * block = (*arr)[0];
257
    *arr = NEW_ARR_D(ir_node *, irg->obst, arity + 1);
258
    (*arr)[0] = block;
259
  }
260
  fix_backedges(irg->obst, node);
261

262
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
263
264
}

265
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
266
(get_irn_intra_n)(const ir_node *node, int n) {
267
  return _get_irn_intra_n (node, n);
268
269
}

270
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
271
(get_irn_inter_n)(const ir_node *node, int n) {
272
  return _get_irn_inter_n (node, n);
273
274
}

275
ir_node *(*_get_irn_n)(const ir_node *node, int n) = _get_irn_intra_n;
276

277
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
278
(get_irn_n)(const ir_node *node, int n) {
279
  return _get_irn_n(node, n);
Christian Schäfer's avatar
Christian Schäfer committed
280
281
}

282
void
283
set_irn_n (ir_node *node, int n, ir_node *in) {
Sebastian Hack's avatar
Sebastian Hack committed
284
285
286
  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
287
  assert(in && in->kind == k_ir_node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
288

289
290
291
292
293
294
295
  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;
  }
296
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
297
298
299
300
301
302
303
304
305
306
    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
307

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

311
312
  /* 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
313

314
  node->in[n + 1] = in;
Christian Schäfer's avatar
Christian Schäfer committed
315
316
}

317
ir_mode *
318
(get_irn_mode)(const ir_node *node) {
319
  return _get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
320
321
}

322
void
323
(set_irn_mode)(ir_node *node, ir_mode *mode)
Till Riedel's avatar
Till Riedel committed
324
{
325
  _set_irn_mode(node, mode);
Till Riedel's avatar
Till Riedel committed
326
327
}

328
modecode
329
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
330
331
332
333
334
{
  assert (node);
  return node->mode->code;
}

335
/** Gets the string representation of the mode .*/
336
const char *
337
338
339
340
341
get_irn_modename (const ir_node *node)
{
  assert(node);
  return get_mode_name(node->mode);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
342

343
ident *
344
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
345
346
{
  assert(node);
347
  return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
348
349
}

350
ir_op *
351
(get_irn_op)(const ir_node *node) {
352
  return _get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
353
354
355
}

/* should be private to the library: */
356
void
357
358
(set_irn_op)(ir_node *node, ir_op *op) {
	_set_irn_op(node, op);
Christian Schäfer's avatar
Christian Schäfer committed
359
360
}

361
opcode
362
(get_irn_opcode)(const ir_node *node)
363
{
364
  return _get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
365
366
}

367
const char *
368
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
369
370
{
  assert(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
371
372
373
  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";
374
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
375
376
}

377
ident *
378
get_irn_opident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
379
380
381
{
  assert(node);
  return node->op->name;
382
383
}

384
unsigned long
385
(get_irn_visited)(const ir_node *node)
386
{
387
  return _get_irn_visited(node);
388
389
}

390
void
391
(set_irn_visited)(ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
392
{
393
  _set_irn_visited(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
394
}
395

396
void
397
(mark_irn_visited)(ir_node *node) {
398
  _mark_irn_visited(node);
399
400
}

401
int
402
(irn_not_visited)(const ir_node *node) {
403
  return _irn_not_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
404
405
}

406
int
407
(irn_visited)(const ir_node *node) {
408
  return _irn_visited(node);
409
410
}

411
void
412
(set_irn_link)(ir_node *node, void *link) {
413
  _set_irn_link(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
414
415
}

416
void *
417
(get_irn_link)(const ir_node *node) {
418
  return _get_irn_link(node);
Christian Schäfer's avatar
Christian Schäfer committed
419
420
}

421
422
op_pin_state
(get_irn_pinned)(const ir_node *node) {
423
  return _get_irn_pinned(node);
424
425
}

426
427
428
429
430
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
431
432
433
434
435
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;

436
  assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned);
Michael Beck's avatar
Michael Beck committed
437
438
439
440
  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
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

#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;
}
458
459
460
461
462
463
#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
464
465
466
#endif /* DO_HEAPANALYSIS */


Götz Lindenmaier's avatar
Götz Lindenmaier committed
467
/* Outputs a unique number for this node */
468
long get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
469
  assert(node);
470
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
471
  return node->node_nr;
472
#else
473
  return (long)PTR_TO_INT(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
474
#endif
475
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
476

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

484
long
Christian Schäfer's avatar
Christian Schäfer committed
485
486
487
488
489
490
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

491
alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
492
493
494
495
496
497
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

498
free_attr
Christian Schäfer's avatar
Christian Schäfer committed
499
500
501
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
502
  return node->attr.f;
Christian Schäfer's avatar
Christian Schäfer committed
503
504
}

505
symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
506
507
508
509
510
511
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

Michael Beck's avatar
Michael Beck committed
512
ir_type *
Christian Schäfer's avatar
Christian Schäfer committed
513
514
515
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
516
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
517
518
}

519
sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
520
521
522
523
524
525
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

526
int
Christian Schäfer's avatar
Christian Schäfer committed
527
528
529
530
531
532
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

533
block_attr
Christian Schäfer's avatar
Christian Schäfer committed
534
535
536
537
538
539
get_irn_block_attr (ir_node *node)
{
  assert (node->op == op_Block);
  return node->attr.block;
}

540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
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 ||
558
          node->op == op_DivMod || node->op == op_Mod || node->op == op_Call || node->op == op_Alloc);
559
560
561
  return node->attr.except;
}

562
563
564
565
566
void *
get_irn_generic_attr (ir_node *node) {
  return &node->attr;
}

567
568
569
570
571
unsigned (get_irn_idx)(const ir_node *node) {
  assert(is_ir_node(node));
  return _get_irn_idx(node);
}

Christian Schäfer's avatar
Christian Schäfer committed
572
573
574
575
/** manipulate fields of individual nodes **/

/* this works for all except Block */
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
576
get_nodes_block (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
577
  assert (!(node->op == op_Block));
578
	assert (is_irn_pinned_in_irg(node) && "block info may be incorrect");
Christian Schäfer's avatar
Christian Schäfer committed
579
580
581
  return get_irn_n(node, -1);
}

582
void
583
set_nodes_block (ir_node *node, ir_node *block) {
Christian Schäfer's avatar
Christian Schäfer committed
584
585
586
587
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

588
589
/* Test whether arbitrary node is frame pointer, i.e. Proj(pn_Start_P_frame_base)
 * from Start.  If so returns frame type, else Null. */
Michael Beck's avatar
Michael Beck committed
590
ir_type *is_frame_pointer(ir_node *n) {
591
592
593
594
595
596
597
598
599
600
601
602
  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. */
Michael Beck's avatar
Michael Beck committed
603
ir_type *is_globals_pointer(ir_node *n) {
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
  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;
}

624
/* Returns an array with the predecessors of the Block. Depending on
625
   the implementation of the graph data structure this can be a copy of
626
627
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
628
ir_node **
629
630
631
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
632
  return (ir_node **)&(get_irn_in(node)[1]);
633
634
}

635
int
636
(get_Block_n_cfgpreds)(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
637
  return _get_Block_n_cfgpreds(node);
Christian Schäfer's avatar
Christian Schäfer committed
638
639
}

640
ir_node *
641
(get_Block_cfgpred)(ir_node *node, int pos) {
Michael Beck's avatar
Michael Beck committed
642
  return _get_Block_cfgpred(node, pos);
Christian Schäfer's avatar
Christian Schäfer committed
643
644
}

645
void
Christian Schäfer's avatar
Christian Schäfer committed
646
647
648
649
650
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

651
652
653
654
655
ir_node  *
(get_Block_cfgpred_block)(ir_node *node, int pos) {
  return _get_Block_cfgpred_block(node, pos);
}

656
int
Christian Schäfer's avatar
Christian Schäfer committed
657
658
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
659
  return (int)node->attr.block.matured;
Christian Schäfer's avatar
Christian Schäfer committed
660
661
}

662
void
663
set_Block_matured (ir_node *node, int matured) {
Christian Schäfer's avatar
Christian Schäfer committed
664
665
666
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
Michael Beck's avatar
Michael Beck committed
667

668
unsigned long
Michael Beck's avatar
Michael Beck committed
669
670
(get_Block_block_visited)(ir_node *node) {
  return _get_Block_block_visited(node);
Christian Schäfer's avatar
Christian Schäfer committed
671
672
}

673
void
Michael Beck's avatar
Michael Beck committed
674
675
(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
676
677
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
678
/* For this current_ir_graph must be set. */
679
void
Michael Beck's avatar
Michael Beck committed
680
681
(mark_Block_block_visited)(ir_node *node) {
  _mark_Block_block_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
682
683
}

684
int
Michael Beck's avatar
Michael Beck committed
685
686
(Block_not_block_visited)(ir_node *node) {
  return _Block_not_block_visited(node);
687
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
688

689
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
690
691
692
693
694
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

695
void
Christian Schäfer's avatar
Christian Schäfer committed
696
697
698
699
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;
}
700

701
702
703
704
705
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;
706
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
707
    {
708
      /* Fix backedge array.  fix_backedges() operates depending on
Florian Liekweg's avatar
Florian Liekweg committed
709
     interprocedural_view. */
710
      int ipv = get_interprocedural_view();
711
      set_interprocedural_view(1);
712
      fix_backedges(current_ir_graph->obst, node);
713
      set_interprocedural_view(ipv);
714
    }
715
716
717
718
719
  }
  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
720
  assert(node->op == op_Block &&
Florian Liekweg's avatar
Florian Liekweg committed
721
722
     node->attr.block.in_cg &&
     0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
723
724
725
726
727
728
729
730
731
  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) {
732
733
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
734
735
}

736
737
738
739
740
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];
}

741
742
743
744
745
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

746
ir_node *(set_Block_dead)(ir_node *block) {
747
  return _set_Block_dead(block);
748
749
750
}

int (is_Block_dead)(const ir_node *block) {
751
  return _is_Block_dead(block);
752
753
}

754
ir_extblk *get_Block_extbb(const ir_node *block) {
Michael Beck's avatar
Michael Beck committed
755
	ir_extblk *res;
756
  assert(is_Block(block));
Michael Beck's avatar
Michael Beck committed
757
758
759
	res = block->attr.block.extblk;
	assert(res == NULL || is_ir_extbb(res));
  return res;
760
761
762
763
}

void set_Block_extbb(ir_node *block, ir_extblk *extblk) {
  assert(is_Block(block));
Michael Beck's avatar
Michael Beck committed
764
	assert(extblk == NULL || is_ir_extbb(extblk));
765
766
767
  block->attr.block.extblk = extblk;
}

768
int
769
770
771
772
773
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

774
ir_node *
775
776
777
778
779
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

780
void
781
782
783
784
785
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

786
void
787
788
789
790
791
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);
}

792
void
793
free_End (ir_node *end) {
794
  assert (end->op == op_End);
795
  end->kind = k_BAD;
796
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
797
  end->in = NULL;   /* @@@ make sure we get an error if we use the
Florian Liekweg's avatar
Florian Liekweg committed
798
               in array afterwards ... */
799
800
}

801
802
803
804
805
806
807
808
809
810
811
/* 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);
}
812

Götz Lindenmaier's avatar
Götz Lindenmaier committed
813
814
815
816
817
818
819
820
821
/*
> 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
822
 - determining the biggest case constant to know the proj number for
Götz Lindenmaier's avatar
Götz Lindenmaier committed
823
824
825
826
827
828
829
830
831
832
833
834
   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.,
835
libFIRM can implement a routine that transforms between the two
Götz Lindenmaier's avatar
Götz Lindenmaier committed
836
837
838
839
840
841
842
843
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).
*/
844
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
845
846
847
848
849
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

850
void
Christian Schäfer's avatar
Christian Schäfer committed
851
852
853
854
855
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

856
cond_kind
857
858
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
859
  return node->attr.c.kind;
860
861
}

862
void
863
864
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
865
  node->attr.c.kind = kind;
866
867
}

868
869
870
871
872
873
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

874
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
875
get_Return_mem (ir_node *node) {
876
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
877
878
879
  return get_irn_n(node, 0);
}

880
void
Christian Schäfer's avatar
Christian Schäfer committed
881
882
883
884
885
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

886
int
887
get_Return_n_ress (ir_node *node) {
888
889
890
891
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

892
ir_node **
893
894
895
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
896
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
897
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
898
899
  else
    return NULL;
900
901
}

Christian Schäfer's avatar
Christian Schäfer committed
902
/*
903
void
Christian Schäfer's avatar
Christian Schäfer committed
904
905
906
907
908
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

909
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
910
911
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
912
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
913
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
914
915
}

916
void
Christian Schäfer's avatar
Christian Schäfer committed
917
set_Return_res (ir_node *node, int pos, ir_node *res){
918
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
919
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
920
921
}

Sebastian Hack's avatar
Sebastian Hack committed
922
923
tarval *(get_Const_tarval)(ir_node *node) {
	return _get_Const_tarval(node);
Christian Schäfer's avatar
Christian Schäfer committed
924
925
}

926
void
Christian Schäfer's avatar
Christian Schäfer committed
927
928
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
929
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
930
931
}

Sebastian Hack's avatar
Sebastian Hack committed
932
933
934
935
936
cnst_classify_t (classify_Const)(ir_node *node)
{
	return _classify_Const(node);
}

937
938
939
940

/* 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. */
Michael Beck's avatar
Michael Beck committed
941
ir_type *
942
943
944
945
946
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

947
void