irnode.c 48.1 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
/**
 * Indicates, whether additional data can be registered to ir nodes.
 * If set to 1, this is not possible anymore.
 */
static int forbid_new_data = 0;

/**
 * The amount of additional space for custom data to be allocated upon
 * creating a new node.
 */
100
unsigned firm_add_node_size = 0;
101
102


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

107
108
  if (forbid_new_data)
    return 0;
109

110
  return firm_add_node_size += size;
111
112
113
}


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

120
121
122
123
124
125
/*
 * irnode constructor.
 * Create a new irnode in irg, with an op, mode, arity and
 * some incoming irnodes.
 * If arity is negative, a node with a dynamic array is created.
 */
126
ir_node *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
127
new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode,
Florian Liekweg's avatar
Florian Liekweg committed
128
         int arity, ir_node **in)
Christian Schäfer's avatar
Christian Schäfer committed
129
130
{
  ir_node *res;
131
  size_t node_size = offsetof(ir_node, attr) + op->attr_size + firm_add_node_size;
132
	char *p;
Christian Schäfer's avatar
Christian Schäfer committed
133

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

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

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

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

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

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

Sebastian Felis's avatar
Sebastian Felis committed
165
int
166
167
(is_ir_node)(const void *thing) {
  return __is_ir_node(thing);
Sebastian Felis's avatar
Sebastian Felis committed
168
169
}

170
int
171
172
(get_irn_intra_arity)(const ir_node *node) {
  return __get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
173
174
}

175
int
176
177
(get_irn_inter_arity)(const ir_node *node) {
  return __get_irn_inter_arity(node);
178
179
}

180
181
int (*__get_irn_arity)(const ir_node *node) = __get_irn_intra_arity;

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

187
188
189
190
191
192
/* 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. */
193
ir_node **
194
get_irn_in (const ir_node *node) {
195
  assert(node);
196
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
197
198
199
200
201
202
203
204
205
    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
206
207
}

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

233
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
234
(get_irn_intra_n)(const ir_node *node, int n) {
235
  return __get_irn_intra_n (node, n);
236
237
}

238
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
239
(get_irn_inter_n)(const ir_node *node, int n) {
240
  return __get_irn_inter_n (node, n);
241
242
}

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

245
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
246
(get_irn_n)(const ir_node *node, int n) {
247
  return __get_irn_n(node, n);
Christian Schäfer's avatar
Christian Schäfer committed
248
249
}

250
void
251
set_irn_n (ir_node *node, int n, ir_node *in) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
252
253
  assert(node && node->kind == k_ir_node && -1 <= n && n < get_irn_arity(node));
  assert(in && in->kind == k_ir_node);
254
255
256
257
258
259
260
  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;
  }
261
  if (get_interprocedural_view()) { /* handle Filter and Block specially */
262
263
264
265
266
267
268
269
270
271
272
    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
273
274
}

275
ir_mode *
276
277
(get_irn_mode)(const ir_node *node) {
  return __get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
278
279
}

280
void
281
(set_irn_mode)(ir_node *node, ir_mode *mode)
Till Riedel's avatar
Till Riedel committed
282
{
283
  __set_irn_mode(node, mode);
Till Riedel's avatar
Till Riedel committed
284
285
}

286
modecode
287
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
288
289
290
291
292
{
  assert (node);
  return node->mode->code;
}

