irnode.c 46.9 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
/* Declarations for inlineing */
38
39
40
41
42
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);
43
44
INLINE type *get_SymConst_type (ir_node *node);
INLINE ir_node *skip_nop (ir_node *node);
45
INLINE int is_Proj (const ir_node *node);
46
47


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

Michael Beck's avatar
Michael Beck committed
55
56
57
/**
 * returns the pnc name from an pnc constant
 */
58
INLINE const char *get_pnc_string(int pnc) {
Christian Schäfer's avatar
Christian Schäfer committed
59
60
61
  return pnc_name_arr[pnc];
}

Michael Beck's avatar
Michael Beck committed
62
63
64
/**
 * Calculates the negated pnc condition.
 */
Christian Schäfer's avatar
Christian Schäfer committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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 */
}

88
const char *pns_name_arr [] = {
89
90
91
  "initial_exec", "global_store",
  "frame_base", "globals", "args"
};
Christian Schäfer's avatar
Christian Schäfer committed
92

93
const char *symconst_name_arr [] = {
94
95
  "type_tag", "size", "linkage_ptr_info"
};
Christian Schäfer's avatar
Christian Schäfer committed
96
97
98
99
100
101

void
init_irnode (void)
{
}

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

115
  assert(irg && op && mode);
Christian Schäfer's avatar
Christian Schäfer committed
116
117
118
119
120
  res = (ir_node *) obstack_alloc (irg->obst, node_size);

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

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

Michael Beck's avatar
Michael Beck committed
137
138
  stat_new_node(res);

Christian Schäfer's avatar
Christian Schäfer committed
139
140
141
  return res;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
142
143
144
/* Copies all attributes stored in the old node to the new node.
   Assumes both have the same opcode and sufficient size. */
void
145
146
147
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
148
}
Christian Schäfer's avatar
Christian Schäfer committed
149
150
151

/** getting some parameters from ir_nodes **/

Sebastian Felis's avatar
Sebastian Felis committed
152
int
153
is_ir_node (const void *thing) {
Sebastian Felis's avatar
Sebastian Felis committed
154
155
156
157
158
159
  if (get_kind(thing) == k_ir_node)
    return 1;
  else
    return 0;
}

160
INLINE int
161
get_irn_intra_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
162
  return intern_get_irn_intra_arity(node);
Christian Schäfer's avatar
Christian Schäfer committed
163
164
}

165
166
INLINE int
get_irn_inter_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
167
  return intern_get_irn_inter_arity(node);
168
169
170
171
}

INLINE int
get_irn_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
172
  return intern_get_irn_arity(node);
173
174
}

175
176
177
178
179
180
/* 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. */
181
INLINE ir_node **
182
get_irn_in (const ir_node *node) {
183
184
185
186
187
188
189
190
191
192
193
  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
194
195
}

196
INLINE void
197
set_irn_in (ir_node *node, int arity, ir_node **in) {
198
  ir_node *** arr;
199
  assert(node);
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
  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;
216
  }
217
  fix_backedges(current_ir_graph->obst, node);
218
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
219
220
}

221
222
INLINE ir_node *
get_irn_intra_n (ir_node *node, int n) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
223
  return intern_get_irn_intra_n (node, n);
224
225
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
226
INLINE ir_node *
227
get_irn_inter_n (ir_node *node, int n) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
228
  return intern_get_irn_inter_n (node, n);
229
230
}

231
INLINE ir_node *
232
get_irn_n (ir_node *node, int n) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
233
  return intern_get_irn_n (node, n);
Christian Schäfer's avatar
Christian Schäfer committed
234
235
}

236
INLINE void
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
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
258
259
}

260
INLINE ir_mode *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
261
262
get_irn_mode (const ir_node *node) {
  return intern_get_irn_mode(node);
Christian Schäfer's avatar
Christian Schäfer committed
263
264
}

Till Riedel's avatar
Till Riedel committed
265
266
267
268
269
270
271
272
INLINE void
set_irn_mode (ir_node *node, ir_mode *mode)
{
  assert (node);
  node->mode=mode;
  return;
}

273
INLINE modecode
274
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
275
276
277
278
279
{
  assert (node);
  return node->mode->code;
}

