irnode.c 45.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
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
32
33
34
/* some constants fixing the positions of nodes predecessors
   in the in array */
#define CALL_PARAM_OFFSET 2
#define SEL_INDEX_OFFSET 2
#define RETURN_RESULT_OFFSET 1  /* mem is not a result */
35
#define END_KEEPALIVE_OFFSET 0
Götz Lindenmaier's avatar
Götz Lindenmaier committed
36

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

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

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

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

82
const char *symconst_name_arr [] = {
83
84
  "type_tag", "size", "linkage_ptr_info"
};
Christian Schäfer's avatar
Christian Schäfer committed
85
86
87
88
89
90

void
init_irnode (void)
{
}

91
92
93
94
95
96
/*
 * 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.
 */
97
ir_node *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
98
new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode,
Christian Schäfer's avatar
Christian Schäfer committed
99
100
101
102
103
	     int arity, ir_node **in)
{
  ir_node *res;
  int node_size = offsetof (ir_node, attr) +  op->attr_size;

104
  assert(irg && op && mode);
Christian Schäfer's avatar
Christian Schäfer committed
105
106
107
108
109
  res = (ir_node *) obstack_alloc (irg->obst, node_size);

  res->kind = k_ir_node;
  res->op = op;
  res->mode = mode;
110
  res->visited = 0;
Christian Schäfer's avatar
Christian Schäfer committed
111
112
  res->link = NULL;
  if (arity < 0) {
113
    res->in = NEW_ARR_F (ir_node *, 1);  /* 1: space for block */
Christian Schäfer's avatar
Christian Schäfer committed
114
115
116
117
118
  } 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
119
  set_irn_dbg_info(res, db);
120
  res->out = NULL;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
121
122
123
124
125

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

Michael Beck's avatar
Michael Beck committed
126
127
  stat_new_node(res);

Christian Schäfer's avatar
Christian Schäfer committed
128
129
130
  return res;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
131
132
133
/* Copies all attributes stored in the old node to the new node.
   Assumes both have the same opcode and sufficient size. */
void
134
135
136
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)));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
137
}
Christian Schäfer's avatar
Christian Schäfer committed
138

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

Sebastian Felis's avatar
Sebastian Felis committed
141
int
142
143
(is_ir_node)(const void *thing) {
  return __is_ir_node(thing);
Sebastian Felis's avatar
Sebastian Felis committed
144
145
}

146
int
147
148
(get_irn_intra_arity)(const ir_node *node) {
  return __get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
149
150
}

151
int
152
153
(get_irn_inter_arity)(const ir_node *node) {
  return __get_irn_inter_arity(node);
154
155
}

156
int
157
158
(get_irn_arity)(const ir_node *node) {
  return __get_irn_arity(node);
159
160
}

