irnode.c 45.5 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
is_ir_node (const void *thing) {
Sebastian Felis's avatar
Sebastian Felis committed
143
144
145
146
147
148
  if (get_kind(thing) == k_ir_node)
    return 1;
  else
    return 0;
}

149
int
150
get_irn_intra_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
151
  return intern_get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
152
153
}

154
int
155
get_irn_inter_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
156
  return intern_get_irn_inter_arity(node);
157
158
}

159
int
160
get_irn_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
161
  return intern_get_irn_arity(node);
162
163
}

164
165
166
167
168
169
/* 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. */
170
ir_node **
171
get_irn_in (const ir_node *node) {
172
173
174
175
176
177
178
179
180
181
182
  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
183
184
}

185
void
186
set_irn_in (ir_node *node, int arity, ir_node **in) {
187
  ir_node *** arr;
188
  assert(node);
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
  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;
205
  }
206
  fix_backedges(current_ir_graph->obst, node);
207
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
208
209
}

210
ir_node *
211
get_irn_intra_n (ir_node *node, int n) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
212
  return intern_get_irn_intra_n (node, n);
213
214
}

215
ir_node *
216
get_irn_inter_n (ir_node *node, int n) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
217
  return intern_get_irn_inter_n (node, n);
218
219
}

220
ir_node *
221
get_irn_n (ir_node *node, int n) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
222
  return intern_get_irn_n (node, n);
Christian Schäfer's avatar
Christian Schäfer committed
223
224
}

225
void
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
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
247
248
}

249
ir_mode *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
250
251
get_irn_mode (const ir_node *node) {
  return intern_get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
252
253
}

254
void
Till Riedel's avatar
Till Riedel committed
255
256
257
258
259
260
261
set_irn_mode (ir_node *node, ir_mode *mode)
{
  assert (node);
  node->mode=mode;
  return;
}

262
modecode
263
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
264
265
266
267
268
{
  assert (node);
  return node->mode->code;
}

269
/** Gets the string representation of the mode .*/
270
const char *
271
272
273
274
275
get_irn_modename (const ir_node *node)
{
  assert(node);
  return get_mode_name(node->mode);
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
276

277
ident *
278
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
279
280
{
  assert(node);
281
  return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
282
283
}

284
ir_op *
285
get_irn_op (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
286
{
Götz Lindenmaier's avatar
Götz Lindenmaier committed
287
  return intern_get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
288
289
290
}

/* should be private to the library: */
291
void
Christian Schäfer's avatar
Christian Schäfer committed
292
293
294
295
296
297
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

298
opcode
299
get_irn_opcode (const ir_node *node)
300
{
Götz Lindenmaier's avatar
Götz Lindenmaier committed
301
  return intern_get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
302
303
}

304
const char *
305
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
306
307
{
  assert(node);
308
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
309
310
}

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

318
unsigned long
319
get_irn_visited (const ir_node *node)
320
321
322
323
324
{
  assert (node);
  return node->visited;
}

325
void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
326
set_irn_visited (ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
327
328
{
  assert (node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
329
  node->visited = visited;
Christian Schäfer's avatar
Christian Schäfer committed
330
}
331

332
void
333
334
335
336
337
mark_irn_visited (ir_node *node) {
  assert (node);
  node->visited = current_ir_graph->visited;
}

338
int
339
irn_not_visited  (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
340
341
342
343
  assert (node);
  return (node->visited < current_ir_graph->visited);
}

344
int
345
irn_visited  (const ir_node *node) {
346
347
348
349
  assert (node);
  return (node->visited >= current_ir_graph->visited);
}

350
void
351
set_irn_link (ir_node *node, void *link) {
Christian Schäfer's avatar
Christian Schäfer committed
352
  assert (node);
353
354
355
356
  /* Link field is used for Phi construction and various optimizations
     in iropt. */
  assert(get_irg_phase_state(current_ir_graph) != phase_building);

Christian Schäfer's avatar
Christian Schäfer committed
357
358
359
  node->link = link;
}

360
void *
361
get_irn_link (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
362
363
364
365
  assert (node);
  return node->link;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
366
/* Outputs a unique number for this node */
367
long
368
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
369
  assert(node);
370
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
371
  return node->node_nr;
372
#else
373
  return (long)&node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
374
#endif
375
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
376

377
const_attr
Christian Schäfer's avatar
Christian Schäfer committed
378
379
380
381
382
383
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

384
long
Christian Schäfer's avatar
Christian Schäfer committed
385
386
387
388
389
390
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

391
alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
392
393
394
395
396
397
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

398
type *
Christian Schäfer's avatar
Christian Schäfer committed
399
400
401
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
402
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
403
404
}

405
symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
406
407
408
409
410
411
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

412
type *
Christian Schäfer's avatar
Christian Schäfer committed
413
414
415
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
416
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
417
418
}

419
type *
Michael Beck's avatar
Michael Beck committed
420
421
422
423
424
425
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);
}

426
sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
427
428
429
430
431
432
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

433
int
Christian Schäfer's avatar
Christian Schäfer committed
434
435
436
437
438
439
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

440
block_attr
Christian Schäfer's avatar
Christian Schäfer committed
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
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);
}