293
/** Gets the string representation of the mode .*/
294
const char *
295
296
297
298
299
get_irn_modename (const ir_node *node)
{
  assert(node);
  return get_mode_name(node->mode);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
300

301
ident *
302
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
303
304
{
  assert(node);
305
  return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
306
307
}

308
ir_op *
309
(get_irn_op)(const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
310
{
311
  return __get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
312
313
314
}

/* should be private to the library: */
315
void
Christian Schäfer's avatar
Christian Schäfer committed
316
317
318
319
320
321
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

322
opcode
323
(get_irn_opcode)(const ir_node *node)
324
{
325
  return __get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
326
327
}

328
const char *
329
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
330
331
{
  assert(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
332
333
334
  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";
335
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
336
337
}

338
ident *
339
get_irn_opident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
340
341
342
{
  assert(node);
  return node->op->name;
343
344
}

345
unsigned long
346
(get_irn_visited)(const ir_node *node)
347
{
348
  return __get_irn_visited(node);
349
350
}

351
void
352
(set_irn_visited)(ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
353
{
354
  __set_irn_visited(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
355
}
356

357
void
358
359
(mark_irn_visited)(ir_node *node) {
  __mark_irn_visited(node);
360
361
}

362
int
363
364
(irn_not_visited)(const ir_node *node) {
  return __irn_not_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
365
366
}

367
int
368
369
(irn_visited)(const ir_node *node) {
  return __irn_visited(node);
370
371
}

372
void
373
374
(set_irn_link)(ir_node *node, void *link) {
  __set_irn_link(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
375
376
}

377
void *
378
379
(get_irn_link)(const ir_node *node) {
  return __get_irn_link(node);
Christian Schäfer's avatar
Christian Schäfer committed
380
381
}

382
383
op_pin_state
(get_irn_pinned)(const ir_node *node) {
384
  return __get_irn_pinned(node);
385
386
}

Michael Beck's avatar
Michael Beck committed
387
388
389
390
391
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;

392
  assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned);
Michael Beck's avatar
Michael Beck committed
393
394
395
396
  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
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413

#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;
}
414
415
416
417
418
419
#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
420
421
422
#endif /* DO_HEAPANALYSIS */


Götz Lindenmaier's avatar
Götz Lindenmaier committed
423
/* Outputs a unique number for this node */
424
long
425
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
426
  assert(node);
427
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
428
  return node->node_nr;
429
#else
430
  return (long)node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
431
#endif
432
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
433

434
const_attr
Christian Schäfer's avatar
Christian Schäfer committed
435
436
437
438
439
440
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

441
long
Christian Schäfer's avatar
Christian Schäfer committed
442
443
444
445
446
447
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

448
alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
449
450
451
452
453
454
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

455
type *
Christian Schäfer's avatar
Christian Schäfer committed
456
457
458
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
459
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
460
461
}

462
symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
463
464
465
466
467
468
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

469
type *
Christian Schäfer's avatar
Christian Schäfer committed
470
471
472
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
473
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
474
475
}

476
sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
477
478
479
480
481
482
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

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

490
block_attr
Christian Schäfer's avatar
Christian Schäfer committed
491
492
493
494
495
496
get_irn_block_attr (ir_node *node)
{
  assert (node->op == op_Block);
  return node->attr.block;
}

497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
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 ||
515
          node->op == op_DivMod || node->op == op_Mod || node->op == op_Call || node->op == op_Alloc);
516
517
518
  return node->attr.except;
}

Christian Schäfer's avatar
Christian Schäfer committed
519
520
521
522
/** manipulate fields of individual nodes **/

/* this works for all except Block */
ir_node *
Sebastian Hack's avatar
Sebastian Hack committed
523
get_nodes_block (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
524
525
526
527
  assert (!(node->op == op_Block));
  return get_irn_n(node, -1);
}

528
void
529
set_nodes_block (ir_node *node, ir_node *block) {
Christian Schäfer's avatar
Christian Schäfer committed
530
531
532
533
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

534
535
536
537
538
539
540
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
/* 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;
}

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


582
int
Christian Schäfer's avatar
Christian Schäfer committed
583
584
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
585
  return get_irn_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
586
587
}

588
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
589
get_Block_cfgpred (ir_node *node, int pos) {
590
  assert(-1 <= pos && pos < get_irn_arity(node));
591
  assert(node->op == op_Block);
Christian Schäfer's avatar
Christian Schäfer committed
592
593
594
  return get_irn_n(node, pos);
}

595
void
Christian Schäfer's avatar
Christian Schäfer committed
596
597
598
599
600
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

601
bool
Christian Schäfer's avatar
Christian Schäfer committed
602
603
604
605
606
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

607
void
Christian Schäfer's avatar
Christian Schäfer committed
608
609
610
611
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
612
unsigned long
613
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
614
  assert (node->op == op_Block);
615
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
616
617
}

618
void
619
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
620
  assert (node->op == op_Block);
621
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
622
623
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
624
/* For this current_ir_graph must be set. */
625
void
626
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
627
628
629
630
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

631
int
632
Block_not_block_visited(ir_node *node) {
633
634
635
  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
636

637
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
638
639
640
641
642
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

643
void
Christian Schäfer's avatar
Christian Schäfer committed
644
645
646
647
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;
}
648

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

684
685
686
687
688
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];
}

689
690
691
692
693
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

694
695
696
697
698
699
700
701
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);
}

702
void
703
704
705
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
706
  assert(0 && " Why set irg? -- use set_irn_irg");
707
708
}

709
int
710
711
712
713
714
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

715
ir_node *
716
717
718
719
720
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

