Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
3f57d89f
Commit
3f57d89f
authored
Sep 06, 2010
by
Matthias Braun
Browse files
remove Abs node, backends can match the abs patterns themselfes
[r27968]
parent
5e24c17a
Changes
19
Hide whitespace changes
Inline
Side-by-side
include/libfirm/firmstat.h
View file @
3f57d89f
...
...
@@ -96,7 +96,6 @@ enum firmstat_optimizations_t {
FS_OPT_MUX_TRANSFORM
,
/**< Mux(t ==/!= f, t, f) = f/t, Mux(t ==/!= 0, -t, t) = -t/t */
FS_OPT_MUX_TO_MIN
,
/**< Mux(a < b, a, b) = Min(a,b) */
FS_OPT_MUX_TO_MAX
,
/**< Mux(a > b, a, b) = Max(a,b) */
FS_OPT_MUX_TO_ABS
,
/**< Mux(a > 0, a, -a) = Abs(a) */
FS_OPT_MUX_TO_BITOP
,
/**< Mux((a & 2^x) ==/!= 0, 2^x, 0) = (a & 2^x) (xor 2^x) */
FS_OPT_IDEM_UNARY
,
/**< Idempotent unary operation */
FS_OPT_MINUS_NOT
,
/**< -(~x) = x + 1 */
...
...
@@ -104,7 +103,6 @@ enum firmstat_optimizations_t {
FS_OPT_NOT_PLUS_1
,
/**< ~x + 1 = -x */
FS_OPT_ADD_X_NOT_X
,
/**< ~x + x = -1 */
FS_OPT_FP_INV_MUL
,
/**< x / y = x * (1.0/y) */
FS_OPT_ABS_MINUS_X
,
/**< Abs(-x) = Abs(x) */
FS_OPT_CONST_PHI
,
/**< Constant evaluation on Phi */
FS_OPT_PREDICATE
,
/**< Predicate optimization */
FS_OPT_DEMORGAN
,
/**< optimization using DeMorgan's law */
...
...
include/libfirm/ircons.h
View file @
3f57d89f
...
...
@@ -272,7 +272,6 @@
* ir_node *new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state);
* ir_node *new_Div (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state);
* ir_node *new_Mod (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state;
* ir_node *new_Abs (ir_node *op, ir_mode *mode);
* ir_node *new_And (ir_node *op1, ir_node *op2, ir_mode *mode);
* ir_node *new_Or (ir_node *op1, ir_node *op2, ir_mode *mode);
* ir_node *new_Eor (ir_node *op1, ir_node *op2, ir_mode *mode);
...
...
@@ -720,11 +719,6 @@
*
* Trivial.
*
* ir_node *new_Abs (ir_node *op, ir_mode *mode)
* ---------------------------------------------
*
* Trivial.
*
* ir_node *new_And (ir_node *op1, ir_node *op2, ir_mode *mode)
* ------------------------------------------------------------
*
...
...
@@ -1555,16 +1549,6 @@ FIRM_API ir_node *new_rd_Mod(dbg_info *db, ir_node *block, ir_node *memop,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a Abs node.
*
* @param *db A pointer for debug information.
* @param *block The IR block the node belongs to.
* @param *op The operand
* @param *mode The mode of the operands and the result.
*/
FIRM_API
ir_node
*
new_rd_Abs
(
dbg_info
*
db
,
ir_node
*
block
,
ir_node
*
op
,
ir_mode
*
mode
);
/** Constructor for a And node.
*
* @param *db A pointer for debug information.
...
...
@@ -2312,14 +2296,6 @@ FIRM_API ir_node *new_r_Mod(ir_node *block, ir_node *memop,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a Abs node.
*
* @param *block The IR block the node belongs to.
* @param *op The operand
* @param *mode The mode of the operands and the result.
*/
FIRM_API
ir_node
*
new_r_Abs
(
ir_node
*
block
,
ir_node
*
op
,
ir_mode
*
mode
);
/** Constructor for a And node.
*
* @param *block The IR block the node belongs to.
...
...
@@ -3077,16 +3053,6 @@ FIRM_API ir_node *new_d_Mod(dbg_info *db, ir_node *memop,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a Abs node.
*
* Adds the node to the block in current_ir_block.
*
* @param *db A pointer for debug information.
* @param *op The operand
* @param *mode The mode of the operands and the result.
*/
FIRM_API
ir_node
*
new_d_Abs
(
dbg_info
*
db
,
ir_node
*
op
,
ir_mode
*
mode
);
/** Constructor for a And node.
*
* Adds the node to the block in current_ir_block.
...
...
@@ -3833,15 +3799,6 @@ FIRM_API ir_node *new_DivRL(ir_node *memop, ir_node *op1, ir_node *op2,
FIRM_API
ir_node
*
new_Mod
(
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a Abs node.
*
* Adds the node to the block in current_ir_block.
*
* @param *op The operand
* @param *mode The mode of the operands and the result.
*/
FIRM_API
ir_node
*
new_Abs
(
ir_node
*
op
,
ir_mode
*
mode
);
/** Constructor for a And node.
*
* Adds the node to the block in current_ir_block.
...
...
include/libfirm/nodeops.h
View file @
3f57d89f
...
...
@@ -198,8 +198,6 @@ typedef enum {
/** Return true of the node is a ASM node. */
FIRM_API
int
is_ASM
(
const
ir_node
*
node
);
/** Return true of the node is a Abs node. */
FIRM_API
int
is_Abs
(
const
ir_node
*
node
);
/** Return true of the node is a Add node. */
FIRM_API
int
is_Add
(
const
ir_node
*
node
);
/** Return true of the node is a Alloc node. */
...
...
@@ -321,9 +319,6 @@ FIRM_API void set_ASM_clobbers(ir_node *node, ident** clobbers);
FIRM_API
ident
*
get_ASM_text
(
const
ir_node
*
node
);
FIRM_API
void
set_ASM_text
(
ir_node
*
node
,
ident
*
text
);
FIRM_API
ir_node
*
get_Abs_op
(
const
ir_node
*
node
);
void
set_Abs_op
(
ir_node
*
node
,
ir_node
*
op
);
FIRM_API
ir_node
*
get_Add_left
(
const
ir_node
*
node
);
void
set_Add_left
(
ir_node
*
node
,
ir_node
*
left
);
FIRM_API
ir_node
*
get_Add_right
(
const
ir_node
*
node
);
...
...
include/libfirm/opcodes.h
View file @
3f57d89f
...
...
@@ -6,7 +6,6 @@
/** The opcodes of the libFirm predefined operations. */
typedef
enum
ir_opcode
{
iro_ASM
,
iro_Abs
,
iro_Add
,
iro_Alloc
,
iro_Anchor
,
...
...
@@ -89,7 +88,6 @@ typedef enum ir_opcode {
FIRM_API
ir_op
*
op_ASM
;
FIRM_API
ir_op
*
op_Abs
;
FIRM_API
ir_op
*
op_Add
;
FIRM_API
ir_op
*
op_Alloc
;
FIRM_API
ir_op
*
op_Anchor
;
...
...
@@ -148,7 +146,6 @@ FIRM_API ir_op *op_Unknown;
FIRM_API
ir_op
*
get_op_ASM
(
void
);
FIRM_API
ir_op
*
get_op_Abs
(
void
);
FIRM_API
ir_op
*
get_op_Add
(
void
);
FIRM_API
ir_op
*
get_op_Alloc
(
void
);
FIRM_API
ir_op
*
get_op_Anchor
(
void
);
...
...
ir/be/betranshlp.c
View file @
3f57d89f
...
...
@@ -476,3 +476,78 @@ void be_transform_graph(ir_graph *irg, arch_pretrans_nodes *func)
edges_deactivate
(
irg
);
edges_activate
(
irg
);
}
int
be_mux_is_abs
(
ir_node
*
sel
,
ir_node
*
mux_true
,
ir_node
*
mux_false
)
{
ir_node
*
cmp_left
;
ir_node
*
cmp_right
;
ir_node
*
cmp
;
ir_mode
*
mode
;
pn_Cmp
pnc
;
if
(
!
is_Proj
(
sel
))
return
0
;
cmp
=
get_Proj_pred
(
sel
);
if
(
!
is_Cmp
(
cmp
))
return
0
;
/**
* Note further that these optimization work even for floating point
* with NaN's because -NaN == NaN.
* However, if +0 and -0 is handled differently, we cannot use the Abs/-Abs
* transformations.
*/
mode
=
get_irn_mode
(
mux_true
);
if
(
mode_honor_signed_zeros
(
mode
))
return
0
;
/* must be <, <=, >=, > */
pnc
=
get_Proj_proj
(
sel
);
switch
(
pnc
)
{
case
pn_Cmp_Ge
:
case
pn_Cmp_Gt
:
case
pn_Cmp_Le
:
case
pn_Cmp_Lt
:
case
pn_Cmp_Uge
:
case
pn_Cmp_Ug
:
case
pn_Cmp_Ul
:
case
pn_Cmp_Ule
:
break
;
default:
return
0
;
}
if
(
!
is_negated_value
(
mux_true
,
mux_false
))
return
0
;
/* must be x cmp 0 */
cmp_right
=
get_Cmp_right
(
cmp
);
if
(
!
is_Const
(
cmp_right
)
||
!
is_Const_null
(
cmp_right
))
return
0
;
cmp_left
=
get_Cmp_left
(
cmp
);
if
(
cmp_left
==
mux_false
)
{
if
(
pnc
&
pn_Cmp_Lt
)
{
return
1
;
}
else
{
assert
(
pnc
&
pn_Cmp_Gt
);
return
-
1
;
}
}
else
if
(
cmp_left
==
mux_true
)
{
if
(
pnc
&
pn_Cmp_Lt
)
{
return
-
1
;
}
else
{
assert
(
pnc
&
pn_Cmp_Gt
);
return
1
;
}
}
return
0
;
}
ir_node
*
be_get_abs_op
(
ir_node
*
sel
)
{
ir_node
*
cmp
=
get_Proj_pred
(
sel
);
ir_node
*
cmp_left
=
get_Cmp_left
(
cmp
);
return
cmp_left
;
}
ir/be/betranshlp.h
View file @
3f57d89f
...
...
@@ -91,4 +91,12 @@ void be_enqueue_preds(ir_node *node);
*/
void
be_transform_graph
(
ir_graph
*
irg
,
arch_pretrans_nodes
*
func
);
/**
* If Mux(sel, t, f) represents an Abs return 1, if it represents -Abs return
* -1, otherwise 0
*/
int
be_mux_is_abs
(
ir_node
*
sel
,
ir_node
*
mux_true
,
ir_node
*
mux_false
);
ir_node
*
be_get_abs_op
(
ir_node
*
sel
);
#endif
ir/be/ia32/bearch_ia32.c
View file @
3f57d89f
...
...
@@ -2060,53 +2060,6 @@ static void ia32_mark_remat(ir_node *node)
}
}
/**
* Check if Mux(sel, t, f) would represent an Abs (or -Abs).
*/
static
bool
mux_is_abs
(
ir_node
*
sel
,
ir_node
*
mux_true
,
ir_node
*
mux_false
)
{
ir_node
*
cmp_left
;
ir_node
*
cmp_right
;
ir_node
*
cmp
;
pn_Cmp
pnc
;
if
(
!
is_Proj
(
sel
))
return
false
;
cmp
=
get_Proj_pred
(
sel
);
if
(
!
is_Cmp
(
cmp
))
return
false
;
/* must be <, <=, >=, > */
pnc
=
get_Proj_proj
(
sel
);
switch
(
pnc
)
{
case
pn_Cmp_Ge
:
case
pn_Cmp_Gt
:
case
pn_Cmp_Le
:
case
pn_Cmp_Lt
:
case
pn_Cmp_Uge
:
case
pn_Cmp_Ug
:
case
pn_Cmp_Ul
:
case
pn_Cmp_Ule
:
break
;
default:
return
false
;
}
if
(
!
is_negated_value
(
mux_true
,
mux_false
))
return
false
;
/* must be x cmp 0 */
cmp_right
=
get_Cmp_right
(
cmp
);
if
(
!
is_Const
(
cmp_right
)
||
!
is_Const_null
(
cmp_right
))
return
0
;
cmp_left
=
get_Cmp_left
(
cmp
);
if
(
cmp_left
!=
mux_true
&&
cmp_left
!=
mux_false
)
return
false
;
return
true
;
}
/**
* Check if Mux(sel, mux_true, mux_false) would represent a Max or Min operation
*/
...
...
@@ -2254,9 +2207,6 @@ static int ia32_is_mux_allowed(ir_node *sel, ir_node *mux_false,
{
ir_mode
*
mode
;
/* we can handle Abs for all modes and compares */
if
(
mux_is_abs
(
sel
,
mux_true
,
mux_false
))
return
true
;
/* we can handle Set for all modes and compares */
if
(
mux_is_set
(
sel
,
mux_true
,
mux_false
))
return
true
;
...
...
@@ -2280,6 +2230,9 @@ static int ia32_is_mux_allowed(ir_node *sel, ir_node *mux_false,
mode
=
get_irn_mode
(
mux_true
);
if
(
get_mode_size_bits
(
mode
)
>
32
)
return
false
;
/* we can handle Abs for all modes and compares (except 64bit) */
if
(
be_mux_is_abs
(
sel
,
mux_true
,
mux_false
)
!=
0
)
return
true
;
/* we can't handle MuxF yet */
if
(
mode_is_float
(
mode
))
return
false
;
...
...
ir/be/ia32/ia32_intrinsics.c
View file @
3f57d89f
...
...
@@ -622,6 +622,7 @@ static int map_Minus(ir_node *call, void *ctx)
return
1
;
}
#if 0
/**
* Map a Abs (a_l, a_h)
*/
...
...
@@ -671,6 +672,7 @@ static int map_Abs(ir_node *call, void *ctx)
return 1;
}
#endif
#define ID(x) new_id_from_chars(x, sizeof(x)-1)
...
...
@@ -908,10 +910,6 @@ ir_entity *ia32_create_intrinsic_fkt(ir_type *method, const ir_op *op,
ent
=
&
i_ents
[
iro_Minus
];
mapper
=
map_Minus
;
break
;
case
iro_Abs
:
ent
=
&
i_ents
[
iro_Abs
];
mapper
=
map_Abs
;
break
;
case
iro_Div
:
ent
=
&
i_ents
[
iro_Div
];
mapper
=
map_Div
;
...
...
ir/be/ia32/ia32_transform.c
View file @
3f57d89f
...
...
@@ -1842,20 +1842,11 @@ static ir_node *gen_Not(ir_node *node)
return
gen_unop
(
node
,
op
,
new_bd_ia32_Not
,
match_mode_neutral
);
}
/**
* Transforms an Abs node.
*
* @return The created ia32 Abs node
*/
static
ir_node
*
gen_Abs
(
ir_node
*
node
)
static
ir_node
*
create_abs
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op
,
bool
negate
,
ir_node
*
node
)
{
ir_node
*
block
=
get_nodes_block
(
node
);
ir_node
*
new_block
=
be_transform_node
(
block
);
ir_node
*
op
=
get_Abs_op
(
node
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_mode
*
mode
=
get_irn_mode
(
node
);
ir_mode
*
mode
=
get_irn_mode
(
op
);
ir_node
*
new_op
;
ir_node
*
new_node
;
int
size
;
...
...
@@ -1878,12 +1869,20 @@ static ir_node *gen_Abs(ir_node *node)
set_ia32_op_type
(
new_node
,
ia32_AddrModeS
);
set_ia32_ls_mode
(
new_node
,
mode
);
/* TODO, implement -Abs case */
assert
(
!
negate
);
}
else
{
new_node
=
new_bd_ia32_vfabs
(
dbgi
,
new_block
,
new_op
);
SET_IA32_ORIG_NODE
(
new_node
,
node
);
if
(
negate
)
{
new_node
=
new_bd_ia32_vfchs
(
dbgi
,
new_block
,
new_node
);
SET_IA32_ORIG_NODE
(
new_node
,
node
);
}
}
}
else
{
ir_node
*
xor
,
*
sign_extension
;
ir_node
*
xor
;
ir_node
*
sign_extension
;
if
(
get_mode_size_bits
(
mode
)
==
32
)
{
new_op
=
be_transform_node
(
op
);
...
...
@@ -1897,8 +1896,13 @@ static ir_node *gen_Abs(ir_node *node)
nomem
,
new_op
,
sign_extension
);
SET_IA32_ORIG_NODE
(
xor
,
node
);
new_node
=
new_bd_ia32_Sub
(
dbgi
,
new_block
,
noreg_GP
,
noreg_GP
,
nomem
,
xor
,
sign_extension
);
if
(
negate
)
{
new_node
=
new_bd_ia32_Sub
(
dbgi
,
new_block
,
noreg_GP
,
noreg_GP
,
nomem
,
sign_extension
,
xor
);
}
else
{
new_node
=
new_bd_ia32_Sub
(
dbgi
,
new_block
,
noreg_GP
,
noreg_GP
,
nomem
,
xor
,
sign_extension
);
}
SET_IA32_ORIG_NODE
(
new_node
,
node
);
}
...
...
@@ -3292,19 +3296,25 @@ static void find_const_transform(pn_Cmp pnc, tarval *t, tarval *f,
*/
static
ir_node
*
gen_Mux
(
ir_node
*
node
)
{
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
ir_node
*
new_block
=
be_transform_node
(
block
);
ir_node
*
mux_true
=
get_Mux_true
(
node
);
ir_node
*
mux_false
=
get_Mux_false
(
node
);
ir_node
*
cond
=
get_Mux_sel
(
node
);
ir_mode
*
mode
=
get_irn_mode
(
node
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
ir_node
*
new_block
=
be_transform_node
(
block
);
ir_node
*
mux_true
=
get_Mux_true
(
node
);
ir_node
*
mux_false
=
get_Mux_false
(
node
);
ir_node
*
cond
=
get_Mux_sel
(
node
);
ir_mode
*
mode
=
get_irn_mode
(
node
);
ir_node
*
flags
;
ir_node
*
new_node
;
int
is_abs
;
pn_Cmp
pnc
;
assert
(
get_irn_mode
(
cond
)
==
mode_b
);
is_abs
=
be_mux_is_abs
(
cond
,
mux_true
,
mux_false
);
if
(
is_abs
!=
0
)
{
return
create_abs
(
dbgi
,
block
,
be_get_abs_op
(
cond
),
is_abs
<
0
,
node
);
}
/* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
if
(
mode_is_float
(
mode
))
{
ir_node
*
cmp
=
get_Proj_pred
(
cond
);
...
...
@@ -5674,7 +5684,6 @@ static void register_transformers(void)
/* first clear the generic function pointer for all ops */
be_start_transform_setup
();
be_set_transform_function
(
op_Abs
,
gen_Abs
);
be_set_transform_function
(
op_Add
,
gen_Add
);
be_set_transform_function
(
op_And
,
gen_And
);
be_set_transform_function
(
op_ASM
,
gen_ASM
);
...
...
ir/be/sparc/sparc_transform.c
View file @
3f57d89f
...
...
@@ -676,6 +676,7 @@ static ir_node *gen_Quot(ir_node *node)
new_bd_sparc_fdiv_d
,
new_bd_sparc_fdiv_q
);
}
#if 0
static ir_node *gen_Abs(ir_node *node)
{
ir_mode *const mode = get_irn_mode(node);
...
...
@@ -694,6 +695,7 @@ static ir_node *gen_Abs(ir_node *node)
return sub;
}
}
#endif
/**
* Transforms a Not node.
...
...
@@ -2018,7 +2020,6 @@ void sparc_register_transformers(void)
{
be_start_transform_setup
();
be_set_transform_function
(
op_Abs
,
gen_Abs
);
be_set_transform_function
(
op_Add
,
gen_Add
);
be_set_transform_function
(
op_And
,
gen_And
);
be_set_transform_function
(
op_Call
,
gen_Call
);
...
...
ir/ir/iropt.c
View file @
3f57d89f
...
...
@@ -254,20 +254,6 @@ static tarval *computed_value_Mul(const ir_node *n)
return
tarval_bad
;
}
/* computed_value_Mul */
/**
* Return the value of an Abs.
*/
static
tarval
*
computed_value_Abs
(
const
ir_node
*
n
)
{
ir_node
*
a
=
get_Abs_op
(
n
);
tarval
*
ta
=
value_of
(
a
);
if
(
ta
!=
tarval_bad
)
return
tarval_abs
(
ta
);
return
tarval_bad
;
}
/* computed_value_Abs */
/**
* Return the value of an And.
* Special case: a & 0, 0 & b
...
...
@@ -737,7 +723,6 @@ static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops
CASE
(
Borrow
);
CASE
(
Minus
);
CASE
(
Mul
);
CASE
(
Abs
);
CASE
(
And
);
CASE
(
Or
);
CASE
(
Eor
);
...
...
@@ -1280,13 +1265,11 @@ restart:
if
(
get_Conv_strict
(
n
))
{
ir_node
*
p
=
a
;
/* neither Minus nor
Abs nor
Confirm change the precision,
/* neither Minus nor Confirm change the precision,
so we can "look-through" */
for
(;;)
{
if
(
is_Minus
(
p
))
{
p
=
get_Minus_op
(
p
);
}
else
if
(
is_Abs
(
p
))
{
p
=
get_Abs_op
(
p
);
}
else
if
(
is_Confirm
(
p
))
{
p
=
get_Confirm_value
(
p
);
}
else
{
...
...
@@ -1296,7 +1279,7 @@ restart:
}
if
(
is_Conv
(
p
)
&&
get_Conv_strict
(
p
))
{
/* we known already, that a_mode == n_mode, and neither
Abs nor
Minus change the mode, so the second Conv
Minus change the mode, so the second Conv
can be kicked */
assert
(
get_irn_mode
(
p
)
==
n_mode
);
n
=
a
;
...
...
@@ -3276,54 +3259,6 @@ static ir_node *transform_node_Quot(ir_node *n)
return
n
;
}
/* transform_node_Quot */
/**
* Optimize Abs(x) into x if x is Confirmed >= 0
* Optimize Abs(x) into -x if x is Confirmed <= 0
* Optimize Abs(-x) int Abs(x)
*/
static
ir_node
*
transform_node_Abs
(
ir_node
*
n
)
{
ir_node
*
c
,
*
oldn
=
n
;
ir_node
*
a
=
get_Abs_op
(
n
);
ir_mode
*
mode
;
HANDLE_UNOP_PHI
(
tarval_abs
,
a
,
c
);
switch
(
classify_value_sign
(
a
))
{
case
value_classified_negative
:
mode
=
get_irn_mode
(
n
);
/*
* We can replace the Abs by -x here.
* We even could add a new Confirm here
* (if not twos complement)
*
* Note that -x would create a new node, so we could
* not run it in the equivalent_node() context.
*/
n
=
new_rd_Minus
(
get_irn_dbg_info
(
n
),
get_nodes_block
(
n
),
a
,
mode
);
DBG_OPT_CONFIRM
(
oldn
,
n
);
return
n
;
case
value_classified_positive
:
/* n is positive, Abs is not needed */
n
=
a
;
DBG_OPT_CONFIRM
(
oldn
,
n
);
return
n
;
default:
break
;
}
if
(
is_Minus
(
a
))
{
/* Abs(-x) = Abs(x) */
mode
=
get_irn_mode
(
n
);
n
=
new_rd_Abs
(
get_irn_dbg_info
(
n
),
get_nodes_block
(
n
),
get_Minus_op
(
a
),
mode
);
DBG_OPT_ALGSIM0
(
oldn
,
n
,
FS_OPT_ABS_MINUS_X
);
return
n
;
}
return
n
;
}
/* transform_node_Abs */
/**
* Optimize -a CMP -b into b CMP a.
* This works only for for modes where unary Minus
...
...
@@ -5922,11 +5857,6 @@ static ir_node *transform_node_Mux(ir_node *n)
/*
* Note: normalization puts the constant on the right side,
* so we check only one case.
*
* Note further that these optimization work even for floating point
* with NaN's because -NaN == NaN.
* However, if +0 and -0 is handled differently, we cannot use the Abs/-Abs
* transformations.
*/
if
(
is_Cmp
(
cmp
))
{
ir_node
*
cmp_r
=
get_Cmp_right
(
cmp
);
...
...
@@ -5934,30 +5864,6 @@ static ir_node *transform_node_Mux(ir_node *n)
ir_node
*
block
=
get_nodes_block
(
n
);
ir_node
*
cmp_l
=
get_Cmp_left
(
cmp
);
if
(
!
mode_honor_signed_zeros
(
mode
)
&&
is_negated_value
(
f
,
t
))
{
/* f = -t */
/* NaN's work fine with abs, so it is ok to remove Uo */
long
pnc
=
pn
&
~
pn_Cmp_Uo
;
if
(
(
cmp_l
==
t
&&
(
pnc
==
pn_Cmp_Ge
||
pnc
==
pn_Cmp_Gt
))
||
(
cmp_l
==
f
&&
(
pnc
==
pn_Cmp_Le
||
pnc
==
pn_Cmp_Lt
)))
{
/* Mux(a >/>= 0, a, -a) = Mux(a </<= 0, -a, a) ==> Abs(a) */
n
=
new_rd_Abs
(
get_irn_dbg_info
(
n
),
block
,
cmp_l
,
mode
);
DBG_OPT_ALGSIM1
(
oldn
,
cmp
,
sel
,
n
,
FS_OPT_MUX_TO_ABS
);
return
n
;
}
else
if
((
cmp_l
==
t
&&
(
pnc
==
pn_Cmp_Le
||
pnc
==
pn_Cmp_Lt
))
||
(
cmp_l
==
f
&&
(
pnc
==
pn_Cmp_Ge
||
pnc
==
pn_Cmp_Gt
)))
{
/* Mux(a </<= 0, a, -a) = Mux(a >/>= 0, -a, a) ==> -Abs(a) */
n
=
new_rd_Abs
(
get_irn_dbg_info
(
n
),
block
,
cmp_l
,
mode
);
n
=
new_rd_Minus
(
get_irn_dbg_info
(
n
),
block
,
n
,
mode
);
DBG_OPT_ALGSIM1
(
oldn
,
cmp
,
sel
,
n
,
FS_OPT_MUX_TO_ABS
);
return
n
;
}
}
if
(
mode_is_int
(
mode
))
{
/* integer only */
if
((
pn
==
pn_Cmp_Lg
||
pn
==
pn_Cmp_Eq
)
&&
is_And
(
cmp_l
))
{
...
...
@@ -6200,7 +6106,6 @@ static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops
CASE_PROJ_EX
(
Mod
);
CASE_PROJ_EX
(
DivMod
);
CASE
(
Quot
);
CASE
(
Abs
);
CASE_PROJ_EX
(
Cmp
);
CASE_PROJ_EX
(
Cond
);
CASE
(
And
);
...
...
ir/ir/irverify.c
View file @
3f57d89f
...
...
@@ -1415,25 +1415,6 @@ static int verify_node_Mod(ir_node *n, ir_graph *irg)
return
1
;
}
/**
* verify an Abs node
*/
static
int
verify_node_Abs
(
ir_node
*
n
,
ir_graph
*
irg
)