irop.c 17.4 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

Matthias Braun's avatar
Matthias Braun committed
6
7
8
9
/**
 * @file
 * @brief   Representation of opcode of intermediate operation.
 * @author  Christian Schaefer, Goetz Lindenmaier, Michael Beck
Götz Lindenmaier's avatar
Götz Lindenmaier committed
10
 */
11
#include <string.h>
12

Matthias Braun's avatar
Matthias Braun committed
13
#include "panic.h"
14
#include "cgana.h"
Michael Beck's avatar
Michael Beck committed
15
16
17
#include "irop_t.h"
#include "irnode_t.h"
#include "irhooks.h"
18
#include "irbackedge_t.h"
19

20
#include "iropt_t.h"
21
#include "irverify_t.h"
Michael Beck's avatar
Michael Beck committed
22
#include "reassoc_t.h"
Florian Liekweg's avatar
Florian Liekweg committed
23

Michael Beck's avatar
Michael Beck committed
24
#include "xmalloc.h"
Matthias Braun's avatar
Matthias Braun committed
25
#include "benode.h"
26
#include "irnode_t.h"
Christian Schäfer's avatar
Christian Schäfer committed
27

Matthias Braun's avatar
Matthias Braun committed
28
static ir_op **opcodes;
Michael Beck's avatar
Michael Beck committed
29
/** the available next opcode */
30
static unsigned next_iro = iro_last+1;
Michael Beck's avatar
Michael Beck committed
31

32
33
34
35
36
static ir_type *default_get_type_attr(const ir_node *node);
static ir_entity *default_get_entity_attr(const ir_node *node);
static unsigned default_hash_node(const ir_node *node);
static void default_copy_attr(ir_graph *irg, const ir_node *old_node,
                              ir_node *new_node);
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
int attrs_equal_false(const ir_node *a, const ir_node *b)
{
	(void)a;
	(void)b;
	return false;
}

static int attrs_equal_true(const ir_node *a, const ir_node *b)
{
	(void)a;
	(void)b;
	return true;
}

52
ir_op *new_ir_op(unsigned code, const char *name, op_pin_state p,
53
54
                 irop_flags flags, op_arity opar, int op_index,
                 size_t attr_size)
Christian Schäfer's avatar
Christian Schäfer committed
55
{
56
	ir_op *res = XMALLOCZ(ir_op);
57
58
59

	res->code      = code;
	res->name      = new_id_from_chars(name, strlen(name));
60
	res->pin_state = p;
61
62
63
64
	res->attr_size = attr_size;
	res->flags     = flags;
	res->opar      = opar;
	res->op_index  = op_index;
Matthias Braun's avatar
Matthias Braun committed
65
	res->tag       = 0;
66

67
68
69
	memset(&res->ops, 0, sizeof(res->ops));
	res->ops.hash            = default_hash_node;
	res->ops.copy_attr       = default_copy_attr;
70
	res->ops.attrs_equal     = attrs_equal_true;
71
72
	res->ops.get_type_attr   = default_get_type_attr;
	res->ops.get_entity_attr = default_get_entity_attr;
73

Matthias Braun's avatar
Matthias Braun committed
74
75
76
77
	size_t len = ARR_LEN(opcodes);
	if ((size_t)code >= len) {
		ARR_RESIZE(ir_op*, opcodes, (size_t)code+1);
		memset(&opcodes[len], 0, (code-len+1) * sizeof(opcodes[0]));
Matthias Braun's avatar
Matthias Braun committed
78
	}
Matthias Braun's avatar
Matthias Braun committed
79
80
81
	if (opcodes[code] != NULL)
		panic("opcode registered twice");
	opcodes[code] = res;
82
83
84

	hook_new_ir_op(res);
	return res;
85
}
Christian Schäfer's avatar
Christian Schäfer committed
86

