Also add a GRAPH_PROPERTY for the analysis state.
*/
FIRM_API void free_postdom(ir_graph *irg);
+/**
+ * Compute the dominance frontiers for a given graph.
+ * The information is freed automatically when dominance info is freed.
+ */
+FIRM_API void ir_compute_dominance_frontiers(ir_graph *irg);
+
+/**
+ * Get the dominance frontier of a block.
+ * @param block The block whose dominance frontier you want.
+ * @return A list containing all blocks in the dominance frontier of
+ * @p block (as array, use ARR_LEN() to determine the size)
+ */
+FIRM_API ir_node **ir_get_dominance_frontier(const ir_node *block);
+
/** @} */
#include "end.h"
* state when they did not affect some properties and want to keep them.
*/
typedef enum ir_graph_properties_t {
- IR_GRAPH_PROPERTIES_NONE = 0,
+ IR_GRAPH_PROPERTIES_NONE = 0,
/** graph contains no critical edges */
- IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES = 1U << 0,
+ IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES = 1U << 0,
/** graph contains no Bad nodes */
- IR_GRAPH_PROPERTY_NO_BADS = 1U << 1,
+ IR_GRAPH_PROPERTY_NO_BADS = 1U << 1,
/** No tuple nodes exist in the graph */
- IR_GRAPH_PROPERTY_NO_TUPLES = 1U << 2,
+ IR_GRAPH_PROPERTY_NO_TUPLES = 1U << 2,
/**
* there exists no (obviously) unreachable code in the graph.
* Unreachable in this context is code that you can't reach by following
* execution flow from the start block.
*/
- IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE = 1U << 3,
+ IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE = 1U << 3,
/** graph contains at most one return */
- IR_GRAPH_PROPERTY_ONE_RETURN = 1U << 4,
+ IR_GRAPH_PROPERTY_ONE_RETURN = 1U << 4,
/** dominance information about the graph is valid */
- IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE = 1U << 5,
+ IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE = 1U << 5,
/** postdominance information about the graph is valid */
- IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE = 1U << 6,
+ IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE = 1U << 6,
+ /** dominance frontiers information is calculated */
+ IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE_FRONTIERS = 1U << 7,
/**
* out edges (=iredges) are enable and there is no dead code that can be
* reached by following them
*/
- IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES = 1U << 7,
+ IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES = 1U << 8,
/** outs (irouts) are computed and up to date */
- IR_GRAPH_PROPERTY_CONSISTENT_OUTS = 1U << 8,
+ IR_GRAPH_PROPERTY_CONSISTENT_OUTS = 1U << 9,
/** loopinfo is computed and up to date */
- IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO = 1U << 9,
+ IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO = 1U << 10,
/** entity usage information is computed and up to date */
- IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE = 1U << 10,
+ IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE = 1U << 11,
/** graph contains as many returns as possible */
- IR_GRAPH_PROPERTY_MANY_RETURNS = 1U << 11,
+ IR_GRAPH_PROPERTY_MANY_RETURNS = 1U << 12,
/**
* List of all graph properties that are only affected byt control flow
| IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE
| IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO
| IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE
- | IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE,
+ | IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE
+ | IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE_FRONTIERS,
/**
* List of all graph properties.
--- /dev/null
+/*
+ * Copyright (C) 1995-2011 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 Algorithms for computing dominance frontiers.
+ * @author Sebastian Hack, Daniel Grund
+ * @date 04.05.2005
+ */
+#include "config.h"
+
+#include "obst.h"
+#include "pmap.h"
+#include "pdeq.h"
+#include "irdom.h"
+#include "array.h"
+#include "irgraph.h"
+#include "iredges_t.h"
+#include "irnodeset.h"
+
+/**
+ * A wrapper for get_Block_idom.
+ * This function returns the block itself, if the block is the start
+ * block. Returning NULL would make any != comparison true which
+ * suggests, that the start block is dominated by some other node.
+ * @param bl The block.
+ * @return The immediate dominator of the block.
+ */
+static inline ir_node *get_idom(ir_node *bl)
+{
+ ir_node *idom = get_Block_idom(bl);
+ return idom == NULL ? bl : idom;
+}
+
+/**
+ * Compute the dominance frontier for a given block.
+ *
+ * @param blk the block where the calculation starts
+ *
+ * @return the list of all blocks in the dominance frontier of blk
+ */
+static ir_node **compute_df(ir_node *blk, ir_dom_front_info_t *info)
+{
+ ir_node *c;
+ const ir_edge_t *edge;
+ ir_node **df_list = NEW_ARR_F(ir_node *, 0);
+ ir_node **df;
+ size_t len;
+
+ /* Add local dominance frontiers */
+ foreach_block_succ(blk, edge) {
+ ir_node *y = get_edge_src_irn(edge);
+
+ if (get_idom(y) != blk) {
+ ARR_APP1(ir_node *, df_list, y);
+ }
+ }
+
+ /*
+ * Go recursively down the dominance tree and add all blocks
+ * into the dominance frontiers of the children, which are not
+ * dominated by the given block.
+ */
+ for (c = get_Block_dominated_first(blk); c; c = get_Block_dominated_next(c)) {
+ size_t i;
+ ir_node **df_c_list = compute_df(c, info);
+
+ for (i = ARR_LEN(df_c_list); i > 0;) {
+ ir_node *w = df_c_list[--i];
+ if (get_idom(w) != blk)
+ ARR_APP1(ir_node *, df_list, w);
+ }
+ }
+
+ /* now copy the flexible array to the obstack */
+ len = ARR_LEN(df_list);
+ df = NEW_ARR_D(ir_node *, &info->obst, len);
+ memcpy(df, df_list, len * sizeof(df[0]));
+ DEL_ARR_F(df_list);
+
+ pmap_insert(info->df_map, blk, df);
+ return df;
+}
+
+void ir_compute_dominance_frontiers(ir_graph *irg)
+{
+ ir_dom_front_info_t *info = &irg->domfront;
+
+ assure_edges(irg);
+ obstack_init(&info->obst);
+ info->df_map = pmap_create();
+ assure_doms(irg);
+ compute_df(get_irg_start_block(irg), info);
+
+ add_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE_FRONTIERS);
+}
+
+void ir_free_dominance_frontiers(ir_graph *irg)
+{
+ clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE_FRONTIERS);
+
+ ir_dom_front_info_t *info = &irg->domfront;
+ if (info->df_map == NULL)
+ return;
+
+ obstack_free(&info->obst, NULL);
+ pmap_destroy(info->df_map);
+ info->df_map = NULL;
+}
+
+/* Get the dominance frontier of a block. */
+ir_node **ir_get_dominance_frontier(const ir_node *block)
+{
+ ir_graph *irg = get_irn_irg(block);
+ ir_dom_front_info_t *info = &irg->domfront;
+ return (ir_node**)pmap_get(info->df_map, block);
+}
assert(get_irg_phase_state(irg) != phase_building);
clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE);
- /* With the implementation right now there is nothing to free,
- but better call it anyways... */
+ /* With the implementation right now there is nothing to free */
+
+ /* free dominance frontiers */
+ ir_free_dominance_frontiers(irg);
}
void compute_postdoms(ir_graph *irg)
#define FIRM_ANA_IRDOM_T_H
#include "irdom.h"
+#include "pmap.h"
+#include "obst.h"
/** For dominator information */
typedef struct ir_dom_info {
int dom_depth; /**< depth in dominator-tree */
} ir_dom_info;
+typedef struct ir_dom_front_info_t {
+ pmap *df_map; /**< A map, mapping every block to a list of its dominance frontier blocks. */
+ struct obstack obst; /**< An obstack holding all the frontier data. */
+} ir_dom_front_info_t;
+
void set_Block_idom(ir_node *bl, ir_node *n);
int get_Block_dom_depth(const ir_node *bl);
unsigned get_Block_dom_max_subtree_pre_num(const ir_node *bl);
unsigned get_Block_pdom_max_subtree_pre_num(const ir_node *bl);
+void ir_free_dominance_frontiers(ir_graph *irg);
+
#endif
typedef struct be_abi_irg_t be_abi_irg_t;
typedef struct be_stack_layout_t be_stack_layout_t;
-typedef struct be_dom_front_info_t be_dom_front_info_t;
-
typedef struct backend_info_t backend_info_t;
typedef struct sched_info_t sched_info_t;
typedef struct reg_out_info_t reg_out_info_t;
+++ /dev/null
-/*
- * Copyright (C) 1995-2011 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 Algorithms for computing dominance frontiers.
- * @author Sebastian Hack, Daniel Grund
- * @date 04.05.2005
- */
-#include "config.h"
-
-#include "obst.h"
-#include "pmap.h"
-#include "pdeq.h"
-#include "irdom.h"
-#include "array.h"
-#include "irgraph.h"
-#include "iredges_t.h"
-#include "irnodeset.h"
-
-#include "bedomfront.h"
-
-/**
- * The dominance frontier for a graph.
- */
-struct be_dom_front_info_t {
- pmap *df_map; /**< A map, mapping every block to a list of its dominance frontier blocks. */
- struct obstack obst; /**< An obstack holding all the frontier data. */
-};
-
-/**
- * A wrapper for get_Block_idom.
- * This function returns the block itself, if the block is the start
- * block. Returning NULL would make any != comparison true which
- * suggests, that the start block is dominated by some other node.
- * @param bl The block.
- * @return The immediate dominator of the block.
- */
-static inline ir_node *get_idom(ir_node *bl)
-{
- ir_node *idom = get_Block_idom(bl);
- return idom == NULL ? bl : idom;
-}
-
-/**
- * Compute the dominance frontier for a given block.
- *
- * @param blk the block where the calculation starts
- *
- * @return the list of all blocks in the dominance frontier of blk
- */
-static ir_node **compute_df(ir_node *blk, be_dom_front_info_t *info)
-{
- ir_node *c;
- const ir_edge_t *edge;
- ir_node **df_list = NEW_ARR_F(ir_node *, 0);
- ir_node **df;
- size_t len;
-
- /* Add local dominance frontiers */
- foreach_block_succ(blk, edge) {
- ir_node *y = get_edge_src_irn(edge);
-
- if (get_idom(y) != blk) {
- ARR_APP1(ir_node *, df_list, y);
- }
- }
-
- /*
- * Go recursively down the dominance tree and add all blocks
- * into the dominance frontiers of the children, which are not
- * dominated by the given block.
- */
- for (c = get_Block_dominated_first(blk); c; c = get_Block_dominated_next(c)) {
- size_t i;
- ir_node **df_c_list = compute_df(c, info);
-
- for (i = ARR_LEN(df_c_list); i > 0;) {
- ir_node *w = df_c_list[--i];
- if (get_idom(w) != blk)
- ARR_APP1(ir_node *, df_list, w);
- }
- }
-
- /* now copy the flexible array to the obstack */
- len = ARR_LEN(df_list);
- df = NEW_ARR_D(ir_node *, &info->obst, len);
- memcpy(df, df_list, len * sizeof(df[0]));
- DEL_ARR_F(df_list);
-
- pmap_insert(info->df_map, blk, df);
- return df;
-}
-
-be_dom_front_info_t *be_compute_dominance_frontiers(ir_graph *irg)
-{
- be_dom_front_info_t *info = XMALLOC(be_dom_front_info_t);
-
- assure_edges(irg);
- obstack_init(&info->obst);
- info->df_map = pmap_create();
- assure_doms(irg);
- (void)compute_df(get_irg_start_block(irg), info);
-
- return info;
-}
-
-void be_free_dominance_frontiers(be_dom_front_info_t *info)
-{
- obstack_free(&info->obst, NULL);
- pmap_destroy(info->df_map);
- free(info);
-}
-
-/* Get the dominance frontier of a block. */
-ir_node **be_get_dominance_frontier(const be_dom_front_info_t *info,
- ir_node *block)
-{
- return (ir_node**)pmap_get(info->df_map, block);
-}
+++ /dev/null
-/*
- * 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 Algorithms for computing dominance frontiers
- * @author Sebastian Hack, Daniel Grund
- * @date: 04.05.2005
- */
-#ifndef FIRM_BE_BEDOMFRONT_H
-#define FIRM_BE_BEDOMFRONT_H
-
-#include "firm_types.h"
-#include "be_types.h"
-
-/**
- * Compute the dominance frontiers for a given graph.
- * @param irg The graphs.
- * @return A pointer to the dominance frontier information.
- */
-be_dom_front_info_t *be_compute_dominance_frontiers(ir_graph *irg);
-
-/**
- * Free some dominance frontier information.
- * @param info Some dominance frontier information.
- */
-void be_free_dominance_frontiers(be_dom_front_info_t *info);
-
-/**
- * Get the dominance frontier of a block.
- * @param info A pointer to the dominance frontier information.
- * @param block The block whose dominance frontier you want.
- * @return A list containing the all blocks in the dominance frontier of
- * @p block.
- */
-ir_node **be_get_dominance_frontier(const be_dom_front_info_t *info, ir_node *block);
-
-#endif
#include "beirg.h"
#include "absgraph.h"
#include "belive.h"
-#include "bedomfront.h"
-
-void be_assure_dom_front(ir_graph *irg)
-{
- be_irg_t *birg = be_birg_from_irg(irg);
- if (birg->dom_front != NULL)
- return;
-
- birg->dom_front = be_compute_dominance_frontiers(birg->irg);
-}
-
-void be_invalidate_dom_front(ir_graph *irg)
-{
- be_irg_t *birg = be_birg_from_irg(irg);
- if (birg->dom_front == NULL)
- return;
-
- be_free_dominance_frontiers(birg->dom_front);
- birg->dom_front = NULL;
-}
void be_invalidate_live_sets(ir_graph *irg)
{
free_execfreq(birg->exec_freq);
birg->exec_freq = NULL;
- if (birg->dom_front != NULL) {
- be_free_dominance_frontiers(birg->dom_front);
- birg->dom_front = NULL;
- }
if (birg->lv != NULL) {
be_liveness_free(birg->lv);
birg->lv = NULL;
#include "be_t.h"
#include "irtypes.h"
-void be_assure_dom_front(ir_graph *irg);
-void be_invalidate_dom_front(ir_graph *irg);
-
void be_assure_live_sets(ir_graph *irg);
void be_assure_live_chk(ir_graph *irg);
/**
void be_invalidate_live_chk(ir_graph *irg);
/**
- * frees all memory allocated by birg structures (liveness, dom_front, ...).
+ * frees all memory allocated by birg structures (liveness, ...).
* The memory of the birg structure itself is not freed.
*/
void be_free_birg(ir_graph *irg);
be_main_env_t *main_env;
be_abi_irg_t *abi;
ir_exec_freq *exec_freq;
- be_dom_front_info_t *dom_front;
be_lv_t *lv;
be_stack_layout_t stack_layout;
unsigned *allocatable_regs; /**< registers available for the
return be_birg_from_irg(irg)->exec_freq;
}
-static inline be_dom_front_info_t *be_get_irg_dom_front(const ir_graph *irg)
-{
- return be_birg_from_irg(irg)->dom_front;
-}
-
static inline be_abi_irg_t *be_get_irg_abi(const ir_graph *irg)
{
return be_birg_from_irg(irg)->abi;
while (!waitq_empty(env->worklist)) {
int i;
ir_node *block = (ir_node*)waitq_get(env->worklist);
- ir_node **domfront = be_get_dominance_frontier(env->domfronts, block);
+ ir_node **domfront = ir_get_dominance_frontier(block);
int domfront_len = ARR_LEN(domfront);
for (i = 0; i < domfront_len; ++i) {
stat_ev_dbl("bessaconstr_n_blocks", n_blocks);
memset(env, 0, sizeof(env[0]));
- be_assure_dom_front(irg);
env->irg = irg;
- env->domfronts = be_get_irg_dom_front(irg);
env->new_phis = NEW_ARR_F(ir_node*, 0);
env->worklist = new_waitq();
ir_nodemap_init(&env->infos, irg);
obstack_init(&env->obst);
+ assure_irg_properties(env->irg,
+ IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE_FRONTIERS);
+
ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED
| IR_RESOURCE_BLOCK_VISITED | IR_RESOURCE_IRN_LINK);
#ifndef FIRM_BE_BESSACONSTR_H
#define FIRM_BE_BESSACONSTR_H
+#include <stdbool.h>
#include "firm_types.h"
-#include "bedomfront.h"
#include "irnodeset.h"
#include "belive.h"
#include "bitset.h"
typedef struct be_ssa_construction_env_t {
ir_graph *irg;
- const be_dom_front_info_t *domfronts;
ir_mode *mode;
const arch_register_req_t *phi_req;
waitq *worklist;
const ir_nodeset_t *ignore_uses;
ir_node **new_phis;
- int iterated_domfront_calculated;
+ bool iterated_domfront_calculated;
ir_nodemap infos;
struct obstack obst;
} be_ssa_construction_env_t;
current_ir_graph = old_current_ir_graph;
/* most analysis info is wrong after transformation */
- free_callee_info(irg);
- free_irg_outs(irg);
- free_trouts();
- free_loop_information(irg);
- clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE);
-
be_invalidate_live_chk(irg);
- be_invalidate_dom_front(irg);
+ confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE);
/* recalculate edges */
- edges_deactivate(irg);
edges_activate(irg);
}
#include "bearch.h"
-/* iterate over a list of ir_nodes linked by link field */
-#define foreach_linked_irns(head, iter) for ((iter) = (head); (iter); (iter) = get_irn_link((iter)))
-
/**
* Convenient block getter.
* Works also, if the given node is a block.
{ IR_GRAPH_PROPERTY_CONSISTENT_OUTS, assure_irg_outs },
{ IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO, assure_loopinfo },
{ IR_GRAPH_PROPERTY_CONSISTENT_ENTITY_USAGE, assure_irg_entity_usage_computed },
+ { IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE_FRONTIERS, ir_compute_dominance_frontiers },
};
size_t i;
for (i = 0; i < ARRAY_SIZE(property_functions); ++i) {
if (! (props & IR_GRAPH_PROPERTY_CONSISTENT_OUTS)
&& (irg->properties & IR_GRAPH_PROPERTY_CONSISTENT_OUTS))
free_irg_outs(irg);
+ if (! (props & IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE_FRONTIERS))
+ ir_free_dominance_frontiers(irg);
}
unsigned marked:1; /**< Can be set/unset to temporary mark a block. */
ir_node **graph_arr; /**< An array to store all parameters. */
/* Attributes holding analyses information */
- ir_dom_info dom; /**< Datastructure that holds information about dominators.
- @@@ @todo
- Eventually overlay with graph_arr as only valid
- in different phases. Eventually inline the whole
- datastructure. */
+ ir_dom_info dom; /**< Datastructure that holds information about dominators. */
ir_dom_info pdom; /**< Datastructure that holds information about post-dominators. */
bitset_t *backedge; /**< Bitfield n set to true if pred n is backedge.*/
ir_entity *entity; /**< entitiy representing this block */
ir_vrp_info vrp; /**< vrp info */
ir_loop *loop; /**< The outermost loop for this graph. */
+ ir_dom_front_info_t domfront; /**< dominance frontier analysis data */
void *link; /**< A void* field to link any information to
the node. */