@@ -958,22 +958,8 @@ class insn_info
958
958
959
959
/** mark usage here as 32 bit. */
960
960
inline void
961
- mark_myuse (int regno )
961
+ mark_myuse (int regno , int sz )
962
962
{
963
- myuse8 |= 1 << regno ;
964
- myuse16 |= 1 << regno ;
965
- myuse32 |= 1 << regno ;
966
- use8 |= 1 << regno ;
967
- use16 |= 1 << regno ;
968
- use32 |= 1 << regno ;
969
- }
970
-
971
- /** mark usage here as 32 bit. */
972
- inline void
973
- mark_myuse (rtx reg )
974
- {
975
- int regno = REGNO (reg );
976
- int sz = GET_MODE_SIZE (GET_MODE (reg ));
977
963
myuse8 |= 1 << regno ;
978
964
use8 |= 1 << regno ;
979
965
if (sz > 1 )
@@ -988,6 +974,15 @@ class insn_info
988
974
}
989
975
}
990
976
977
+ /** mark usage here as 32 bit. */
978
+ inline void
979
+ mark_myuse (rtx reg )
980
+ {
981
+ int regno = REGNO (reg );
982
+ int sz = GET_MODE_SIZE (GET_MODE (reg ));
983
+ mark_myuse (regno , sz );
984
+ }
985
+
991
986
/** mark usage as 32 bit. */
992
987
inline void
993
988
mark_use (int regno )
@@ -1526,11 +1521,11 @@ insn_info::scan ()
1526
1521
if (sz && sz <= 64 )
1527
1522
{
1528
1523
mark_hard (0 );
1529
- mark_myuse (0 );
1524
+ mark_myuse (0 , sz / 8 );
1530
1525
if (sz > 32 )
1531
1526
{
1532
1527
mark_hard (1 );
1533
- mark_myuse (1 );
1528
+ mark_myuse (1 , 4 );
1534
1529
}
1535
1530
}
1536
1531
}
@@ -1545,13 +1540,13 @@ insn_info::scan ()
1545
1540
{
1546
1541
if (REG_NREGS (reg ) > 1 )
1547
1542
for (unsigned r = REGNO (reg ); r < END_REGNO (reg ); ++ r )
1548
- mark_myuse (r );
1543
+ mark_myuse (r , 4 );
1549
1544
else
1550
1545
mark_myuse (reg );
1551
1546
}
1552
1547
}
1553
1548
/* mark stack pointer used. there could be parameters on stack*/
1554
- mark_myuse (15 );
1549
+ mark_myuse (15 , 4 );
1555
1550
/* mark scratch registers. */
1556
1551
mark_def (0 );
1557
1552
mark_def (1 );
@@ -1568,7 +1563,7 @@ insn_info::scan ()
1568
1563
if (global_regs [i ])
1569
1564
{
1570
1565
mark_hard (i );
1571
- mark_myuse (i );
1566
+ mark_myuse (i , 4 );
1572
1567
}
1573
1568
}
1574
1569
scan_rtx (pattern );
@@ -1583,38 +1578,23 @@ insn_info::scan_rtx (rtx x)
1583
1578
if (!REG_P (x ))
1584
1579
x = XEXP (x , 0 );
1585
1580
1586
- int msize = GET_MODE_SIZE (GET_MODE (x ));
1587
1581
int n0 = REG_NREGS (x );
1588
1582
if (n0 > 1 )
1589
1583
{
1590
1584
for (int n = n0 , r = REGNO (x ); n > 0 ; -- n , ++ r )
1591
1585
{
1592
- mark_myuse (r );
1586
+ mark_myuse (r , 4 );
1593
1587
multi_reg |= 1 <<r ;
1594
1588
}
1595
1589
}
1596
1590
else
1597
- {
1598
- unsigned regno = REGNO (x );
1599
- myuse8 |= 1 << regno ;
1600
- use8 |= 1 << regno ;
1601
- if (msize > 1 )
1602
- {
1603
- myuse16 |= 1 << regno ;
1604
- use16 |= 1 << regno ;
1605
- if (msize > 2 )
1606
- {
1607
- myuse32 |= 1 << regno ;
1608
- use32 |= 1 << regno ;
1609
- }
1610
- }
1611
- }
1591
+ mark_myuse (x );
1612
1592
return ;
1613
1593
}
1614
1594
1615
1595
if (x == cc0_rtx )
1616
1596
{
1617
- mark_myuse (FIRST_PSEUDO_REGISTER );
1597
+ mark_myuse (FIRST_PSEUDO_REGISTER , 4 );
1618
1598
return ;
1619
1599
}
1620
1600
@@ -2145,7 +2125,7 @@ insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
2145
2125
SET_INSN_DELETED (insn );
2146
2126
insn = emit_insn_after (pattern , insn );
2147
2127
2148
- mark_myuse (regno );
2128
+ mark_myuse (regno , 4 );
2149
2129
2150
2130
insn2info -> insert (std ::make_pair (insn , this ));
2151
2131
}
@@ -3572,7 +3552,6 @@ opt_const_cmp_to_sub (void)
3572
3552
for (unsigned index = infos -> size () - 2 ; index > 0 ; -- index )
3573
3553
{
3574
3554
insn_info & i1 = (* infos )[index ];
3575
-
3576
3555
/* we wan't a compare or tst insn, */
3577
3556
if (!i1 .is_compare ())
3578
3557
continue ;
@@ -5860,6 +5839,179 @@ void print_inline_info()
5860
5839
printf (":bbb: inline weight = %4d\t%s\n" , count , get_current_function_name ());
5861
5840
}
5862
5841
5842
+ static unsigned
5843
+ opt_shift (void )
5844
+ {
5845
+ unsigned change_count = 0 ;
5846
+ for (int index = infos -> size () - 2 ; index > 0 ; -- index )
5847
+ {
5848
+ insn_info & ii = (* infos )[index ];
5849
+ // it's a shift ?
5850
+ if (ii .get_mode () != SImode || !ii .get_dst_reg () || !(ii .get_src_op () == ASHIFT || ii .get_src_op () == ASHIFTRT || ii .get_src_op () == LSHIFTRT ))
5851
+ continue ;
5852
+
5853
+ int dy = ii .get_dst_regno ();
5854
+
5855
+ // check the next insn if only a word/byte is used.
5856
+ insn_info & next = (* infos )[index + 1 ];
5857
+ int usedSize = next .getX (dy );
5858
+ if (usedSize >= 4 )
5859
+ continue ;
5860
+
5861
+ // debug(ii.get_insn());
5862
+ machine_mode mode = usedSize == 1 ? QImode : HImode ;
5863
+ int srcop = ii .get_src_op (); // can be changed
5864
+
5865
+ // are there insns like move.l dx,dy in front of that can be changed too?
5866
+ bool reduce = false;
5867
+ for (int jndex = index - 1 ; jndex > 0 ; -- jndex )
5868
+ {
5869
+ insn_info * jj = & (* infos )[jndex ];
5870
+ if (jj -> is_label ())
5871
+ break ;
5872
+
5873
+ // skip unrelated insns
5874
+ if (!jj -> is_def (dy ) && !jj -> is_myuse (dy ))
5875
+ continue ;
5876
+
5877
+ // we want sign_extend or set
5878
+ if (!jj -> is_def (dy ))
5879
+ break ;
5880
+
5881
+ // debug(jj->get_insn());
5882
+
5883
+ // there might be the use of a temp register:
5884
+ // moveq #0,dx
5885
+ // move.w dy,dx
5886
+ // move.l dx,dy <--- this one
5887
+ if (jj -> get_mode () == SImode && !jj -> get_src_op () && jj -> get_src_reg ())
5888
+ {
5889
+ int dx = jj -> get_src_regno ();
5890
+ // search the assignment for dx
5891
+
5892
+ for (int kndex = jndex - 1 ; kndex > 0 ; -- kndex )
5893
+ {
5894
+ insn_info * kk = & (* infos )[kndex ];
5895
+ if (kk -> is_label ())
5896
+ break ;
5897
+
5898
+ // skip unrelated insns
5899
+ if (!kk -> is_def (dx ) && !kk -> is_myuse (dx ))
5900
+ continue ;
5901
+
5902
+ // we want sign_extend or set
5903
+ if (!kk -> is_def (dx ))
5904
+ break ;
5905
+
5906
+ if (kk -> get_mode () == mode && !kk -> get_src_op ())
5907
+ {
5908
+ if (srcop == ASHIFTRT )
5909
+ {
5910
+ // we need a clr.l dx
5911
+ insn_info * ll = & (* infos )[kndex - 1 ];
5912
+ if (ll -> get_dst_reg () && ll -> get_dst_regno () == dx && ll -> get_mode () == SImode
5913
+ && !ll -> get_src_op () && !ll -> is_src_mem ()
5914
+ && ll -> get_src_intval () == 0 )
5915
+ {
5916
+ srcop = LSHIFTRT ;
5917
+ reduce = true;
5918
+ }
5919
+ }
5920
+ else
5921
+ reduce = true;
5922
+
5923
+ // if dx is dead after assignment to dy
5924
+ if (reduce && is_reg_dead (dx , jndex ))
5925
+ {
5926
+ // assign src to dy unless src == dy
5927
+ if (!kk -> get_src_reg () || kk -> get_src_regno () != dy )
5928
+ {
5929
+ rtx set = single_set (kk -> get_insn ());
5930
+ rtx x = gen_rtx_SET (gen_rtx_REG (mode , dy ), SET_SRC (set ));
5931
+ rtx notes = REG_NOTES (ii .get_insn ());
5932
+ rtx_insn * neu = emit_insn_before (x , kk -> get_insn ());
5933
+ REG_NOTES (neu ) = notes ;
5934
+ }
5935
+ SET_INSN_DELETED (kk -> get_insn ());
5936
+ SET_INSN_DELETED (jj -> get_insn ());
5937
+ }
5938
+ }
5939
+ break ;
5940
+ }
5941
+ break ;
5942
+ }
5943
+ // there might be one or two sign extends
5944
+ // ext.w dy
5945
+ // ext.l dy
5946
+ else if (jj -> get_mode () == SImode && jj -> get_src_op () == SIGN_EXTEND )
5947
+ {
5948
+ if (GET_MODE (jj -> get_src_reg ()) == mode )
5949
+ {
5950
+ SET_INSN_DELETED (jj -> get_insn ());
5951
+ reduce = true;
5952
+ }
5953
+ else if (mode == QImode && GET_MODE (jj -> get_src_reg ()) == HImode )
5954
+ {
5955
+ // check previous insn for 2nd SIGN_EXTEND
5956
+ insn_info * ll = & (* infos )[jndex - 1 ];
5957
+ if (ll -> get_dst_reg () && ll -> get_dst_regno () == dy
5958
+ && ll -> get_src_op () == SIGN_EXTEND
5959
+ && GET_MODE (ll -> get_src_reg ()) == QImode )
5960
+ {
5961
+ SET_INSN_DELETED (ll -> get_insn ());
5962
+ SET_INSN_DELETED (jj -> get_insn ());
5963
+ reduce = true;
5964
+ }
5965
+ }
5966
+ }
5967
+ // move.b ..,dy or move.w ...,dy
5968
+ else if (jj -> get_mode () == mode )
5969
+ {
5970
+ if (srcop == ASHIFT )
5971
+ reduce = true;
5972
+ else if (srcop == ASHIFTRT )
5973
+ {
5974
+ // we need a clr.l dy
5975
+ insn_info * ll = & (* infos )[jndex - 1 ];
5976
+ if (ll -> get_dst_reg () && ll -> get_dst_regno () == dy && ll -> get_mode () == SImode
5977
+ && !ll -> get_src_op () && !ll -> is_src_mem ()
5978
+ && ll -> get_src_intval () == 0 )
5979
+ {
5980
+ srcop = LSHIFTRT ;
5981
+ reduce = true;
5982
+ }
5983
+ }
5984
+ }
5985
+
5986
+ break ;
5987
+ }
5988
+
5989
+ if (reduce )
5990
+ {
5991
+ rtx op1 = XEXP (SET_SRC (PATTERN (ii .get_insn ())), 1 );
5992
+ rtx r = gen_rtx_REG (mode , dy );
5993
+ rtx shift ;
5994
+ if (srcop == ASHIFT )
5995
+ shift = gen_rtx_ASHIFT (mode , r , op1 );
5996
+ else if (srcop == ASHIFTRT )
5997
+ shift = gen_rtx_ASHIFTRT (mode , r , op1 );
5998
+ else
5999
+ shift = gen_rtx_LSHIFTRT (mode , r , op1 );
6000
+ rtx x = gen_rtx_SET (r , shift );
6001
+ rtx notes = REG_NOTES (ii .get_insn ());
6002
+ SET_INSN_DELETED (ii .get_insn ());
6003
+
6004
+ rtx_insn * neu = emit_insn_before (x , ii .get_insn ());
6005
+ REG_NOTES (neu ) = notes ;
6006
+ ++ change_count ;
6007
+
6008
+ log ("(h) long shift replaced with shorter variant for %s\n" , reg_names [ii .get_dst_regno ()]);
6009
+ }
6010
+ }
6011
+ return change_count ;
6012
+ }
6013
+
6014
+
5863
6015
namespace
5864
6016
{
5865
6017
@@ -5943,6 +6095,7 @@ namespace
5943
6095
bool do_const_cmp_to_sub = strchr (string_bbb_opts , 'c' ) || strchr (string_bbb_opts , '+' );
5944
6096
bool do_elim_dead_assign = strchr (string_bbb_opts , 'e' ) || strchr (string_bbb_opts , '+' );
5945
6097
bool do_shrink_stack_frame = strchr (string_bbb_opts , 'f' ) || strchr (string_bbb_opts , '+' );
6098
+ bool do_handle_shift = strchr (string_bbb_opts , 'h' ) || strchr (string_bbb_opts , '+' );
5946
6099
bool do_autoinc = strchr (string_bbb_opts , 'i' ) || strchr (string_bbb_opts , '+' );
5947
6100
bool do_lea_mem = strchr (string_bbb_opts , 'l' ) || strchr (string_bbb_opts , '+' );
5948
6101
bool do_merge_add = strchr (string_bbb_opts , 'm' ) || strchr (string_bbb_opts , '+' );
@@ -5959,6 +6112,9 @@ namespace
5959
6112
unsigned r = update_insns ();
5960
6113
if (!r )
5961
6114
{
6115
+ if (do_handle_shift && opt_shift ())
6116
+ update_insns ();
6117
+
5962
6118
if (do_lea_mem && opt_lea_mem ())
5963
6119
update_insns ();
5964
6120
0 commit comments