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
7b0fa77b
Commit
7b0fa77b
authored
Aug 03, 2007
by
Matthias Braun
Browse files
more conv_conv optimisations
[r15462]
parent
852719b5
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/ia32_optimize.c
View file @
7b0fa77b
...
...
@@ -373,14 +373,14 @@ static int is_addr_candidate(const ir_node *irn)
right
=
get_irn_n
(
irn
,
3
);
if
(
pred_is_specific_nodeblock
(
block
,
left
,
is_ia32_Ld
))
{
n
=
ia32_get_irn_n_edges
(
left
);
n
=
ia32_get_irn_n_edges
(
left
);
/* load with only one user: don't create LEA */
if
(
n
==
1
)
return
0
;
}
if
(
pred_is_specific_nodeblock
(
block
,
right
,
is_ia32_Ld
))
{
n
=
ia32_get_irn_n_edges
(
right
);
n
=
ia32_get_irn_n_edges
(
right
);
if
(
n
==
1
)
return
0
;
}
...
...
@@ -1163,14 +1163,19 @@ static void optimize_load_conv(ir_node *node)
static
void
optimize_conv_conv
(
ir_node
*
node
)
{
ir_node
*
pred
,
*
result_conv
;
ir_node
*
pred_proj
,
*
pred
,
*
result_conv
;
ir_mode
*
pred_mode
,
*
conv_mode
;
if
(
!
is_ia32_Conv_I2I
(
node
)
&&
!
is_ia32_Conv_I2I8Bit
(
node
))
return
;
assert
(
n_ia32_Conv_I2I_val
==
n_ia32_Conv_I2I8Bit_val
);
pred
=
get_irn_n
(
node
,
n_ia32_Conv_I2I_val
);
pred_proj
=
get_irn_n
(
node
,
n_ia32_Conv_I2I_val
);
if
(
is_Proj
(
pred_proj
))
pred
=
get_Proj_pred
(
pred_proj
);
else
pred
=
pred_proj
;
if
(
!
is_ia32_Conv_I2I
(
pred
)
&&
!
is_ia32_Conv_I2I8Bit
(
pred
))
return
;
...
...
@@ -1178,30 +1183,48 @@ static void optimize_conv_conv(ir_node *node)
* so we only need the 2nd conv if it shrinks the mode */
conv_mode
=
get_ia32_ls_mode
(
node
);
pred_mode
=
get_ia32_ls_mode
(
pred
);
i
f
(
get_mode_size_bits
(
conv_mode
)
<
get_mode_size_bits
(
pred
_mode
))
return
;
/* adjust for signedness
*/
if
(
get_mode_si
gn
(
conv_mode
)
!
=
get_mode_si
gn
(
pred_mode
))
{
i
r_mode
*
mode
;
if
(
mode_is_signed
(
conv_mode
))
{
mode
=
find_signed
_mode
(
pred_mode
);
i
r_fprintf
(
stderr
,
"Looking at %+F(%+F) and %+F(%+F)
\n
"
,
node
,
conv
_mode
,
pred
,
pred_mode
)
;
/* if 2nd conv is smaller then first conv, then we can always take the 2nd
* conv
*/
if
(
get_mode_si
ze_bits
(
conv_mode
)
<
=
get_mode_si
ze_bits
(
pred_mode
))
{
i
f
(
get_irn_n_edges
(
pred_proj
)
==
1
)
{
result_conv
=
pred_proj
;
set_ia32_ls
_mode
(
pred
,
conv
_mode
);
}
else
{
mode
=
find_unsigned_mode
(
pred_mode
);
}
/* TODO: construct syncs/stuff here but we'll probably end up with
* 2 statements anyway */
if
(
get_irn_mode
(
pred
)
==
mode_T
)
{
fprintf
(
stderr
,
"skipping replacement becaue of n_edges > 1
\n
"
);
return
;
}
result_conv
=
exact_copy
(
pred
);
set_ia32_ls_mode
(
result_conv
,
mode
);
result_conv
=
exact_copy
(
pred
);
set_ia32_ls_mode
(
result_conv
,
conv_mode
);
}
}
else
{
result_conv
=
pred
;
/* if both convs have the same sign, then we can take the smaller one */
if
(
get_mode_sign
(
conv_mode
)
==
get_mode_sign
(
pred_mode
))
{
result_conv
=
pred_proj
;
}
else
{
/* no optimisation possible if smaller conv is sign-extend */
if
(
mode_is_signed
(
pred_mode
))
{
ir_fprintf
(
stderr
,
"Not optimising
\n
"
);
return
;
}
/* we can take the smaller conv if it is unsigned */
result_conv
=
pred_proj
;
}
}
/* kill the conv */
ir_fprintf
(
stderr
,
"replace %+F with %+F
\n
"
,
node
,
result_conv
);
exchange
(
node
,
result_conv
);
if
(
get_irn_n_edges
(
pred
)
==
0
)
{
be_kill_node
(
pred
);
}
optimize_conv_conv
(
result_conv
);
}
static
void
optimize_node
(
ir_node
*
node
,
void
*
env
)
...
...
@@ -1449,12 +1472,14 @@ static void optimize_am(ir_node *irn, void *env) {
if
(
get_irn_n_edges
(
right
)
>
1
)
{
source_possible
=
0
;
}
#if 1
/* TODO: this isn't really needed, but the code below is buggy
as heights won't get recomputed when the graph is reconstructed
so we can only transform loads with the result proj only */
if
(
get_irn_n_edges
(
load
)
>
1
)
{
source_possible
=
0
;
}
#endif
}
if
(
source_possible
)
{
...
...
ir/be/ia32/ia32_spec.pl
View file @
7b0fa77b
...
...
@@ -1297,6 +1297,7 @@ CopyB_i => {
# Conversions
Conv_I2I
=>
{
state
=>
"
exc_pinned
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
gp
",
"
none
"
],
out
=>
[
"
in_r3
",
"
none
"
]
},
units
=>
[
"
GP
"
],
ins
=>
[
"
base
",
"
index
",
"
val
",
"
mem
"
],
...
...
@@ -1307,6 +1308,7 @@ Conv_I2I => {
},
Conv_I2I8Bit
=>
{
state
=>
"
exc_pinned
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
eax ebx ecx edx
",
"
none
"
],
out
=>
[
"
in_r3
",
"
none
"
]
},
ins
=>
[
"
base
",
"
index
",
"
val
",
"
mem
"
],
units
=>
[
"
GP
"
],
...
...
ir/be/ia32/ia32_transform.c
View file @
7b0fa77b
...
...
@@ -1563,7 +1563,13 @@ static ir_node *gen_Load(ir_node *node) {
if
(
mode
==
mode_b
)
mode
=
mode_Iu
;
new_op
=
new_rd_ia32_Load
(
dbgi
,
irg
,
block
,
lptr
,
noreg
,
new_mem
);
/* create a conv node with address mode for smaller modes */
if
(
get_mode_size_bits
(
mode
)
<
32
)
{
new_op
=
new_rd_ia32_Conv_I2I
(
dbgi
,
irg
,
block
,
lptr
,
noreg
,
noreg
,
new_mem
,
mode
);
}
else
{
new_op
=
new_rd_ia32_Load
(
dbgi
,
irg
,
block
,
lptr
,
noreg
,
new_mem
);
}
res_mode
=
mode_Iu
;
}
...
...
@@ -3777,6 +3783,13 @@ static ir_node *gen_Proj_Load(ir_node *node) {
}
else
if
(
proj
==
pn_Load_M
)
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_M
,
pn_ia32_Load_M
);
}
}
else
if
(
is_ia32_Conv_I2I
(
new_pred
))
{
set_irn_mode
(
new_pred
,
mode_T
);
if
(
proj
==
pn_Load_res
)
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_Iu
,
0
);
}
else
if
(
proj
==
pn_Load_M
)
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_M
,
1
);
}
}
else
if
(
is_ia32_xLoad
(
new_pred
))
{
if
(
proj
==
pn_Load_res
)
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_xmm
,
pn_ia32_xLoad_res
);
...
...
Write
Preview
Supports
Markdown
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