2 * Chordal register allocation.
3 * @author Sebastian Hack
6 * Copyright (C) Universitaet Karlsruhe
7 * Released under the GPL
29 #include "bipartite.h"
32 #include "irgraph_t.h"
33 #include "irprintf_t.h"
43 #include "besched_t.h"
51 #include "bechordal_t.h"
52 #include "bechordal_draw.h"
54 #define DBG_LEVEL SET_LEVEL_0
55 #define DBG_LEVEL_CHECK SET_LEVEL_0
59 #define MAX(x, y) ((x) > (y) ? (x) : (y))
60 #define MIN(x, y) ((x) < (y) ? (x) : (y))
62 #define DUMP_INTERVALS
64 typedef struct _be_chordal_alloc_env_t {
65 be_chordal_env_t *chordal_env;
67 pset *pre_colored; /**< Set of precolored nodes. */
68 bitset_t *live; /**< A liveness bitset. */
69 bitset_t *tmp_colors; /**< An auxiliary bitset which is as long as the number of colors in the class. */
70 bitset_t *colors; /**< The color mask. */
71 bitset_t *in_colors; /**< Colors used by live in values. */
72 int colors_n; /**< The number of colors. */
73 DEBUG_ONLY(firm_dbg_module_t *constr_dbg;) /**< Debug output for the constraint handler. */
74 } be_chordal_alloc_env_t;
78 /* Make a fourcc for border checking. */
79 #define BORDER_FOURCC FOURCC('B', 'O', 'R', 'D')
81 static void check_border_list(struct list_head *head)
84 list_for_each_entry(border_t, x, head, list) {
85 assert(x->magic == BORDER_FOURCC);
89 static void check_heads(be_chordal_env_t *env)
92 for(ent = pmap_first(env->border_heads); ent; ent = pmap_next(env->border_heads)) {
93 /* ir_printf("checking border list of block %+F\n", ent->key); */
94 check_border_list(ent->value);
100 * Add an interval border to the list of a block's list
101 * of interval border.
102 * @note You always have to create the use before the def.
103 * @param env The environment.
104 * @param head The list head to enqueue the borders.
105 * @param irn The node (value) the border belongs to.
106 * @param pressure The pressure at this point in time.
107 * @param step A time step for the border.
108 * @param is_def Is the border a use or a def.
109 * @return The created border.
111 static INLINE border_t *border_add(be_chordal_env_t *env, struct list_head *head,
112 ir_node *irn, unsigned step, unsigned pressure,
113 unsigned is_def, unsigned is_real)
120 b = obstack_alloc(&env->obst, sizeof(*b));
122 /* also allocate the def and tie it to the use. */
123 def = obstack_alloc(&env->obst, sizeof(*def));
124 memset(def, 0, sizeof(*def));
129 * Set the link field of the irn to the def.
130 * This strongly relies on the fact, that the use is always
131 * made before the def.
133 set_irn_link(irn, def);
135 b->magic = BORDER_FOURCC;
136 def->magic = BORDER_FOURCC;
140 * If the def is encountered, the use was made and so was the
141 * the def node (see the code above). It was placed into the
142 * link field of the irn, so we can get it there.
145 b = get_irn_link(irn);
147 assert(b && b->magic == BORDER_FOURCC && "Illegal border encountered");
150 b->pressure = pressure;
152 b->is_real = is_real;
155 list_add_tail(&b->list, head);
156 DBG((env->dbg, LEVEL_5, "\t\t%s adding %+F, step: %d\n", is_def ? "def" : "use", irn, step));
163 * Check, if an irn is of the register class currently under processing.
164 * @param env The chordal environment.
165 * @param irn The node.
166 * @return 1, if the node is of that register class, 0 if not.
168 static INLINE int has_reg_class(const be_chordal_env_t *env, const ir_node *irn)
170 return arch_irn_has_reg_class(env->birg->main_env->arch_env, irn, -1, env->cls);
171 // return arch_irn_consider_in_reg_alloc(env->birg->main_env->arch_env, env->cls, irn);
174 #define has_limited_constr(req, irn) \
175 (arch_get_register_req(arch_env, (req), irn, -1) && (req)->type == arch_register_req_type_limited)
177 static int get_next_free_reg(const be_chordal_alloc_env_t *alloc_env, bitset_t *colors)
179 bitset_t *tmp = alloc_env->tmp_colors;
180 bitset_copy(tmp, colors);
181 bitset_or(tmp, alloc_env->chordal_env->ignore_colors);
182 return bitset_next_clear(tmp, 0);
185 static bitset_t *get_decisive_partner_regs(bitset_t *bs, const be_operand_t *o1, const be_operand_t *o2)
190 bitset_copy(bs, o2->regs);
195 bitset_copy(bs, o1->regs);
199 assert(o1->req.cls == o2->req.cls);
201 if(bitset_contains(o1->regs, o2->regs))
202 bitset_copy(bs, o1->regs);
203 else if(bitset_contains(o2->regs, o1->regs))
204 bitset_copy(bs, o2->regs);
211 static be_insn_t *chordal_scan_insn(be_chordal_alloc_env_t *env, ir_node *irn)
215 ie.ignore_colors = env->chordal_env->ignore_colors;
216 ie.aenv = env->chordal_env->birg->main_env->arch_env;
217 ie.obst = &env->chordal_env->obst;
218 ie.cls = env->chordal_env->cls;
219 return be_scan_insn(&ie, irn);
222 static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, be_insn_t *insn)
224 const be_chordal_env_t *env = alloc_env->chordal_env;
226 int n_uses = be_insn_n_uses(insn);
227 int n_defs = be_insn_n_defs(insn);
228 bitset_t *bs = bitset_alloca(env->cls->n_regs);
229 bipartite_t *bp = bipartite_new(n_defs, n_uses);
230 int *pairing = alloca(MAX(n_defs, n_uses) * sizeof(pairing[0]));
235 For each out operand, try to find an in operand which can be assigned the
236 same register as the out operand.
238 for(j = 0; j < insn->use_start; ++j) {
239 be_operand_t *out_op = &insn->ops[j];
241 /* Try to find an in operand which has ... */
242 for(i = insn->use_start; i < insn->n_ops; ++i) {
243 const be_operand_t *op = &insn->ops[i];
246 The in operand can only be paired with a def, if the node defining the
247 operand's value does not interfere with the instruction itself. That
248 would mean, that it is live at the instruction, so no result of the instruction
249 can have the same register as the operand.
251 Furthermore, tow operands can be paired, if the admissible registers
252 of one are a subset of the other's. We record the operand whose constraints
253 count in the decisive array.
255 if(!values_interfere(op->irn, op->carrier)) {
256 if(get_decisive_partner_regs(bs, out_op, op))
257 bipartite_add(bp, j, i - insn->use_start);
262 /* Compute the pairing. */
263 bipartite_matching(bp, pairing);
264 for(i = 0; i < insn->use_start; ++i) {
265 int p = pairing[i] + insn->use_start;
267 if(p >= insn->use_start) {
268 insn->ops[i].partner = &insn->ops[p];
269 insn->ops[p].partner = &insn->ops[i];
277 static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, be_insn_t **the_insn)
279 be_chordal_env_t *env = alloc_env->chordal_env;
280 const arch_env_t *aenv = env->birg->main_env->arch_env;
281 be_insn_t *insn = *the_insn;
282 ir_node *bl = get_nodes_block(insn->irn);
283 ir_node *copy = NULL;
284 ir_node *perm = NULL;
285 bitset_t *out_constr = bitset_alloca(env->cls->n_regs);
286 bitset_t *bs = bitset_alloca(env->cls->n_regs);
287 DEBUG_ONLY(firm_dbg_module_t *dbg = alloc_env->constr_dbg;)
291 assert(insn->has_constraints && "only do this for constrained nodes");
294 Collect all registers that occur in output constraints.
295 This is necessary, since if the insn has one of these as an input constraint
296 and the corresponding operand interferes with the insn, the operand must
299 for(i = 0; i < insn->use_start; ++i) {
300 be_operand_t *op = &insn->ops[i];
301 if(op->has_constraints)
302 bitset_or(out_constr, op->regs);
306 Now, figure out which input operand must be copied since it has input
307 constraints which are also output constraints.
309 for(i = insn->use_start; i < insn->n_ops; ++i) {
310 be_operand_t *op = &insn->ops[i];
311 if(op->has_constraints && (values_interfere(op->carrier, insn->irn) || arch_irn_is(aenv, op->carrier, ignore))) {
312 bitset_copy(bs, op->regs);
313 bitset_and(bs, out_constr);
316 The operand (interfering with the node) has input constraints
317 which also occur as output constraints, so insert a copy.
319 if(bitset_popcnt(bs) > 0) {
320 copy = be_new_Copy(op->req.cls, env->irg, bl, op->carrier);
322 sched_add_before(insn->irn, copy);
323 set_irn_n(insn->irn, op->pos, op->carrier);
325 DBG((dbg, LEVEL_2, "adding copy for interfering and constrained op %+F\n", op->carrier));
331 Make the Perm, recompute liveness and re-scan the insn since the
332 in operands are now the Projs of the Perm.
334 perm = insert_Perm_after(aenv, env->cls, env->dom_front, sched_prev(insn->irn));
336 /* Registers are propagated by insert_Perm_after(). Clean them here! */
338 const ir_edge_t *edge;
340 foreach_out_edge(perm, edge) {
341 ir_node *proj = get_edge_src_irn(edge);
342 arch_set_irn_register(aenv, proj, NULL);
346 We also have to re-build the insn since the input operands are now the Projs of
347 the Perm. Recomputing liveness is also a good idea if a Perm is inserted, since
348 the live sets may change.
350 be_liveness(env->irg);
351 obstack_free(&env->obst, insn);
352 *the_insn = insn = chordal_scan_insn(alloc_env, insn->irn);
355 Copy the input constraints of the insn to the Perm as output
356 constraints. Succeeding phases (coalescing will need that).
358 for(i = insn->use_start; i < insn->n_ops; ++i) {
359 be_operand_t *op = &insn->ops[i];
360 ir_node *proj = op->carrier;
362 Note that the predecessor must not be a Proj of the Perm,
363 since ignore-nodes are not Perm'ed.
365 if(op->has_constraints && is_Proj(proj) && get_Proj_pred(proj) == perm) {
366 be_set_constr_limited(perm, BE_OUT_POS(get_Proj_proj(proj)), &op->req);
374 static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *irn, int *silent)
376 be_chordal_env_t *env = alloc_env->chordal_env;
377 void *base = obstack_base(&env->obst);
378 be_insn_t *insn = chordal_scan_insn(alloc_env, irn);
379 ir_node *res = insn->next_insn;
380 int be_silent = *silent;
382 if(insn->pre_colored) {
384 for(i = 0; i < insn->use_start; ++i)
385 pset_insert_ptr(alloc_env->pre_colored, insn->ops[i].carrier);
389 If the current node is a barrier toggle the silent flag.
390 If we are in the start block, we are ought to be silent at the beginning,
391 so the toggling activates the constraint handling but skips the barrier.
392 If we are in the end block we handle the in requirements of the barrier
393 and set the rest to silent.
395 if(be_is_Barrier(irn))
402 Perms inserted before the constraint handling phase are considered to be
403 correctly precolored. These Perms arise during the ABI handling phase.
405 if(insn->has_constraints) {
406 const arch_env_t *aenv = env->birg->main_env->arch_env;
407 int n_regs = env->cls->n_regs;
408 bitset_t *bs = bitset_alloca(n_regs);
409 ir_node **alloc_nodes = alloca(n_regs * sizeof(alloc_nodes[0]));
410 bipartite_t *bp = bipartite_new(n_regs, n_regs);
411 int *assignment = alloca(n_regs * sizeof(assignment[0]));
412 pmap *partners = pmap_create();
413 DEBUG_ONLY(firm_dbg_module_t *dbg = alloc_env->constr_dbg;)
417 const ir_edge_t *edge;
418 ir_node *perm = NULL;
421 prepare the constraint handling of this node.
422 Perms are constructed and Copies are created for constrained values
423 interfering with the instruction.
425 perm = pre_process_constraints(alloc_env, &insn);
427 /* find suitable in operands to the out operands of the node. */
428 pair_up_operands(alloc_env, insn);
431 look at the in/out operands and add each operand (and its possible partner)
432 to a bipartite graph (left: nodes with partners, right: admissible colors).
434 for(i = 0, n_alloc = 0; i < insn->n_ops; ++i) {
435 be_operand_t *op = &insn->ops[i];
438 If the operand has no partner or the partner has not been marked
439 for allocation, determine the admissible registers and mark it
440 for allocation by associating the node and its partner with the
441 set of admissible registers via a bipartite graph.
443 if(!op->partner || !pmap_contains(partners, op->partner->carrier)) {
445 pmap_insert(partners, op->carrier, op->partner ? op->partner->carrier : NULL);
446 alloc_nodes[n_alloc] = op->carrier;
448 DBG((dbg, LEVEL_2, "\tassociating %+F and %+F\n", op->carrier, op->partner ? op->partner->carrier : NULL));
450 bitset_clear_all(bs);
451 get_decisive_partner_regs(bs, op, op->partner);
453 DBG((dbg, LEVEL_2, "\tallowed registers for %+F: %B\n", op->carrier, bs));
455 bitset_foreach(bs, col)
456 bipartite_add(bp, n_alloc, col);
463 Put all nodes which live by the constrained instruction also to the
464 allocation bipartite graph. They are considered unconstrained.
467 foreach_out_edge(perm, edge) {
468 ir_node *proj = get_edge_src_irn(edge);
470 assert(is_Proj(proj));
472 if(values_interfere(proj, irn) && !pmap_contains(partners, proj)) {
473 assert(n_alloc < n_regs);
474 alloc_nodes[n_alloc] = proj;
475 pmap_insert(partners, proj, NULL);
477 bitset_clear_all(bs);
478 arch_put_non_ignore_regs(aenv, env->cls, bs);
479 bitset_foreach(bs, col)
480 bipartite_add(bp, n_alloc, col);
487 /* Compute a valid register allocation. */
488 bipartite_matching(bp, assignment);
490 /* Assign colors obtained from the matching. */
491 for(i = 0; i < n_alloc; ++i) {
492 const arch_register_t *reg;
496 assert(assignment[i] >= 0 && "there must have been a register assigned");
497 reg = arch_register_for_index(env->cls, assignment[i]);
499 nodes[0] = alloc_nodes[i];
500 nodes[1] = pmap_get(partners, alloc_nodes[i]);
502 for(j = 0; j < 2; ++j) {
506 arch_set_irn_register(aenv, nodes[j], reg);
507 pset_hinsert_ptr(alloc_env->pre_colored, nodes[j]);
508 DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", nodes[j], reg->name));
513 /* Allocate the non-constrained Projs of the Perm. */
516 bitset_clear_all(bs);
518 /* Put the colors of all Projs in a bitset. */
519 foreach_out_edge(perm, edge) {
520 ir_node *proj = get_edge_src_irn(edge);
521 const arch_register_t *reg = arch_get_irn_register(aenv, proj);
524 bitset_set(bs, reg->index);
527 /* Assign the not yet assigned Projs of the Perm a suitable color. */
528 foreach_out_edge(perm, edge) {
529 ir_node *proj = get_edge_src_irn(edge);
530 const arch_register_t *reg = arch_get_irn_register(aenv, proj);
532 DBG((dbg, LEVEL_2, "\tchecking reg of %+F: %s\n", proj, reg ? reg->name : "<none>"));
535 col = get_next_free_reg(alloc_env, bs);
536 reg = arch_register_for_index(env->cls, col);
537 bitset_set(bs, reg->index);
538 arch_set_irn_register(aenv, proj, reg);
539 pset_insert_ptr(alloc_env->pre_colored, proj);
540 DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", proj, reg->name));
546 pmap_destroy(partners);
550 obstack_free(&env->obst, base);
555 * Handle constraint nodes in each basic block.
556 * handle_constraints() inserts Perm nodes which perm
557 * over all values live at the constrained node right in front
558 * of the constrained node. These Perms signal a constrained node.
559 * For further comments, refer to handle_constraints().
561 static void constraints(ir_node *bl, void *data)
563 be_chordal_alloc_env_t *env = data;
566 Start silent in the start block.
567 The silence remains until the first barrier is seen.
568 Each other block is begun loud.
570 int silent = bl == get_irg_start_block(get_irn_irg(bl));
574 If the block is the start block search the barrier and
575 start handling constraints from there.
578 for(irn = sched_first(bl); !sched_is_end(irn);) {
579 irn = handle_constraints(env, irn, &silent);
584 * Annotate the register pressure to the nodes and compute
585 * the liveness intervals.
586 * @param block The block to do it for.
587 * @param env_ptr The environment.
589 static void pressure(ir_node *block, void *env_ptr)
591 /* Convenience macro for a def */
592 #define border_def(irn, step, real) \
593 border_add(env, head, irn, step, pressure--, 1, real)
595 /* Convenience macro for a use */
596 #define border_use(irn, step, real) \
597 border_add(env, head, irn, step, ++pressure, 0, real)
599 be_chordal_alloc_env_t *alloc_env = env_ptr;
600 be_chordal_env_t *env = alloc_env->chordal_env;
601 bitset_t *live = alloc_env->live;
603 DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg;)
607 unsigned pressure = 0;
608 struct list_head *head;
609 pset *live_in = put_live_in(block, pset_new_ptr_default());
610 pset *live_end = put_live_end(block, pset_new_ptr_default());
612 DBG((dbg, LEVEL_1, "Computing pressure in block %+F\n", block));
613 bitset_clear_all(live);
615 /* Set up the border list in the block info */
616 head = obstack_alloc(&env->obst, sizeof(*head));
617 INIT_LIST_HEAD(head);
618 assert(pmap_get(env->border_heads, block) == NULL);
619 pmap_insert(env->border_heads, block, head);
622 * Make final uses of all values live out of the block.
623 * They are necessary to build up real intervals.
625 foreach_pset(live_end, irn) {
626 if(has_reg_class(env, irn)) {
627 DBG((dbg, LEVEL_3, "\tMaking live: %+F/%d\n", irn, get_irn_idx(irn)));
628 bitset_set(live, get_irn_idx(irn));
629 border_use(irn, step, 0);
635 * Determine the last uses of a value inside the block, since they are
636 * relevant for the interval borders.
638 sched_foreach_reverse(block, irn) {
639 DBG((dbg, LEVEL_1, "\tinsn: %+F, pressure: %d\n", irn, pressure));
640 DBG((dbg, LEVEL_2, "\tlive: %B\n", live));
643 * If the node defines some value, which can put into a
644 * register of the current class, make a border for it.
646 if(has_reg_class(env, irn)) {
647 int nr = get_irn_idx(irn);
649 bitset_clear(live, nr);
650 border_def(irn, step, 1);
654 * If the node is no phi node we can examine the uses.
657 for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
658 ir_node *op = get_irn_n(irn, i);
660 if(has_reg_class(env, op)) {
661 int nr = get_irn_idx(op);
662 const char *msg = "-";
664 if(!bitset_is_set(live, nr)) {
665 border_use(op, step, 1);
666 bitset_set(live, nr);
670 DBG((dbg, LEVEL_4, "\t\t%s pos: %d, use: %+F\n", msg, i, op));
678 * Add initial defs for all values live in.
680 foreach_pset(live_in, irn) {
681 if(has_reg_class(env, irn)) {
683 /* Mark the value live in. */
684 bitset_set(live, get_irn_idx(irn));
687 border_def(irn, step, 0);
695 static void assign(ir_node *block, void *env_ptr)
697 be_chordal_alloc_env_t *alloc_env = env_ptr;
698 be_chordal_env_t *env = alloc_env->chordal_env;
699 bitset_t *live = alloc_env->live;
700 bitset_t *colors = alloc_env->colors;
701 bitset_t *in_colors = alloc_env->in_colors;
702 const arch_env_t *arch_env = env->birg->main_env->arch_env;
703 struct list_head *head = get_block_border_head(env, block);
704 pset *live_in = put_live_in(block, pset_new_ptr_default());
708 DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg;)
710 bitset_clear_all(colors);
711 bitset_clear_all(live);
712 bitset_clear_all(in_colors);
714 DBG((dbg, LEVEL_4, "Assigning colors for block %+F\n", block));
715 DBG((dbg, LEVEL_4, "\tusedef chain for block\n"));
716 list_for_each_entry(border_t, b, head, list) {
717 DBG((dbg, LEVEL_4, "\t%s %+F/%d\n", b->is_def ? "def" : "use",
718 b->irn, get_irn_idx(b->irn)));
722 * Add initial defs for all values live in.
723 * Since their colors have already been assigned (The dominators were
724 * allocated before), we have to mark their colors as used also.
726 foreach_pset(live_in, irn) {
727 if(has_reg_class(env, irn)) {
728 const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
731 assert(reg && "Node must have been assigned a register");
732 col = arch_register_get_index(reg);
734 DBG((dbg, LEVEL_4, "%+F has reg %s\n", irn, reg->name));
736 /* Mark the color of the live in value as used. */
737 bitset_set(colors, col);
738 bitset_set(in_colors, col);
740 /* Mark the value live in. */
741 bitset_set(live, get_irn_idx(irn));
746 * Mind that the sequence
747 * of defs from back to front defines a perfect
748 * elimination order. So, coloring the definitions from first to last
751 list_for_each_entry_reverse(border_t, b, head, list) {
752 ir_node *irn = b->irn;
753 int nr = get_irn_idx(irn);
754 int ignore = arch_irn_is(arch_env, irn, ignore);
757 * Assign a color, if it is a local def. Global defs already have a
760 if(b->is_def && !is_live_in(block, irn)) {
761 const arch_register_t *reg;
764 if(pset_find_ptr(alloc_env->pre_colored, irn) || ignore) {
765 reg = arch_get_irn_register(arch_env, irn);
767 assert(!bitset_is_set(colors, col) && "pre-colored register must be free");
771 col = get_next_free_reg(alloc_env, colors);
772 reg = arch_register_for_index(env->cls, col);
773 assert(arch_get_irn_register(arch_env, irn) == NULL && "This node must not have been assigned a register yet");
774 assert(!arch_register_type_is(reg, ignore) && "Must not assign ignore register");
777 bitset_set(colors, col);
778 arch_set_irn_register(arch_env, irn, reg);
780 DBG((dbg, LEVEL_1, "\tassigning register %s(%d) to %+F\n", arch_register_get_name(reg), col, irn));
782 assert(!bitset_is_set(live, nr) && "Value's definition must not have been encountered");
783 bitset_set(live, nr);
786 /* Clear the color upon a use. */
787 else if(!b->is_def) {
788 const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
791 assert(reg && "Register must have been assigned");
793 col = arch_register_get_index(reg);
794 assert(bitset_is_set(live, nr) && "Cannot have a non live use");
796 bitset_clear(colors, col);
797 bitset_clear(live, nr);
804 void be_ra_chordal_color(be_chordal_env_t *chordal_env)
806 be_chordal_alloc_env_t env;
809 int colors_n = arch_register_class_n_regs(chordal_env->cls);
810 ir_graph *irg = chordal_env->irg;
815 env.chordal_env = chordal_env;
816 env.colors_n = colors_n;
817 env.colors = bitset_alloca(colors_n);
818 env.tmp_colors = bitset_alloca(colors_n);
819 env.in_colors = bitset_alloca(colors_n);
820 env.pre_colored = pset_new_ptr_default();
821 FIRM_DBG_REGISTER(env.constr_dbg, "firm.be.chordal.constr");
824 /* Handle register targeting constraints */
825 dom_tree_walk_irg(irg, constraints, NULL, &env);
827 if(chordal_env->opts->dump_flags & BE_CH_DUMP_CONSTR) {
828 snprintf(buf, sizeof(buf), "-%s-constr", chordal_env->cls->name);
829 be_dump(chordal_env->irg, buf, dump_ir_block_graph_sched);
833 env.live = bitset_malloc(get_irg_last_idx(chordal_env->irg));
835 /* First, determine the pressure */
836 dom_tree_walk_irg(irg, pressure, NULL, &env);
838 /* Assign the colors */
839 dom_tree_walk_irg(irg, assign, NULL, &env);
841 be_numbering_done(irg);
843 if(chordal_env->opts->dump_flags & BE_CH_DUMP_TREE_INTV) {
845 ir_snprintf(buf, sizeof(buf), "ifg_%s_%F.eps", chordal_env->cls->name, irg);
846 plotter = new_plotter_ps(buf);
847 draw_interval_tree(&draw_chordal_def_opts, chordal_env, plotter);
848 plotter_free(plotter);
851 bitset_free(env.live);
852 del_pset(env.pre_colored);