280
281
282
283
284
285
286
/** 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
287

288
INLINE ident *
289
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
290
291
{
  assert(node);
292
  return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
293
294
}

295
INLINE ir_op *
296
get_irn_op (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
297
{
Götz Lindenmaier's avatar
Götz Lindenmaier committed
298
  return intern_get_irn_op(node);
Christian Schäfer's avatar
Christian Schäfer committed
299
300
301
}

/* should be private to the library: */
302
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
303
304
305
306
307
308
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

309
INLINE opcode
310
get_irn_opcode (const ir_node *node)
311
{
Götz Lindenmaier's avatar
Götz Lindenmaier committed
312
  return intern_get_irn_opcode(node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
313
314
}

315
INLINE const char *
316
get_irn_opname (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
317
318
{
  assert(node);
319
  return get_id_str(node->op->name);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
320
321
}

322
INLINE ident *
323
get_irn_opident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
324
325
326
{
  assert(node);
  return node->op->name;
327
328
}

329
INLINE unsigned long
330
get_irn_visited (const ir_node *node)
331
332
333
334
335
{
  assert (node);
  return node->visited;
}

336
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
337
set_irn_visited (ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
338
339
{
  assert (node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
340
  node->visited = visited;
Christian Schäfer's avatar
Christian Schäfer committed
341
}
342

343
INLINE void
344
345
346
347
348
mark_irn_visited (ir_node *node) {
  assert (node);
  node->visited = current_ir_graph->visited;
}

349
INLINE int
350
irn_not_visited  (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
351
352
353
354
  assert (node);
  return (node->visited < current_ir_graph->visited);
}

355
INLINE int
356
irn_visited  (const ir_node *node) {
357
358
359
360
  assert (node);
  return (node->visited >= current_ir_graph->visited);
}

361
INLINE void
362
set_irn_link (ir_node *node, void *link) {
Christian Schäfer's avatar
Christian Schäfer committed
363
  assert (node);
364
365
366
367
  /* 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
368
369
370
  node->link = link;
}

371
INLINE void *
372
get_irn_link (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
373
374
375
376
  assert (node);
  return node->link;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
377
/* Outputs a unique number for this node */
378
INLINE long
379
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
380
  assert(node);
381
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
382
  return node->node_nr;
383
#else
384
  return (long)&node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
385
#endif
386
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
387

388
INLINE const_attr
Christian Schäfer's avatar
Christian Schäfer committed
389
390
391
392
393
394
get_irn_const_attr (ir_node *node)
{
  assert (node->op == op_Const);
  return node->attr.con;
}

395
INLINE long
Christian Schäfer's avatar
Christian Schäfer committed
396
397
398
399
400
401
get_irn_proj_attr (ir_node *node)
{
  assert (node->op == op_Proj);
  return node->attr.proj;
}

402
INLINE alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
403
404
405
406
407
408
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

409
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
410
411
412
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
413
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
414
415
}

416
INLINE symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
417
418
419
420
421
422
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

423
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
424
425
426
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
427
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
428
429
}

Michael Beck's avatar
Michael Beck committed
430
431
432
433
434
435
436
INLINE type *
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);
}

437
INLINE sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
438
439
440
441
442
443
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

444
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
445
446
447
448
449
450
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

451
INLINE block_attr
Christian Schäfer's avatar
Christian Schäfer committed
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
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);
}

467
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
468
469
470
471
472
set_nodes_Block (ir_node *node, ir_node *block) {
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

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
498
499
500
501
502
503
504
505
506
507
508
/* 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;
}

509
/* Returns an array with the predecessors of the Block. Depending on
510
   the implementation of the graph data structure this can be a copy of
511
512
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
513
INLINE ir_node **
514
515
516
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
517
  return (ir_node **)&(get_irn_in(node)[1]);
518
519
520
}


521
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
522
523
524
525
526
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
  return (get_irn_arity(node));
}

527
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
528
529
get_Block_cfgpred (ir_node *node, int pos) {
  assert (node->op == op_Block);
530
  /* debug @@@
531
532
533
534
  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);
535
    } */
536
  assert(node); assert(-1 <= pos && pos < get_irn_arity(node));
Christian Schäfer's avatar
Christian Schäfer committed
537
538
539
  return get_irn_n(node, pos);
}

