Commit 9c47bb54 authored by Matthias Braun's avatar Matthias Braun
Browse files

minir_dumping should do something usefull now

[r27461]
parent 72fca46d
====== 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)
......
......@@ -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) {
......
......@@ -28,14 +28,56 @@
#include <stdbool.h>
#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();
}
/*
* 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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment