irnode.c 57.6 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.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
98
99
100
101

void
init_irnode (void)
{
}

/* irnode constructor                                             */
/* create a new irnode in irg, with an op, mode, arity and        */
/* some incoming irnodes                                          */
/* this constructor is used in every specified irnode constructor */
102
INLINE ir_node *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
103
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
104
105
106
107
108
109
110
111
112
113
	     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;
114
  res->visited = 0;
Christian Schäfer's avatar
Christian Schäfer committed
115
116
  res->link = NULL;
  if (arity < 0) {
117
    res->in = NEW_ARR_F (ir_node *, 1);  /* 1: space for block */
Christian Schäfer's avatar
Christian Schäfer committed
118
119
120
121
122
  } 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
123
  set_irn_dbg_info(res, db);
124
  res->out = NULL;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
125
126
127
128
129

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

Christian Schäfer's avatar
Christian Schäfer committed
130
131
132
  return res;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
133
134
135
136
/* Copies all attributes stored in the old node to the new node.
   Assumes both have the same opcode and sufficient size. */
void
copy_attrs (ir_node *old, ir_node *new) {
137
  assert (get_irn_op(old) == get_irn_op(new));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
138
139
  memcpy (&new->attr, &old->attr, get_op_attr_size(get_irn_op(old)));
}
Christian Schäfer's avatar
Christian Schäfer committed
140
141
142

/** getting some parameters from ir_nodes **/

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

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

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/* 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);
}

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

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

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
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
244
245
246
/* to iterate through the predecessors without touching the array */
/* To iterate over the operands iterate from 0 to i < get_irn_arity(),
   to iterate includind the Block predecessor iterate from i = -1 to
247
248
   i < get_irn_arity.
   If it is a block, the entry -1 is NULL. */
249
INLINE ir_node *
250
get_irn_n (ir_node *node, int n) {
251
  assert(node); assert(-1 <= n && n < get_irn_arity(node));
252
253
  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
254
255
}

256

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

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

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

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

303
304
305
306
307
308
309
/** 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
310

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

634
635
ir_node *
get_Node_handler (ir_node *node) {
636
637
638
  return (get_Block_handler (get_nodes_Block (node)));
}

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

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

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

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

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

695
696
697
698
699
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];
}

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

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

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

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

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

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

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

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

752
753
ir_graph *get_EndReg_irg (ir_node *end) {
  return get_irn_irg(end);
754
755
}

756
757
ir_graph *get_EndExcept_irg  (ir_node *end) {
  return get_irn_irg(end);
758
759
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1042
1043
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
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);
}

1078
1079
1080
1081

/* 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
1082
   unops are: Minus, Abs, Not, Conv, Cast
1083
1084
1085
1086
1087
   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
1088
1089
1090
1091
1092
get_Call_mem (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 0);
}

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

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

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

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

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

1123
INLINE int
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1124
get_Call_arity (ir_node *node) {
1125
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1126
1127
1128
  return get_Call_n_params(node);
}

1129
/* INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1130
1131
1132
1133
1134
set_Call_arity (ir_node *node, ir_node *arity) {
  assert (node->op == op_Call);
}
*/

1135
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1136
1137
get_Call_param (ir_node *node, int pos) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1138
  return get_irn_n(node, pos + CALL_PARAM_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1139
1140
}