irnode.c 48.3 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"
28
#include "irprog_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
29

Michael Beck's avatar
Michael Beck committed
30
31
#include "firmstat.h"

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

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


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

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

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

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

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

void
init_irnode (void)
{
}

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

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

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

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

Michael Beck's avatar
Michael Beck committed
139
140
  stat_new_node(res);

Christian Schäfer's avatar
Christian Schäfer committed
141
142
143
  return res;
}

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

/** getting some parameters from ir_nodes **/

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

Christian Schäfer's avatar
Christian Schäfer committed
162
/* returns the number of predecessors without the block predecessor. */
163
INLINE int
164
get_irn_intra_arity (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
165
  assert(node);
166
  return ARR_LEN(node->in) - 1;
Christian Schäfer's avatar
Christian Schäfer committed
167
168
}

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/* 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);
}

190
191
192
193
194
195
/* 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. */
196
INLINE ir_node **
197
get_irn_in (const ir_node *node) {
198
199
200
201
202
203
204
205
206
207
208
  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
209
210
}

211
INLINE void
212
set_irn_in (ir_node *node, int arity, ir_node **in) {
213
  ir_node *** arr;
214
  assert(node);
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  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;
231
  }
232
  fix_backedges(current_ir_graph->obst, node);
233
  memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
234
235
}

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
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
254
255
/* to iterate through the predecessors without touching the array */
/* To iterate over the operands iterate from 0 to i < get_irn_arity(),
256
   to iterate including the Block predecessor iterate from i = -1 to
257
258
   i < get_irn_arity.
   If it is a block, the entry -1 is NULL. */
259
INLINE ir_node *
260
get_irn_n (ir_node *node, int n) {
261
  assert(node); assert(-1 <= n && n < get_irn_arity(node));
262
263
  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
264
265
}

266

267
INLINE void
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
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
289
290
}

291
INLINE ir_mode *
292
get_irn_mode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
293
294
295
296
297
{
  assert (node);
  return node->mode;
}

Till Riedel's avatar
Till Riedel committed
298
299
300
301
302
303
304
305
INLINE void
set_irn_mode (ir_node *node, ir_mode *mode)
{
  assert (node);
  node->mode=mode;
  return;
}

306
INLINE modecode
307
get_irn_modecode (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
308
309
310
311
312
{
  assert (node);
  return node->mode->code;
}

313
314
315
316
317
318
319
/** 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
320

321
INLINE ident *
322
get_irn_modeident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
323
324
{
  assert(node);
325
  return get_mode_ident(node->mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
326
327
}

328
INLINE ir_op *
329
get_irn_op (const ir_node *node)
Christian Schäfer's avatar
Christian Schäfer committed
330
331
332
333
334
335
{
  assert (node);
  return node->op;
}

/* should be private to the library: */
336
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
337
338
339
340
341
342
set_irn_op (ir_node *node, ir_op *op)
{
  assert (node);
  node->op = op;
}

343
INLINE opcode
344
get_irn_opcode (const ir_node *node)
345
{
Boris Boesler's avatar
Boris Boesler committed
346
347
  assert (k_ir_node == get_kind(node));
  assert (node -> op);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
348
349
350
  return node->op->code;
}

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

358
INLINE ident *
359
get_irn_opident (const ir_node *node)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
360
361
362
{
  assert(node);
  return node->op->name;
363
364
}

365
INLINE unsigned long
366
get_irn_visited (const ir_node *node)
367
368
369
370
371
{
  assert (node);
  return node->visited;
}

372
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
373
set_irn_visited (ir_node *node, unsigned long visited)
Christian Schäfer's avatar
Christian Schäfer committed
374
375
{
  assert (node);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
376
  node->visited = visited;
Christian Schäfer's avatar
Christian Schäfer committed
377
}
378

379
INLINE void
380
381
382
383
384
mark_irn_visited (ir_node *node) {
  assert (node);
  node->visited = current_ir_graph->visited;
}

385
INLINE int
386
irn_not_visited  (const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
387
388
389
390
  assert (node);
  return (node->visited < current_ir_graph->visited);
}

391
INLINE int
392
irn_visited  (const ir_node *node) {
393
394
395
396
  assert (node);
  return (node->visited >= current_ir_graph->visited);
}

397
INLINE void
398
set_irn_link (ir_node *node, void *link) {
Christian Schäfer's avatar
Christian Schäfer committed
399
  assert (node);
400
401
402
403
  /* 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
404
405
406
  node->link = link;
}

407
INLINE void *
408
get_irn_link (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
409
410
411
412
  assert (node);
  return node->link;
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
413
/* Outputs a unique number for this node */
414
INLINE long
415
get_irn_node_nr(const ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
416
  assert(node);
417
#ifdef DEBUG_libfirm
Götz Lindenmaier's avatar
Götz Lindenmaier committed
418
  return node->node_nr;
419
#else
420
  return (long)&node;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
421
#endif
422
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
423

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

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

438
INLINE alloc_attr
Christian Schäfer's avatar
Christian Schäfer committed
439
440
441
442
443
444
get_irn_alloc_attr (ir_node *node)
{
  assert (node->op == op_Alloc);
  return node->attr.a;
}

445
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
446
447
448
get_irn_free_attr     (ir_node *node)
{
  assert (node->op == op_Free);
449
  return node->attr.f = skip_tid(node->attr.f);
Christian Schäfer's avatar
Christian Schäfer committed
450
451
}

452
INLINE symconst_attr
Christian Schäfer's avatar
Christian Schäfer committed
453
454
455
456
457
458
get_irn_symconst_attr (ir_node *node)
{
  assert (node->op == op_SymConst);
  return node->attr.i;
}

459
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
460
461
462
get_irn_call_attr (ir_node *node)
{
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
463
  return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
Christian Schäfer's avatar
Christian Schäfer committed
464
465
}

Michael Beck's avatar
Michael Beck committed
466
467
468
469
470
471
472
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);
}

473
INLINE sel_attr
Christian Schäfer's avatar
Christian Schäfer committed
474
475
476
477
478
479
get_irn_sel_attr (ir_node *node)
{
  assert (node->op == op_Sel);
  return node->attr.s;
}

480
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
481
482
483
484
485
486
get_irn_phi_attr (ir_node *node)
{
  assert (node->op == op_Phi);
  return node->attr.phi0_pos;
}

487
INLINE block_attr
Christian Schäfer's avatar
Christian Schäfer committed
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
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);
}