87
88
void free_ir_op(ir_op *code)
{
89
	hook_free_ir_op(code);
90

Matthias Braun's avatar
Matthias Braun committed
91
92
93
	assert(opcodes[code->code] == code);
	opcodes[code->code] = NULL;

94
	free(code);
95
}
Christian Schäfer's avatar
Christian Schäfer committed
96

Matthias Braun's avatar
Matthias Braun committed
97
98
99
100
101
102
103
104
105
106
107
108
109
unsigned ir_get_n_opcodes(void)
{
	return ARR_LEN(opcodes);
}

ir_op *ir_get_opcode(unsigned code)
{
	assert((size_t)code < ARR_LEN(opcodes));
	return opcodes[code];
}

void ir_clear_opcodes_generic_func(void)
{
Matthias Braun's avatar
Matthias Braun committed
110
	for (size_t i = 0, n = ir_get_n_opcodes(); i < n; ++i) {
Matthias Braun's avatar
Matthias Braun committed
111
		ir_op *op = ir_get_opcode(i);
112
113
114
115
116
		if (op == NULL)
			continue;
		op->ops.generic  = (op_func)NULL;
		op->ops.generic1 = (op_func)NULL;
		op->ops.generic2 = (op_func)NULL;
Matthias Braun's avatar
Matthias Braun committed
117
118
119
	}
}

120
void ir_op_set_memory_index(ir_op *op, int memory_index)
Matthias Braun's avatar
Matthias Braun committed
121
{
122
123
124
125
126
127
128
	assert(op->flags & irop_flag_uses_memory);
	op->memory_index = memory_index;
}

void ir_op_set_fragile_indices(ir_op *op, int pn_x_regular, int pn_x_except)
{
	assert(op->flags & irop_flag_fragile);
Matthias Braun's avatar
Matthias Braun committed
129
130
131
132
	op->pn_x_regular = pn_x_regular;
	op->pn_x_except = pn_x_except;
}

133
134
const char *get_op_name (const ir_op *op)
{
135
	return get_id_str(op->name);
136
}
Christian Schäfer's avatar
Christian Schäfer committed
137

138
139
unsigned (get_op_code)(const ir_op *op)
{
140
  return get_op_code_(op);
141
}
Christian Schäfer's avatar
Christian Schäfer committed
142

143
144
ident *(get_op_ident)(const ir_op *op)
{
145
  return get_op_ident_(op);
146
}
Christian Schäfer's avatar
Christian Schäfer committed
147