161
162
163
164
165
166
/* 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. */
167
ir_node **
168
get_irn_in (const ir_node *node) {
169
170
171
172
173
174
175
176
177
178
179
  assert(node);
  if (interprocedural_view) { /* handle Filter and Block specially */
    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
180
181
}

182
void
183
set_irn_in (ir_node *node, int arity, ir_node **in) {
184
  ir_node *** arr;
185
  assert(node);
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  if (interprocedural_view) { /* handle Filter and Block specially */
    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;
202
  }
203
  fix_backedges(current_ir_graph->obst, node);
204
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
205
206
}

207
ir_node *
208
209
(get_irn_intra_n)(ir_node *node, int n) {
  return __get_irn_intra_n (node, n);
210
211
}

212
ir_node *
213
214
(get_irn_inter_n)(ir_node *node, int n) {
  return __get_irn_inter_n (node, n);
215
216
}

217
ir_node *
218
219
(get_irn_n)(ir_node *node, int n) {
  return __get_irn_n (node, n);
Christian Schäfer's avatar
Christian Schäfer committed
220
221
}

222
void
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
set_irn_n (ir_node *node, int n, ir_node *in) {
  assert(node && -1 <= n && n < get_irn_arity(node));
  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;
  }
  if (interprocedural_view) { /* handle Filter and Block specially */
    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
244
245
}

246
ir_mode *
247
248
(get_irn_mode)(const ir_node *node) {
  return __get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
249
250
}

251
void
252
(set_irn_mode)(ir_node *node, ir_mode *mode)
Till Riedel's avatar
Till Riedel committed
253
{
254
  __set_irn_mode(node, mode);
Till Riedel's avatar
Till Riedel committed
255
256
}

257
modecode
258
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
259
260
261
262
263
{
  assert (node);
  return node->mode->code;
}

264
/** Gets the string representation of the mode .*/
265
const char *
266
267
268
269
270
get_irn_modename (const ir_node *node)
{
  assert(node);
  return get_mode_name(node->mode);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
271

272
ident *
273
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
274
275
{
  assert(node);
276
  return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
277
278
}

279
ir_op *
280
(get_irn_op)(const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
281
{
282
  return __get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
283
284
285
}

/* should be private to the library: */
286
void
Christian Schäfer's avatar
Christian Schäfer committed
287
288
289
290
291
292
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

293
opcode
294
(get_irn_opcode)(const ir_node *node)
295
{
296
  return __get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
297
298
}

299
const char *
300
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
301
302
{
  assert(node);
303
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
304
305
}

306
ident *
307
get_irn_opident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
308
309
310
{
  assert(node);
  return node->op->name;
311
312
}

313
unsigned long
314
(get_irn_visited)(const ir_node *node)
315
{
316
  return __get_irn_visited(node);
317
318
}

319
void
320
(set_irn_visited)(ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
321
{
322
  __set_irn_visited(node, visited);
Christian Schäfer's avatar
Christian Schäfer committed
323
}
324

325
void
326
327
(mark_irn_visited)(ir_node *node) {
  __mark_irn_visited(node);
328
329
}

330
int
331
332
(irn_not_visited)(const ir_node *node) {
  return __irn_not_visited(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
333
334
}

335
int
336
337
(irn_visited)(const ir_node *node) {
  return __irn_visited(node);
338
339
}

340
void
341
342
(set_irn_link)(ir_node *node, void *link) {
  __set_irn_link(node, link);
Christian Schäfer's avatar
Christian Schäfer committed
343
344
}

345
void *
346
347
(get_irn_link)(const ir_node *node) {
  return __get_irn_link(node);
Christian Schäfer's avatar
Christian Schäfer committed
348
349
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
350
/* Outputs a unique number for this node */
351
long
352
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
353
  assert(node);
354
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
355
  return node->node_nr;
356
#else
357
  return (long)&node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
358
#endif
359
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
360

361
const_attr
Christian Schäfer's avatar
Christian Schäfer committed
362
363
364
365
366
367
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

368
long
Christian Schäfer's avatar
Christian Schäfer committed
369
370
371
372
373
374
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

375
alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
376
377
378
379
380
381
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

382
type *
Christian Schäfer's avatar
Christian Schäfer committed
383
384
385
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
386
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
387
388
}

389
symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
390
391
392
393
394
395
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

396
type *
Christian Schäfer's avatar
Christian Schäfer committed
397
398
399
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
400
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
401
402
}

403
type *
Michael Beck's avatar
Michael Beck committed
404
405
406
407
408
409
get_irn_funccall_attr (ir_node *node)
{
  assert (node->op == op_FuncCall);
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
}

410
sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
411
412
413
414
415
416
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

417
int
Christian Schäfer's avatar
Christian Schäfer committed
418
419
420
421
422
423
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

424
block_attr
Christian Schäfer's avatar
Christian Schäfer committed
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
get_irn_block_attr (ir_node *node)
{
  assert (node->op == op_Block);
  return node->attr.block;
}

/** manipulate fields of individual nodes **/

/* this works for all except Block */
ir_node *
get_nodes_Block (ir_node *node) {
  assert (!(node->op == op_Block));
  return get_irn_n(node, -1);
}

440
void
Christian Schäfer's avatar
Christian Schäfer committed
441
442
443
444
445
set_nodes_Block (ir_node *node, ir_node *block) {
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
/* 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;
}

482
/* Returns an array with the predecessors of the Block. Depending on
483
   the implementation of the graph data structure this can be a copy of
484
485
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
486
ir_node **
487
488
489
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
490
  return (ir_node **)&(get_irn_in(node)[1]);
491
492
493
}


494
int
Christian Schäfer's avatar
Christian Schäfer committed
495
496
497
498
499
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
  return (get_irn_arity(node));
}

500
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
501
502
get_Block_cfgpred (ir_node *node, int pos) {
  assert (node->op == op_Block);
503
  /* debug @@@
504
505
506
507
  if (-1 > pos || get_irn_arity(node) <= pos) {
    dump_ir_block_graph(current_ir_graph);
    printf("pos: %d, arity: %d ", pos, get_irn_arity(node));
    DDMN(node);
508
    } */
509
  assert(node); assert(-1 <= pos && pos < get_irn_arity(node));
Christian Schäfer's avatar
Christian Schäfer committed
510
511
512
  return get_irn_n(node, pos);
}

513
void
Christian Schäfer's avatar
Christian Schäfer committed
514
515
516
517
518
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

519
bool
Christian Schäfer's avatar
Christian Schäfer committed
520
521
522
523
524
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

525
void
Christian Schäfer's avatar
Christian Schäfer committed
526
527
528
529
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
530
unsigned long
531
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
532
  assert (node->op == op_Block);
533
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
534
535
}

536
void
537
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
538
  assert (node->op == op_Block);
539
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
540
541
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
542
/* For this current_ir_graph must be set. */
543
void
544
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
545
546
547
548
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

549
int
550
Block_not_block_visited(ir_node *node) {
551
552
553
  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
554

555
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
556
557
558
559
560
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

561
void
Christian Schäfer's avatar
Christian Schäfer committed
562
563
564
565
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;
}
566

567
/* handler handling for Blocks * /
568
569
void
set_Block_handler (ir_node *block, ir_node *handler)  {
570
571
572
573
574
  assert ((block->op == op_Block));
  assert ((handler->op == op_Block));
  block->attr.block.handler_entry = handler;
}

575
576
ir_node *
get_Block_handler (ir_node *block) {
577
578
579
580
  assert ((block->op == op_Block));
  return (block->attr.block.handler_entry);
}

581
/ * handler handling for Nodes * /
582
583
void
set_Node_handler (ir_node *node, ir_node *handler) {
584
585
586
  set_Block_handler (get_nodes_Block (node), handler);
}

587
588
ir_node *
get_Node_handler (ir_node *node) {
589
590
591
  return (get_Block_handler (get_nodes_Block (node)));
}

592
/ * exc_t handling for Blocks * /
593
void set_Block_exc (ir_node *block, exc_t exc) {
594
  assert ((block->op == op_Block));
595
596
597
  block->attr.block.exc = exc;
}

598
exc_t get_Block_exc (ir_node *block) {
599
  assert ((block->op == op_Block));
600
601
602
  return (block->attr.block.exc);
}

603
/ * exc_t handling for Nodes * /
604
void set_Node_exc (ir_node *node, exc_t exc) {
605
606
607
  set_Block_exc (get_nodes_Block (node), exc);
}

608
exc_t get_Node_exc (ir_node *node) {
609
610
  return (get_Block_exc (get_nodes_Block (node)));
}
611
*/
612

613
614
615
616
617
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;
618
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
619
620
621
622
623
624
625
626
    {
      /* Fix backedge array.  fix_backedges operates depending on
	 interprocedural_view. */
      bool ipv = interprocedural_view;
      interprocedural_view = true;
      fix_backedges(current_ir_graph->obst, node);
      interprocedural_view = ipv;
    }
627
628
629
630
631
  }
  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
632
633
634
  assert(node->op == op_Block &&
	 node->attr.block.in_cg &&
	 0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
635
636
637
638
639
640
641
642
643
  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) {
644
645
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
646
647
}

648
649
650
651
652
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];
}

