irnode.c 57.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"
Christian Schäfer's avatar
Christian Schäfer committed
23
#include "array.h"
24
#include "irbackedge_t.h"
25
#include "irdump.h"
26
#include "irflag_t.h"
27
#include "irop_t.h"
Christian Schäfer's avatar
Christian Schäfer committed
28

29
#include "irprog_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
30

Götz Lindenmaier's avatar
Götz Lindenmaier committed
31
32
33
34
35
/* 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 */
36
#define END_KEEPALIVE_OFFSET 0
Götz Lindenmaier's avatar
Götz Lindenmaier committed
37

38
/* Declarations for inlineing */
39
40
41
42
43
INLINE ir_node ** get_irn_in (const ir_node *node);
INLINE ir_mode *get_irn_mode (const ir_node *node);
INLINE ir_op *get_irn_op (const ir_node *node);
INLINE opcode get_irn_opcode (const ir_node *node);
INLINE ident *get_irn_opident (const ir_node *node);
44
45
INLINE type *get_SymConst_type (ir_node *node);
INLINE ir_node *skip_nop (ir_node *node);
46
INLINE int is_Proj (const ir_node *node);
47
48


49
50
51
52
53
54
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
55

56
INLINE const char *get_pnc_string(int pnc) {
Christian Schäfer's avatar
Christian Schäfer committed
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
  return pnc_name_arr[pnc];
}


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 */
}

84
const char *pns_name_arr [] = {
85
86
87
  "initial_exec", "global_store",
  "frame_base", "globals", "args"
};
Christian Schäfer's avatar
Christian Schäfer committed
88

89
const char *symconst_name_arr [] = {
90
91
  "type_tag", "size", "linkage_ptr_info"
};
Christian Schäfer's avatar
Christian Schäfer committed
92
93
94
95
96
97

void
init_irnode (void)
{
}

98
99
100
101
102
103
/*
 * 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.
 */
104
INLINE ir_node *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
105
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
106
107
108
109
110
111
112
113
114
115
	     int arity, ir_node **in)
{
  ir_node *res;
  int node_size = offsetof (ir_node, attr) +  op->attr_size;

  res = (ir_node *) obstack_alloc (irg->obst, node_size);

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

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

Christian Schäfer's avatar
Christian Schäfer committed
132
133
134
  return res;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
135
136
137
/* Copies all attributes stored in the old node to the new node.
   Assumes both have the same opcode and sufficient size. */
void
138
139
140
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
141
}
Christian Schäfer's avatar
Christian Schäfer committed
142
143
144

/** getting some parameters from ir_nodes **/

Sebastian Felis's avatar
Sebastian Felis committed
145
int
146
is_ir_node (const void *thing) {
Sebastian Felis's avatar
Sebastian Felis committed
147
148
149
150
151
152
153
  assert(thing);
  if (get_kind(thing) == k_ir_node)
    return 1;
  else
    return 0;
}

Christian Schäfer's avatar
Christian Schäfer committed
154
/* returns the number of predecessors without the block predecessor. */
155
INLINE int
156
get_irn_intra_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
157
  assert(node);
158
  return ARR_LEN(node->in) - 1;
Christian Schäfer's avatar
Christian Schäfer committed
159
160
}

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/* returns the number of predecessors without the block predecessor. */
INLINE int
get_irn_inter_arity (const ir_node *node) {
  assert(node);
  if (get_irn_opcode(node) == iro_Filter) {
    assert(node->attr.filter.in_cg);
    return ARR_LEN(node->attr.filter.in_cg) - 1;
  } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
    return ARR_LEN(node->attr.block.in_cg) - 1;
  }
  return get_irn_intra_arity(node);
}

/* returns the number of predecessors without the block predecessor. */
INLINE int
get_irn_arity (const ir_node *node) {
  assert(node);
  if (interprocedural_view) return get_irn_inter_arity(node);
  return get_irn_intra_arity(node);
}

182
183
184
185
186
187
/* 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. */
188
INLINE ir_node **
189
get_irn_in (const ir_node *node) {
190
191
192
193
194
195
196
197
198
199
200
  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
201
202
}

203
INLINE void
204
set_irn_in (ir_node *node, int arity, ir_node **in) {
205
  ir_node *** arr;
206
  assert(node);
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  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;
223
  }
