irnode.c 47.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
14
15
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
16
#include <string.h>
Boris Boesler's avatar
added    
Boris Boesler committed
17

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

Michael Beck's avatar
Michael Beck committed
28
29
#include "firmstat.h"

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

38
39
40
41
42
43
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
44

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

Michael Beck's avatar
Michael Beck committed
52
53
54
/**
 * Calculates the negated pnc condition.
 */
Christian Schäfer's avatar
Christian Schäfer committed
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
int
get_negated_pnc(int pnc) {
  switch (pnc) {
  case False: return True;  break;
  case Eq:    return Ne;    break;
  case Lt:    return Uge;   break;
  case Le:    return Ug;    break;
  case Gt:    return Ule;   break;
  case Ge:    return Ul;    break;
  case Lg:    return Ue;    break;
  case Leg:   return Uo;    break;
  case Uo:    return Leg;   break;
  case Ue:    return Lg;    break;
  case Ul:    return Ge;    break;
  case Ule:   return Gt;    break;
  case Ug:    return Le;    break;
  case Uge:   return Lt;    break;
  case Ne:    return Eq;    break;
  case True:  return False; break;
  }
  return 99; /* to shut up gcc */
}

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

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

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
 * 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.
 */
static size_t additional_node_data_size = 0;


size_t register_additional_node_data(size_t size)
{
	assert(!forbid_new_data && "Too late to register additional node data");

	if(forbid_new_data)
		return 0;

	return additional_node_data_size += size;
}


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

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

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

Michael Beck's avatar
Michael Beck committed
137
138
139
  res->kind    = k_ir_node;
  res->op      = op;
  res->mode    = mode;
140
  res->visited = 0;
Michael Beck's avatar
Michael Beck committed
141
  res->link    = NULL;
Christian Schäfer's avatar
Christian Schäfer committed
142
  if (arity < 0) {
143
    res->in = NEW_ARR_F (ir_node *, 1);  /* 1: space for block */
Christian Schäfer's avatar
Christian Schäfer committed
144
145
146
147
148
  } else {
    res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1));
    memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
  }
  res->in[0] = block;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
149
  set_irn_dbg_info(res, db);
150
  res->out = NULL;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
151
152
153
154
155

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

Michael Beck's avatar
Michael Beck committed
156
157
  stat_new_node(res);

Christian Schäfer's avatar
Christian Schäfer committed
158
159
160
  return res;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
161
162
163
/* Copies all attributes stored in the old node to the new node.
   Assumes both have the same opcode and sufficient size. */
void
164
165
166
copy_attrs (const ir_node *old_node, ir_node *new_node) {
  assert(get_irn_op(old_node) == get_irn_op(new_node));
  memcpy(&new_node->attr, &old_node->attr, get_op_attr_size(get_irn_op(old_node)));
167
  if (get_irn_op(new_node) == op_Call) remove_Call_callee_arr(new_node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
168
}
Christian Schäfer's avatar
Christian Schäfer committed
169

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

Sebastian Felis's avatar
Sebastian Felis committed
172
int
173
174
(is_ir_node)(const void *thing) {
  return __is_ir_node(thing);
Sebastian Felis's avatar
Sebastian Felis committed
175
176
}

177
int
178
179
(get_irn_intra_arity)(const ir_node *node) {
  return __get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
180
181
}

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

187
188
int (*__get_irn_arity)(const ir_node *node) = __get_irn_intra_arity;

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

194
195
196
197
198
199
/* 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. */
200
ir_node **
201
get_irn_in (const ir_node *node) {
202
  assert(node);
203
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
204
205
206
207
208
209
210
211
212
    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
213
214
}

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

240
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
241
(get_irn_intra_n)(const ir_node *node, int n) {
242
  return __get_irn_intra_n (node, n);
243
244
}

245
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
246
(get_irn_inter_n)(const ir_node *node, int n) {
247
  return __get_irn_inter_n (node, n);
248
249
}

Sebastian Hack's avatar
Sebastian Hack committed
250
ir_node *(*__get_irn_n)(const ir_node *node, int n) = __get_irn_intra_n;
251

252
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
253
(get_irn_n)(const ir_node *node, int n) {
254
  return __get_irn_n(node, n);
Christian Schäfer's avatar
Christian Schäfer committed
255
256
}

257
void
258
set_irn_n (ir_node *node, int n, ir_node *in) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
259
260
  assert(node && node->kind == k_ir_node && -1 <= n && n < get_irn_arity(node));
  assert(in && in->kind == k_ir_node);
261
262
263
264
265
266
267
  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;
  }