456
void
Christian Schäfer's avatar
Christian Schäfer committed
457
458
459
460
461
set_nodes_Block (ir_node *node, ir_node *block) {
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
/* 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;
}

498
/* Returns an array with the predecessors of the Block. Depending on
499
   the implementation of the graph data structure this can be a copy of
500
501
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
502
ir_node **
503
504
505
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
506
  return (ir_node **)&(get_irn_in(node)[1]);
507
508
509
}


510
int
Christian Schäfer's avatar
Christian Schäfer committed
511
512
513
514
515
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
  return (get_irn_arity(node));
}

516
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
517
518
get_Block_cfgpred (ir_node *node, int pos) {
  assert (node->op == op_Block);
519
  /* debug @@@
520
521
522
523
  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);
524
    } */
525
  assert(node); assert(-1 <= pos && pos < get_irn_arity(node));
Christian Schäfer's avatar
Christian Schäfer committed
526
527
528
  return get_irn_n(node, pos);
}

529
void
Christian Schäfer's avatar
Christian Schäfer committed
530
531
532
533
534
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

535
bool
Christian Schäfer's avatar
Christian Schäfer committed
536
537
538
539
540
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

541
void
Christian Schäfer's avatar
Christian Schäfer committed
542
543
544
545
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
546
unsigned long
547
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
548
  assert (node->op == op_Block);
549
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
550
551
}

552
void
553
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
554
  assert (node->op == op_Block);
555
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
556
557
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
558
/* For this current_ir_graph must be set. */
559
void
560
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
561
562
563
564
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

565
int
566
Block_not_block_visited(ir_node *node) {
567
568
569
  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
570

571
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
572
573
574
575
576
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

577
void
Christian Schäfer's avatar
Christian Schäfer committed
578
579
580
581
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;
}
582

583
/* handler handling for Blocks * /
584
585
void
set_Block_handler (ir_node *block, ir_node *handler)  {
586
587
588
589
590
  assert ((block->op == op_Block));
  assert ((handler->op == op_Block));
  block->attr.block.handler_entry = handler;
}

591
592
ir_node *
get_Block_handler (ir_node *block) {
593
594
595
596
  assert ((block->op == op_Block));
  return (block->attr.block.handler_entry);
}

597
/ * handler handling for Nodes * /
598
599
void
set_Node_handler (ir_node *node, ir_node *handler) {
600
601
602
  set_Block_handler (get_nodes_Block (node), handler);
}

603
604
ir_node *
get_Node_handler (ir_node *node) {
605
606
607
  return (get_Block_handler (get_nodes_Block (node)));
}

608
/ * exc_t handling for Blocks * /
609
void set_Block_exc (ir_node *block, exc_t exc) {
610
  assert ((block->op == op_Block));
611
612
613
  block->attr.block.exc = exc;
}

614
exc_t get_Block_exc (ir_node *block) {
615
  assert ((block->op == op_Block));
616
617
618
  return (block->attr.block.exc);
}

619
/ * exc_t handling for Nodes * /
620
void set_Node_exc (ir_node *node, exc_t exc) {
621
622
623
  set_Block_exc (get_nodes_Block (node), exc);
}

624
exc_t get_Node_exc (ir_node *node) {
625
626
  return (get_Block_exc (get_nodes_Block (node)));
}
627
*/
628

629
630
631
632
633
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;
634
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
635
636
637
638
639
640
641
642
    {
      /* 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;
    }
643
644
645
646
647
  }
  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
648
649
650
  assert(node->op == op_Block &&
	 node->attr.block.in_cg &&
	 0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
651
652
653
654
655
656
657
658
659
  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) {
660
661
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
662
663
}

664
665
666
667
668
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];
}

669
670
671
672
673
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

674
/* Start references the irg it is in. */
675
ir_graph *
676
get_Start_irg(ir_node *node) {
677
  return get_irn_irg(node);
678
679
}

680
void
681
682
683
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
684
  assert(0 && " Why set irg? -- use set_irn_irg");
685
686
}

687
int
688
689
690
691
692
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

693
ir_node *
694
695
696
697
698
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

699
void
700
701
702
703
704
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

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

711
void
712
free_End (ir_node *end) {
713
  assert (end->op == op_End);
714
  end->kind = k_BAD;
715
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
716
717
718
719
  end->in = NULL;   /* @@@ make sure we get an error if we use the
		       in array afterwards ... */
}

720
721
ir_graph *get_EndReg_irg (ir_node *end) {
  return get_irn_irg(end);
722
723
}

724
725
ir_graph *get_EndExcept_irg  (ir_node *end) {
  return get_irn_irg(end);
726
727
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
728
729
730
731
732
733
734
735
736
/*
> 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
737
 - determining the biggest case constant to know the proj number for
Götz Lindenmaier's avatar
Götz Lindenmaier committed
738
739
740
741
742
743
744
745
746
747
748
749
   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.,
750
libFIRM can implement a routine that transforms between the two
Götz Lindenmaier's avatar
Götz Lindenmaier committed
751
752
753
754
755
756
757
758
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).
*/
759
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
760
761
762
763
764
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

765
void
Christian Schäfer's avatar
Christian Schäfer committed
766
767
768
769
770
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

771
cond_kind
772
773
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
774
  return node->attr.c.kind;
775
776
}

777
void
778
779
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
780
  node->attr.c.kind = kind;
781
782
}

783
784
785
786
787
788
long
get_Cond_defaultProj (ir_node *node) {
  assert (node->op == op_Cond);
  return node->attr.c.default_proj;
}

789
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
790
get_Return_mem (ir_node *node) {
791
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
792
793
794
  return get_irn_n(node, 0);
}

795
void
Christian Schäfer's avatar
Christian Schäfer committed
796
797
798
799
800
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

801
int
802
get_Return_n_ress (ir_node *node) {
803
804
805
806
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

807
ir_node **
808
809
810
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
811
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
812
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
813
814
  else
    return NULL;
815
816
}

