Commit 79adebd5 authored by Matthias Braun's avatar Matthias Braun
Browse files

be: introduce verboseasm flag (enabled by default)

Also factor out code that emits the label and comment at the beginning
of a basic block.
parent 381cf8f2
......@@ -214,9 +214,7 @@ static void TEMPLATE_emit_block(ir_node *block)
{
ir_node *node;
be_gas_emit_block_name(block);
be_emit_cstring(":\n");
be_emit_write_line();
be_gas_begin_block(block, true);
sched_foreach(block, node) {
TEMPLATE_emit_node(node);
......
......@@ -201,9 +201,11 @@ static void emit_amd64_Jmp(const ir_node *node)
be_emit_cstring("\tjmp ");
amd64_emit_cfop_target(node);
} else {
be_emit_cstring("\t/* fallthrough to ");
amd64_emit_cfop_target(node);
be_emit_cstring(" */");
if (be_options.verbose_asm) {
be_emit_cstring("\t/* fallthrough to ");
amd64_emit_cfop_target(node);
be_emit_cstring(" */");
}
}
be_emit_finish_line_gas(node);
}
......@@ -276,10 +278,12 @@ static void emit_amd64_Jcc(const ir_node *irn)
be_emit_finish_line_gas(proj_true);
if (get_cfop_target_block(proj_false) == next_block) {
be_emit_cstring("\t/* fallthrough to ");
amd64_emit_cfop_target(proj_false);
be_emit_cstring(" */");
be_emit_finish_line_gas(proj_false);
if (be_options.verbose_asm) {
be_emit_cstring("\t/* fallthrough to ");
amd64_emit_cfop_target(proj_false);
be_emit_cstring(" */");
be_emit_finish_line_gas(proj_false);
}
} else {
be_emit_cstring("\tjmp ");
amd64_emit_cfop_target(proj_false);
......@@ -536,10 +540,7 @@ static void amd64_gen_block(ir_node *block, void *data)
if (! is_Block(block))
return;
be_gas_emit_block_name(block);
be_emit_char(':');
be_emit_write_line();
be_gas_begin_block(block, false);
sched_foreach(block, node) {
amd64_emit_node(node);
......
......@@ -410,10 +410,12 @@ static void emit_arm_B(const ir_node *irn)
be_emit_finish_line_gas(proj_true);
if (get_cfop_target_block(proj_false) == next_block) {
be_emit_cstring("\t/* fallthrough to ");
arm_emit_cfop_target(proj_false);
be_emit_cstring(" */");
be_emit_finish_line_gas(proj_false);
if (be_options.verbose_asm) {
be_emit_cstring("\t/* fallthrough to ");
arm_emit_cfop_target(proj_false);
be_emit_cstring(" */");
be_emit_finish_line_gas(proj_false);
}
} else {
be_emit_cstring("\tb ");
arm_emit_cfop_target(proj_false);
......@@ -459,20 +461,22 @@ static void emit_arm_CopyB(const ir_node *irn)
t2 = arch_register_get_name(tmpregs[2]);
t3 = arch_register_get_name(tmpregs[3]);
be_emit_cstring("/* MemCopy (");
be_emit_string(src);
be_emit_cstring(")->(");
arm_emit_source_register(irn, 0);
be_emit_irprintf(" [%u bytes], Uses ", size);
be_emit_string(t0);
be_emit_cstring(", ");
be_emit_string(t1);
be_emit_cstring(", ");
be_emit_string(t2);
be_emit_cstring(", and ");
be_emit_string(t3);
be_emit_cstring("*/");
be_emit_finish_line_gas(NULL);
if (be_options.verbose_asm) {
be_emit_cstring("/* MemCopy (");
be_emit_string(src);
be_emit_cstring(")->(");
arm_emit_source_register(irn, 0);
be_emit_irprintf(" [%u bytes], Uses ", size);
be_emit_string(t0);
be_emit_cstring(", ");
be_emit_string(t1);
be_emit_cstring(", ");
be_emit_string(t2);
be_emit_cstring(", and ");
be_emit_string(t3);
be_emit_cstring("*/");
be_emit_finish_line_gas(NULL);
}
assert(size > 0 && "CopyB needs size > 0" );
......@@ -759,12 +763,15 @@ static void emit_arm_Jmp(const ir_node *node)
if (get_cfop_target_block(node) != next_block) {
be_emit_cstring("\tb ");
arm_emit_cfop_target(node);
be_emit_finish_line_gas(node);
} else {
be_emit_cstring("\t/* fallthrough to ");
arm_emit_cfop_target(node);
be_emit_cstring(" */");
if (be_options.verbose_asm) {
be_emit_cstring("\t/* fallthrough to ");
arm_emit_cfop_target(node);
be_emit_cstring(" */");
be_emit_finish_line_gas(node);
}
}
be_emit_finish_line_gas(node);
}
static void emit_nothing(const ir_node *irn)
......@@ -840,13 +847,9 @@ static void arm_emit_node(const ir_node *irn)
*/
static void arm_emit_block_header(ir_node *block, ir_node *prev)
{
int n_cfgpreds;
int need_label;
int i, arity;
ir_graph *irg = get_irn_irg(block);
ir_exec_freq *exec_freq = be_get_irg_exec_freq(irg);
bool need_label = false;
int n_cfgpreds;
need_label = 0;
n_cfgpreds = get_Block_n_cfgpreds(block);
if (n_cfgpreds == 1) {
ir_node *pred = get_Block_cfgpred(block, 0);
......@@ -856,38 +859,15 @@ static void arm_emit_block_header(ir_node *block, ir_node *prev)
* are no fallthroughs */
if (pred_block == prev &&
!(is_Proj(pred) && is_arm_SwitchJmp(get_Proj_pred(pred)))) {
need_label = 0;
need_label = false;
} else {
need_label = 1;
need_label = true;
}
} else {
need_label = 1;
need_label = true;
}
if (need_label) {
be_gas_emit_block_name(block);
be_emit_char(':');
be_emit_pad_comment();
be_emit_cstring(" /* preds:");
/* emit list of pred blocks in comment */
arity = get_irn_arity(block);
for (i = 0; i < arity; ++i) {
ir_node *predblock = get_Block_cfgpred_block(block, i);
be_emit_irprintf(" %d", get_irn_node_nr(predblock));
}
} else {
be_emit_cstring("\t/* ");
be_gas_emit_block_name(block);
be_emit_cstring(": ");
}
if (exec_freq != NULL) {
be_emit_irprintf(" freq: %f",
get_block_execfreq(exec_freq, block));
}
be_emit_cstring(" */\n");
be_emit_write_line();
be_gas_begin_block(block, need_label);
}
/**
......
......@@ -70,6 +70,7 @@ struct be_options_t {
char ilp_solver[128]; /**< the ilp solver name */
int statev; /**< enable stat event dumping */
char filtev[128]; /**< filter mask for stat events */
int verbose_asm; /**< dump verbose assembler */
};
extern be_options_t be_options;
......
......@@ -26,6 +26,7 @@
#include "config.h"
#include "beemitter.h"
#include "be_t.h"
#include "irnode_t.h"
#include "irprintf.h"
#include "ident.h"
......@@ -80,10 +81,10 @@ void be_emit_pad_comment(void)
void be_emit_finish_line_gas(const ir_node *node)
{
dbg_info *dbg;
src_loc_t loc;
dbg_info *dbg;
src_loc_t loc;
if (node == NULL) {
if (node == NULL || !be_options.verbose_asm) {
be_emit_char('\n');
be_emit_write_line();
return;
......
......@@ -536,10 +536,12 @@ void be_gas_emit_function_prolog(const ir_entity *entity, unsigned po2alignment,
/* write the begin line (makes the life easier for scripts parsing the
* assembler) */
be_emit_cstring("# -- Begin ");
be_gas_emit_entity(entity);
be_emit_char('\n');
be_emit_write_line();
if (be_options.verbose_asm) {
be_emit_cstring("# -- Begin ");
be_gas_emit_entity(entity);
be_emit_char('\n');
be_emit_write_line();
}
if (po2alignment > 0) {
const char *fill_byte = "";
......@@ -598,10 +600,12 @@ void be_gas_emit_function_epilog(const ir_entity *entity)
be_emit_write_line();
}
be_emit_cstring("# -- End ");
be_gas_emit_entity(entity);
be_emit_char('\n');
be_emit_write_line();
if (be_options.verbose_asm) {
be_emit_cstring("# -- End ");
be_gas_emit_entity(entity);
be_emit_char('\n');
be_emit_write_line();
}
be_emit_char('\n');
be_emit_write_line();
......@@ -1566,6 +1570,48 @@ void be_gas_emit_block_name(const ir_node *block)
}
}
void be_gas_begin_block(const ir_node *block, bool needs_label)
{
if (needs_label) {
be_gas_emit_block_name(block);
be_emit_char(':');
} else {
if (!be_options.verbose_asm)
return;
be_emit_cstring("/*");
be_gas_emit_block_name(block);
be_emit_cstring(":*/");
}
if (be_options.verbose_asm) {
int arity;
ir_graph *irg = get_irn_irg(block);
ir_exec_freq *exec_freq = be_get_irg_exec_freq(irg);
be_emit_pad_comment();
be_emit_cstring("/* preds:");
arity = get_irn_arity(block);
if (arity == 0) {
be_emit_cstring(" none");
} else {
int i;
for (i = 0; i < arity; ++i) {
ir_node *predblock = get_Block_cfgpred_block(block, i);
be_emit_char(' ');
be_gas_emit_block_name(predblock);
}
}
if (exec_freq != NULL) {
be_emit_irprintf(", freq: %.3f",
get_block_execfreq(exec_freq, block));
}
be_emit_cstring(" */");
}
be_emit_char('\n');
be_emit_write_line();
}
/**
* Dump a global entity.
*
......
......@@ -107,6 +107,12 @@ void be_gas_emit_entity(const ir_entity *entity);
*/
void be_gas_emit_block_name(const ir_node *block);
/**
* Starts a basic block. Emits an assembler label "blockname:" if needs_label
* is true, otherwise a comment with the blockname if verboseasm is enabled.
*/
void be_gas_begin_block(const ir_node *block, bool needs_label);
/**
* Starts emitting a compilation unit. This emits:
* - global assembler snippets
......
......@@ -89,6 +89,7 @@ be_options_t be_options = {
"", /* ilp solver */
0, /* enable statistic event dumping */
"", /* print stat events */
1, /* verbose assembler output */
};
/* back end instruction set architecture to use */
......@@ -134,6 +135,7 @@ static const lc_opt_table_entry_t be_main_options[] = {
LC_OPT_ENT_BOOL ("profileuse", "use existing profile data", &be_options.opt_profile_use),
LC_OPT_ENT_BOOL ("statev", "dump statistic events", &be_options.statev),
LC_OPT_ENT_STR ("filtev", "filter for stat events (regex if support is active", be_options.filtev),
LC_OPT_ENT_BOOL ("verboseasm", "enable verbose assembler output", &be_options.verbose_asm),
LC_OPT_ENT_STR("ilp.server", "the ilp server name", be_options.ilp_server),
LC_OPT_ENT_STR("ilp.solver", "the ilp solver name", be_options.ilp_solver),
......
......@@ -987,7 +987,8 @@ static void emit_ia32_Jcc(const ir_node *node)
/* the second Proj might be a fallthrough */
if (can_be_fallthrough(proj_false)) {
ia32_emitf(proj_false, "\t/* fallthrough to %L */\n");
if (be_options.verbose_asm)
ia32_emitf(proj_false, "\t/* fallthrough to %L */\n");
} else {
ia32_emitf(proj_false, "\tjmp %L\n");
}
......@@ -1081,7 +1082,8 @@ static void emit_ia32_Jmp(const ir_node *node)
{
/* we have a block schedule */
if (can_be_fallthrough(node)) {
ia32_emitf(node, "\t/* fallthrough to %L */\n");
if (be_options.verbose_asm)
ia32_emitf(node, "\t/* fallthrough to %L */\n");
} else {
ia32_emitf(node, "\tjmp %L\n");
}
......@@ -1748,8 +1750,6 @@ static void ia32_emit_block_header(ir_node *block)
{
ir_graph *irg = current_ir_graph;
int need_label = block_needs_label(block);
ir_exec_freq *exec_freq = be_get_irg_exec_freq(irg);
int arity;
if (block == get_irg_end_block(irg))
return;
......@@ -1780,37 +1780,7 @@ static void ia32_emit_block_header(ir_node *block)
}
}
if (need_label) {
be_gas_emit_block_name(block);
be_emit_char(':');
be_emit_pad_comment();
be_emit_cstring(" /* ");
} else {
be_emit_cstring("\t/* ");
be_gas_emit_block_name(block);
be_emit_cstring(": ");
}
be_emit_cstring("preds:");
/* emit list of pred blocks in comment */
arity = get_irn_arity(block);
if (arity <= 0) {
be_emit_cstring(" none");
} else {
int i;
for (i = 0; i < arity; ++i) {
ir_node *predblock = get_Block_cfgpred_block(block, i);
be_emit_irprintf(" %d", get_irn_node_nr(predblock));
}
}
if (exec_freq != NULL) {
be_emit_irprintf(", freq: %f",
get_block_execfreq(exec_freq, block));
}
be_emit_cstring(" */\n");
be_emit_write_line();
be_gas_begin_block(block, need_label);
}
/**
......
......@@ -1070,13 +1070,16 @@ static void emit_sparc_branch(const ir_node *node, get_cc_func get_cc)
fill_delay_slot();
sparc_emit_indent();
if (get_irn_link(proj_false) == next_block) {
be_emit_cstring("/* fallthrough to ");
sparc_emit_cfop_target(proj_false);
be_emit_cstring(" */");
be_emit_finish_line_gas(proj_false);
if (be_options.verbose_asm) {
sparc_emit_indent();
be_emit_cstring("/* fallthrough to ");
sparc_emit_cfop_target(proj_false);
be_emit_cstring(" */");
be_emit_finish_line_gas(proj_false);
}
} else {
sparc_emit_indent();
be_emit_cstring("ba ");
sparc_emit_cfop_target(proj_false);
be_emit_finish_line_gas(proj_false);
......@@ -1112,13 +1115,16 @@ static void emit_sparc_fbfcc(const ir_node *node)
static void emit_sparc_Ba(const ir_node *node)
{
sparc_emit_indent();
if (ba_is_fallthrough(node)) {
be_emit_cstring("/* fallthrough to ");
sparc_emit_cfop_target(node);
be_emit_cstring(" */");
be_emit_finish_line_gas(node);
if (be_options.verbose_asm) {
sparc_emit_indent();
be_emit_cstring("/* fallthrough to ");
sparc_emit_cfop_target(node);
be_emit_cstring(" */");
be_emit_finish_line_gas(node);
}
} else {
sparc_emit_indent();
be_emit_cstring("ba ");
sparc_emit_cfop_target(node);
be_emit_finish_line_gas(node);
......@@ -1295,14 +1301,9 @@ static void sparc_emit_block(ir_node *block, ir_node *prev)
{
ir_node *node;
ir_node *next_delay_slot;
bool needs_label = block_needs_label(block, prev);
assert(is_Block(block));
if (block_needs_label(block, prev)) {
be_gas_emit_block_name(block);
be_emit_cstring(":\n");
be_emit_write_line();
}
be_gas_begin_block(block, needs_label);
next_delay_slot = find_next_delay_slot(sched_first(block));
if (next_delay_slot != NULL)
......
Markdown is supported
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