503
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
504
505
506
507
508
set_nodes_Block (ir_node *node, ir_node *block) {
  assert (!(node->op == op_Block));
  set_irn_n(node, -1, block);
}

509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
/* 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;
}

545
/* Returns an array with the predecessors of the Block. Depending on
546
   the implementation of the graph data structure this can be a copy of
547
548
   the internal representation of predecessors as well as the internal
   array itself. Therefore writing to this array might obstruct the ir. */
549
INLINE ir_node **
550
551
552
get_Block_cfgpred_arr (ir_node *node)
{
  assert ((node->op == op_Block));
Götz Lindenmaier's avatar
Götz Lindenmaier committed
553
  return (ir_node **)&(get_irn_in(node)[1]);
554
555
556
}


557
INLINE int
Christian Schäfer's avatar
Christian Schäfer committed
558
559
560
561
562
get_Block_n_cfgpreds (ir_node *node) {
  assert ((node->op == op_Block));
  return (get_irn_arity(node));
}

563
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
564
565
get_Block_cfgpred (ir_node *node, int pos) {
  assert (node->op == op_Block);
566
  /* debug @@@
567
568
569
570
  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);
571
    } */
572
  assert(node); assert(-1 <= pos && pos < get_irn_arity(node));
Christian Schäfer's avatar
Christian Schäfer committed
573
574
575
  return get_irn_n(node, pos);
}

576
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
577
578
579
580
581
set_Block_cfgpred (ir_node *node, int pos, ir_node *pred) {
  assert (node->op == op_Block);
  set_irn_n(node, pos, pred);
}

582
INLINE bool
Christian Schäfer's avatar
Christian Schäfer committed
583
584
585
586
587
get_Block_matured (ir_node *node) {
  assert (node->op == op_Block);
  return node->attr.block.matured;
}

588
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
589
590
591
592
set_Block_matured (ir_node *node, bool matured) {
  assert (node->op == op_Block);
  node->attr.block.matured = matured;
}
593
INLINE unsigned long
594
get_Block_block_visited (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
595
  assert (node->op == op_Block);
596
  return node->attr.block.block_visited;
Christian Schäfer's avatar
Christian Schäfer committed
597
598
}

