Lines 1-5
Link Here
|
1 |
/* RTL-based forward propagation pass for GNU compiler. |
1 |
/* RTL-based forward propagation pass for GNU compiler. |
2 |
Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
2 |
Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. |
3 |
Contributed by Paolo Bonzini and Steven Bosscher. |
3 |
Contributed by Paolo Bonzini and Steven Bosscher. |
4 |
|
4 |
|
5 |
This file is part of GCC. |
5 |
This file is part of GCC. |
Lines 852-857
forward_propagate_subreg (df_ref use, rt
Link Here
|
852 |
return false; |
852 |
return false; |
853 |
} |
853 |
} |
854 |
|
854 |
|
|
|
855 |
static int |
856 |
check_reg_count_callback (rtx *px, void *data) |
857 |
{ |
858 |
int *regnop = (int *) data; |
859 |
|
860 |
if (!REG_P (*px)) |
861 |
return 0; |
862 |
|
863 |
if (*regnop < 0 || *regnop == (int) REGNO (*px)) |
864 |
{ |
865 |
*regnop = REGNO (*px); |
866 |
return 0; |
867 |
} |
868 |
|
869 |
return 1; |
870 |
} |
871 |
|
872 |
/* Try to replace USE with SRC (defined in DEF_INSN) in __asm. */ |
873 |
|
874 |
static bool |
875 |
forward_propagate_asm (df_ref use, rtx def_set, rtx reg) |
876 |
{ |
877 |
rtx use_insn = DF_REF_INSN (use), src, use_pat, asm_operands, new_rtx, *loc; |
878 |
int regno, speed_p, i; |
879 |
|
880 |
gcc_assert ((DF_REF_FLAGS (use) & DF_REF_IN_NOTE) == 0); |
881 |
|
882 |
src = SET_SRC (def_set); |
883 |
use_pat = PATTERN (use_insn); |
884 |
|
885 |
/* In __asm don't replace if src might need more registers than |
886 |
reg, as that could increase register pressure on the __asm. */ |
887 |
regno = -1; |
888 |
if (for_each_rtx (&src, check_reg_count_callback, ®no) > 0) |
889 |
return false; |
890 |
|
891 |
speed_p = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn)); |
892 |
asm_operands = NULL_RTX; |
893 |
switch (GET_CODE (use_pat)) |
894 |
{ |
895 |
case ASM_OPERANDS: |
896 |
asm_operands = use_pat; |
897 |
break; |
898 |
case SET: |
899 |
loc = &SET_DEST (use_pat); |
900 |
new_rtx = propagate_rtx (*loc, GET_MODE (*loc), reg, src, speed_p); |
901 |
if (new_rtx) |
902 |
validate_unshare_change (use_insn, loc, new_rtx, true); |
903 |
asm_operands = SET_SRC (use_pat); |
904 |
break; |
905 |
case PARALLEL: |
906 |
for (i = 0; i < XVECLEN (use_pat, 0); i++) |
907 |
if (GET_CODE (XVECEXP (use_pat, 0, i)) == SET) |
908 |
{ |
909 |
loc = &SET_DEST (XVECEXP (use_pat, 0, i)); |
910 |
new_rtx = propagate_rtx (*loc, GET_MODE (*loc), reg, src, speed_p); |
911 |
if (new_rtx) |
912 |
validate_unshare_change (use_insn, loc, new_rtx, true); |
913 |
asm_operands = SET_SRC (XVECEXP (use_pat, 0, i)); |
914 |
} |
915 |
else if (GET_CODE (XVECEXP (use_pat, 0, i)) == ASM_OPERANDS) |
916 |
asm_operands = XVECEXP (use_pat, 0, i); |
917 |
break; |
918 |
default: |
919 |
gcc_unreachable (); |
920 |
} |
921 |
|
922 |
gcc_assert (asm_operands && GET_CODE (asm_operands) == ASM_OPERANDS); |
923 |
for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (asm_operands); i++) |
924 |
{ |
925 |
loc = &ASM_OPERANDS_INPUT (asm_operands, i); |
926 |
new_rtx = propagate_rtx (*loc, GET_MODE (*loc), reg, src, speed_p); |
927 |
if (new_rtx) |
928 |
validate_unshare_change (use_insn, loc, new_rtx, true); |
929 |
} |
930 |
|
931 |
if (num_changes_pending () == 0) |
932 |
return false; |
933 |
|
934 |
if (!verify_changes (0)) |
935 |
{ |
936 |
cancel_changes (0); |
937 |
return 0; |
938 |
} |
939 |
|
940 |
confirm_change_group (); |
941 |
num_changes++; |
942 |
return true; |
943 |
} |
944 |
|
855 |
/* Try to replace USE with SRC (defined in DEF_INSN) and simplify the |
945 |
/* Try to replace USE with SRC (defined in DEF_INSN) and simplify the |
856 |
result. */ |
946 |
result. */ |
857 |
|
947 |
|
Lines 863-874
forward_propagate_and_simplify (df_ref u
Link Here
|
863 |
rtx src, reg, new_rtx, *loc; |
953 |
rtx src, reg, new_rtx, *loc; |
864 |
bool set_reg_equal; |
954 |
bool set_reg_equal; |
865 |
enum machine_mode mode; |
955 |
enum machine_mode mode; |
|
|
956 |
int asm_use = -1; |
866 |
|
957 |
|
867 |
if (!use_set) |
958 |
if (INSN_CODE (use_insn) < 0) |
|
|
959 |
asm_use = asm_noperands (PATTERN (use_insn)); |
960 |
|
961 |
if (!use_set && asm_use < 0) |
868 |
return false; |
962 |
return false; |
869 |
|
963 |
|
870 |
/* Do not propagate into PC, CC0, etc. */ |
964 |
/* Do not propagate into PC, CC0, etc. */ |
871 |
if (GET_MODE (SET_DEST (use_set)) == VOIDmode) |
965 |
if (use_set && GET_MODE (SET_DEST (use_set)) == VOIDmode) |
872 |
return false; |
966 |
return false; |
873 |
|
967 |
|
874 |
/* If def and use are subreg, check if they match. */ |
968 |
/* If def and use are subreg, check if they match. */ |
Lines 900-906
forward_propagate_and_simplify (df_ref u
Link Here
|
900 |
if (MEM_P (src) && MEM_READONLY_P (src)) |
994 |
if (MEM_P (src) && MEM_READONLY_P (src)) |
901 |
{ |
995 |
{ |
902 |
rtx x = avoid_constant_pool_reference (src); |
996 |
rtx x = avoid_constant_pool_reference (src); |
903 |
if (x != src) |
997 |
if (x != src && use_set) |
904 |
{ |
998 |
{ |
905 |
rtx note = find_reg_note (use_insn, REG_EQUAL, NULL_RTX); |
999 |
rtx note = find_reg_note (use_insn, REG_EQUAL, NULL_RTX); |
906 |
rtx old_rtx = note ? XEXP (note, 0) : SET_SRC (use_set); |
1000 |
rtx old_rtx = note ? XEXP (note, 0) : SET_SRC (use_set); |
Lines 911-916
forward_propagate_and_simplify (df_ref u
Link Here
|
911 |
return false; |
1005 |
return false; |
912 |
} |
1006 |
} |
913 |
|
1007 |
|
|
|
1008 |
if (asm_use >= 0) |
1009 |
return forward_propagate_asm (use, def_set, reg); |
1010 |
|
914 |
/* Else try simplifying. */ |
1011 |
/* Else try simplifying. */ |
915 |
|
1012 |
|
916 |
if (DF_REF_TYPE (use) == DF_REF_REG_MEM_STORE) |
1013 |
if (DF_REF_TYPE (use) == DF_REF_REG_MEM_STORE) |