224
  fix_backedges(current_ir_graph->obst, node);
225
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
226
227
}

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
INLINE ir_node *
get_irn_intra_n (ir_node *node, int n) {
  return (node->in[n + 1] = skip_nop(node->in[n + 1]));
}

INLINE ir_node*
get_irn_inter_n (ir_node *node, int n) {
  /* handle Filter and Block specially */
  if (get_irn_opcode(node) == iro_Filter) {
    assert(node->attr.filter.in_cg);
    return (node->attr.filter.in_cg[n + 1] = skip_nop(node->attr.filter.in_cg[n + 1]));
  } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
    return (node->attr.block.in_cg[n + 1] = skip_nop(node->attr.block.in_cg[n + 1]));
  }

  return get_irn_intra_n (node, n);
}

Christian Schäfer's avatar
Christian Schäfer committed
246
247
/* to iterate through the predecessors without touching the array */
/* To iterate over the operands iterate from 0 to i < get_irn_arity(),
248
   to iterate including the Block predecessor iterate from i = -1 to
249
250
   i < get_irn_arity.
   If it is a block, the entry -1 is NULL. */
251
INLINE ir_node *
252
get_irn_n (ir_node *node, int n) {
253
  assert(node); assert(-1 <= n && n < get_irn_arity(node));
254
255
  if (interprocedural_view)  return get_irn_inter_n (node, n);
  return get_irn_intra_n (node, n);
Christian Schäfer's avatar
Christian Schäfer committed
256
257
}

258

259
INLINE void
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
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
281
282
}

283
INLINE ir_mode *
284
get_irn_mode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
285
286
287
288
289
{
  assert (node);
  return node->mode;
}

Till Riedel's avatar
Till Riedel committed
290
291
292
293
294
295
296
297
INLINE void
set_irn_mode (ir_node *node, ir_mode *mode)
{
  assert (node);
  node->mode=mode;
  return;
}

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

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

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

320
INLINE ir_op *
321
get_irn_op (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
322
323
324
325
326
327
{
  assert (node);
  return node->op;
}

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

335
INLINE opcode
336
get_irn_opcode (const ir_node *node)
337
338
{
  assert (node);
Boris Boesler's avatar
Boris Boesler committed
339
340
  assert (k_ir_node == get_kind(node));
  assert (node -> op);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
341
342
343
  return node->op->code;
}

344
INLINE const char *
345
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
346
347
{
  assert(node);
348
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
349
350
}

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

358
INLINE unsigned long
359
get_irn_visited (const ir_node *node)
360
361
362
363
364
{
  assert (node);
  return node->visited;
}

365
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
366
set_irn_visited (ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
367
368
{
  assert (node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
369
  node->visited = visited;
Christian Schäfer's avatar
Christian Schäfer committed
370
}
371

372
INLINE void
373
374
375
376
377
mark_irn_visited (ir_node *node) {
  assert (node);
  node->visited = current_ir_graph->visited;
}

378
INLINE int
379
irn_not_visited  (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
380
381
382
383
  assert (node);
  return (node->visited < current_ir_graph->visited);
}

384
INLINE int
385
irn_visited  (const ir_node *node) {
386
387
388
389
  assert (node);
  return (node->visited >= current_ir_graph->visited);
}

390
INLINE void
391
set_irn_link (ir_node *node, void *link) {
Christian Schäfer's avatar
Christian Schäfer committed
392
  assert (node);
393
394
395
396
  /* 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
397
398
399
  node->link = link;
}

400
INLINE void *
401
get_irn_link (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
402
403
404
405
  assert (node);
  return node->link;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
406
/* Outputs a unique number for this node */
407
INLINE long
408
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
409
  assert(node);
410
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
411
  return node->node_nr;
412
#else
413
  return (long)&node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
414
#endif
415
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
416

417
INLINE const_attr
Christian Schäfer's avatar
Christian Schäfer committed
418
419
420
421
422
423
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

424
INLINE long
Christian Schäfer's avatar
Christian Schäfer committed
425
426
427
428
429
430
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

431
INLINE alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
432
433
434
435
436
437
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

438
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
439
440
441
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
442
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
443
444
}

445
INLINE symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
446
447
448
449
450
451
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

452
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
453
454
455
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
456
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
457
458
}

459
INLINE sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
460
461
462
463
464
465
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

466
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
467
468
469
470
471
472
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

473
INLINE block_attr
Christian Schäfer's avatar
Christian Schäfer committed
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
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);
}