653
654
655
656
657
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

658
/* Start references the irg it is in. */
659
ir_graph *
660
get_Start_irg(ir_node *node) {
661
  return get_irn_irg(node);
662
663
}

664
void
665
666
667
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
668
  assert(0 && " Why set irg? -- use set_irn_irg");
669
670
}

671
int
672
673
674
675
676
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

677
ir_node *
678
679
680
681
682
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

683
void
684
685
686
687
688
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

689
void
690
691
692
693
694
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);
}

695
void
696
free_End (ir_node *end) {
697
  assert (end->op == op_End);
698
  end->kind = k_BAD;
699
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
700
701
702
703
  end->in = NULL;   /* @@@ make sure we get an error if we use the
		       in array afterwards ... */
}

704
705
ir_graph *get_EndReg_irg (ir_node *end) {
  return get_irn_irg(end);
706
707
}

708
709
ir_graph *get_EndExcept_irg  (ir_node *end) {
  return get_irn_irg(end);
710
711
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
712
713
714
715
716
717
718
719
720
/*
> 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
721
 - determining the biggest case constant to know the proj number for
Götz Lindenmaier's avatar
Götz Lindenmaier committed
722
723
724
725
726
727
728
729
730
731
732
733
   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.,
734
libFIRM can implement a routine that transforms between the two
Götz Lindenmaier's avatar
Götz Lindenmaier committed
735
736
737
738
739
740
741
742
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).
*/
743
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
744
745
746
747
748
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

749
void
Christian Schäfer's avatar
Christian Schäfer committed
750
751
752
753
754
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

755
cond_kind
756
757
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
758
  return node->attr.c.kind;
759
760
}

