/* the first SymConst of a DAG can be fold into an immediate */
#ifndef SUPPORT_NEGATIVE_SYMCONSTS
/* unfortunately the assembler/linker doesn't support -symconst */
/* the first SymConst of a DAG can be fold into an immediate */
#ifndef SUPPORT_NEGATIVE_SYMCONSTS
/* unfortunately the assembler/linker doesn't support -symconst */
left = get_Add_left(node);
right = get_Add_right(node);
eat_immediate(addr, left, negate);
eat_immediate(addr, right, negate);
break;
case iro_Sub:
left = get_Add_left(node);
right = get_Add_right(node);
eat_immediate(addr, left, negate);
eat_immediate(addr, right, negate);
break;
case iro_Sub:
left = get_Sub_left(node);
right = get_Sub_right(node);
eat_immediate(addr, left, negate);
left = get_Sub_left(node);
right = get_Sub_right(node);
eat_immediate(addr, left, negate);
-static ir_node *eat_immediates(ia32_address_t *addr, ir_node *node, int force)
+static ir_node *eat_immediates(ia32_address_t *addr, ir_node *node,
+ ia32_create_am_flags_t flags)
- if(!force && bitset_is_set(non_address_mode_nodes, get_irn_idx(node)))
+ if (!(flags & ia32_create_am_force) &&
+ ia32_is_non_address_mode_node(node) &&
+ (!(flags & ia32_create_am_double_use) || get_irn_n_edges(node) > 2))
eat_immediate(addr, left, 0);
return eat_immediates(addr, right, 0);
}
eat_immediate(addr, left, 0);
return eat_immediates(addr, right, 0);
}
eat_immediate(addr, right, 0);
return eat_immediates(addr, left, 0);
}
eat_immediate(addr, right, 0);
return eat_immediates(addr, left, 0);
}
eat_immediate(addr, right, 1);
return eat_immediates(addr, left, 0);
}
eat_immediate(addr, right, 1);
return eat_immediates(addr, left, 0);
}
ir_node *right = get_Shl_right(node);
tarval *tv;
/* we can use shl with 1, 2 or 3 shift */
ir_node *right = get_Shl_right(node);
tarval *tv;
/* we can use shl with 1, 2 or 3 shift */
ir_fprintf(stderr, "Optimisation warning: unoptimized Shl(,0) found\n");
}
shifted_val = get_Shl_left(node);
ir_fprintf(stderr, "Optimisation warning: unoptimized Shl(,0) found\n");
}
shifted_val = get_Shl_left(node);
/* might be an add x, x */
ir_node *left = get_Add_left(node);
ir_node *right = get_Add_right(node);
/* might be an add x, x */
ir_node *left = get_Add_left(node);
ir_node *right = get_Add_right(node);
- if(!force && bitset_is_set(non_address_mode_nodes, get_irn_idx(node))) {
+ if (!(flags & ia32_create_am_force) &&
+ ia32_is_non_address_mode_node(node) &&
+ (!(flags & ia32_create_am_double_use) || get_irn_n_edges(node) > 2)) {
- eat_imms = eat_immediates(addr, node, force);
- if(eat_imms != node) {
- if(force) {
+ eat_imms = eat_immediates(addr, node, flags);
+ if (eat_imms != node) {
+ if (flags & ia32_create_am_force) {
/* We don't want to eat add x, x as shl here, so only test for real Shl
* instructions, because we want the former as Lea x, x, not Shl x, 1 */
/* We don't want to eat add x, x as shl here, so only test for real Shl
* instructions, because we want the former as Lea x, x, not Shl x, 1 */
assert(addr->base == NULL);
assert(addr->frame_entity == NULL);
addr->base = be_get_FrameAddr_frame(node);
addr->use_frame = 1;
addr->frame_entity = be_get_FrameAddr_entity(node);
return;
assert(addr->base == NULL);
assert(addr->frame_entity == NULL);
addr->base = be_get_FrameAddr_frame(node);
addr->use_frame = 1;
addr->frame_entity = be_get_FrameAddr_entity(node);
return;
- assert(force || !is_immediate(addr, left, 0));
- assert(force || !is_immediate(addr, right, 0));
+ assert(flags & ia32_create_am_force || !is_immediate(addr, left, 0));
+ assert(flags & ia32_create_am_force || !is_immediate(addr, right, 0));
- if(left != NULL && be_is_FrameAddr(left)
- && !bitset_is_set(non_address_mode_nodes, get_irn_idx(left))) {
+ if (left != NULL &&
+ be_is_FrameAddr(left) &&
+ !ia32_is_non_address_mode_node(left)) {
assert(addr->base == NULL);
assert(addr->frame_entity == NULL);
addr->base = be_get_FrameAddr_frame(left);
addr->use_frame = 1;
addr->frame_entity = be_get_FrameAddr_entity(left);
left = NULL;
assert(addr->base == NULL);
assert(addr->frame_entity == NULL);
addr->base = be_get_FrameAddr_frame(left);
addr->use_frame = 1;
addr->frame_entity = be_get_FrameAddr_entity(left);
left = NULL;
- } else if(right != NULL && be_is_FrameAddr(right)
- && !bitset_is_set(non_address_mode_nodes, get_irn_idx(right))) {
+ } else if (right != NULL &&
+ be_is_FrameAddr(right) &&
+ !ia32_is_non_address_mode_node(right)) {
assert(addr->base == NULL);
assert(addr->frame_entity == NULL);
addr->base = be_get_FrameAddr_frame(right);
assert(addr->base == NULL);
assert(addr->frame_entity == NULL);
addr->base = be_get_FrameAddr_frame(right);
case iro_Store:
/* Do not mark the pointer, because we want to turn it into AM. */
val = get_Store_value(node);
case iro_Store:
/* Do not mark the pointer, because we want to turn it into AM. */
val = get_Store_value(node);
* 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 */
* 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)) {
+ if (!value_last_used_here(lv, node, left) ||
+ !value_last_used_here(lv, 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. */
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. */
- irg_walk_graph(irg, NULL, mark_non_address_nodes, NULL);
+ irg_walk_graph(irg, NULL, mark_non_address_nodes, lv);