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->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);
321 insn->ops[i].carrier = copy;
322 sched_add_before(insn->irn, copy);
324 DBG((dbg, LEVEL_2, "adding copy for interfering and constrained op %+F\n", op->carrier));
330 Make the Perm, recompute liveness and re-scan the insn since the
331 in operands are now the Projs of the Perm.
333 perm = insert_Perm_after(aenv, env->cls, env->dom_front, sched_prev(insn->irn));
335 /* Registers are propagated by insert_Perm_after(). Clean them here! */
337 const ir_edge_t *edge;
339 foreach_out_edge(perm, edge) {
340 ir_node *proj = get_edge_src_irn(edge);
341 arch_set_irn_register(aenv, proj, NULL);
345 We also have to re-build the insn since the input operands are now the Projs of
346 the Perm. Recomputing liveness is also a good idea if a Perm is inserted, since
347 the live sets may change.
349 be_liveness(env->irg);
350 obstack_free(&env->obst, insn);
351 *the_insn = insn = chordal_scan_insn(alloc_env, insn->irn);
354 Copy the input constraints of the insn to the Perm as output
355 constraints. Succeeding phases (coalescing will need that).
357 for(i = insn->use_start; i < insn->n_ops; ++i) {
358 be_operand_t *op = &insn->ops[i];
359 ir_node *proj = op->carrier;
361 Note that the predecessor must not be a Proj of the Perm,
362 since ignore-nodes are not Perm'ed.
364 if(op->has_constraints && is_Proj(proj) && get_Proj_pred(proj) == perm) {
365 be_set_constr_limited(perm, BE_OUT_POS(get_Proj_proj(proj)), &op->req);
373 static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *irn, int *silent)
375 be_chordal_env_t *env = alloc_env->chordal_env;
376 void *base = obstack_base(&env->obst);
377 be_insn_t *insn = chordal_scan_insn(alloc_env, irn);
378 ir_node *res = insn->next_insn;
379 int be_silent = *silent;
381 if(insn->pre_colored) {
383 for(i = 0; i < insn->use_start; ++i)
384 pset_insert_ptr(alloc_env->pre_colored, insn->ops[i].carrier);
388 If the current node is a barrier toggle the silent flag.
389 If we are in the start block, we are ought to be silent at the beginning,
390 so the toggling activates the constraint handling but skips the barrier.
391 If we are in the end block we handle the in requirements of the barrier
392 and set the rest to silent.
394 if(be_is_Barrier(irn))
401 Perms inserted before the constraint handling phase are considered to be
402 correctly precolored. These Perms arise during the ABI handling phase.
404 if(insn->has_constraints) {
405 const arch_env_t *aenv = env->birg->main_env->arch_env;
406 int n_regs = env->cls->n_regs;
407 bitset_t *bs = bitset_alloca(n_regs);
408 ir_node **alloc_nodes = alloca(n_regs * sizeof(alloc_nodes[0]));
409 bipartite_t *bp = bipartite_new(n_regs, n_regs);
410 int *assignment = alloca(n_regs * sizeof(assignment[0]));
411 pmap *partners = pmap_create();
412 DEBUG_ONLY(firm_dbg_module_t *dbg = alloc_env->constr_dbg;)
416 const ir_edge_t *edge;
417 ir_node *perm = NULL;
420 prepare the constraint handling of this node.
421 Perms are constructed and Copies are created for constrained values
422 interfering with the instruction.
424 perm = pre_process_constraints(alloc_env, &insn);
426 /* find suitable in operands to the out operands of the node. */
427 pair_up_operands(alloc_env, insn);
430 look at the in/out operands and add each operand (and its possible partner)
431 to a bipartite graph (left: nodes with partners, right: admissible colors).
433 for(i = 0, n_alloc = 0; i < insn->n_ops; ++i) {
434 be_operand_t *op = &insn->ops[i];
437 If the operand has no partner or the partner has not been marked
438 for allocation, determine the admissible registers and mark it
439 for allocation by associating the node and its partner with the
440 set of admissible registers via a bipartite graph.
442 if(!op->partner || !pmap_contains(partners, op->partner->carrier)) {
444 pmap_insert(partners, op->carrier, op->partner ? op->partner->carrier : NULL);
445 alloc_nodes[n_alloc] = op->carrier;
447 DBG((dbg, LEVEL_2, "\tassociating %+F and %+F\n", op->carrier, op->partner ? op->partner->carrier : NULL));
449 bitset_clear_all(bs);
450 get_decisive_partner_regs(bs, op, op->partner);
452 DBG((dbg, LEVEL_2, "\tallowed registers for %+F: %B\n", op->carrier, bs));
454 bitset_foreach(bs, col)
455 bipartite_add(bp, n_alloc, col);
462 Put all nodes which live by the constrained instruction also to the
463 allocation bipartite graph. They are considered unconstrained.
466 foreach_out_edge(perm, edge) {
467 ir_node *proj = get_edge_src_irn(edge);
469 assert(is_Proj(proj));
471 if(values_interfere(proj, irn) && !pmap_contains(partners, proj)) {
472 assert(n_alloc < n_regs);
473 alloc_nodes[n_alloc] = proj;
474 pmap_insert(partners, proj, NULL);
476 bitset_clear_all(bs);
477 arch_put_non_ignore_regs(aenv, env->cls, bs);
478 bitset_foreach(bs, col)
479 bipartite_add(bp, n_alloc, col);
486 /* Compute a valid register allocation. */
487 bipartite_matching(bp, assignment);
489 /* Assign colors obtained from the matching. */
490 for(i = 0; i < n_alloc; ++i) {
491 const arch_register_t *reg;
495 assert(assignment[i] >= 0 && "there must have been a register assigned");
496 reg = arch_register_for_index(env->cls, assignment[i]);
498 nodes[0] = alloc_nodes[i];
499 nodes[1] = pmap_get(partners, alloc_nodes[i]);
501 for(j = 0; j < 2; ++j) {
505 arch_set_irn_register(aenv, nodes[j], reg);
506 pset_hinsert_ptr(alloc_env->pre_colored, nodes[j]);
507 DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", nodes[j], reg->name));
512 /* Allocate the non-constrained Projs of the Perm. */
515 bitset_clear_all(bs);
517 /* Put the colors of all Projs in a bitset. */
518 foreach_out_edge(perm, edge) {
519 ir_node *proj = get_edge_src_irn(edge);
520 const arch_register_t *reg = arch_get_irn_register(aenv, proj);
523 bitset_set(bs, reg->index);
526 /* Assign the not yet assigned Projs of the Perm a suitable color. */
527 foreach_out_edge(perm, edge) {
528 ir_node *proj = get_edge_src_irn(edge);
529 const arch_register_t *reg = arch_get_irn_register(aenv, proj);
531 DBG((dbg, LEVEL_2, "\tchecking reg of %+F: %s\n", proj, reg ? reg->name : "<none>"));
534 col = get_next_free_reg(alloc_env, bs);
535 reg = arch_register_for_index(env->cls, col);
536 bitset_set(bs, reg->index);
537 arch_set_irn_register(aenv, proj, reg);
538 pset_insert_ptr(alloc_env->pre_colored, proj);
539 DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", proj, reg->name));
544 pmap_destroy(partners);
548 obstack_free(&env->obst, base);
553 * Handle constraint nodes in each basic block.
554 * handle_constraints() inserts Perm nodes which perm
555 * over all values live at the constrained node right in front
556 * of the constrained node. These Perms signal a constrained node.
557 * For further comments, refer to handle_constraints().
559 static void constraints(ir_node *bl, void *data)
561 be_chordal_alloc_env_t *env = data;
564 Start silent in the start block.
565 The silence remains until the first barrier is seen.
566 Each other block is begun loud.
568 int silent = bl == get_irg_start_block(get_irn_irg(bl));
572 If the block is the start block search the barrier and
573 start handling constraints from there.
576 for(irn = sched_first(bl); !sched_is_end(irn);) {
577 irn = handle_constraints(env, irn, &silent);
582 * Annotate the register pressure to the nodes and compute
583 * the liveness intervals.
584 * @param block The block to do it for.
585 * @param env_ptr The environment.
587 static void pressure(ir_node *block, void *env_ptr)
589 /* Convenience macro for a def */
590 #define border_def(irn, step, real) \
591 border_add(env, head, irn, step, pressure--, 1, real)
593 /* Convenience macro for a use */
594 #define border_use(irn, step, real) \
595 border_add(env, head, irn, step, ++pressure, 0, real)
597 be_chordal_alloc_env_t *alloc_env = env_ptr;
598 be_chordal_env_t *env = alloc_env->chordal_env;
599 bitset_t *live = alloc_env->live;
601 DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg;)
605 unsigned pressure = 0;
606 struct list_head *head;
607 pset *live_in = put_live_in(block, pset_new_ptr_default());
608 pset *live_end = put_live_end(block, pset_new_ptr_default());
610 DBG((dbg, LEVEL_1, "Computing pressure in block %+F\n", block));
611 bitset_clear_all(live);
613 /* Set up the border list in the block info */
614 head = obstack_alloc(&env->obst, sizeof(*head));
615 INIT_LIST_HEAD(head);
616 assert(pmap_get(env->border_heads, block) == NULL);
617 pmap_insert(env->border_heads, block, head);
620 * Make final uses of all values live out of the block.
621 * They are necessary to build up real intervals.
623 for(irn = pset_first(live_end); irn; irn = pset_next(live_end)) {
624 if(has_reg_class(env, irn)) {
625 DBG((dbg, LEVEL_3, "\tMaking live: %+F/%d\n", irn, get_irn_graph_nr(irn)));
626 bitset_set(live, get_irn_graph_nr(irn));
627 border_use(irn, step, 0);
633 * Determine the last uses of a value inside the block, since they are
634 * relevant for the interval borders.
636 sched_foreach_reverse(block, irn) {
637 DBG((dbg, LEVEL_1, "\tinsn: %+F, pressure: %d\n", irn, pressure));
638 DBG((dbg, LEVEL_2, "\tlive: %b\n", live));
641 * If the node defines some value, which can put into a
642 * register of the current class, make a border for it.
644 if(has_reg_class(env, irn)) {
645 int nr = get_irn_graph_nr(irn);
647 bitset_clear(live, nr);
648 border_def(irn, step, 1);
652 * If the node is no phi node we can examine the uses.
655 for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
656 ir_node *op = get_irn_n(irn, i);
658 if(has_reg_class(env, op)) {
659 int nr = get_irn_graph_nr(op);
661 DBG((dbg, LEVEL_4, "\t\tpos: %d, use: %+F\n", i, op));
663 if(!bitset_is_set(live, nr)) {
664 border_use(op, step, 1);
665 bitset_set(live, nr);
674 * Add initial defs for all values live in.
676 for(irn = pset_first(live_in); irn; irn = pset_next(live_in)) {
677 if(has_reg_class(env, irn)) {
679 /* Mark the value live in. */
680 bitset_set(live, get_irn_graph_nr(irn));
683 border_def(irn, step, 0);
692 static void assign(ir_node *block, void *env_ptr)
694 be_chordal_alloc_env_t *alloc_env = env_ptr;
695 be_chordal_env_t *env = alloc_env->chordal_env;
696 bitset_t *live = alloc_env->live;
697 bitset_t *colors = alloc_env->colors;
698 bitset_t *in_colors = alloc_env->in_colors;
699 const arch_env_t *arch_env = env->birg->main_env->arch_env;
700 DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg;)
704 struct list_head *head = get_block_border_head(env, block);
705 pset *live_in = put_live_in(block, pset_new_ptr_default());
707 bitset_clear_all(colors);
708 bitset_clear_all(live);
709 bitset_clear_all(in_colors);
711 DBG((dbg, LEVEL_4, "Assigning colors for block %+F\n", block));
712 DBG((dbg, LEVEL_4, "\tusedef chain for block\n"));
713 list_for_each_entry(border_t, b, head, list) {
714 DBG((dbg, LEVEL_4, "\t%s %+F/%d\n", b->is_def ? "def" : "use",
715 b->irn, get_irn_graph_nr(b->irn)));
719 * Add initial defs for all values live in.
720 * Since their colors have already been assigned (The dominators were
721 * allocated before), we have to mark their colors as used also.
723 for(irn = pset_first(live_in); irn; irn = pset_next(live_in)) {
724 if(has_reg_class(env, irn)) {
725 const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
728 assert(reg && "Node must have been assigned a register");
729 col = arch_register_get_index(reg);
731 /* Mark the color of the live in value as used. */
732 bitset_set(colors, col);
733 bitset_set(in_colors, col);
735 /* Mark the value live in. */
736 bitset_set(live, get_irn_graph_nr(irn));
741 * Mind that the sequence
742 * of defs from back to front defines a perfect
743 * elimination order. So, coloring the definitions from first to last
746 list_for_each_entry_reverse(border_t, b, head, list) {
747 ir_node *irn = b->irn;
748 int nr = get_irn_graph_nr(irn);
751 * Assign a color, if it is a local def. Global defs already have a
754 if(b->is_def && !is_live_in(block, irn)) {
755 const arch_register_t *reg;
758 if(pset_find_ptr(alloc_env->pre_colored, irn)) {
759 reg = arch_get_irn_register(arch_env, irn);
761 assert(!bitset_is_set(colors, col) && "pre-colored register must be free");
765 col = get_next_free_reg(alloc_env, colors);
766 reg = arch_register_for_index(env->cls, col);
767 assert(arch_get_irn_register(arch_env, irn) == NULL && "This node must not have been assigned a register yet");
768 assert(!arch_register_type_is(reg, ignore) && "Must not assign ignore register");
771 bitset_set(colors, col);
772 arch_set_irn_register(arch_env, irn, reg);
774 DBG((dbg, LEVEL_1, "\tassigning register %s(%d) to %+F\n",
775 arch_register_get_name(reg), col, irn));
777 assert(!bitset_is_set(live, nr) && "Value's definition must not have been encountered");
778 bitset_set(live, nr);
781 /* Clear the color upon a use. */
782 else if(!b->is_def) {
783 const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
786 assert(reg && "Register must have been assigned");
788 col = arch_register_get_index(reg);
789 assert(bitset_is_set(live, nr) && "Cannot have a non live use");
791 bitset_clear(colors, col);
792 bitset_clear(live, nr);
799 void be_ra_chordal_color(be_chordal_env_t *chordal_env)
801 be_chordal_alloc_env_t env;
804 int colors_n = arch_register_class_n_regs(chordal_env->cls);
805 ir_graph *irg = chordal_env->irg;
808 if(get_irg_dom_state(irg) != dom_consistent)
811 env.chordal_env = chordal_env;
812 env.colors_n = colors_n;
813 env.colors = bitset_alloca(colors_n);
814 env.tmp_colors = bitset_alloca(colors_n);
815 env.in_colors = bitset_alloca(colors_n);
816 env.pre_colored = pset_new_ptr_default();
817 FIRM_DBG_REGISTER(env.constr_dbg, "firm.be.chordal.constr");
820 /* Handle register targeting constraints */
821 dom_tree_walk_irg(irg, constraints, NULL, &env);
823 if(chordal_env->opts->dump_flags & BE_CH_DUMP_CONSTR) {
824 snprintf(buf, sizeof(buf), "-%s-constr", chordal_env->cls->name);
825 be_dump(chordal_env->irg, buf, dump_ir_block_graph_sched);
829 env.live = bitset_malloc(get_graph_node_count(chordal_env->irg));
831 /* First, determine the pressure */
832 dom_tree_walk_irg(irg, pressure, NULL, &env);
834 /* Assign the colors */
835 dom_tree_walk_irg(irg, assign, NULL, &env);
837 be_numbering_done(irg);
839 if(chordal_env->opts->dump_flags & BE_CH_DUMP_TREE_INTV) {
841 ir_snprintf(buf, sizeof(buf), "ifg_%s_%F.eps", chordal_env->cls->name, irg);
842 plotter = new_plotter_ps(buf);
843 draw_interval_tree(&draw_chordal_def_opts, chordal_env, plotter);
844 plotter_free(plotter);
847 del_pset(env.pre_colored);