540
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
541
542
543
544
545
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

546
INLINE bool
Christian Schäfer's avatar
Christian Schäfer committed
547
548
549
550
551
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

552
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
553
554
555
556
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
557
INLINE unsigned long
558
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
559
  assert (node->op == op_Block);
560
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
561
562
}

563
INLINE void
564
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
565
  assert (node->op == op_Block);
566
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
567
568
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
569
/* For this current_ir_graph must be set. */
570
571
INLINE void
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
572
573
574
575
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

576
577
INLINE int
Block_not_block_visited(ir_node *node) {
578
579
580
  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
581

582
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
583
584
585
586
587
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

588
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
589
590
591
592
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;
}
593

594
/* handler handling for Blocks * /
595
596
void
set_Block_handler (ir_node *block, ir_node *handler)  {
597
598
599
600
601
  assert ((block->op == op_Block));
  assert ((handler->op == op_Block));
  block->attr.block.handler_entry = handler;
}

602
603
ir_node *
get_Block_handler (ir_node *block) {
604
605
606
607
  assert ((block->op == op_Block));
  return (block->attr.block.handler_entry);
}

608
/ * handler handling for Nodes * /
609
610
void
set_Node_handler (ir_node *node, ir_node *handler) {
611
612
613
  set_Block_handler (get_nodes_Block (node), handler);
}

614
615
ir_node *
get_Node_handler (ir_node *node) {
616
617
618
  return (get_Block_handler (get_nodes_Block (node)));
}

619
/ * exc_t handling for Blocks * /
620
void set_Block_exc (ir_node *block, exc_t exc) {
621
  assert ((block->op == op_Block));
622
623
624
  block->attr.block.exc = exc;
}

625
exc_t get_Block_exc (ir_node *block) {
626
  assert ((block->op == op_Block));
627
628
629
  return (block->attr.block.exc);
}

630
/ * exc_t handling for Nodes * /
631
void set_Node_exc (ir_node *node, exc_t exc) {
632
633
634
  set_Block_exc (get_nodes_Block (node), exc);
}

635
exc_t get_Node_exc (ir_node *node) {
636
637
  return (get_Block_exc (get_nodes_Block (node)));
}
638
*/
639

640
641
642
643
644
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;
645
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
646
647
648
649
650
651
652
653
    {
      /* 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;
    }
654
655
656
657
658
  }
  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
659
660
661
  assert(node->op == op_Block &&
	 node->attr.block.in_cg &&
	 0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
662
663
664
665
666
667
668
669
670
  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) {
671
672
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
673
674
}

675
676
677
678
679
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];
}

680
681
682
683
684
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

685
686
687
/* Start references the irg it is in. */
INLINE ir_graph *
get_Start_irg(ir_node *node) {
688
  return get_irn_irg(node);
689
690
691
692
693
694
}

INLINE void
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
695
  assert(0 && " Why set irg? -- use set_irn_irg");
696
697
}

698
INLINE int
699
700
701
702
703
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

704
INLINE ir_node *
705
706
707
708
709
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

710
INLINE void
711
712
713
714
715
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

716
INLINE void
717
718
719
720
721
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);
}

722
INLINE void
723
free_End (ir_node *end) {
724
  assert (end->op == op_End);
725
  end->kind = k_BAD;
726
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
727
728
729
730
  end->in = NULL;   /* @@@ make sure we get an error if we use the
		       in array afterwards ... */
}

731
732
ir_graph *get_EndReg_irg (ir_node *end) {
  return get_irn_irg(end);
733
734
}

735
736
ir_graph *get_EndExcept_irg  (ir_node *end) {
  return get_irn_irg(end);
737
738
}

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

776
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
777
778
779
780
781
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

782
INLINE cond_kind
783
784
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
785
  return node->attr.c.kind;
786
787
}

788
INLINE void
789
790
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
791
  node->attr.c.kind = kind;
792
793
}

794
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
795
get_Return_mem (ir_node *node) {
796
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
797
798
799
  return get_irn_n(node, 0);
}

