+ ir_node *nn;
+ ir_node **in;
+ int i, arity;
+
+ if (is_Phi(node)) {
+ if (get_nodes_block(node) == block) {
+ /* a Phi inside target block */
+ return get_Phi_pred(node, pos);
+ }
+ /* already outside */
+ return node;
+ }
+
+ arity = get_irn_arity(node);
+ in = XMALLOCN(ir_node *, arity);
+
+ for (i = 0; i < arity; ++i) {
+ ir_node *pred = get_irn_n(node, i);
+ ir_node *pred_block = get_Block_cfgpred_block(block,pos);
+ ir_node *trans = get_translated(pred, pred_block);
+
+ /* if node is topologically first in block then
+ there is no translated predecessor.
+ We do not check cleanliness here, so pred might be not clean. */
+ if (trans == NULL)
+ in[i] = pred;
+ else
+ in[i] = trans;
+ }
+
+ nn = new_ir_node(
+ get_irn_dbg_info(node),
+ get_irn_irg(node),
+ get_Block_cfgpred_block(block, pos),
+ get_irn_op(node),
+ get_irn_mode(node),
+ arity,
+ in);
+ free(in);
+ /* We need the attribute copy here, because the Hash value of a
+ node might depend on that. */
+ copy_node_attr(get_irn_irg(node), node, nn);
+ DB((dbg, LEVEL_5, "New node %+F in %+F origin %+F\n", nn, get_Block_cfgpred_block(block, pos), node));
+
+
+ nn = optimize_node(nn);
+ DB((dbg, LEVEL_5, "New gcse optimized node %+F origin %+F\n", nn, node));
+
+ /* During the insert phase we need to compare the global value numbers
+ of blocks that do not dominate each other. 'Blocksafe' GCSE requires
+ the two equivalent nodes to be in blocks that dominate each other.
+ (see identities_cmp() in iropt.c)
+ If we do not translate a node into the predecessor block, their values
+ will not be considered equivalent. (we are at a merging block.)
+ So we have to translate a node into its predecessor block.
+ If we switched off blocksafety we will find matching values that are
+ not dominating (in loops) which we cannot use.
+
+ Also, blocksafe GCSE does not kill nn even if its value is already
+ present in the successor because the predecessor blocks do not dominate.
+ This is required for antic_in.
+
+ The nodes produced here are not necessarily in the designated block.
+ They are used to determine the value of node node.
+ If we use them for hoisting, we need to make sure that they are in the
+ designated block. fix_translated() does this job. */
+
+ return nn;
+} /* phi_translate */
+
+/**
+ * Block-walker, computes Antic_in(block).
+ *
+ * @param block the block
+ * @param ctx the walker environment
+ */
+static void compute_antic(ir_node *block, void *ctx)
+{
+ pre_env *env = (pre_env*)ctx;
+ block_info *succ_info;
+ block_info *info;
+ ir_node *succ, *value, *expr;
+ size_t size;
+ ir_valueset_iterator_t iter;
+
+ /* filter blocks from topologic walker */
+ if (! is_Block(block))
+ return;
+
+ /* no need for computations in start block */
+ if (block == env->start_block)
+ return;
+
+ /* the end block has no successor */
+ if (block == env->end_block)
+ return;
+
+ info = get_block_info(block);
+ size = ir_valueset_size(info->antic_in);
+ int n_succ;
+
+ /* This step puts all generated expression from the
+ current block into antic_in.
+ This is needs to be done in the first iteration only. */
+ if (env->first_iter) {
+ foreach_valueset(info->exp_gen, value, expr, iter) {
+ /* We will have phi nodes in antic in.
+ This should prevent special cases in several places. */
+ ir_valueset_insert(info->antic_in, value, expr);
+ }
+ }
+
+ /* TODO handle endless loops. */
+
+ n_succ = get_Block_n_cfg_outs(block);
+ if (n_succ == 1) {
+ int pos = -1;
+
+ /* find blocks position in succ's block predecessors */
+ succ = get_Block_cfg_out(block, 0);
+ pos = get_Block_cfgpred_pos(succ, block);
+ assert(pos >= 0);
+
+ succ_info = get_block_info(succ);
+ /* translate into list: we cannot insert into a set we iterate
+ * and succ might be equal to block for endless loops */
+ foreach_valueset(succ_info->antic_in, value, expr, iter) {
+ ir_node *trans, *newval;
+
+ DB((dbg, LEVEL_5, "Begin phi translate antic: expr %+F from %+F to %d\n", expr, succ, pos));
+
+ /* TODO if successor block has 1 predecessor we need no phi translation.
+ But the clean_in_block check is still needed! */
+ /* TODO phi translation and clean in block are overlapping,
+ because phi trans perhaps should know in advance if predecessors are clean. */
+ trans = phi_translate(expr, succ, pos);
+ newval = remember(trans);
+
+ DB((dbg, LEVEL_5, "----> phi translate antic: expr %+F from %+F to %d is trans %+F\n", expr, succ, pos, trans));
+
+ if (is_clean_in_block_antic(trans, block)) {
+ if (! is_irn_constlike(trans)) {
+ ir_valueset_insert(info->antic_in, newval, trans);
+ }
+ DB((dbg, LEVEL_5, " translated %+F clean in %+F\n", trans, block));
+
+ } else {
+ DB((dbg, LEVEL_5, " translated %+F not clean in %+F\n", trans, block));
+ }
+
+ /* We have to set translated anyway
+ because expr might still be hoisted _into_ block. */
+ set_translated(expr, succ, pos, trans);
+
+ DB((dbg, LEVEL_5, "- end: expr %+F -----\n\n", expr));
+ }
+
+ } else if (n_succ > 1) {
+ ir_node *succ0;
+ block_info *succ0_info;
+ int i, common = 1;
+
+ /* Select a successor to compute the disjoint of all nodes
+ sets, it might be useful to select the block with the
+ smallest number of nodes. For simplicity we choose the
+ first one. */
+ succ0 = get_Block_cfg_out(block, 0);
+ succ0_info = get_block_info(succ0);
+
+ foreach_valueset(succ0_info->antic_in, value, expr, iter) {
+ /* we need the disjoint */
+ for (i = 1; i < n_succ; ++i) {
+ ir_node *succ = get_Block_cfg_out(block, i);
+ block_info *succ_info = get_block_info(succ);
+
+ if (ir_valueset_lookup(succ_info->antic_in, value) == NULL) {
+ common = 0;
+ break;
+ }
+ }
+
+ if (common) {
+ /* we found a value that is common in all Antic_in(succ(b)),
+ put it in Antic_in(b) if the value is not already represented. */
+ if (is_clean_in_block_antic(expr, block)) {
+ ir_valueset_insert(info->antic_in, value, expr);
+ }
+ set_translated(expr, succ0, 0, expr);
+
+ } else {
+ set_translated(expr, succ0, 0, expr);
+ }
+
+ }
+ }
+
+ dump_value_set(info->antic_in, "Antic_in", block);
+ if (size != ir_valueset_size(info->antic_in)) {
+ env->changes |= 1;
+ }
+
+} /* compute_antic */