721
void
722
723
724
725
726
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

727
void
728
729
730
731
732
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);
}

733
void
734
free_End (ir_node *end) {
735
  assert (end->op == op_End);
736
  end->kind = k_BAD;
737
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
738
  end->in = NULL;   /* @@@ make sure we get an error if we use the
Florian Liekweg's avatar
Florian Liekweg committed
739
               in array afterwards ... */
740
741
}

742

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

780
void
Christian Schäfer's avatar
Christian Schäfer committed
781
782
783
784
785
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

786
cond_kind
787
788
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
789
  return node->attr.c.kind;
790
791
}

792
void
793
794
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
795
  node->attr.c.kind = kind;
796
797
}

798
799
800
801
802
803
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

804
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
805
get_Return_mem (ir_node *node) {
806
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
807
808
809
  return get_irn_n(node, 0);
}

810
void
Christian Schäfer's avatar
Christian Schäfer committed
811
812
813
814
815
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

816
int
817
get_Return_n_ress (ir_node *node) {
818
819
820
821
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

822
ir_node **
823
824
825
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
826
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
827
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
828
829
  else
    return NULL;
830
831
}

Christian Schäfer's avatar
Christian Schäfer committed
832
/*
833
void
Christian Schäfer's avatar
Christian Schäfer committed
834
835
836
837
838
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

839
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
840
841
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
842
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
843
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
844
845
}

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

852
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
853
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
854
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
855
856
857
  return get_irn_n(node, 0);
}

858
void
Christian Schäfer's avatar
Christian Schäfer committed
859
860
861
862
863
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

864
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
865
866
867
868
869
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

870
void
Christian Schäfer's avatar
Christian Schäfer committed
871
872
873
874
875
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

876
tarval *get_Const_tarval (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
877
  assert (node->op == op_Const);
878
  return node->attr.con.tv;
Christian Schäfer's avatar
Christian Schäfer committed
879
880
}

881
void
Christian Schäfer's avatar
Christian Schäfer committed
882
883
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
884
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
885
886
}

887
888
889
890

/* 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. */
891
type *
892
893
894
895
896
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

897
void
898
899
set_Const_type (ir_node *node, type *tp) {
  assert (node->op == op_Const);
900
  if (tp != firm_unknown_type) {
901
    assert (is_Atomic_type(tp));
902
903
904
905
906
907
    assert (get_type_mode(tp) == get_irn_mode(node));
  }
  node->attr.con.tp = tp;
}


908
symconst_kind
909
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
910
911
912
913
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

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

920
type *
Christian Schäfer's avatar
Christian Schäfer committed
921
922
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
923
924
925
          && (   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
926
927
}

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

936
ident *
Beyhan's avatar
Beyhan committed
937
get_SymConst_name (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
938
  assert (   (node->op == op_SymConst)
Beyhan's avatar
Beyhan committed
939
940
          && (get_SymConst_kind(node) == symconst_addr_name));
  return node->attr.i.sym.ident_p;
Christian Schäfer's avatar
Christian Schäfer committed
941
942
}

943
void
Beyhan's avatar
Beyhan committed
944
set_SymConst_name (ir_node *node, ident *name) {
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));
  node->attr.i.sym.ident_p = name;
Christian Schäfer's avatar
Christian Schäfer committed
948
949
}

Beyhan's avatar
Beyhan committed
950
951
952
953

/* 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
954
          && (get_SymConst_kind (node) == symconst_addr_ent));
Beyhan's avatar
Beyhan committed
955
956
957
958
959
960
961
962
963
  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
964
965
union symconst_symbol
get_SymConst_symbol (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
966
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
967
  return node->attr.i.sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
968
969
}

970
void
Michael Beck's avatar
Michael Beck committed
971
set_SymConst_symbol (ir_node *node, union symconst_symbol sym) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
972
  assert (node->op == op_SymConst);
Beyhan's avatar
Beyhan committed
973
974
  //memcpy (&(node->attr.i.sym), sym, sizeof(type_or_id));
  node->attr.i.sym = sym;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
975
976
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
977
978
979
type *
get_SymConst_value_type (ir_node *node) {
  assert (node->op == op_SymConst);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
980
981
  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
982
983
984
985
986
987
988
989
}

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

990
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
991
992
993
994
995
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

996
void
Christian Schäfer's avatar
Christian Schäfer committed
997
998
999
1000
1001
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

1002
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1003
1004
1005
1006
1007
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

1008
void
Christian Schäfer's avatar
Christian Schäfer committed
1009
1010