599
INLINE void
600
set_Block_block_visited (ir_node *node, unsigned long visit) {
Christian Schäfer's avatar
Christian Schäfer committed
601
  assert (node->op == op_Block);
602
  node->attr.block.block_visited = visit;
Christian Schäfer's avatar
Christian Schäfer committed
603
604
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
605
/* For this current_ir_graph must be set. */
606
607
INLINE void
mark_Block_block_visited (ir_node *node) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
608
609
610
611
  assert (node->op == op_Block);
  node->attr.block.block_visited = get_irg_block_visited(current_ir_graph);
}

612
613
INLINE int
Block_not_block_visited(ir_node *node) {
614
615
616
  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
617

618
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
619
620
621
622
623
get_Block_graph_arr (ir_node *node, int pos) {
  assert (node->op == op_Block);
  return node->attr.block.graph_arr[pos+1];
}

624
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
625
626
627
628
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;
}
629

630
/* handler handling for Blocks * /
631
632
void
set_Block_handler (ir_node *block, ir_node *handler)  {
633
634
635
636
637
  assert ((block->op == op_Block));
  assert ((handler->op == op_Block));
  block->attr.block.handler_entry = handler;
}

638
639
ir_node *
get_Block_handler (ir_node *block) {
640
641
642
643
  assert ((block->op == op_Block));
  return (block->attr.block.handler_entry);
}

644
/ * handler handling for Nodes * /
645
646
void
set_Node_handler (ir_node *node, ir_node *handler) {
647
648
649
  set_Block_handler (get_nodes_Block (node), handler);
}

650
651
ir_node *
get_Node_handler (ir_node *node) {
652
653
654
  return (get_Block_handler (get_nodes_Block (node)));
}

655
/ * exc_t handling for Blocks * /
656
void set_Block_exc (ir_node *block, exc_t exc) {
657
  assert ((block->op == op_Block));
658
659
660
  block->attr.block.exc = exc;
}

661
exc_t get_Block_exc (ir_node *block) {
662
  assert ((block->op == op_Block));
663
664
665
  return (block->attr.block.exc);
}

666
/ * exc_t handling for Nodes * /
667
void set_Node_exc (ir_node *node, exc_t exc) {
668
669
670
  set_Block_exc (get_nodes_Block (node), exc);
}

671
exc_t get_Node_exc (ir_node *node) {
672
673
  return (get_Block_exc (get_nodes_Block (node)));
}
674
*/
675

676
677
678
679
680
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;
681
    node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
682
683
684
685
686
687
688
689
    {
      /* 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;
    }
690
691
692
693
694
  }
  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
695
696
697
  assert(node->op == op_Block &&
	 node->attr.block.in_cg &&
	 0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
698
699
700
701
702
703
704
705
706
  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) {
707
708
  assert(node->op == op_Block);
  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
709
710
}

711
712
713
714
715
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];
}

716
717
718
719
720
void remove_Block_cg_cfgpred_arr(ir_node * node) {
  assert(node->op == op_Block);
  node->attr.block.in_cg = NULL;
}

721
722
723
/* Start references the irg it is in. */
INLINE ir_graph *
get_Start_irg(ir_node *node) {
724
  return get_irn_irg(node);
725
726
727
728
729
730
}

INLINE void
set_Start_irg(ir_node *node, ir_graph *irg) {
  assert(node->op == op_Start);
  assert(is_ir_graph(irg));
731
732
  assert(0 && " Why set irg? ");
  //node->attr.start.irg = irg;
733
734
}

735
INLINE int
736
737
738
739
740
get_End_n_keepalives(ir_node *end) {
  assert (end->op == op_End);
  return (get_irn_arity(end) - END_KEEPALIVE_OFFSET);
}

741
INLINE ir_node *
742
743
744
745
746
get_End_keepalive(ir_node *end, int pos) {
  assert (end->op == op_End);
  return get_irn_n(end, pos + END_KEEPALIVE_OFFSET);
}

747
INLINE void
748
749
750
751
752
add_End_keepalive (ir_node *end, ir_node *ka) {
  assert (end->op == op_End);
  ARR_APP1 (ir_node *, end->in, ka);
}

753
INLINE void
754
755
756
757
758
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);
}

759
INLINE void
760
free_End (ir_node *end) {
761
  assert (end->op == op_End);
762
  end->kind = k_BAD;
763
  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
764
765
766
767
  end->in = NULL;   /* @@@ make sure we get an error if we use the
		       in array afterwards ... */
}

768
769
ir_graph *get_EndReg_irg (ir_node *end) {
  return get_irn_irg(end);
770
771
}

772
773
ir_graph *get_EndExcept_irg  (ir_node *end) {
  return get_irn_irg(end);
774
775
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
776
777
778
779
780
781
782
783
784
/*
> 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
785
 - determining the biggest case constant to know the proj number for
Götz Lindenmaier's avatar
Götz Lindenmaier committed
786
787
788
789
790
791
792
793
794
795
796
797
   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.,
798
libFIRM can implement a routine that transforms between the two
Götz Lindenmaier's avatar
Götz Lindenmaier committed
799
800
801
802
803
804
805
806
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).
*/
807
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
808
809
810
811
812
get_Cond_selector (ir_node *node) {
  assert (node->op == op_Cond);
  return get_irn_n(node, 0);
}

813
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
814
815
816
817
818
set_Cond_selector (ir_node *node, ir_node *selector) {
  assert (node->op == op_Cond);
  set_irn_n(node, 0, selector);
}

819
INLINE cond_kind
820
821
get_Cond_kind (ir_node *node) {
  assert (node->op == op_Cond);
822
  return node->attr.c.kind;
823
824
}

825
INLINE void
826
827
set_Cond_kind (ir_node *node, cond_kind kind) {
  assert (node->op == op_Cond);
828
  node->attr.c.kind = kind;
829
830
}

831
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
832
get_Return_mem (ir_node *node) {
833
  assert (node->op == op_Return);
Christian Schäfer's avatar
Christian Schäfer committed
834
835
836
  return get_irn_n(node, 0);
}

837
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
838
839
840
841
842
set_Return_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Return);
  set_irn_n(node, 0, mem);
}

843
INLINE int
844
get_Return_n_ress (ir_node *node) {
845
846
847
848
849
  assert (node->op == op_Return);
  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
}

INLINE ir_node **
850
851
852
get_Return_res_arr (ir_node *node)
{
  assert ((node->op == op_Return));
853
  if (get_Return_n_ress(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
854
    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
855
856
  else
    return NULL;
857
858
}

Christian Schäfer's avatar
Christian Schäfer committed
859
/*
860
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
861
862
863
864
865
set_Return_n_res (ir_node *node, int results) {
  assert (node->op == op_Return);
}
*/

866
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
867
868
get_Return_res (ir_node *node, int pos) {
  assert (node->op == op_Return);
869
  assert (get_Return_n_ress(node) > pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
870
  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
871
872
}

873
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
874
set_Return_res (ir_node *node, int pos, ir_node *res){
875
  assert (node->op == op_Return);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
876
  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
Christian Schäfer's avatar
Christian Schäfer committed
877
878
}

879
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
880
get_Raise_mem (ir_node *node) {
Till Riedel's avatar
Till Riedel committed
881
  assert (node->op == op_Raise);
Christian Schäfer's avatar
Christian Schäfer committed
882
883
884
  return get_irn_n(node, 0);
}

885
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
886
887
888
889
890
set_Raise_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Raise);
  set_irn_n(node, 0, mem);
}

891
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
892
893
894
895
896
get_Raise_exo_ptr (ir_node *node) {
  assert (node->op == op_Raise);
  return get_irn_n(node, 1);
}

897
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
898
899
900
901
902
set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
  assert (node->op == op_Raise);
  set_irn_n(node, 1, exo_ptr);
}

903
INLINE tarval *get_Const_tarval (ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
904
  assert (node->op == op_Const);
905
  return node->attr.con.tv;
Christian Schäfer's avatar
Christian Schäfer committed
906
907
}

908
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
909
910
set_Const_tarval (ir_node *node, tarval *con) {
  assert (node->op == op_Const);
911
  node->attr.con.tv = con;
Christian Schäfer's avatar
Christian Schäfer committed
912
913
}

914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939

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


940
INLINE symconst_kind
941
get_SymConst_kind (const ir_node *node) {
Christian Schäfer's avatar
Christian Schäfer committed
942
943
944
945
  assert (node->op == op_SymConst);
  return node->attr.i.num;
}

946
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
947
948
949
950
951
set_SymConst_kind (ir_node *node, symconst_kind num) {
  assert (node->op == op_SymConst);
  node->attr.i.num = num;
}

