/*
- * Project: libFIRM
- * File name: ir/opt/data_flow_scalar_replace.c
- * Purpose: scalar replacement of arrays and compounds
- * Author: Beyhan Veliev
- * Modified by: Michael Beck
- * Created:
- * CVS-ID: $Id$
- * Copyright: (c) 1998-2005 Universität Karlsruhe
- * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
+ * 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.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
+/**
+ * @file
+ * @brief scalar replacement of arrays and compounds
+ * @author Beyhan Veliev, Michael Beck
+ * @version $Id$
+ */
+#include "config.h"
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
+#include "iroptimize.h"
-#ifdef HAVE_STRING_H
#include <string.h>
-#endif
-#include "data_flow_scalar_replace.h"
#include "irflag_t.h"
#include "irouts.h"
#include "pset.h"
#include "irloop.h"
#include "analyze_irg_args.h"
#include "irprintf.h"
-#include "compute_loop_info.h"
#include "irgopt.h"
+#include "xmalloc.h"
#define SET_ENT_VNUM(ent, vnum) set_entity_link(ent, INT_TO_PTR(vnum))
#define GET_ENT_VNUM(ent) (unsigned)PTR_TO_INT(get_entity_link(ent))
{
const ent_leaves_t *c1 = elt;
const ent_leaves_t *c2 = key;
+ (void) size;
return c1->ent != c2->ent;
}
{
const sels_t *c1 = elt;
const sels_t *c2 = key;
+ (void) size;
return c1->sel != c2->sel;
}
{
const call_access_t *c1 = elt;
const call_access_t *c2 = key;
+ (void) size;
return c1->call != c2->call;
}
{
const path_t *p1 = elt;
const path_t *p2 = key;
+ (void) size;
/* we can use memcmp here, because identical tarvals should have identical addresses */
return memcmp(p1->path, p2->path, p1->path_len * sizeof(p1->path[0]));
for (i = 0; i < n; ++i) {
ir_node *idx = get_Sel_index(sel, i);
- if (get_irn_op(idx) != op_Const)
+ if (!is_Const(idx))
return 0;
}
return 1;
* Returns non-zero, if the address of an entity
* represented by a Sel node (or it's successor Sels) is taken.
*/
-static int is_address_taken(ir_node *sel)
+static int is_address_taken_2(ir_node *sel)
{
int i;
case iro_Sel: {
/* Check the Sel successor of Sel */
- int res = is_address_taken(succ);
+ int res = is_address_taken_2(succ);
if (res)
return 1;
for (i = 0; i < n; ++i) {
ir_node *succ = get_irn_out(sel, i);
- if (get_irn_op(succ) == op_Sel)
+ if (is_Sel(succ))
link_all_leave_sels(ent, succ);
-
}
/* if Sel nodes with memory inputs are used, a entity can be
* visited more than once causing a ring here, so we use the
* node flag to mark linked nodes
*/
- if (irn_visited(sel))
+ if (irn_visited_else_mark(sel))
return;
/*
*/
set_irn_link(sel, get_entity_link(ent));
set_entity_link(ent, sel);
-
- mark_irn_visited(sel);
}
/* we need a special address that serves as an address taken marker */
static int find_possible_replacements(ir_graph *irg)
{
ir_node *irg_frame = get_irg_frame(irg);
+ ir_type *frame_tp;
int i, n;
int res = 0;
n = get_irn_n_outs(irg_frame);
/*
- * First, clear the link field of all interestingentities.
- * Note that we did not rely on the fact that there is only
- * one Sel node per entity, so we might access one entity
- * more than once here.
- * That's why we have need two loops.
+ * First, clear the link field of all interesting entities.
*/
- for (i = 0; i < n; ++i) {
- ir_node *succ = get_irn_out(irg_frame, i);
-
- if (get_irn_op(succ) == op_Sel) {
- ir_entity *ent = get_Sel_entity(succ);
- set_entity_link(ent, NULL);
- }
+ frame_tp = get_irg_frame_type(irg);
+ for (i = get_class_n_members(frame_tp) - 1; i >= 0; --i) {
+ ir_entity *ent = get_class_member(frame_tp, i);
+ set_entity_link(ent, NULL);
}
/*
for (i = 0; i < n; ++i) {
ir_node *succ = get_irn_out(irg_frame, i);
- if (get_irn_op(succ) == op_Sel) {
+ if (is_Sel(succ)) {
ir_entity *ent = get_Sel_entity(succ);
ir_type *ent_type;
- if (get_entity_link(ent) == ADDRESS_TAKEN)
+ /* we are only interested in entities on the frame, NOT
+ on the value type */
+ if (get_entity_owner(ent) != frame_tp)
+ continue;
+
+ if (get_entity_link(ent) == ADDRESS_TAKEN)
continue;
/*
/* we can handle arrays, structs and atomic types yet */
if (is_Array_type(ent_type) || is_Struct_type(ent_type) || is_atomic_type(ent_type)) {
- if (is_address_taken(succ)) {
+ if (is_address_taken_2(succ)) {
if (get_entity_link(ent)) /* killing one */
--res;
set_entity_link(ent, ADDRESS_TAKEN);
for(i = get_irn_n_outs(sel) - 1; i >= 0; i--) {
succ = get_irn_out(sel, i);
- if(get_irn_op(succ) == op_Sel)
+ if (is_Sel(succ))
return 0;
}
n = get_Sel_n_indexs(sel);
len += n + 1;
- if (get_irn_op(pred) != op_Sel) {
+ if (!is_Sel(pred)) {
/* we found the root */
-
- res = xmalloc(sizeof(*res) + (len - 1) * sizeof(res->path));
+ res = XMALLOCF(path_t, path, len);
res->path_len = len;
}
else
for (i = 0; i < n; ++i) {
ir_node *index = get_Sel_index(sel, i);
- if(get_irn_op(index) == op_Const)
+ if (is_Const(index))
res->path[pos++].tv = get_Const_tarval(index);
}
return res;
/* We must check this, why it is possible to get a Bad node
* form new_r_Sync(), when the node can be optimized.
* In this case we must do nothing.*/
- if(get_irn_op(sync) == op_Sync) {
+ if (is_Sync(sync)) {
val_arr[env->gl_mem_vnum].mem_edge_state = sync;
/* We add this sync node to the sync's fix list.*/
add_sync_to_fixlist(val_arr[env->gl_mem_vnum].mem_edge_state, unk_vnum, env);
irn_blk = get_nodes_block(irn);
val_arr = get_irn_link(irn_blk);
- n = get_Block_n_cfgpreds(irn_blk);
-
- in = alloca(sizeof(*in) * n);
+ n = get_Block_n_cfgpreds(irn_blk);
+ in = ALLOCAN(ir_node*, n);
for(value_ent = set_first(env->set_ent); value_ent; value_ent = set_next(env->set_ent))
if(val_arr[GET_ENT_VNUM(value_ent->ent)].access_type < 3)
int *accessed_leaves_vnum = NULL; /**< An arraw, where are saved the value number, that
are synced from call's sync node, if we need it.*/
- if(get_irn_node_nr(call) == 2763)
- printf("\nHi\n");
-
call_blk = get_nodes_block(call);
val_arr = get_irn_link(call_blk);
/* An array to save the memory edges, that must be
/* We must check this, why it is possible to get a Bad node
* form new_r_Sync(), when the node can be optimized.
* In this case we must do nothing.*/
- if(get_irn_op(sync) == op_Sync) {
-
+ if (is_Sync(sync)) {
set_Call_mem(call, sync);
if(ARR_LEN(accessed_leaves_vnum))
/* We add this sync node to the sync's fix list.*/
else
irn_blk = get_nodes_block(irn);
- if (Block_not_block_visited(irn_blk)) {
+ if (!Block_block_visited(irn_blk)) {
/* We sync first the stored scalar address in this block.*/
mark_Block_block_visited(irn_blk);
sync_stored_scalars(irn_blk, env);
/* Calls that have a NoMem input do neither read nor write memory.
We can completely ignore them here. */
- if (get_irn_op(get_Call_mem(irn)) == op_NoMem)
+ if (is_NoMem(get_Call_mem(irn)))
return;
/* We save in this set all entities,
sel = get_Call_param(irn, i);
value_sels = NULL;
- if(get_irn_op(sel) == op_Sel) {
+ if (is_Sel(sel)) {
key_sels.sel = sel;
value_sels = set_find(env->set_sels, &key_sels, sizeof(key_sels), HASH_PTR(key_sels.sel));
int i;
ir_node *res;
- if (Block_not_block_visited(block)) {
+ if (!Block_block_visited(block)) {
mark_Block_block_visited(block);
val_arr = get_irn_link(block);
pred = get_nodes_block(pred);
/* We first repair the global memory edge at the first position of sync predecessors.*/
- if(get_irn_op(get_irn_n(sync, 0)) == op_Unknown) {
+ if (is_Unknown(get_irn_n(sync, 0))) {
inc_irg_block_visited(current_ir_graph);
val = find_vnum_value(pred, env->gl_mem_vnum);
/* We repair the leaves*/
assert(k <= ARR_LEN(l->accessed_vnum) && "The algorythm for sync repair is wron");
- if(get_irn_op(get_irn_n(sync, i)) == op_Unknown) {
+ if (is_Unknown(get_irn_n(sync, i))) {
inc_irg_block_visited(current_ir_graph);
val = find_vnum_value(pred, l->accessed_vnum[k++]);
vnum_state++;
/* We allocate the memory, that we need for the predecessors of the sync.*/
- in = xmalloc(sizeof(ir_node*) *vnum_state);
+ in = XMALLOCN(ir_node*, vnum_state);
/* The global memory edge is the first predecessor of this sync node.*/
if(val_arr[env->gl_mem_vnum].mem_edge_state == NULL) {
int i, vnum;
unsigned int acces_type;
ir_node *param, *call_ptr, *blk;
- ir_op *op;
ir_entity *meth_ent;
sels_t key_sels, *value_sels;
call_access_t key_call, *value_call;
env_t *env;
env = ctx;
- if(get_irn_op(irn) != op_Call)
+ if (!is_Call(irn))
return;
/* Calls that have a NoMem input do neither read nor write memory.
We can completely ignore them here. */
- if (get_irn_op(get_Call_mem(irn)) == op_NoMem)
+ if (is_NoMem(get_Call_mem(irn)))
return;
/* We iterate over the parameters of this call nodes.*/
for ( i = get_Call_n_params(irn) - 1; i >= 0; i--) {
param = get_Call_param(irn, i);
- if(get_irn_op(param) == op_Sel) {
+ if (is_Sel(param)) {
/* We have found a parameter with operation sel.*/
key_sels.sel = param;
value_sels = set_find(env->set_sels, &key_sels, sizeof(key_sels), HASH_PTR(key_sels.sel));
/* We have found a call, that have as parameter a sel from our set_sels.*/
call_ptr = get_Call_ptr(irn);
- op = get_irn_op(call_ptr);
- if(op == op_SymConst && get_SymConst_kind(call_ptr) == symconst_addr_ent) {
+ if (is_SymConst(call_ptr) && get_SymConst_kind(call_ptr) == symconst_addr_ent) {
meth_ent = get_SymConst_entity(call_ptr);
/* we get the access type for our sel.*/
acces_type = get_method_param_access(meth_ent, i);
remove_critical_cf_edges(irg);
/* Call algorithm that computes the out edges.*/
- if (get_irg_outs_state(irg) != outs_consistent)
- compute_irg_outs(irg);
+ assure_irg_outs(irg);
/* Call algorithm that computes the loop information.*/
- compute_loop_info(irg);
+ construct_cf_backedges(irg);
+
/* Call algorithm that computes the dominance information.*/
- compute_doms(irg);
+ assure_doms(irg);
/* Find possible scalar replacements */
if (find_possible_replacements(irg)) {
for (i = 0 ; i < get_irn_n_outs(irg_frame); i++) {
ir_node *succ = get_irn_out(irg_frame, i);
- if (get_irn_op(succ) == op_Sel) {
+ if (is_Sel(succ)) {
ir_entity *ent = get_Sel_entity(succ);
if (get_entity_link(ent) == NULL || get_entity_link(ent) == ADDRESS_TAKEN)
}
}
- if(get_firm_verbosity())
- printf("vnumber in data flow= %i\n", vnum);
-
/* Allocate value number for the globule memory edge.
* and a value number for the value numbers state.*/
vnum = vnum + 2;