489
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
490
491
492
493
494
set_nodes_Block (ir_node *node, ir_node *block) {
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
/* 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;
}

531
/* Returns an array with the predecessors of the Block. Depending on
532
   the implementation of the graph data structure this can be a copy of
533
534
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
535
INLINE ir_node **
536
537
538
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
539
  return (ir_node **)&(get_irn_in(node)[1]);
540
541
542
}


543
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
544
545
546
547
548
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
  return (get_irn_arity(node));
}

549
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
550
551
get_Block_cfgpred (ir_node *node, int pos) {
  assert (node->op == op_Block);
552
  /* debug @@@
553
554
555
556
  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);
557
    } */
558
  assert(node); assert(-1 <= pos && pos < get_irn_arity(node));
Christian Schäfer's avatar
Christian Schäfer committed
559
560
561
  return get_irn_n(node, pos);
}

562
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
563
564
565
566
567
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

568
INLINE bool
Christian Schäfer's avatar
Christian Schäfer committed
569
570
571
572
573
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

574
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
575
576
577
578
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
579
INLINE unsigned long
580
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
581
  assert (node->op == op_Block);
582
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
583
584
}

585
INLINE void
586
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
587
  assert (node->op == op_Block);
588
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
589
590
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
591
/* For this current_ir_graph must be set. */
592
593
INLINE void
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
594
595
596
597
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

598
599
INLINE int
Block_not_block_visited(ir_node *node) {
600
601
602
  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
603

604
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
605
606
607
608
609
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

610
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
611
612
613
614
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;
}
615

616
/* handler handling for Blocks * /
617
618
void
set_Block_handler (ir_node *block, ir_node *handler)  {
619
620
621
622
623
  assert ((block->op == op_Block));
  assert ((handler->op == op_Block));
  block->attr.block.handler_entry = handler;
}

624
625
ir_node *
get_Block_handler (ir_node *block) {
626
627
628
629
  assert ((block->op == op_Block));
  return (block->attr.block.handler_entry);
}

630
/ * handler handling for Nodes * /
631
632
void
set_Node_handler (ir_node *node, ir_node *handler) {
633
634
635
  set_Block_handler (get_nodes_Block (node), handler);
}

636
637
ir_node *
get_Node_handler (ir_node *node) {
638
639
640
  return (get_Block_handler (get_nodes_Block (node)));
}

641
/ * exc_t handling for Blocks * /
642
void set_Block_exc (ir_node *block, exc_t exc) {
643
  assert ((block->op == op_Block));
644
645
646
  block->attr.block.exc = exc;
}

647
exc_t get_Block_exc (ir_node *block) {
648
  assert ((block->op == op_Block));
649
650
651
  return (block->attr.block.exc);
}

652
/ * exc_t handling for Nodes * /
653
void set_Node_exc (ir_node *node, exc_t exc) {
654
655
656
  set_Block_exc (get_nodes_Block (node), exc);
}

657
exc_t get_Node_exc (ir_node *node) {
658
659
  return (get_Block_exc (get_nodes_Block (node)));
}
660
*/
661

662
663
664
665
666
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;
667
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
668
669
670
671
672
673
674
675
    {
      /* 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;
    }
676
677
678
679
680
  }
  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
681
682
683
  assert(node->op == op_Block &&
	 node->attr.block.in_cg &&
	 0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
684
685
686
687
688
689
690
691
692
  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) {
693
694
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
695
696
}

697
698
699
700
701
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];
}

702
703
704
705
706
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

707
708
709
/* Start references the irg it is in. */
INLINE ir_graph *
get_Start_irg(ir_node *node) {
710
  return get_irn_irg(node);
711
712
713
714
715
716
}

INLINE void
set_Start_irg(ir_node *node, ir_graph *irg) {
  assert(node->op == op_Start);
  assert(is_ir_graph(irg));
717
718
  assert(0 && " Why set irg? ");
  //node->attr.start.irg = irg;
719
720
}

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

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

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

739
INLINE void
740
741
742
743
744
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);
}

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

