Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
82228630
Commit
82228630
authored
Feb 16, 2011
by
Matthias Braun
Browse files
normalize some bittest constructs
[r28381]
parent
96f04053
Changes
2
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/ia32_transform.c
View file @
82228630
...
...
@@ -1933,28 +1933,24 @@ static ir_node *get_flags_node(ir_node *node, int *pnc_out)
ir_node
*
ra
=
get_And_right
(
l
);
if
(
is_Shl
(
la
))
{
ir_node
*
c
=
get_Shl_left
(
la
);
if
(
is_Const_1
(
c
)
&&
(
is_Const_0
(
r
)
||
r
==
la
)
)
{
if
(
is_Const_1
(
c
)
&&
is_Const_0
(
r
))
{
/* (1 << n) & ra) */
ir_node
*
n
=
get_Shl_right
(
la
);
flags
=
gen_bt
(
pred
,
ra
,
n
);
/* we must generate a Jc/Jnc jump */
pnc
=
pnc
==
pn_Cmp_Lg
?
pn_Cmp_Lt
:
pn_Cmp_Ge
;
if
(
r
==
la
)
pnc
^=
pn_Cmp_Leg
;
*
pnc_out
=
ia32_pn_Cmp_unsigned
|
pnc
;
return
flags
;
}
}
if
(
is_Shl
(
ra
))
{
ir_node
*
c
=
get_Shl_left
(
ra
);
if
(
is_Const_1
(
c
)
&&
(
is_Const_0
(
r
)
||
r
==
ra
)
)
{
if
(
is_Const_1
(
c
)
&&
is_Const_0
(
r
))
{
/* la & (1 << n)) */
ir_node
*
n
=
get_Shl_right
(
ra
);
flags
=
gen_bt
(
pred
,
la
,
n
);
/* we must generate a Jc/Jnc jump */
pnc
=
pnc
==
pn_Cmp_Lg
?
pn_Cmp_Lt
:
pn_Cmp_Ge
;
if
(
r
==
ra
)
pnc
^=
pn_Cmp_Leg
;
*
pnc_out
=
ia32_pn_Cmp_unsigned
|
pnc
;
return
flags
;
}
...
...
ir/ir/iropt.c
View file @
82228630
...
...
@@ -3847,6 +3847,29 @@ static ir_node *transform_node_Proj_Cond(ir_node *proj)
return
proj
;
}
/* transform_node_Proj_Cond */
/**
* return true if the operation returns a value with exactly 1 bit set
* or none set
*/
static
bool
is_single_bit
(
const
ir_node
*
node
)
{
/* a first implementation, could be extended with vrp and others... */
if
(
is_Shl
(
node
))
{
ir_node
*
shl_l
=
get_Shl_left
(
node
);
ir_mode
*
mode
=
get_irn_mode
(
node
);
int
modulo
=
get_mode_modulo_shift
(
mode
);
/* this works if we shift a 1 and we have modulo shift */
if
(
is_Const
(
shl_l
)
&&
is_Const_one
(
shl_l
)
&&
0
<
modulo
&&
modulo
<=
(
int
)
get_mode_size_bits
(
mode
))
{
return
true
;
}
}
else
if
(
is_Const
(
node
))
{
ir_tarval
*
tv
=
get_Const_tarval
(
node
);
return
tarval_is_single_bit
(
tv
);
}
return
false
;
}
/**
* Create a 0 constant of given mode.
*/
...
...
@@ -3868,7 +3891,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
ir_node
*
right
=
get_Cmp_right
(
n
);
ir_tarval
*
tv
=
NULL
;
int
changed
=
0
;
ir_mode
*
mode
=
NULL
;
ir_mode
*
mode
=
get_irn_mode
(
left
)
;
long
proj_nr
=
get_Proj_proj
(
proj
);
/* we can evaluate some cases directly */
...
...
@@ -3882,7 +3905,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
return
new_r_Const
(
irg
,
get_tarval_b_true
());
}
case
pn_Cmp_Leg
:
if
(
!
mode_is_float
(
get_irn_mode
(
left
)
))
{
if
(
!
mode_is_float
(
mode
))
{
ir_graph
*
irg
=
get_irn_irg
(
proj
);
return
new_r_Const
(
irg
,
get_tarval_b_true
());
}
...
...
@@ -3898,7 +3921,6 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
/* Remove unnecessary conversions */
/* TODO handle constants */
if
(
is_Conv
(
left
)
&&
is_Conv
(
right
))
{
ir_mode
*
mode
=
get_irn_mode
(
left
);
ir_node
*
op_left
=
get_Conv_op
(
left
);
ir_node
*
op_right
=
get_Conv_op
(
right
);
ir_mode
*
mode_left
=
get_irn_mode
(
op_left
);
...
...
@@ -3933,7 +3955,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
* The following operations are NOT safe for floating point operations, for instance
* 1.0 + inf == 2.0 + inf, =/=> x == y
*/
if
(
mode_is_int
(
get_irn_mode
(
left
)
))
{
if
(
mode_is_int
(
mode
))
{
unsigned
lop
=
get_irn_opcode
(
left
);
if
(
lop
==
get_irn_opcode
(
right
))
{
...
...
@@ -4028,7 +4050,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
if
(
ll
==
right
)
{
ir_graph
*
irg
=
get_irn_irg
(
n
);
left
=
lr
;
right
=
create_zero_const
(
irg
,
get_irn_mode
(
left
)
);
right
=
create_zero_const
(
irg
,
mode
);
changed
|=
1
;
DBG_OPT_ALGSIM0
(
n
,
n
,
FS_OPT_CMP_OP_OP
);
}
...
...
@@ -4045,11 +4067,29 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
if
(
rl
==
left
)
{
ir_graph
*
irg
=
get_irn_irg
(
n
);
left
=
rr
;
right
=
create_zero_const
(
irg
,
get_irn_mode
(
left
)
);
right
=
create_zero_const
(
irg
,
mode
);
changed
|=
1
;
DBG_OPT_ALGSIM0
(
n
,
n
,
FS_OPT_CMP_OP_OP
);
}
}
/* Cmp(And(1bit, val), 1bit) "bit-testing" can be replaced
* by the simpler Cmp(And(1bit), val), 0) negated pnc */
if
(
is_And
(
left
))
{
ir_node
*
and0
=
get_And_left
(
left
);
ir_node
*
and1
=
get_And_right
(
left
);
if
(
is_single_bit
(
and1
))
{
ir_node
*
tmp
=
and0
;
and0
=
and1
;
and1
=
tmp
;
}
if
(
and0
==
right
&&
is_single_bit
(
and0
))
{
ir_graph
*
irg
=
get_irn_irg
(
n
);
proj_nr
=
get_negated_pnc
(
proj_nr
,
mode
);
right
=
create_zero_const
(
irg
,
mode
);
changed
|=
1
;
}
}
if
(
is_And
(
left
)
&&
is_Const
(
right
))
{
ir_node
*
ll
=
get_binop_left
(
left
);
ir_node
*
lr
=
get_binop_right
(
left
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment