+/*
+ * Copyright (C) 1995-2007 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 SSA construction for a set of nodes
+ * @brief SSA construction for a set of nodes
* @author Sebastian Hack, Daniel Grund, Matthias Braun, Christian Wuerdig
* @date 04.05.2005
* @version $Id$
- * Copyright: (c) Universitaet Karlsruhe
- * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*
* The problem: Given a value and a set of "copies" that are known to
* represent the same abstract value, rewire all usages of the original value
* found, then we search one in the immediate dominator. If we are in a block
* of the dominance frontier, create a phi and search do the same search for
* the phi arguments.
+ *
+ * A copy in this context means, that you want to introduce several new
+ * abstract values (in Firm: nodes) for which you know, that they
+ * represent the same concrete value. This is the case if you
+ * - copy
+ * - spill and reload
+ * - re-materialize
+ * a value.
+ *
+ * This function reroutes all uses of the original value to the copies in the
+ * corresponding dominance subtrees and creates Phi functions where necessary.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "bessaconstr.h"
#include "bemodule.h"
#include "besched_t.h"
-#include "bera.h"
+#include "beintlive_t.h"
#include "beirg_t.h"
#include "debug.h"
ir_node *get_def_at_idom(be_ssa_construction_env_t *env, ir_node *block)
{
ir_node *dom = get_Block_idom(block);
- ir_node *def = search_def_end_of_block(env, dom);
-
- return def;
+ assert(dom != NULL);
+ return search_def_end_of_block(env, dom);
}
static
}
}
-#if 0
-ir_node **be_ssa_construction(const be_dom_front_info_t *domfronts, be_lv_t *lv,
- ir_node *value, int copies_len, ir_node **copies,
- const ir_nodeset_t *ignore_uses, int need_new_phis)
-{
- ir_graph *irg = get_irn_irg(value);
- const ir_edge_t *edge, *next;
- int i;
- ir_node *block;
- waitq *worklist;
- be_ssa_construction_env_t env;
-
- /* We need to collect the phi functions to compute their liveness. */
- if(lv != NULL || need_new_phis) {
- env.new_phis = NEW_ARR_F(ir_node*, 0);
- } else {
- env.new_phis = NULL;
- }
- env.mode = get_irn_mode(value);
-
- set_using_visited(irg);
- set_using_block_visited(irg);
- set_using_irn_link(irg);
-
- /* we use the visited flag to indicate blocks in the dominance frontier
- * and blocks that already have the relevant value at the end calculated */
- inc_irg_visited(irg);
- /* We use the block visited flag to indicate blocks in the dominance
- * froniter of some values (and this potentially needing phis) */
- inc_irg_block_visited(irg);
-
- DBG((dbg, LEVEL_1, "Introducing following copies for: %+F\n", value));
- /* compute iterated dominance frontiers and create lists in the block link
- * fields that sort usages by dominance. Blocks in the dominance frontier
- * are marked by links back to the block. */
- worklist = new_waitq();
-
- block = get_nodes_block(value);
- /* we sometimes replace virtual values by real ones, in this case we do
- not want to insert them into the def list (they're not scheduled
- and can't be used anyway) */
- if(sched_is_scheduled(value)) {
- introduce_def_at_block(block, value);
- }
- waitq_put(worklist, block);
-
- for(i = 0; i < copies_len; ++i) {
- ir_node *copy = copies[i];
- block = get_nodes_block(copy);
-
- if(!irn_visited(block)) {
- waitq_put(worklist, block);
- }
- introduce_def_at_block(block, copy);
- DBG((dbg, LEVEL_1, "\t%+F in %+F\n", copy, block));
- }
-
- mark_iterated_dominance_frontiers(domfronts, worklist);
- del_waitq(worklist);
-
- DBG((dbg, LEVEL_2, "New Definitions:\n"));
- /*
- * Search the valid def for each use and set it.
- */
- foreach_out_edge_safe(value, edge, next) {
- ir_node *use = get_edge_src_irn(edge);
- ir_node *at = use;
- int pos = get_edge_src_pos(edge);
-
- if(ignore_uses != NULL && ir_nodeset_contains(ignore_uses, use))
- continue;
-
- if(is_Phi(use)) {
- ir_node *block = get_nodes_block(use);
- ir_node *predblock = get_Block_cfgpred_block(block, pos);
- at = sched_last(predblock);
- }
-
- ir_node *def = search_def(&env, at);
-
- if(def == NULL) {
- panic("no definition found for %+F at position %d\n", use, pos);
- }
-
- DBG((dbg, LEVEL_2, "\t%+F(%d) -> %+F\n", use, pos, def));
- set_irn_n(use, pos, def);
- }
-
- /* Recompute the liveness of the original nodes, the copies and the
- * inserted phis. */
- if(lv != NULL) {
- int n;
-
- be_liveness_update(lv, value);
- for(i = 0; i < copies_len; ++i) {
- ir_node *copy = copies[i];
- be_liveness_update(lv, copy);
- }
-
- n = ARR_LEN(env.new_phis);
- for(i = 0; i < n; ++i) {
- ir_node *phi = env.new_phis[i];
- be_liveness_introduce(lv, phi);
- }
- }
-
- clear_using_visited(irg);
- clear_using_block_visited(irg);
- clear_using_irn_link(irg);
-
- if(!need_new_phis && env.new_phis != NULL) {
- DEL_ARR_F(env.new_phis);
- return NULL;
- }
- return env.new_phis;
-}
-#endif
-
void be_init_ssaconstr(void)
{
FIRM_DBG_REGISTER(dbg, "firm.be.ssaconstr");