754
755
ir_graph *get_EndReg_irg (ir_node *end) {
  return get_irn_irg(end);
756
757
}

758
759
ir_graph *get_EndExcept_irg  (ir_node *end) {
  return get_irn_irg(end);
760
761
}

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

799
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
800
801
802
803
804
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

805
INLINE cond_kind
806
807
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
808
  return node->attr.c.kind;
809
810
}

811
INLINE void
812
813
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
814
  node->attr.c.kind = kind;
815
816
}

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

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

829
INLINE int
830
get_Return_n_ress (ir_node *node) {
831
832
833
834
835
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

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

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

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

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

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

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

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

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

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

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

900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925

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

INLINE void
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;
}


926
INLINE symconst_kind
927
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
928
929
930
931
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

932
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
933
934
935
936
937
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

938
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
939
940
941
942
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
943
  return node->attr.i.tori.typ = skip_tid(node->attr.i.tori.typ);
Christian Schäfer's avatar
Christian Schäfer committed
944
945
}

946
INLINE void
947
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
948
949
950
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
951
  node->attr.i.tori.typ = tp;
Christian Schäfer's avatar
Christian Schäfer committed
952
953
}

954
INLINE ident *
Christian Schäfer's avatar
Christian Schäfer committed
955
956
957
958
959
960
get_SymConst_ptrinfo (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == linkage_ptr_info));
  return node->attr.i.tori.ptrinfo;
}

961
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
962
963
964
965
966
967
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;
}

968
INLINE type_or_id_p
Götz Lindenmaier's avatar
Götz Lindenmaier committed
969
970
971
972
973
get_SymConst_type_or_id (ir_node *node) {
  assert (node->op == op_SymConst);
  return &(node->attr.i.tori);
}

974
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
975
976
977
978
979
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));
}

980
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
981
982
983
984
985
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

986
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
987
988
989
990
991
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

992
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
993
994
995
996
997
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

998
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
999
1000
1001
1002
1003
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

1004
INLINE int
1005
get_Sel_n_indexs (ir_node *node) {
1006
1007
1008
1009
1010
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

INLINE ir_node **
1011
1012
1013
get_Sel_index_arr (ir_node *node)
{
  assert ((node->op == op_Sel));
1014
  if (get_Sel_n_indexs(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1015
    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1016
1017
  else
    return NULL;
1018
1019
}

1020
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1021
1022
get_Sel_index (ir_node *node, int pos) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1023
  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1024
1025
}

1026
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1027
1028
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
1029
  set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
Christian Schäfer's avatar
Christian Schäfer committed
1030
1031
}

1032
INLINE entity *
Christian Schäfer's avatar
Christian Schäfer committed
1033
1034
1035
1036
1037
get_Sel_entity (ir_node *node) {
  assert (node->op == op_Sel);
  return node->attr.s.ent;
}

1038
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1039
1040
1041
1042
1043
set_Sel_entity (ir_node *node, entity *ent) {
  assert (node->op == op_Sel);
  node->attr.s.ent = ent;
}

1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
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);
}

1080
1081
1082
1083

/* 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
1084
   unops are: Minus, Abs, Not, Conv, Cast
1085
1086
1087
1088
1089
   binops are: Add, Sub, Mul, Quot, DivMod, Div, Mod, And, Or, Eor, Shl,
   Shr, Shrs, Rotate, Cmp */


INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1090
1091
1092
1093
1094
get_Call_mem (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 0);
}

1095
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1096
1097
1098
1099
1100
set_Call_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Call);
  set_irn_n(node, 0, mem);
}

1101
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1102
1103
1104
1105
1106
get_Call_ptr (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 1);
}

1107
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1108
1109
1110
1111
1112
set_Call_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Call);
  set_irn_n(node, 1, ptr);
}

1113
INLINE ir_node **
1114
1115
get_Call_param_arr (ir_node *node) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1116
  return (ir_node **)&get_irn_in(node)[CALL_PARAM_OFFSET + 1];
1117
1118
}

1119
INLINE int
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1120
get_Call_n_params (ir_node *node)  {
Christian Schäfer's avatar
Christian Schäfer committed
1121
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1122
  return (get_irn_arity(node) - CALL_PARAM_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1123
1124
}

1125
INLINE int
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1126
get_Call_arity (ir_node *node) {