From 60787c33b1e35cad2937fcd434bdb6aa25bde561 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Mon, 14 Apr 2008 01:17:52 +0000 Subject: [PATCH] add Linux grof support [r19271] --- ir/be/ia32/bearch_ia32.c | 15 ++++++ ir/ir/instrument.c | 101 +++++++++++++++++++++++++++++++++++++++ ir/ir/instrument.h | 36 ++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 ir/ir/instrument.c create mode 100644 ir/ir/instrument.h diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 67463b402..32f1dc2b5 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -51,6 +51,7 @@ #include "xmalloc.h" #include "irtools.h" #include "iroptimize.h" +#include "instrument.h" #include "../beabi.h" #include "../beirg_t.h" @@ -927,6 +928,10 @@ static ia32_irn_ops_t ia32_irn_ops = { * |___/ **************************************************/ +static ir_entity *mcount = NULL; + +#define ID(s) new_id_from_chars(s, sizeof(s) - 1) + static void ia32_before_abi(void *self) { lower_mode_b_config_t lower_mode_b_config = { mode_Iu, /* lowered mode */ @@ -938,6 +943,16 @@ static void ia32_before_abi(void *self) { ir_lower_mode_b(cg->irg, &lower_mode_b_config); if (cg->dump) be_dump(cg->irg, "-lower_modeb", dump_ir_block_graph_sched); + if (cg->gprof) { + if (mcount == NULL) { + ir_type *tp = new_type_method(ID("FKT.mcount"), 0, 0); + mcount = new_entity(get_glob_type(), ID("mcount"), tp); + /* FIXME: enter the right ld_ident here */ + set_entity_ld_ident(mcount, get_entity_ident(mcount)); + set_entity_visibility(mcount, visibility_external_allocated); + } + instrument_initcall(cg->irg, mcount); + } } /** diff --git a/ir/ir/instrument.c b/ir/ir/instrument.c new file mode 100644 index 000000000..8e9882930 --- /dev/null +++ b/ir/ir/instrument.c @@ -0,0 +1,101 @@ +/* + * 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 Instrumentation of graphs. + * @date 14.4.2008 + * @author Michael Beck + * @version $Id: $ + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "irgraph_t.h" +#include "iredges.h" +#include "error.h" +#include "ircons.h" +#include "instrument.h" + +/** + * Adds a Call at the beginning of the given irg. + */ +void instrument_initcall(ir_graph *irg, ir_entity *ent) { + const ir_edge_t *edge; + ir_node *initial_exec; + ir_node *initial_mem; + ir_node *start_block; + ir_node *adr, *call, *new_mem; + ir_node *first_block = NULL; + int i, idx, need_new_block; + symconst_symbol sym; + + edges_assure(irg); + + /* find the first block */ + initial_exec = get_irg_initial_exec(irg); + start_block = get_irg_start_block(irg); + + foreach_out_edge(initial_exec, edge) { + ir_node *succ = get_edge_src_irn(edge); + + if (succ != start_block && is_Block(succ)) { + /* found the first block */ + first_block = succ; + break; + } + } + if (first_block == NULL) { + panic("Cannot find first block of irg %+F\n", irg); + } + + /* check if this block has only one predecessor */ + idx = -1; + need_new_block = 0; + for (i = get_Block_n_cfgpreds(first_block) - 1; i >= 0; --i) { + ir_node *p = get_Block_cfgpred(first_block, i); + + if (is_Bad(p)) + continue; + if (p == initial_exec) + idx = i; + else + need_new_block = 1; + } + + if (need_new_block) { + ir_node *blk = new_r_Block(irg, 1, &initial_exec); + set_Block_cfgpred(first_block, idx, new_r_Jmp(irg, blk)); + first_block = blk; + } + + /* place the call */ + sym.entity_p = ent; + adr = new_r_SymConst(irg, start_block, mode_P_code, sym, symconst_addr_ent); + + call = new_r_Call(irg, first_block, get_irg_no_mem(irg), adr, 0, NULL, get_entity_type(ent)); + new_mem = new_r_Proj(irg, first_block, call, mode_M, pn_Call_M_regular); + + initial_mem = get_irg_initial_mem(irg); + edges_reroute(initial_mem, new_mem, irg); + /* beware: reroute routes anchor edges also, revert this */ + set_irg_initial_mem(irg, initial_mem); + set_Call_mem(call, initial_mem); +} diff --git a/ir/ir/instrument.h b/ir/ir/instrument.h new file mode 100644 index 000000000..6636b53e1 --- /dev/null +++ b/ir/ir/instrument.h @@ -0,0 +1,36 @@ +/* + * 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 Instrumentation of graphs. + * @version $Id: $ + */ +#ifndef FIRM_IR_INSTRUMENT_H +#define FIRM_IR_INSTRUMENT_H + +/** + * Adds a Call at the beginning of the given irg. + * + * @param irg the graph to instrument + * @param ent the entity to call + */ +void instrument_initcall(ir_graph *irg, ir_entity *ent); + +#endif -- 2.20.1