268
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
269
270
271
272
273
274
275
276
277
278
279
    if (get_irn_opcode(node) == iro_Filter) {
      assert(node->attr.filter.in_cg);
      node->attr.filter.in_cg[n + 1] = in;
      return;
    } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
      node->attr.block.in_cg[n + 1] = in;
      return;
    }
    /* else fall through */
  }
  node->in[n + 1] = in;
Christian Schäfer's avatar
Christian Schäfer committed
280
281
}

282
ir_mode *
283
284
(get_irn_mode)(const ir_node *node) {
  return __get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
285
286
}

287
void
288
(set_irn_mode)(ir_node *node, ir_mode *mode)
Till Riedel's avatar
Till Riedel committed
289
{
290
  __set_irn_mode(node, mode);
Till Riedel's avatar
Till Riedel committed
291
292
}

293
modecode
294
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
295
296
297
298
299
{
  assert (node);
  return node->mode->code;
}

300
/** Gets the string representation of the mode .*/
301
const char *
302
303
304
305
306
get_irn_modename (const ir_node *node)
{
  assert(node);
  return get_mode_name(node->mode);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
307

308
ident *
309
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
310
311
{
  assert(node);
312
  return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
313
314
}

315
ir_op *
316
(get_irn_op)(const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
317
{
318
  return __get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
319
320
321
}

/* should be private to the library: */
322
void
Christian Schäfer's avatar
Christian Schäfer committed
323
324
325
326
327
328
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

329
opcode
330
(get_irn_opcode)(const ir_node *node)
331
{
332
  return __get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
333
334
}

335
const char *
336
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
337
338
{
  assert(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
339
340
341
  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";
342
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
343
344
}

345
ident *
346
get_irn_opident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
347
348
349
{
  assert(node);
  return node->op->name;
350
351
}

352
unsigned long
353
(get_irn_visited)(const ir_node *node)
354
{
355
  return __get_irn_visited(node);
356
357
}

358
void
359
(set_irn_visited)(ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
360
{
361
  __set_irn_visited(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
362
}
363

364
void
365
366
(mark_irn_visited)(ir_node *node) {
  __mark_irn_visited(node);
367
368
}

369
int
370
371
(irn_not_visited)(const ir_node *node) {
  return __irn_not_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
372
373
}

374
int
375
376
(irn_visited)(const ir_node *node) {
  return __irn_visited(node);
377
378
}

379
void
380
381
(set_irn_link)(ir_node *node, void *link) {
  __set_irn_link(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
382
383
}

384
void *
385
386
(get_irn_link)(const ir_node *node) {
  return __get_irn_link(node);
Christian Schäfer's avatar
Christian Schäfer committed
387
388
}

389
390
op_pin_state
(get_irn_pinned)(const ir_node *node) {
391
  return __get_irn_pinned(node);
392
393
}

Michael Beck's avatar
Michael Beck committed
394
395
396
397
398
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;

399
  assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned);
Michael Beck's avatar
Michael Beck committed
400
401
402
403
  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
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420

#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;
}
421
422
423
424
425
426
#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
427
428
429
#endif /* DO_HEAPANALYSIS */


Götz Lindenmaier's avatar
Götz Lindenmaier committed
430
/* Outputs a unique number for this node */
431
long
432
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
433
  assert(node);
434
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
435
  return node->node_nr;
436
#else
437
  return (long)node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
438
#endif
439
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
440

441
const_attr
Christian Schäfer's avatar
Christian Schäfer committed
442
443
444
445
446
447
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

448
long
Christian Schäfer's avatar
Christian Schäfer committed
449
450
451
452
453
454
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

455
alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
456
457
458
459
460
461
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

462
type *
Christian Schäfer's avatar
Christian Schäfer committed
463
464
465
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
466
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
467
468
}

469
symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
470
471
472
473
474
475
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

476
type *
Christian Schäfer's avatar
Christian Schäfer committed
477
478
479
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
480
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
481
482
}

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

490
int
Christian Schäfer's avatar
Christian Schäfer committed
491
492
493
494
495
496
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

497
block_attr
Christian Schäfer's avatar
Christian Schäfer committed
498
499
500
501
502
503
get_irn_block_attr (ir_node *node)
{
  assert (node->op == op_Block);
  return node->attr.block;
}

504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
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 ||
522
          node->op == op_DivMod || node->op == op_Mod || node->op == op_Call || node->op == op_Alloc);
523
524
525
  return node->attr.except;
}

