2 * Copyright (C) 2010 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief Dump MinIR format for register coalescing
23 * @author Matthias Braun
31 #include "iredges_t.h"
34 #include "bedump_minir.h"
36 typedef enum yaml_state_t {
44 static const arch_env_t *arch_env;
47 static bool had_list_item;
48 static bool had_dict_item;
49 static bool no_newline;
50 static unsigned state_pos;
51 static yaml_state_t state_stack[1024];
52 static yaml_state_t state;
54 static void init_yaml(FILE *new_out)
59 state = STATE_BLOCK_MAPPING;
62 static void exit_yaml(void)
65 assert(state_pos == 0);
69 static void push_state(yaml_state_t new_state)
71 assert(state_pos < sizeof(state_stack)/sizeof(yaml_state_t));
72 state_stack[state_pos++] = state;
76 static void pop_state(void)
78 assert(state_pos > 0);
79 state = state_stack[--state_pos];
82 static void newline(void)
92 for (i = 0; i < indent; ++i) {
97 static void list_item(void);
98 static void mapping_item(const char *name);
100 static void start(const char *name)
104 } else if (state == STATE_LIST || state == STATE_BLOCK_SEQUENCE) {
108 assert(state == STATE_EXPECT_VALUE);
112 static void begin_block_sequence(const char *name)
115 push_state(STATE_BLOCK_SEQUENCE);
118 static void end_block_sequence(const char *name)
121 assert(state == STATE_BLOCK_SEQUENCE);
125 static void begin_block_mapping(const char *name)
129 push_state(STATE_BLOCK_MAPPING);
135 static void end_block_mapping(const char *name)
139 assert(state == STATE_BLOCK_MAPPING);
143 static void mapping_item(const char *name)
145 if (state == STATE_BLOCK_MAPPING) {
148 assert(state == STATE_MAPPING);
151 had_dict_item = true;
153 fprintf(out, "%s: ", name);
154 push_state(STATE_EXPECT_VALUE);
157 static void list_item(void)
159 if (state == STATE_BLOCK_SEQUENCE) {
163 assert(state == STATE_LIST);
166 had_list_item = true;
168 push_state(STATE_EXPECT_VALUE);
171 static void value(const char *val)
173 if (state == STATE_BLOCK_SEQUENCE
174 || state == STATE_LIST) {
178 assert(state == STATE_EXPECT_VALUE);
183 static void key_value(const char *name, const char *val)
189 static void begin_list(const char *name)
193 had_list_item = false;
194 push_state(STATE_LIST);
197 static void end_list(const char *name)
201 assert(state == STATE_LIST);
205 static void begin_mapping(const char *name)
209 had_dict_item = false;
210 push_state(STATE_MAPPING);
213 static void end_mapping(const char *name)
217 assert(state == STATE_MAPPING);
221 static void print_regclasses(void)
223 int n_classes = arch_env_get_n_reg_class(arch_env);
226 begin_block_sequence("regclasses");
227 for (c = 0; c < n_classes; ++c) {
230 const arch_register_class_t *cls = arch_env_get_reg_class(arch_env, c);
231 if (arch_register_class_flags(cls) & arch_register_class_flag_manual_ra)
234 n_regs = arch_register_class_n_regs(cls);
236 begin_block_mapping(NULL);
238 key_value("name", cls->name);
239 begin_list("registers");
240 for (r = 0; r < n_regs; ++r) {
241 const arch_register_t *reg = arch_register_for_index(cls, r);
244 end_list("registers");
246 begin_block_mapping("flags");
247 for (r = 0; r < n_regs; ++r) {
248 const arch_register_t *reg = arch_register_for_index(cls, r);
249 unsigned type = reg->type;
250 if (type & arch_register_type_ignore) {
251 begin_list(reg->name);
253 value("nossa"); /* do we need this? */
257 end_block_mapping("flags");
259 end_block_mapping(NULL);
261 end_block_sequence("regclasses");
264 static void print_value_name(ir_node *node)
267 const arch_register_req_t *req = arch_get_register_req_out(node);
268 snprintf(name, sizeof(name), "V%ld.%s", get_irn_node_nr(node),
274 static void print_node(ir_node *node)
276 ir_op *op = get_irn_op(node);
283 value(get_op_name(op));
285 mapping_item("defs");
287 if (get_irn_mode(node) == mode_T) {
288 const ir_edge_t *edge;
289 foreach_out_edge(node, edge) {
290 ir_node *proj = get_edge_src_irn(edge);
291 const arch_register_req_t *req = arch_get_register_req_out(proj);
293 if (req->cls == NULL || (req->type & arch_register_req_type_ignore))
297 print_value_name(proj);
300 const arch_register_req_t *req = arch_get_register_req_out(node);
301 if (req->cls != NULL && !(req->type & arch_register_req_type_ignore)) {
303 print_value_name(node);
308 mapping_item("uses");
310 arity = get_irn_arity(node);
311 for (i = 0; i < arity; ++i) {
312 const arch_register_req_t *req = arch_get_register_req(node, i);
313 ir_node *op = get_irn_n(node, i);
315 if (req->cls == NULL || (req->type & arch_register_req_type_ignore))
319 print_value_name(op);
326 static void dump_block(ir_node *block, void *data)
328 ir_graph *irg = get_irn_irg(block);
332 begin_block_mapping(NULL);
334 if (block == get_irg_start_block(irg)) {
335 key_value("label", "start");
336 } else if (block == get_irg_end_block(irg)) {
337 key_value("label", "end");
340 snprintf(name, sizeof(name), "BB%ld", get_irn_node_nr(block));
341 key_value("label", name);
344 begin_block_sequence("ops");
346 sched_foreach(block, node) {
350 end_block_sequence("ops");
352 end_block_mapping(NULL);
355 static void print_function(ir_graph *irg)
357 ir_entity *entity = get_irg_entity(irg);
359 begin_block_mapping(NULL);
361 key_value("label", get_entity_name(entity));
362 begin_list("entries"); value("start"); end_list("entries");
363 begin_list("exit"); value("end"); end_list("exit");
365 begin_block_sequence("bbs");
366 irg_block_walk_graph(irg, dump_block, NULL, NULL);
367 end_block_sequence("bbs");
369 end_block_mapping(NULL);
372 void be_export_minir(FILE *out, ir_graph *irg)
374 arch_env = be_get_irg_arch_env(irg);
379 begin_block_sequence("functions");
381 end_block_sequence("functions");