761
void
762
763
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
764
  node->attr.c.kind = kind;
765
766
}

767
768
769
770
771
772
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

773
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
774
get_Return_mem (ir_node *node) {
775
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
776
777
778
  return get_irn_n(node, 0);
}

779
void
Christian Schäfer's avatar
Christian Schäfer committed
780
781
782
783
784
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

785
int
786
get_Return_n_ress (ir_node *node) {
787
788
789
790
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

791
ir_node **
792
793
794
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
795
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
796
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
797
798
  else
    return NULL;
799
800
}

Christian Schäfer's avatar
Christian Schäfer committed
801
/*
802
void
Christian Schäfer's avatar
Christian Schäfer committed
803
804
805
806
807
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

808
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
809
810
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
811
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
812
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
813
814
}

815
void
Christian Schäfer's avatar
Christian Schäfer committed
816
set_Return_res (ir_node *node, int pos, ir_node *res){
817
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
818
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
819
820
}

821
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
822
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
823
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
824
825
826
  return get_irn_n(node, 0);
}

827
void
Christian Schäfer's avatar
Christian Schäfer committed
828
829
830
831
832
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

833
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
834
835
836
837
838
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

839
void
Christian Schäfer's avatar
Christian Schäfer committed
840
841
842
843
844
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

845
tarval *get_Const_tarval (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
846
  assert (node->op == op_Const);
847
  return node->attr.con.tv;
Christian Schäfer's avatar
Christian Schäfer committed
848
849
}

850
void
Christian Schäfer's avatar
Christian Schäfer committed
851
852
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
853
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
854
855
}

856
857
858
859

/* 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. */
860
type *
861
862
863
864
865
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

866
void
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
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));
    assert (!tarval_is_entity(get_Const_tarval(node)) ||
	    (is_pointer_type(tp) &&
	     (get_pointer_points_to_type(tp) ==
	      get_entity_type(get_tarval_entity(get_Const_tarval(node))))));
  }

  node->attr.con.tp = tp;
}


882
symconst_kind
883
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
884
885
886
887
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

888
void
Christian Schäfer's avatar
Christian Schäfer committed
889
890
891
892
893
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

894
type *
Christian Schäfer's avatar
Christian Schäfer committed
895
896
897
898
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
899
  return node->attr.i.tori.typ = skip_tid(node->attr.i.tori.typ);
Christian Schäfer's avatar
Christian Schäfer committed
900
901
}

902
void
903
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
904
905
906
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
907
  node->attr.i.tori.typ = tp;
Christian Schäfer's avatar
Christian Schäfer committed
908
909
}

910
ident *
Christian Schäfer's avatar
Christian Schäfer committed
911
912
913
914
915
916
get_SymConst_ptrinfo (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == linkage_ptr_info));
  return node->attr.i.tori.ptrinfo;
}