Christian Schäfer's avatar
Christian Schäfer committed
526
527
528
529
/** manipulate fields of individual nodes **/

/* this works for all except Block */
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
530
get_nodes_block (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
531
532
533
534
  assert (!(node->op == op_Block));
  return get_irn_n(node, -1);
}

535
void
536
set_nodes_block (ir_node *node, ir_node *block) {
Christian Schäfer's avatar
Christian Schäfer committed
537
538
539
540
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
/* 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;
}

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


589
int
Christian Schäfer's avatar
Christian Schäfer committed
590
591
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
592
  return get_irn_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
593
594
}

595
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
596
get_Block_cfgpred (ir_node *node, int pos) {
597
  assert(-1 <= pos && pos < get_irn_arity(node));
598
  assert(node->op == op_Block);
Christian Schäfer's avatar
Christian Schäfer committed
599
600
601
  return get_irn_n(node, pos);
}

602
void
Christian Schäfer's avatar
Christian Schäfer committed
603
604
605
606
607
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

608
bool
Christian Schäfer's avatar
Christian Schäfer committed
609
610
611
612
613
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

614
void
Christian Schäfer's avatar
Christian Schäfer committed
615
616
617
618
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
619
unsigned long
620
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
621
  assert (node->op == op_Block);
622
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
623
624
}

625
void
626
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
627
  assert (node->op == op_Block);
628
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
629
630
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
631
/* For this current_ir_graph must be set. */
632
void
633
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
634
635
636
637
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

638
int
639
Block_not_block_visited(ir_node *node) {
640
641
642
  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
643

644
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
645
646
647
648
649
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

650
void
Christian Schäfer's avatar
Christian Schäfer committed
651
652
653
654
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;
}
655

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

691
692
693
694
695
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];
}

696
697
698
699
700
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

701
702
703
704
705
706
707
708
ir_node *(set_Block_dead)(ir_node *block) {
  return __set_Block_dead(block);
}

int (is_Block_dead)(const ir_node *block) {
  return __is_Block_dead(block);
}

709
void
710
711
712
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
713
  assert(0 && " Why set irg? -- use set_irn_irg");
714
715
}

716
int
717
718
719
720
721
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

722
ir_node *
723
724
725
726
727
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

728
void
729
730
731
732
733
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

734
void
735
736
737
738
739
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);
}

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

749

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

787
void
Christian Schäfer's avatar
Christian Schäfer committed
788
789
790
791
792
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

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

799
void
800
801
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
802
  node->attr.c.kind = kind;
803
804
}

805
806
807
808
809
810
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

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

817
void
Christian Schäfer's avatar
Christian Schäfer committed
818
819
820
821
822
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

823
int
824
get_Return_n_ress (ir_node *node) {
825
826
827
828
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

829
ir_node **
830
831
832
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
833
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
834
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
835
836
  else
    return NULL;
837
838
}

