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
#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"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
30

Michael Beck's avatar
Michael Beck committed
31
32
#include "firmstat.h"

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

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

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

Michael Beck's avatar
Michael Beck committed
55
56
57
/**
 * Calculates the negated pnc condition.
 */
Christian Schäfer's avatar
Christian Schäfer committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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 */
}

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
 * 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
114
115
116
void
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
133
  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
134

135
  assert(irg && op && mode);
136
137
138
  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
139

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

Michael Beck's avatar
Michael Beck committed
159
160
  stat_new_node(res);

Christian Schäfer's avatar
Christian Schäfer committed
161
162
163
  return res;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
164
165
166
/* Copies all attributes stored in the old node to the new node.
   Assumes both have the same opcode and sufficient size. */
void
167
168
169
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)));
170
  if (get_irn_op(new_node) == op_Call) remove_Call_callee_arr(new_node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
171
}
Christian Schäfer's avatar
Christian Schäfer committed
172

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

Sebastian Felis's avatar
Sebastian Felis committed
175
int
176
177
(is_ir_node)(const void *thing) {
  return __is_ir_node(thing);
Sebastian Felis's avatar
Sebastian Felis committed
178
179
}

180
int
181
182
(get_irn_intra_arity)(const ir_node *node) {
  return __get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
183
184
}

185
int
186
187
(get_irn_inter_arity)(const ir_node *node) {
  return __get_irn_inter_arity(node);
188
189
}

190
191
int (*__get_irn_arity)(const ir_node *node) = __get_irn_intra_arity;

192
int
193
194
(get_irn_arity)(const ir_node *node) {
  return __get_irn_arity(node);
195
196
}

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

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

243
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
244
(get_irn_intra_n)(const ir_node *node, int n) {
245
  return __get_irn_intra_n (node, n);
246
247
}

248
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
249
(get_irn_inter_n)(const ir_node *node, int n) {
250
  return __get_irn_inter_n (node, n);
251
252
}

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

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

260
void
261
set_irn_n (ir_node *node, int n, ir_node *in) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
262
263
  assert(node && node->kind == k_ir_node && -1 <= n && n < get_irn_arity(node));
  assert(in && in->kind == k_ir_node);
264
265
266
267
268
269
270
  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;
  }
271
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
272
273
274
275
276
277
278
279
280
281
282
    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
283
284
}

285
ir_mode *
286
287
(get_irn_mode)(const ir_node *node) {
  return __get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
288
289
}

290
void
291
(set_irn_mode)(ir_node *node, ir_mode *mode)
Till Riedel's avatar
Till Riedel committed
292
{
293
  __set_irn_mode(node, mode);
Till Riedel's avatar
Till Riedel committed
294
295
}

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

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

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

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

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

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

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

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

355
unsigned long
356
(get_irn_visited)(const ir_node *node)
357
{
358
  return __get_irn_visited(node);
359
360
}

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

367
void
368
369
(mark_irn_visited)(ir_node *node) {
  __mark_irn_visited(node);
370
371
}

372
int
373
374
(irn_not_visited)(const ir_node *node) {
  return __irn_not_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
375
376
}

377
int
378
379
(irn_visited)(const ir_node *node) {
  return __irn_visited(node);
380
381
}

382
void
383
384
(set_irn_link)(ir_node *node, void *link) {
  __set_irn_link(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
385
386
}

387
void *
388
389
(get_irn_link)(const ir_node *node) {
  return __get_irn_link(node);
Christian Schäfer's avatar
Christian Schäfer committed
390
391
}

392
393
op_pin_state
(get_irn_pinned)(const ir_node *node) {
394
  return __get_irn_pinned(node);
395
396
}

Michael Beck's avatar
Michael Beck committed
397
398
399
400
401
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;

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

#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;
}
424
425
426
427
428
429
#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
430
431
432
#endif /* DO_HEAPANALYSIS */


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

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

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

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

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

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

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

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

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

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

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

Christian Schäfer's avatar
Christian Schäfer committed
529
530
531
532
/** manipulate fields of individual nodes **/

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

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

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
577
578
579
/* 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;
}

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


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

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

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

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

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

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

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

641
int
642
Block_not_block_visited(ir_node *node) {
643
644
645
  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
646

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

653
void
Christian Schäfer's avatar
Christian Schäfer committed
654
655
656
657
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;
}
658

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

694
695
696
697
698
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];
}

699
700
701
702
703
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

704
705
706
707
708
709
710
711
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);
}

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

719
int
720
721
722
723
724
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

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

731
void
732
733
734
735
736
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

737
void
738
739
740
741
742
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);
}

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

752

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

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

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

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

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

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

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

826
int
827
get_Return_n_ress (ir_node *node) {
828
829
830
831
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

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

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

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

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

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

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

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

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

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

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

897
898
899
900

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

907
void
908
909
910
911
912
913
914
915
916
917
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;
}


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

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

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

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

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

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

Beyhan's avatar
Beyhan committed
960
961
962
963

/* 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
964
          && (get_SymConst_kind (node) == symconst_addr_ent));
Beyhan's avatar
Beyhan committed
965
966
967
968
969
970
971
972
973
  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
974
975
union symconst_symbol
get_SymConst_symbol (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
976
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
977
  return node->attr.i.sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
978
979
}

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

Götz Lindenmaier's avatar
Götz Lindenmaier committed
987
988
989
type *
get_SymConst_value_type (ir_node *node) {
  assert (node->op == op_SymConst);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
990
991
  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
992
993
994
995
996
997
998
999
}

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

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

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

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

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

1024
int
1025
get_Sel_n_indexs (ir_node *node) {
1026
1027
1028
1029
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

1030
ir_node