- bitset_set(env->non_address_nodes, get_irn_idx(node));
-
- if(is_Load(node)) {
- ir_node *ptr = get_Load_ptr(node);
- ir_node *mem = get_Load_mem(node);
-
- mark_non_address_nodes(env, mem);
- (void) ptr;
- } else if(is_Store(node)) {
- ir_node *val = get_Store_value(node);
- ir_node *ptr = get_Store_ptr(node);
- ir_node *mem = get_Store_mem(node);
-
- mark_non_address_nodes(env, val);
- mark_non_address_nodes(env, mem);
- (void) ptr;
- } else {
- int i;
- int arity = get_irn_arity(node);
+ int i, arity;
+ ir_node *val;
+ ir_node *left;
+ ir_node *right;
+ ir_mode *mode;
+ (void) env;
+
+ mode = get_irn_mode(node);
+ if (!mode_is_int(mode) && !mode_is_reference(mode) && mode != mode_b)
+ return;
+
+ switch (get_irn_opcode(node)) {
+ case iro_Load:
+ /* Nothing to do. especially do not mark the pointer, because we want to
+ * turn it into AM. */
+ break;
+
+ case iro_Store:
+ /* Do not mark the pointer, because we want to turn it into AM. */
+ val = get_Store_value(node);
+ bitset_set(non_address_mode_nodes, get_irn_idx(val));
+ break;
+
+ case iro_Shl:
+ case iro_Add:
+ /* only 1 user: AM folding is always beneficial */
+ if (get_irn_n_edges(node) <= 1)
+ break;
+
+ /* for adds and shls with multiple users we use this heuristic:
+ * we do not fold them into address mode if their operands don't live
+ * out of the block, because in this case we will reduce register
+ * pressure. Otherwise we fold them in aggressively in the hope, that
+ * the node itself doesn't exist anymore and we were able to save the
+ * register for the result */
+ left = get_binop_left(node);
+ right = get_binop_right(node);
+
+ /* Fold AM if any of the two operands does not die here. This duplicates
+ * an addition and has the same register pressure for the case that only
+ * one operand dies, but is faster (on Pentium 4).
+ * && instead of || only folds AM if both operands do not die here */
+ if (!value_last_used_here(node, left) ||
+ !value_last_used_here(node, right)) {
+ return;
+ }
+
+ /* At least one of left and right are not used by anyone else, so it is
+ * beneficial for the register pressure (if both are unused otherwise,
+ * else neutral) and ALU use to not fold AM. */
+ bitset_set(non_address_mode_nodes, get_irn_idx(node));
+ break;