Christian Schäfer's avatar
Christian Schäfer committed
839
/*
840
void
Christian Schäfer's avatar
Christian Schäfer committed
841
842
843
844
845
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

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

853
void
Christian Schäfer's avatar
Christian Schäfer committed
854
set_Return_res (ir_node *node, int pos, ir_node *res){
855
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
856
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
857
858
}

859
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
860
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
861
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
862
863
864
  return get_irn_n(node, 0);
}

865
void
Christian Schäfer's avatar
Christian Schäfer committed
866
867
868
869
870
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

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

877
void
Christian Schäfer's avatar
Christian Schäfer committed
878
879
880
881
882
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

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

888
void
Christian Schäfer's avatar
Christian Schäfer committed
889
890
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
891
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
892
893
}

894
895
896
897

/* 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. */
898
type *
899
900
901
902
903
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

904
void
905
906
907
908
909
910
911
912
913
914
set_Const_type (ir_node *node, type *tp) {
  assert (node->op == op_Const);
  if (tp != unknown_type) {
    assert (is_atomic_type(tp));
    assert (get_type_mode(tp) == get_irn_mode(node));
  }
  node->attr.con.tp = tp;
}


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

921
void
Christian Schäfer's avatar
Christian Schäfer committed
922
923
924
925
926
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

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

935
void
936
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
937
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
938
939
940
          && (   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
941
942
}

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

950
void
Beyhan's avatar
Beyhan committed
951
set_SymConst_name (ir_node *node, ident *name) {
Christian Schäfer's avatar
Christian Schäfer committed
952
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
953
954
          && (get_SymConst_kind(node) == symconst_addr_name));
  node->attr.i.sym.ident_p = name;
Christian Schäfer's avatar
Christian Schäfer committed
955
956
}

Beyhan's avatar
Beyhan committed
957
958
959
960

/* Only to access SymConst of kind symconst_addr_ent.  Else assertion: */
entity   *get_SymConst_entity (ir_node *node) {
  assert (   (node->op == op_SymConst)
Florian Liekweg's avatar
Florian Liekweg committed
961
          && (get_SymConst_kind (node) == symconst_addr_ent));
Beyhan's avatar
Beyhan committed
962
963
964
965
966
967
968
969
970
  return node->attr.i.sym.entity_p;
}

void     set_SymConst_entity (ir_node *node, entity *ent) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == symconst_addr_ent));
  node->attr.i.sym.entity_p  = ent;
}

Michael Beck's avatar
Michael Beck committed
971
972
union symconst_symbol
get_SymConst_symbol (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
973
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
974
  return node->attr.i.sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
975
976
}

977
void
Michael Beck's avatar
Michael Beck committed
978
set_SymConst_symbol (ir_node *node, union symconst_symbol sym) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
979
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
980
981
  //memcpy (&(node->attr.i.sym), sym, sizeof(type_or_id));
  node->attr.i.sym = sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
982
983
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
984
985
986
type *
get_SymConst_value_type (ir_node *node) {
  assert (node->op == op_SymConst);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
987
988
  if (node->attr.i.tp) node->attr.i.tp = skip_tid(node->attr.i.tp);
  return node->attr.i.tp;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
989
990
991
992
993
994
995
996
}

void
set_SymConst_value_type (ir_node *node, type *tp) {
  assert (node->op == op_SymConst);
  node->attr.i.tp = tp;
}

997
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
998
999
1000
1001
1002
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

1003
void
Christian Schäfer's avatar
Christian Schäfer committed
1004
1005
1006
1007
1008
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

1009
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1010
1011
1012
1013
1014
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

1015
void
Christian Schäfer's avatar
Christian Schäfer committed
1016
1017
1018
1019
1020
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

1021
int
1022
get_Sel_n_indexs (ir_node *node) {
1023
1024
1025
1026
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

1027
ir_node **
Christian Schäfer's avatar