irop.c 17.3 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

	res->code      = code;
59
	res->name      = new_id_from_str(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
	assert(is_op_uses_memory(op));
123
124
125
	op->memory_index = memory_index;
}

126
127
void ir_op_set_fragile_indices(ir_op *op, unsigned pn_x_regular,
                               unsigned pn_x_except)
128
{
129
	assert(is_op_fragile(op));
Matthias Braun's avatar
Matthias Braun committed
130
131
132
133
	op->pn_x_regular = pn_x_regular;
	op->pn_x_except = pn_x_except;
}

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

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

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

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

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

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

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

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

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

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

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
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
208
209
	int      arity = get_irn_arity(node);
	unsigned hash  = (unsigned)arity;
210
211

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

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

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

/**
 * 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
231
232
	unsigned hash = hash_ptr(node->attr.con.tarval);
	return hash;
233
234
235
}

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

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

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

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

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

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

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

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

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

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

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

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

/** Compares the attributes of two Load nodes. */
330
static int attrs_equal_Load(const ir_node *a, const ir_node *b)
331
{
332
333
334
335
336
337
	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);
338
339
340
}

/** Compares the attributes of two Store nodes. */
341
static int attrs_equal_Store(const ir_node *a, const ir_node *b)
342
{
343
344
345
346
347
	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);
348
349
}

350
static int attrs_equal_CopyB(const ir_node *a, const ir_node *b)
351
{
352
353
354
355
	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;
356
357
358
}

/** Compares the attributes of two Div nodes. */
359
static int attrs_equal_Div(const ir_node *a, const ir_node *b)
360
{
361
362
363
364
365
	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);
366
367
368
}

/** Compares the attributes of two Mod nodes. */
369
static int attrs_equal_Mod(const ir_node *a, const ir_node *b)
370
{
371
372
373
374
	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);
375
376
}

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

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

/** Compares the attributes of two Builtin nodes. */
393
static int attrs_equal_Builtin(const ir_node *a, const ir_node *b)
394
{
395
396
397
398
	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);
399
400
401
}

/** Compares the attributes of two ASM nodes. */
402
static int attrs_equal_ASM(const ir_node *a, const ir_node *b)
403
{
404
405
406
407
	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;
408

409
410
	int n_inputs = get_ASM_n_inputs(a);
	if (n_inputs != get_ASM_n_inputs(b))
411
		return false;
412

413
414
415
416
417
418
	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)
419
			return false;
420
421
	}

422
423
	size_t n_outputs = get_ASM_n_output_constraints(a);
	if (n_outputs != get_ASM_n_output_constraints(b))
424
		return false;
425

426
427
428
429
430
431
	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)
432
			return false;
433
434
	}

435
436
	size_t n_clobbers = get_ASM_n_clobbers(a);
	if (n_clobbers != get_ASM_n_clobbers(b))
437
		return false;
438

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

446
	return except_attrs_equal(&attr_a->exc, &attr_b->exc);
447
448
449
450
451
}

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

/**
 * 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);
465
	cg_remove_call_callee_arr(new_node);
466
467
468
469
470
471
472
473
474
475
}

/**
 * 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.phis          = NULL;
476
	new_node->attr.block.backedge      = new_backedge_arr(get_irg_obstack(irg), get_irn_arity(new_node));
477
478
479
	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
480
481
482
483
	/* 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.
	 */
484
485
486
487
488
489
490
491
492
493
494
495
	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;
496
	new_node->attr.phi.u.backedge = new_backedge_arr(get_irg_obstack(irg), get_irn_arity(new_node));
497
498
499
500
501
502
503
504
505
}

/**
 * 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);
506
507
508
509
	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);
510
511
512
513
514
515
516
517
518
519
}

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

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
545
546
547
548
549
550
551
552
553
554
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;
}

555
void set_op_attrs_equal(ir_op *op, node_attrs_equal_func func)
556
{
557
	op->ops.attrs_equal = func;
558
559
}

560
void set_op_reassociate(ir_op *op, reassociate_func func)
561
{
562
	op->ops.reassociate = func;
563
564
}

565
void set_op_copy_attr(ir_op *op, copy_attr_func func)
566
567
568
569
{
	op->ops.copy_attr = func;
}

570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
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
595
596
597
void firm_init_op(void)
{
	opcodes = NEW_ARR_F(ir_op*, 0);
598
	ir_init_opcodes();
Matthias Braun's avatar
Matthias Braun committed
599
	be_init_op();
600

601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
	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);
623
624
625
626
627
628

	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);
629
630
631
632
633
634

	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);
635
636
637
638

	ir_register_opt_node_ops();
	ir_register_reassoc_node_ops();
	ir_register_verify_node_ops();
639
	ir_register_getter_ops();
Matthias Braun's avatar
Matthias Braun committed
640
641
642
643
644
}

void firm_finish_op(void)
{
	be_finish_op();
645
	ir_finish_opcodes();
Matthias Braun's avatar
Matthias Braun committed
646
647
648
	DEL_ARR_F(opcodes);
	opcodes = NULL;
}