952
INLINE type *
Christian Schäfer's avatar
Christian Schäfer committed
953
954
955
956
get_SymConst_type (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
957
  return node->attr.i.tori.typ = skip_tid(node->attr.i.tori.typ);
Christian Schäfer's avatar
Christian Schäfer committed
958
959
}

960
INLINE void
961
set_SymConst_type (ir_node *node, type *tp) {
Christian Schäfer's avatar
Christian Schäfer committed
962
963
964
  assert (   (node->op == op_SymConst)
          && (   get_SymConst_kind(node) == type_tag
              || get_SymConst_kind(node) == size));
965
  node->attr.i.tori.typ = tp;
Christian Schäfer's avatar
Christian Schäfer committed
966
967
}

968
INLINE ident *
Christian Schäfer's avatar
Christian Schäfer committed
969
970
971
972
973
974
get_SymConst_ptrinfo (ir_node *node) {
  assert (   (node->op == op_SymConst)
          && (get_SymConst_kind(node) == linkage_ptr_info));
  return node->attr.i.tori.ptrinfo;
}

975
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
976
977
978
979
980
981
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;
}

982
INLINE type_or_id_p
Götz Lindenmaier's avatar
Götz Lindenmaier committed
983
984
985
986
987
get_SymConst_type_or_id (ir_node *node) {
  assert (node->op == op_SymConst);
  return &(node->attr.i.tori);
}

988
INLINE void
Götz Lindenmaier's avatar
Götz Lindenmaier committed
989
990
991
992
993
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));
}

994
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
995
996
997
998
999
get_Sel_mem (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 0);
}

1000
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1001
1002
1003
1004
1005
set_Sel_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Sel);
  set_irn_n(node, 0, mem);
}

1006
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1007
1008
1009
1010
1011
get_Sel_ptr (ir_node *node) {
  assert (node->op == op_Sel);
  return get_irn_n(node, 1);
}

1012
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1013
1014
1015
1016
1017
set_Sel_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Sel);
  set_irn_n(node, 1, ptr);
}

1018
INLINE int
1019
get_Sel_n_indexs (ir_node *node) {
1020
1021
1022
1023
1024
  assert (node->op == op_Sel);
  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
}

INLINE ir_node **
1025
1026
1027
get_Sel_index_arr (ir_node *node)
{
  assert ((node->op == op_Sel));
1028
  if (get_Sel_n_indexs(node) > 0)
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1029
    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1030
1031
  else
    return NULL;
1032
1033
}

1034
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1035
1036
get_Sel_index (ir_node *node, int pos) {
  assert (node->op == op_Sel);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1037
  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
Christian Schäfer's avatar
Christian Schäfer committed
1038
1039
}

1040
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1041
1042
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
1043
  set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
Christian Schäfer's avatar
Christian Schäfer committed
1044
1045
}

1046
INLINE entity *
Christian Schäfer's avatar
Christian Schäfer committed
1047
1048
1049
1050
1051
get_Sel_entity (ir_node *node) {
  assert (node->op == op_Sel);
  return node->attr.s.ent;
}

1052
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1053
1054
1055
1056
1057
set_Sel_entity (ir_node *node, entity *ent) {
  assert (node->op == op_Sel);
  node->attr.s.ent = ent;
}

1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
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);
}

1094
1095
1096
1097

/* 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
1098
   unops are: Minus, Abs, Not, Conv, Cast
1099
1100
1101
1102
1103
   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
1104
1105
1106
1107
1108
get_Call_mem (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 0);
}

1109
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1110
1111
1112
1113
1114
set_Call_mem (ir_node *node, ir_node *mem) {
  assert (node->op == op_Call);
  set_irn_n(node, 0, mem);
}

1115
INLINE ir_node *
Christian Schäfer's avatar
Christian Schäfer committed
1116
1117
1118
1119
1120
get_Call_ptr (ir_node *node) {
  assert (node->op == op_Call);
  return get_irn_n(node, 1);
}

1121
INLINE void
Christian Schäfer's avatar
Christian Schäfer committed
1122
1123
1124
1125
1126
set_Call_ptr (ir_node *node, ir_node *ptr) {
  assert (node->op == op_Call);
  set_irn_n(node, 1, ptr);
}

1127
INLINE ir_node **
1128
1129
get_Call_param_arr (ir_node *node) {
  assert (node->op == op_Call);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1130
  return (ir_node **)&get_irn_in(node)[CALL_PARAM_OFFSET + 1];