148
149
const char *get_op_pin_state_name(op_pin_state s)
{
150
	switch (s) {
Sebastian Hack's avatar
Sebastian Hack committed
151
#define XXX(s) case s: return #s
152
153
154
	XXX(op_pin_state_floats);
	XXX(op_pin_state_pinned);
	XXX(op_pin_state_exc_pinned);
Sebastian Hack's avatar
Sebastian Hack committed
155
#undef XXX
156
157
	}
	return "<none>";
158
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
159

160
161
op_pin_state (get_op_pinned)(const ir_op *op)
{
162
	return get_op_pinned_(op);
163
}
164

165
166
unsigned get_next_ir_opcode(void)
{
167
	return next_iro++;
168
}
169

170
171
unsigned get_next_ir_opcodes(unsigned num)
{
172
173
174
	unsigned base = next_iro;
	next_iro += num;
	return base;
175
}
176

177
178
op_func (get_generic_function_ptr)(const ir_op *op)
{
179
	return get_generic_function_ptr_(op);
180
}
181

182
183
void (set_generic_function_ptr)(ir_op *op, op_func func)
{
184
	set_generic_function_ptr_(op, func);
185
}
Michael Beck's avatar
Michael Beck committed
186

187
188
irop_flags get_op_flags(const ir_op *op)
{
189
	return (irop_flags)op->flags;
190
}
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
static ir_type *default_get_type_attr(const ir_node *node)
{
	(void)node;
	return get_unknown_type();
}

static ir_entity *default_get_entity_attr(const ir_node *node)
{
	(void)node;
	return NULL;
}

static unsigned default_hash_node(const ir_node *node)
{
	/* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
Matthias Braun's avatar
Matthias Braun committed
207
208
	int      arity = get_irn_arity(node);
	unsigned hash  = (unsigned)arity;
209
210

	/* consider all in nodes... except the block if not a control flow. */
Matthias Braun's avatar
Matthias Braun committed
211
	for (int i = is_cfop(node) ? -1 : 0;  i < arity;  ++i) {
212
213
		ir_node *pred = get_irn_n(node, i);
		if (is_irn_cse_neutral(pred))
Matthias Braun's avatar
Matthias Braun committed
214
			hash *= 9;
215
		else
Matthias Braun's avatar
Matthias Braun committed
216
			hash = 9*hash + hash_ptr(pred);
217
218
219
	}

	/* ...mode,... */
Matthias Braun's avatar
Matthias Braun committed
220
	hash = 9*hash + hash_ptr(get_irn_mode(node));
221
	/* ...and code */
Matthias Braun's avatar
Matthias Braun committed
222
	hash = 9*hash + hash_ptr(get_irn_op(node));
223

Matthias Braun's avatar
Matthias Braun committed
224
	return hash;
225
226
227
228
229
230
231
232
}

/**
 * Calculate a hash value of a Const node.
 */
static unsigned hash_Const(const ir_node *node)
{
	/* special value for const, as they only differ in their tarval. */
Matthias Braun's avatar
Matthias Braun committed
233
234
	unsigned hash = hash_ptr(node->attr.con.tarval);
	return hash;
235
236
237
}

/**
238
 * Calculate a hash value of an Address/Offset node.
239
 */
240
static unsigned hash_entconst(const ir_node *node)
241
{
242
243
244
245
246
	unsigned hash = hash_ptr(node->attr.entc.entity);
	return hash;
}

/**
247
 * Calculate a hash value of an Align/Size node.
248
 */
249
static unsigned hash_typeconst(const ir_node *node)
250
251
{
	unsigned hash = hash_ptr(node->attr.typec.type);
Matthias Braun's avatar
Matthias Braun committed
252
	return hash;
253
254
255
}

/** Compares two exception attributes */
256
static bool except_attrs_equal(const except_attr *a, const except_attr *b)
257
{
258
	return a->pin_state == b->pin_state;
259
260
261
}

/** Compares the attributes of two Const nodes. */
262
static int attrs_equal_Const(const ir_node *a, const ir_node *b)
263
{
264
	return get_Const_tarval(a) == get_Const_tarval(b);
265
266
267
}

/** Compares the attributes of two Proj nodes. */
268
static int attrs_equal_Proj(const ir_node *a, const ir_node *b)
269
{
270
	return a->attr.proj.proj == b->attr.proj.proj;
271
272
273
}

/** Compares the attributes of two Alloc nodes. */
274
static int attrs_equal_Alloc(const ir_node *a, const ir_node *b)
275
276
277
{
	const alloc_attr *pa = &a->attr.alloc;
	const alloc_attr *pb = &b->attr.alloc;
278
	return pa->alignment == pb->alignment;
279
280
}

281
/** Compares the attributes of two Address/Offset nodes. */
282
static int attrs_equal_entconst(const ir_node *a, const ir_node *b)
283
284
285
{
	const entconst_attr *pa = &a->attr.entc;
	const entconst_attr *pb = &b->attr.entc;
286
	return pa->entity == pb->entity;
287
288
}

289
/** Compares the attributes of two Align/Size nodes. */
290
static int attrs_equal_typeconst(const ir_node *a, const ir_node *b)
291
{
292
293
	const typeconst_attr *pa = &a->attr.typec;
	const typeconst_attr *pb = &b->attr.typec;
294
	return pa->type == pb->type;
295
296
297
}

/** Compares the attributes of two Call nodes. */
298
static int attrs_equal_Call(const ir_node *a, const ir_node *b)
299
300
301
{
	const call_attr *pa = &a->attr.call;
	const call_attr *pb = &b->attr.call;
302
	return pa->type == pb->type && except_attrs_equal(&pa->exc, &pb->exc);
303
304
305
}

/** Compares the attributes of two Sel nodes. */
306
static int attrs_equal_Sel(const ir_node *a, const ir_node *b)
307
{
308
309
	const ir_type *a_type = get_Sel_type(a);
	const ir_type *b_type = get_Sel_type(b);
310
	return a_type == b_type;
311
312
}

313
static int attrs_equal_Member(const ir_node *a, const ir_node *b)
314
315
316
{
	const ir_entity *a_ent = get_Member_entity(a);
	const ir_entity *b_ent = get_Member_entity(b);
317
	return a_ent == b_ent;
318
319
320
}

/** Compares the attributes of two Phi nodes. */
321
static int attrs_equal_Phi(const ir_node *a, const ir_node *b)
322
{
323
	(void)b;
324
325
	/* do not CSE Phi-nodes without any inputs when building new graphs */
	if (get_irn_arity(a) == 0 &&
326
327
328
		irg_is_constrained(get_irn_irg(a), IR_GRAPH_CONSTRAINT_CONSTRUCTION))
	    return false;
	return true;
329
330
331
}

/** Compares the attributes of two Load nodes. */
332
static int attrs_equal_Load(const ir_node *a, const ir_node *b)
333
{
334
335
336
337
338
339
	const load_attr *attr_a = &a->attr.load;
	const load_attr *attr_b = &b->attr.load;
	return attr_a->volatility == attr_b->volatility
	    && attr_a->unaligned == attr_b->unaligned
	    && attr_a->mode == attr_b->mode
	    && except_attrs_equal(&attr_a->exc, &attr_b->exc);
340
341
342
}

/** Compares the attributes of two Store nodes. */
343
static int attrs_equal_Store(const ir_node *a, const ir_node *b)
344
{
345
346
347
348
349
	const store_attr *attr_a = &a->attr.store;
	const store_attr *attr_b = &b->attr.store;
	return attr_a->unaligned == attr_b->unaligned
	    && attr_a->volatility == attr_b->volatility
	    && except_attrs_equal(&attr_a->exc, &attr_b->exc);
350
351
}

352
static int attrs_equal_CopyB(const ir_node *a, const ir_node *b)
353
{
354
355
356
357
	const copyb_attr *attr_a = &a->attr.copyb;
	const copyb_attr *attr_b = &b->attr.copyb;
	return attr_a->type == attr_b->type
	    && attr_a->volatility == attr_b->volatility;
358
359
360
}

/** Compares the attributes of two Div nodes. */
361
static int attrs_equal_Div(const ir_node *a, const ir_node *b)
362
{
363
364
365
366
367
	const div_attr *attr_a = &a->attr.div;
	const div_attr *attr_b = &b->attr.div;
	return attr_a->resmode == attr_b->resmode
	    && attr_a->no_remainder == attr_b->no_remainder
	    && except_attrs_equal(&attr_a->exc, &attr_b->exc);
368
369
370
}

/** Compares the attributes of two Mod nodes. */
371
static int attrs_equal_Mod(const ir_node *a, const ir_node *b)
372
{
373
374
375
376
	const mod_attr *attr_a = &a->attr.mod;
	const mod_attr *attr_b = &b->attr.mod;
	return attr_a->resmode == attr_b->resmode
	    && except_attrs_equal(&attr_a->exc, &attr_b->exc);
377
378
}

379
static int attrs_equal_Cmp(const ir_node *a, const ir_node *b)
380
{
381
382
383
	const cmp_attr *attr_a = &a->attr.cmp;
	const cmp_attr *attr_b = &b->attr.cmp;
	return attr_a->relation == attr_b->relation;
384
385
386
}

/** Compares the attributes of two Confirm nodes. */
387
static int attrs_equal_Confirm(const ir_node *a, const ir_node *b)
388
{
389
390
391
	const confirm_attr *attr_a = &a->attr.confirm;
	const confirm_attr *attr_b = &b->attr.confirm;
	return attr_a->relation == attr_b->relation;
392
393
394
}

/** Compares the attributes of two Builtin nodes. */
395
static int attrs_equal_Builtin(const ir_node *a, const ir_node *b)
396
{
397
398
399
400
	const builtin_attr *attr_a = &a->attr.builtin;
	const builtin_attr *attr_b = &b->attr.builtin;
	return attr_a->kind == attr_b->kind && attr_a->type == attr_b->type
	    && except_attrs_equal(&attr_a->exc, &attr_b->exc);
401
402
403
}

/** Compares the attributes of two ASM nodes. */
404
static int attrs_equal_ASM(const ir_node *a, const ir_node *b)
405
{
406
407
408
409
	const asm_attr *attr_a = &a->attr.assem;
	const asm_attr *attr_b = &b->attr.assem;
	if (attr_a->text != attr_b->text)
		return false;
410

411
412
	int n_inputs = get_ASM_n_inputs(a);
	if (n_inputs != get_ASM_n_inputs(b))
413
		return false;
414

415
416
417
418
419
420
	const ir_asm_constraint *in_a = get_ASM_input_constraints(a);
	const ir_asm_constraint *in_b = get_ASM_input_constraints(b);
	for (int i = 0; i < n_inputs; ++i) {
		if (in_a[i].pos != in_b[i].pos
		    || in_a[i].constraint != in_b[i].constraint
		    || in_a[i].mode != in_b[i].mode)
421
			return false;
422
423
	}

424
425
	size_t n_outputs = get_ASM_n_output_constraints(a);
	if (n_outputs != get_ASM_n_output_constraints(b))
426
		return false;
427

428
429
430
431
432
433
	const ir_asm_constraint *out_a = get_ASM_output_constraints(a);
	const ir_asm_constraint *out_b = get_ASM_output_constraints(b);
	for (size_t i = 0; i < n_outputs; ++i) {
		if (out_a[i].pos != out_b[i].pos
		    || out_a[i].constraint != out_b[i].constraint
		    || out_a[i].mode != out_b[i].mode)
434
			return false;
435
436
	}

437
438
	size_t n_clobbers = get_ASM_n_clobbers(a);
	if (n_clobbers != get_ASM_n_clobbers(b))
439
		return false;
440

441
442
443
	ident **cla = get_ASM_clobbers(a);
	ident **clb = get_ASM_clobbers(b);
	for (size_t i = 0; i < n_clobbers; ++i) {
444
		if (cla[i] != clb[i])
445
			return false;
446
447
	}

448
	return except_attrs_equal(&attr_a->exc, &attr_b->exc);
449
450
451
452
453
454
455
}

static void default_copy_attr(ir_graph *irg, const ir_node *old_node,
                              ir_node *new_node)
{
	(void) irg;
	assert(get_irn_op(old_node) == get_irn_op(new_node));
Matthias Braun's avatar
Matthias Braun committed
456
457
	size_t size = get_op_attr_size(get_irn_op(old_node));
	memcpy(&new_node->attr, &old_node->attr, size);
458
459
460
461
462
463
464
465
466
}

/**
 * Copies all Call attributes stored in the old node to the new node.
 */
static void call_copy_attr(ir_graph *irg, const ir_node *old_node,
                           ir_node *new_node)
{
	default_copy_attr(irg, old_node, new_node);
467
	cg_remove_call_callee_arr(new_node);
468
469
470
471
472
473
474
475
476
477
478
}

/**
 * Copies all Block attributes stored in the old node to the new node.
 */
static void block_copy_attr(ir_graph *irg, const ir_node *old_node,
                            ir_node *new_node)
{
	default_copy_attr(irg, old_node, new_node);
	new_node->attr.block.irg.irg       = irg;
	new_node->attr.block.phis          = NULL;
479
	new_node->attr.block.backedge      = new_backedge_arr(get_irg_obstack(irg), get_irn_arity(new_node));
480
481
482
	new_node->attr.block.block_visited = 0;
	memset(&new_node->attr.block.dom, 0, sizeof(new_node->attr.block.dom));
	memset(&new_node->attr.block.pdom, 0, sizeof(new_node->attr.block.pdom));
Matthias Braun's avatar
Matthias Braun committed
483
484
485
486
	/* It should be safe to copy the entity here, as it has no back-link to the
	 * old block. It serves just as a label number, so copying a labeled block
	 * results in an exact copy. This is at least what we need for DCE to work.
	 */
487
488
489
490
491
492
493
494
495
496
497
498
	new_node->attr.block.entity         = old_node->attr.block.entity;
	new_node->attr.block.phis           = NULL;
}

/**
 * Copies all phi attributes stored in old node to the new node
 */
static void phi_copy_attr(ir_graph *irg, const ir_node *old_node,
                          ir_node *new_node)
{
	default_copy_attr(irg, old_node, new_node);
	new_node->attr.phi.next       = NULL;
499
	new_node->attr.phi.u.backedge = new_backedge_arr(get_irg_obstack(irg), get_irn_arity(new_node));
500
501
502
503
504
505
506
507
508
}

/**
 * Copies all ASM attributes stored in old node to the new node
 */
static void ASM_copy_attr(ir_graph *irg, const ir_node *old_node,
                          ir_node *new_node)
{
	default_copy_attr(irg, old_node, new_node);
509
510
511
512
	struct obstack *const obst = get_irg_obstack(irg);
	new_node->attr.assem.input_constraints  = DUP_ARR_D(ir_asm_constraint, obst, old_node->attr.assem.input_constraints);
	new_node->attr.assem.output_constraints = DUP_ARR_D(ir_asm_constraint, obst, old_node->attr.assem.output_constraints);
	new_node->attr.assem.clobbers           = DUP_ARR_D(ident*,            obst, old_node->attr.assem.clobbers);
513
514
515
516
517
518
519
520
521
522
}

static void switch_copy_attr(ir_graph *irg, const ir_node *old_node,
                             ir_node *new_node)
{
	const ir_switch_table *table = get_Switch_table(old_node);
	new_node->attr.switcha.table = ir_switch_table_duplicate(irg, table);
	new_node->attr.switcha.n_outs = old_node->attr.switcha.n_outs;
}

523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
void set_op_hash(ir_op *op, hash_func func)
{
	op->ops.hash = func;
}

void set_op_computed_value(ir_op *op, computed_value_func func)
{
	op->ops.computed_value = func;
}

void set_op_computed_value_proj(ir_op *op, computed_value_func func)
{
	op->ops.computed_value_Proj = func;
}

void set_op_equivalent_node(ir_op *op, equivalent_node_func func)
{
	op->ops.equivalent_node = func;
}

void set_op_equivalent_node_proj(ir_op *op, equivalent_node_func func)
{
	op->ops.equivalent_node_Proj = func;
}

void set_op_transform_node(ir_op *op, transform_node_func func)
{
	op->ops.transform_node = func;
}

void set_op_transform_node_proj(ir_op *op, transform_node_func func)
{
	op->ops.transform_node_Proj = func;
}

558
void set_op_attrs_equal(ir_op *op, node_attrs_equal_func func)
559
{
560
	op->ops.attrs_equal = func;
561
562
}

563
void set_op_reassociate(ir_op *op, reassociate_func func)
564
{
565
	op->ops.reassociate = func;
566
567
}

568
void set_op_copy_attr(ir_op *op, copy_attr_func func)
569
570
571
572
{
	op->ops.copy_attr = func;
}

573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
void set_op_get_type_attr(ir_op *op, get_type_attr_func func)
{
	op->ops.get_type_attr = func;
}

void set_op_get_entity_attr(ir_op *op, get_entity_attr_func func)
{
	op->ops.get_entity_attr = func;
}

void set_op_verify(ir_op *op, verify_node_func func)
{
	op->ops.verify_node = func;
}

void set_op_verify_proj(ir_op *op, verify_proj_node_func func)
{
	op->ops.verify_proj_node = func;
}

void set_op_dump(ir_op *op, dump_node_func func)
{
	op->ops.dump_node = func;
}

Matthias Braun's avatar
Matthias Braun committed
598
599
600
void firm_init_op(void)
{
	opcodes = NEW_ARR_F(ir_op*, 0);
601
	ir_init_opcodes();
Matthias Braun's avatar
Matthias Braun committed
602
	be_init_op();
603

604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
	set_op_attrs_equal(op_ASM,     attrs_equal_ASM);
	set_op_attrs_equal(op_Address, attrs_equal_entconst);
	set_op_attrs_equal(op_Align,   attrs_equal_typeconst);
	set_op_attrs_equal(op_Alloc,   attrs_equal_Alloc);
	set_op_attrs_equal(op_Builtin, attrs_equal_Builtin);
	set_op_attrs_equal(op_Call,    attrs_equal_Call);
	set_op_attrs_equal(op_Cmp,     attrs_equal_Cmp);
	set_op_attrs_equal(op_Confirm, attrs_equal_Confirm);
	set_op_attrs_equal(op_Const,   attrs_equal_Const);
	set_op_attrs_equal(op_CopyB,   attrs_equal_CopyB);
	set_op_attrs_equal(op_Div,     attrs_equal_Div);
	set_op_attrs_equal(op_Dummy,   attrs_equal_false);
	set_op_attrs_equal(op_Load,    attrs_equal_Load);
	set_op_attrs_equal(op_Member,  attrs_equal_Member);
	set_op_attrs_equal(op_Mod,     attrs_equal_Mod);
	set_op_attrs_equal(op_Offset,  attrs_equal_entconst);
	set_op_attrs_equal(op_Phi,     attrs_equal_Phi);
	set_op_attrs_equal(op_Proj,    attrs_equal_Proj);
	set_op_attrs_equal(op_Sel,     attrs_equal_Sel);
	set_op_attrs_equal(op_Size,    attrs_equal_typeconst);
	set_op_attrs_equal(op_Store,   attrs_equal_Store);
	set_op_attrs_equal(op_Unknown, attrs_equal_false);
626
627
628
629
630
631

	set_op_hash(op_Address, hash_entconst);
	set_op_hash(op_Align,   hash_typeconst);
	set_op_hash(op_Const,   hash_Const);
	set_op_hash(op_Offset,  hash_entconst);
	set_op_hash(op_Size,    hash_typeconst);
632
633
634
635
636
637

	set_op_copy_attr(op_Call,   call_copy_attr);
	set_op_copy_attr(op_Block,  block_copy_attr);
	set_op_copy_attr(op_Phi,    phi_copy_attr);
	set_op_copy_attr(op_ASM,    ASM_copy_attr);
	set_op_copy_attr(op_Switch, switch_copy_attr);
638
639
640
641

	ir_register_opt_node_ops();
	ir_register_reassoc_node_ops();
	ir_register_verify_node_ops();
642
	ir_register_getter_ops();
Matthias Braun's avatar
Matthias Braun committed
643
644
645
646
647
}

void firm_finish_op(void)
{
	be_finish_op();
648
	ir_finish_opcodes();
Matthias Braun's avatar
Matthias Braun committed
649
650
651
	DEL_ARR_F(opcodes);
	opcodes = NULL;
}