Christian Schäfer's avatar
Christian Schäfer committed
817
/*
818
void
Christian Schäfer's avatar
Christian Schäfer committed
819
820
821
822
823
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

824
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
825
826
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
827
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
828
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
829
830
}

831
void
Christian Schäfer's avatar
Christian Schäfer committed
832
set_Return_res (ir_node *node, int pos, ir_node *res){
833
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
834
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
835
836
}

837
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
838
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
839
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
840
841
842
  return get_irn_n(node, 0);
}

843
void
Christian Schäfer's avatar
Christian Schäfer committed
844
845
846
847
848
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

849
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
850
851
852
853
854
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

855
void
Christian Schäfer's avatar
Christian Schäfer committed
856
857
858
859
860
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

861
tarval *get_Const_tarval (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
862
  assert (node->op == op_Const);
863
  return node->attr.con.tv;
Christian Schäfer's avatar
Christian Schäfer committed
864
865
}

866
void
Christian Schäfer's avatar
Christian Schäfer committed
867
868
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
869
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
870
871
}

872
873
874
875

/* 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. */
876
type *
877
878
879
880
881
get_Const_type (ir_node *node) {
  assert (node->op == op_Const);
  return node->attr.con.tp;
}

882
void
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
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;
}


898
symconst_kind
899
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
900
901
902
903
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

904
void
Christian Schäfer's avatar
Christian Schäfer committed
905
906
907
908
909
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

910
type *
Christian Schäfer's avatar
Christian Schäfer committed
911
912
913
914
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
915
  return node->attr.i.tori.typ = skip_tid(node->attr.i.tori.typ);
Christian Schäfer's avatar
Christian Schäfer committed
916
917
}

918
void
919
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
920
921
922
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
923
  node->attr.i.tori.typ = tp;
Christian Schäfer's avatar
Christian Schäfer committed
924
925
}

926
ident *
Christian Schäfer's avatar
Christian Schäfer committed
927
928
929
930
931
932
get_SymConst_ptrinfo (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == linkage_ptr_info));
  return node->attr.i.tori.ptrinfo;
}

933
void
Christian Schäfer's avatar
Christian Schäfer committed
934
935
936
937
938
939
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;
}

940
type_or_id_p
Götz Lindenmaier's avatar
Götz Lindenmaier committed
941
942
943
944
945
get_SymConst_type_or_id (ir_node *node) {
  assert (node->op == op_SymConst);
  return &(node->attr.i.tori);
}

946
void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
947
948
949
950
951
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));
}

952
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
953
954
955
956
957
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

958
void
Christian Schäfer's avatar
Christian Schäfer committed
959
960
961
962
963
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

964
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
965
966
967
968
969
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

970
void
Christian Schäfer's avatar
Christian Schäfer committed
971
972
973
974
975
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

976
int
977
get_Sel_n_indexs (ir_node *node) {
978
979
980
981
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

982
ir_node **
983
984
985
get_Sel_index_arr (ir_node *node)
{
  assert ((node->op == op_Sel));
986
  if (get_Sel_n_indexs(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
987
    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
988
989
  else
    return NULL;
990
991
}

992
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
993
994
get_Sel_index (ir_node *node, int pos) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
995
  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
996
997
}

998
void
Christian Schäfer's avatar
Christian Schäfer committed
999
1000
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
1001
  set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
Christian Schäfer's avatar
Christian Schäfer committed
1002
1003
}

1004
entity *
Christian Schäfer's avatar
Christian Schäfer committed
1005
1006
1007
1008
1009
get_Sel_entity (ir_node *node) {
  assert (node->op == op_Sel);
  return node->attr.s.ent;
}

1010
void
Christian Schäfer's avatar
Christian Schäfer committed
1011
1012
1013
1014
1015
set_Sel_entity (ir_node *node, entity *ent) {
  assert (node->op == op_Sel);
  node->attr.s.ent = ent;
}

1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
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);
}

1052
1053
1054
1055

/* 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
1056
   unops are: Minus, Abs, Not, Conv, Cast
1057
1058
1059
1060
   binops are: Add, Sub, Mul, Quot, DivMod, Div, Mod, And, Or, Eor, Shl,
   Shr, Shrs, Rotate, Cmp */


1061
ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1062
1063
1064
1065
1066
get_Call_mem (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 0);
}

1067
void
Christian Schäfer's avatar
Christian Schäfer committed
1068
1069
1070
1071
1072
set_Call_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Call);
  set_irn_n(node, 0, mem);
}