From 9c47bb543ad91bdfe94f5ad6cf63f49d901bdebe Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Fri, 30 Apr 2010 16:29:48 +0000 Subject: [PATCH] minir_dumping should do something usefull now [r27461] --- NEWS | 2 +- ir/be/bechordal_main.c | 3 +- ir/be/bedump_minir.c | 280 +++++++++++++++++++++++++++++++---------- ir/be/bedump_minir.h | 31 +++++ 4 files changed, 249 insertions(+), 67 deletions(-) create mode 100644 ir/be/bedump_minir.h diff --git a/NEWS b/NEWS index 77820e5c2..510923182 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ ====== libFirm 1.18.0 (2010-??) ====== * Includes "Preference Guided Register Assignment" algorithm * Experimental Value Range Propagation -* Experimental Loop Inversion and Loop Unrolling code +* Loop Inversion and experimental Loop Unrolling code * Simplified construction interface. Most node constructors don't need graph/block arguments anymore. * Reworked type interface. Type names are optional now. Support for additional linkage types that among others support C++ 'linkonce' semantics now. * Small changes in constructors and node getters/setters (mostly adding 'const' to some getters) diff --git a/ir/be/bechordal_main.c b/ir/be/bechordal_main.c index c5a6e0e7d..6461dd5e1 100644 --- a/ir/be/bechordal_main.c +++ b/ir/be/bechordal_main.c @@ -71,6 +71,7 @@ #include "be_t.h" #include "bera.h" #include "beirg.h" +#include "bedump_minir.h" #include "bespillslots.h" #include "bespill.h" @@ -341,8 +342,6 @@ static void post_spill(post_spill_env_t *pse, int iteration) be_timer_push(T_RA_COPYMIN); if (minir_file[0] != '\0') { - extern void be_export_minir(const arch_env_t *arch_env, FILE *out, - ir_graph *irg); FILE *out; if (strcmp(minir_file, "-") == 0) { diff --git a/ir/be/bedump_minir.c b/ir/be/bedump_minir.c index d5eb65b09..b6ef2359d 100644 --- a/ir/be/bedump_minir.c +++ b/ir/be/bedump_minir.c @@ -28,14 +28,56 @@ #include #include "irgwalk.h" +#include "iredges_t.h" #include "bearch.h" +#include "besched.h" +#include "bedump_minir.h" + +typedef enum yaml_state_t { + STATE_BLOCK_MAPPING, + STATE_BLOCK_SEQUENCE, + STATE_LIST, + STATE_MAPPING, + STATE_EXPECT_VALUE +} yaml_state_t; static const arch_env_t *arch_env; static FILE *out; static int indent; -static int item_indent_add; static bool had_list_item; +static bool had_dict_item; static bool no_newline; +static unsigned state_pos; +static yaml_state_t state_stack[1024]; +static yaml_state_t state; + +static void init_yaml(FILE *new_out) +{ + out = new_out; + indent = 0; + state_pos = 0; + state = STATE_BLOCK_MAPPING; +} + +static void exit_yaml(void) +{ + assert(indent == 0); + assert(state_pos == 0); + fputs("\n", out); +} + +static void push_state(yaml_state_t new_state) +{ + assert(state_pos < sizeof(state_stack)/sizeof(yaml_state_t)); + state_stack[state_pos++] = state; + state = new_state; +} + +static void pop_state(void) +{ + assert(state_pos > 0); + state = state_stack[--state_pos]; +} static void newline(void) { @@ -47,94 +89,133 @@ static void newline(void) } fputc('\n', out); - for (i = 0; i < indent + item_indent_add; ++i) { + for (i = 0; i < indent; ++i) { fputs(" ", out); } } -static void begin_key(const char *name) -{ - newline(); - fprintf(out, "%s: ", name); -} +static void list_item(void); +static void mapping_item(const char *name); -static void end_key(const char *name) +static void start(const char *name) { - /* TODO verify */ - (void) name; + if (name != NULL) { + mapping_item(name); + } else if (state == STATE_LIST || state == STATE_BLOCK_SEQUENCE) { + list_item(); + } + + assert(state == STATE_EXPECT_VALUE); + pop_state(); } static void begin_block_sequence(const char *name) { - begin_key(name); - indent++; + start(name); + push_state(STATE_BLOCK_SEQUENCE); } static void end_block_sequence(const char *name) { - end_key(name); - indent--; - item_indent_add = 0; + (void) name; + assert(state == STATE_BLOCK_SEQUENCE); + pop_state(); } -static void block_sequence_item(void) +static void begin_block_mapping(const char *name) { - item_indent_add = 0; - newline(); - fputs("- ", out); - item_indent_add = 1; - no_newline = true; + start(name); + ++indent; + push_state(STATE_BLOCK_MAPPING); + if (name == NULL) { + no_newline = true; + } } -static void begin_mapping(const char *name) +static void end_block_mapping(const char *name) { - begin_key(name); - indent++; + (void) name; + --indent; + assert(state == STATE_BLOCK_MAPPING); + pop_state(); } -static void end_maping(const char *name) +static void mapping_item(const char *name) { - end_key(name); - indent--; + if (state == STATE_BLOCK_MAPPING) { + newline(); + } else { + assert(state == STATE_MAPPING); + if (had_dict_item) + fputs(", ", out); + had_dict_item = true; + } + fprintf(out, "%s: ", name); + push_state(STATE_EXPECT_VALUE); +} + +static void list_item(void) +{ + if (state == STATE_BLOCK_SEQUENCE) { + newline(); + fputs("- ", out); + } else { + assert(state == STATE_LIST); + if (had_list_item) + fputs(", ", out); + had_list_item = true; + } + push_state(STATE_EXPECT_VALUE); } static void value(const char *val) { + if (state == STATE_BLOCK_SEQUENCE + || state == STATE_LIST) { + list_item(); + } + + assert(state == STATE_EXPECT_VALUE); + pop_state(); fputs(val, out); } static void key_value(const char *name, const char *val) { - begin_key(name); + mapping_item(name); value(val); - end_key(name); } static void begin_list(const char *name) { - begin_key(name); + start(name); fputs("[", out); had_list_item = false; + push_state(STATE_LIST); } static void end_list(const char *name) { - /* TODO: verify that we started a list */ fputs("]", out); - end_key(name); + (void) name; + assert(state == STATE_LIST); + pop_state(); } -static void list_item(void) +static void begin_mapping(const char *name) { - if (had_list_item) - fputs(", ", out); - had_list_item = true; + start(name); + fputs("{", out); + had_dict_item = false; + push_state(STATE_MAPPING); } -static void list_item_value(const char *val) +static void end_mapping(const char *name) { - list_item(); - value(val); + fputs("}", out); + (void) name; + assert(state == STATE_MAPPING); + pop_state(); } static void print_regclasses(void) @@ -152,73 +233,146 @@ static void print_regclasses(void) n_regs = arch_register_class_n_regs(cls); - block_sequence_item(); + begin_block_mapping(NULL); key_value("name", cls->name); begin_list("registers"); for (r = 0; r < n_regs; ++r) { const arch_register_t *reg = arch_register_for_index(cls, r); - list_item_value(reg->name); + value(reg->name); } end_list("registers"); - begin_mapping("flags"); - for (r = 0; r < n_regs; ++r) { - const arch_register_t *reg = arch_register_for_index(cls, r); - unsigned type = reg->type; - if (type & arch_register_type_ignore) { - begin_list(reg->name); - list_item_value("reserved"); - list_item_value("nossa"); /* do we need this? */ - end_list(reg->name); - } + begin_block_mapping("flags"); + for (r = 0; r < n_regs; ++r) { + const arch_register_t *reg = arch_register_for_index(cls, r); + unsigned type = reg->type; + if (type & arch_register_type_ignore) { + begin_list(reg->name); + value("reserved"); + value("nossa"); /* do we need this? */ + end_list(reg->name); } - end_maping("flags"); + } + end_block_mapping("flags"); + + end_block_mapping(NULL); } end_block_sequence("regclasses"); } +static void print_value_name(ir_node *node) +{ + char name[128]; + const arch_register_req_t *req = arch_get_register_req_out(node); + snprintf(name, sizeof(name), "V%ld.%s", get_irn_node_nr(node), + req->cls->name); + + value(name); +} + +static void print_node(ir_node *node) +{ + ir_op *op = get_irn_op(node); + int arity; + int i; + + begin_mapping(NULL); + + mapping_item("op"); + value(get_op_name(op)); + + mapping_item("defs"); + begin_list(NULL); + if (get_irn_mode(node) == mode_T) { + const ir_edge_t *edge; + foreach_out_edge(node, edge) { + ir_node *proj = get_edge_src_irn(edge); + const arch_register_req_t *req = arch_get_register_req_out(proj); + + if (req->cls == NULL || (req->type & arch_register_req_type_ignore)) + continue; + + list_item(); + print_value_name(proj); + } + } else { + const arch_register_req_t *req = arch_get_register_req_out(node); + if (req->cls != NULL && !(req->type & arch_register_req_type_ignore)) { + list_item(); + print_value_name(node); + } + } + end_list(NULL); + + mapping_item("uses"); + begin_list(NULL); + arity = get_irn_arity(node); + for (i = 0; i < arity; ++i) { + const arch_register_req_t *req = arch_get_register_req(node, i); + ir_node *op = get_irn_n(node, i); + + if (req->cls == NULL || (req->type & arch_register_req_type_ignore)) + continue; + + list_item(); + print_value_name(op); + } + end_list(NULL); + + end_mapping(NULL); +} + static void dump_block(ir_node *block, void *data) { ir_graph *irg = get_irn_irg(block); + ir_node *node; (void) data; - block_sequence_item(); + begin_block_mapping(NULL); + if (block == get_irg_start_block(irg)) { key_value("label", "start"); } else if (block == get_irg_end_block(irg)) { key_value("label", "end"); } else { char name[128]; - snprintf(name, sizeof(name), "bb%ld", get_irn_node_nr(block)); + snprintf(name, sizeof(name), "BB%ld", get_irn_node_nr(block)); key_value("label", name); } begin_block_sequence("ops"); + + sched_foreach(block, node) { + print_node(node); + } + end_block_sequence("ops"); + + end_block_mapping(NULL); } static void print_function(ir_graph *irg) { ir_entity *entity = get_irg_entity(irg); - block_sequence_item(); + begin_block_mapping(NULL); key_value("label", get_entity_name(entity)); - begin_list("entries"); list_item_value("start"); end_list("entries"); - begin_list("exit"); list_item_value("end"); end_list("entries"); + begin_list("entries"); value("start"); end_list("entries"); + begin_list("exit"); value("end"); end_list("exit"); begin_block_sequence("bbs"); irg_block_walk_graph(irg, dump_block, NULL, NULL); end_block_sequence("bbs"); + + end_block_mapping(NULL); } -void be_export_minir(const arch_env_t *new_arch_env, FILE *new_out, ir_graph *irg) +void be_export_minir(const arch_env_t *new_arch_env, FILE *out, ir_graph *irg) { arch_env = new_arch_env; - out = new_out; - - no_newline = true; + init_yaml(out); print_regclasses(); @@ -226,7 +380,5 @@ void be_export_minir(const arch_env_t *new_arch_env, FILE *new_out, ir_graph *ir print_function(irg); end_block_sequence("functions"); - assert(indent == 0); - fputs("\n", out); - + exit_yaml(); } diff --git a/ir/be/bedump_minir.h b/ir/be/bedump_minir.h new file mode 100644 index 000000000..5e861b57c --- /dev/null +++ b/ir/be/bedump_minir.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/** + * @file + * @brief minir dumper + * @author Matthias Braun + * @version $Id$ + */ +#ifndef FIRM_BE_BEDUMP_MINIR_H +#define FIRM_BE_BEDUMP_MINIR_H + +void be_export_minir(const arch_env_t *arch_env, FILE *out, ir_graph *irg); + +#endif -- 2.20.1