800
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
801
802
803
804
805
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

806
INLINE int
807
get_Return_n_ress (ir_node *node) {
808
809
810
811
812
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

INLINE ir_node **
813
814
815
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
816
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
817
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
818
819
  else
    return NULL;
820
821
}

Christian Schäfer's avatar
Christian Schäfer committed
822
/*
823
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
824
825
826
827
828
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

829
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
830
831
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
832
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
833
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
834
835
}

836
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
837
set_Return_res (ir_node *node, int pos, ir_node *res){
838
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
839
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
840
841
}

842
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
843
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
844
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
845
846
847
  return get_irn_n(node, 0);
}

848
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
849
850
851
852
853
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

854
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
855
856
857
858
859
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

860
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
861
862
863
864
865
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

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

871
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
872
873
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
874
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
875
876
}

877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902

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


903
INLINE symconst_kind
904
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
905
906
907
908
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

909
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
910
911
912
913
914
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

915
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
916
917
918
919
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
920
  return node->attr.i.tori.typ = skip_tid(node->attr.i.tori.typ);
Christian Schäfer's avatar
Christian Schäfer committed
921
922
}

923
INLINE void
924
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
925
926
927
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
928
  node->attr.i.tori.typ = tp;
Christian Schäfer's avatar
Christian Schäfer committed
929
930
}

931
INLINE ident *
Christian Schäfer's avatar
Christian Schäfer committed
932
933
934
935
936
937
get_SymConst_ptrinfo (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == linkage_ptr_info));
  return node->attr.i.tori.ptrinfo;
}

938
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
939
940
941
942
943
944
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;
}

945
INLINE type_or_id_p
Götz Lindenmaier's avatar
Götz Lindenmaier committed
946
947
948
949
950
get_SymConst_type_or_id (ir_node *node) {
  assert (node->op == op_SymConst);
  return &(node->attr.i.tori);
}

951
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
952
953
954
955
956
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));
}

957
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
958
959
960
961
962
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

963
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
964
965
966
967
968
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

969
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
970
971
972
973
974
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

975
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
976
977
978
979
980
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

981
INLINE int
982
get_Sel_n_indexs (ir_node *node) {
983
984
985
986
987
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

INLINE ir_node **
988
989
990
get_Sel_index_arr (ir_node *node)
{
  assert ((node->op == op_Sel));
991
  if (get_Sel_n_indexs(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
992
    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
993
994
  else
    return NULL;
995
996
}

997
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
998
999
get_Sel_index (ir_node *node, int pos) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1000
  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1001
1002
}

1003
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1004
1005
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
1006
  set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
Christian Schäfer's avatar
Christian Schäfer committed
1007
1008
}

1009
INLINE entity *
Christian Schäfer's avatar
Christian Schäfer committed
1010
1011
1012
1013
1014
get_Sel_entity (ir_node *node) {
  assert (node->op == op_Sel);
  return node->attr.s.ent;
}

1015
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1016
1017
1018
1019
1020
set_Sel_entity (ir_node *node, entity *ent) {
  assert (node->op == op_Sel);
  node->attr.s.ent = ent;
}

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
1052
1053
1054
1055
1056
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);
}

1057
1058
1059
1060

/* 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
1061
   unops are: Minus, Abs, Not, Conv, Cast
1062
1063
1064
1065
1066
   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
1067
1068
1069
1070
1071
get_Call_mem (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 0);
}

1072
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1073
1074
1075
1076
1077
set_Call_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Call);
  set_irn_n(node, 0, mem);
}

1078
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1079
1080
1081
1082
1083
get_Call_ptr (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 1);
}

1084
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1085
1086
1087
1088
1089
set_Call_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Call);
  set_irn_n(node, 1, ptr);
}

1090
INLINE ir_node **
1091
1092
get_Call_param_arr (ir_node *node) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1093
  return (ir_node **)&get_irn_in(node)[CALL_PARAM_OFFSET + 1];
1094
1095
}

1096
INLINE int
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1097
get_Call_n_params (ir_node *node)  {
Christian Schäfer's avatar
Christian Schäfer committed
1098
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1099
  return (get_irn_arity(node) - CALL_PARAM_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1100
1101
}