917
void
Christian Schäfer's avatar
Christian Schäfer committed
918
919
920
921
922
923
set_SymConst_ptrinfo (ir_node *node, ident *ptrinfo) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == linkage_ptr_info));
  node->attr.i.tori.ptrinfo = ptrinfo;
}

924
type_or_id_p
Götz Lindenmaier's avatar
Götz Lindenmaier committed
925
926
927
928
929
get_SymConst_type_or_id (ir_node *node) {
  assert (node->op == op_SymConst);
  return &(node->attr.i.tori);
}

930
void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
931
932
933
934
935
set_SymConst_type_or_id (ir_node *node, type_or_id_p tori) {
  assert (node->op == op_SymConst);
  memcpy (&(node->attr.i.tori), tori, sizeof(type_or_id));
}

936
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
937
938
939
940
941
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

942
void
Christian Schäfer's avatar
Christian Schäfer committed
943
944
945
946
947
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

948
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
949
950
951
952
953
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

954
void
Christian Schäfer's avatar
Christian Schäfer committed
955
956
957
958
959
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

960
int
961
get_Sel_n_indexs (ir_node *node) {
962
963
964
965
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

966
ir_node **
967
968
969
get_Sel_index_arr (ir_node *node)
{
  assert ((node->op == op_Sel));
970
  if (get_Sel_n_indexs(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
971
    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
972
973
  else
    return NULL;
974
975
}

976
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
977
978
get_Sel_index (ir_node *node, int pos) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
979
  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
980
981
}

982
void
Christian Schäfer's avatar
Christian Schäfer committed
983
984
set_Sel_index (ir_node *node, int pos, ir_node *index) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
985
  set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
Christian Schäfer's avatar
Christian Schäfer committed
986
987
}

988
entity *
Christian Schäfer's avatar
Christian Schäfer committed
989
990
991
992
993
get_Sel_entity (ir_node *node) {
  assert (node->op == op_Sel);
  return node->attr.s.ent;
}

994
void
Christian Schäfer's avatar
Christian Schäfer committed
995
996
997
998
999
set_Sel_entity (ir_node *node, entity *ent) {
  assert (node->op == op_Sel);
  node->attr.s.ent = ent;
}

1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
type *
get_InstOf_ent (ir_node *node) {
  assert (node->op = op_InstOf);
  return (node->attr.io.ent);
}

void
set_InstOf_ent (ir_node *node, type *ent) {
  assert (node->op = op_InstOf);
  node->attr.io.ent = ent;
}

ir_node *
get_InstOf_store (ir_node *node) {
  assert (node->op = op_InstOf);
  return (get_irn_n (node, 0));
}

void
set_InstOf_store (ir_node *node, ir_node *obj) {
  assert (node->op = op_InstOf);
  set_irn_n (node, 0, obj);
}

ir_node *
get_InstOf_obj (ir_node *node) {
  assert (node->op = op_InstOf);
  return (get_irn_n (node, 1));
}

void
set_InstOf_obj (ir_node *node, ir_node *obj) {
  assert (node->op = op_InstOf);
  set_irn_n (node, 1, obj);
}

1036
1037
1038
1039

/* For unary and binary arithmetic operations the access to the
   operands can be factored out.  Left is the first, right the
   second arithmetic value  as listed in tech report 0999-33.
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1040
   unops are: Minus, Abs, Not, Conv, Cast
1041
1042
1043
1044
   binops are: Add, Sub, Mul, Quot, DivMod, Div, Mod, And, Or, Eor, Shl,
   Shr, Shrs, Rotate, Cmp */


1045
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1046
1047
1048
1049
1050
get_Call_mem (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 0);
}

1051
void
Christian Schäfer's avatar
Christian Schäfer committed
1052
1053
1054
1055
1056
set_Call_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Call);
  set_irn_n(node, 0, mem);
}

1057
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1058
1059
1060
1061
1062
get_Call_ptr (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 1);
}

1063
void
Christian Schäfer's avatar
Christian Schäfer committed
1064
1065
1066
1067
1068
set_Call_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Call);
  set_irn_n(node, 1, ptr);<