• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

コミットメタ情報

リビジョンf4e4e414a8e9a2693b6b245c00ea11befb852283 (tree)
日時2015-04-24 13:49:34
作者thopre01 <thopre01@138b...>
コミッターthopre01

ログメッセージ

2015-04-24 Thomas Preud'homme <thomas.preudhomme@arm.com>

Steven Bosscher <steven@gcc.gnu.org>
gcc/
PR rtl-optimization/34503
    • cprop.c (cprop_reg_p): New.
      (hash_scan_set): Use above function to check if register can be
      propagated.
      (find_avail_set): Return up to two sets, one whose source is a
      register and one whose source is a constant. Sets are returned in an
      array passed as parameter rather than as a return value.
      (cprop_insn): Use a do while loop rather than a goto. Try each of the
      sets returned by find_avail_set, starting with the one whose source is
      a constant. Use cprop_reg_p to check if register can be propagated.
      (do_local_cprop): Use cprop_reg_p to check if register can be
      propagated.
      (implicit_set_cond_p): Likewise.
gcc/testsuite/
PR rtl-optimization/34503
    • gcc.target/arm/pr64616.c: New file.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@222398 138bc75d-0d04-0410-961f-82ee72b054a4

変更サマリ

差分

--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
1+2015-04-24 Thomas Preud'homme <thomas.preudhomme@arm.com>
2+ Steven Bosscher <steven@gcc.gnu.org>
3+
4+ PR rtl-optimization/34503
5+ * cprop.c (cprop_reg_p): New.
6+ (hash_scan_set): Use above function to check if register can be
7+ propagated.
8+ (find_avail_set): Return up to two sets, one whose source is a
9+ register and one whose source is a constant. Sets are returned in an
10+ array passed as parameter rather than as a return value.
11+ (cprop_insn): Use a do while loop rather than a goto. Try each of the
12+ sets returned by find_avail_set, starting with the one whose source is
13+ a constant. Use cprop_reg_p to check if register can be propagated.
14+ (do_local_cprop): Use cprop_reg_p to check if register can be
15+ propagated.
16+ (implicit_set_cond_p): Likewise.
17+
118 2015-04-23 Jan Hubicka <hubicka@ucw.cz>
219
320 * ipa-icf.c (sem_function::equals_wpa): Compare thunk info.
--- a/gcc/cprop.c
+++ b/gcc/cprop.c
@@ -285,6 +285,15 @@ cprop_constant_p (const_rtx x)
285285 return CONSTANT_P (x) && (GET_CODE (x) != CONST || shared_const_p (x));
286286 }
287287
288+/* Determine whether the rtx X should be treated as a register that can
289+ be propagated. Any pseudo-register is fine. */
290+
291+static bool
292+cprop_reg_p (const_rtx x)
293+{
294+ return REG_P (x) && !HARD_REGISTER_P (x);
295+}
296+
288297 /* Scan SET present in INSN and add an entry to the hash TABLE.
289298 IMPLICIT is true if it's an implicit set, false otherwise. */
290299
@@ -295,8 +304,7 @@ hash_scan_set (rtx set, rtx_insn *insn, struct hash_table_d *table,
295304 rtx src = SET_SRC (set);
296305 rtx dest = SET_DEST (set);
297306
298- if (REG_P (dest)
299- && ! HARD_REGISTER_P (dest)
307+ if (cprop_reg_p (dest)
300308 && reg_available_p (dest, insn)
301309 && can_copy_p (GET_MODE (dest)))
302310 {
@@ -321,9 +329,8 @@ hash_scan_set (rtx set, rtx_insn *insn, struct hash_table_d *table,
321329 src = XEXP (note, 0), set = gen_rtx_SET (VOIDmode, dest, src);
322330
323331 /* Record sets for constant/copy propagation. */
324- if ((REG_P (src)
332+ if ((cprop_reg_p (src)
325333 && src != dest
326- && ! HARD_REGISTER_P (src)
327334 && reg_available_p (src, insn))
328335 || cprop_constant_p (src))
329336 insert_set_in_table (dest, src, insn, table, implicit);
@@ -821,15 +828,15 @@ try_replace_reg (rtx from, rtx to, rtx_insn *insn)
821828 return success;
822829 }
823830
824-/* Find a set of REGNOs that are available on entry to INSN's block. Return
825- NULL no such set is found. */
831+/* Find a set of REGNOs that are available on entry to INSN's block. If found,
832+ SET_RET[0] will be assigned a set with a register source and SET_RET[1] a
833+ set with a constant source. If not found the corresponding entry is set to
834+ NULL. */
826835
827-static struct cprop_expr *
828-find_avail_set (int regno, rtx_insn *insn)
836+static void
837+find_avail_set (int regno, rtx_insn *insn, struct cprop_expr *set_ret[2])
829838 {
830- /* SET1 contains the last set found that can be returned to the caller for
831- use in a substitution. */
832- struct cprop_expr *set1 = 0;
839+ set_ret[0] = set_ret[1] = NULL;
833840
834841 /* Loops are not possible here. To get a loop we would need two sets
835842 available at the start of the block containing INSN. i.e. we would
@@ -869,8 +876,10 @@ find_avail_set (int regno, rtx_insn *insn)
869876 If the source operand changed, we may still use it for the next
870877 iteration of this loop, but we may not use it for substitutions. */
871878
872- if (cprop_constant_p (src) || reg_not_set_p (src, insn))
873- set1 = set;
879+ if (cprop_constant_p (src))
880+ set_ret[1] = set;
881+ else if (reg_not_set_p (src, insn))
882+ set_ret[0] = set;
874883
875884 /* If the source of the set is anything except a register, then
876885 we have reached the end of the copy chain. */
@@ -881,10 +890,6 @@ find_avail_set (int regno, rtx_insn *insn)
881890 and see if we have an available copy into SRC. */
882891 regno = REGNO (src);
883892 }
884-
885- /* SET1 holds the last set that was available and anticipatable at
886- INSN. */
887- return set1;
888893 }
889894
890895 /* Subroutine of cprop_insn that tries to propagate constants into
@@ -1048,40 +1053,40 @@ cprop_insn (rtx_insn *insn)
10481053 int changed = 0, changed_this_round;
10491054 rtx note;
10501055
1051-retry:
1052- changed_this_round = 0;
1053- reg_use_count = 0;
1054- note_uses (&PATTERN (insn), find_used_regs, NULL);
1055-
1056- /* We may win even when propagating constants into notes. */
1057- note = find_reg_equal_equiv_note (insn);
1058- if (note)
1059- find_used_regs (&XEXP (note, 0), NULL);
1060-
1061- for (i = 0; i < reg_use_count; i++)
1056+ do
10621057 {
1063- rtx reg_used = reg_use_table[i];
1064- unsigned int regno = REGNO (reg_used);
1065- rtx src;
1066- struct cprop_expr *set;
1058+ changed_this_round = 0;
1059+ reg_use_count = 0;
1060+ note_uses (&PATTERN (insn), find_used_regs, NULL);
10671061
1068- /* If the register has already been set in this block, there's
1069- nothing we can do. */
1070- if (! reg_not_set_p (reg_used, insn))
1071- continue;
1062+ /* We may win even when propagating constants into notes. */
1063+ note = find_reg_equal_equiv_note (insn);
1064+ if (note)
1065+ find_used_regs (&XEXP (note, 0), NULL);
10721066
1073- /* Find an assignment that sets reg_used and is available
1074- at the start of the block. */
1075- set = find_avail_set (regno, insn);
1076- if (! set)
1077- continue;
1067+ for (i = 0; i < reg_use_count; i++)
1068+ {
1069+ rtx reg_used = reg_use_table[i];
1070+ unsigned int regno = REGNO (reg_used);
1071+ rtx src_cst = NULL, src_reg = NULL;
1072+ struct cprop_expr *set[2];
10781073
1079- src = set->src;
1074+ /* If the register has already been set in this block, there's
1075+ nothing we can do. */
1076+ if (! reg_not_set_p (reg_used, insn))
1077+ continue;
10801078
1081- /* Constant propagation. */
1082- if (cprop_constant_p (src))
1083- {
1084- if (constprop_register (reg_used, src, insn))
1079+ /* Find an assignment that sets reg_used and is available
1080+ at the start of the block. */
1081+ find_avail_set (regno, insn, set);
1082+ if (set[0])
1083+ src_reg = set[0]->src;
1084+ if (set[1])
1085+ src_cst = set[1]->src;
1086+
1087+ /* Constant propagation. */
1088+ if (src_cst && cprop_constant_p (src_cst)
1089+ && constprop_register (reg_used, src_cst, insn))
10851090 {
10861091 changed_this_round = changed = 1;
10871092 global_const_prop_count++;
@@ -1091,18 +1096,16 @@ retry:
10911096 "GLOBAL CONST-PROP: Replacing reg %d in ", regno);
10921097 fprintf (dump_file, "insn %d with constant ",
10931098 INSN_UID (insn));
1094- print_rtl (dump_file, src);
1099+ print_rtl (dump_file, src_cst);
10951100 fprintf (dump_file, "\n");
10961101 }
10971102 if (insn->deleted ())
10981103 return 1;
10991104 }
1100- }
1101- else if (REG_P (src)
1102- && REGNO (src) >= FIRST_PSEUDO_REGISTER
1103- && REGNO (src) != regno)
1104- {
1105- if (try_replace_reg (reg_used, src, insn))
1105+ /* Copy propagation. */
1106+ else if (src_reg && cprop_reg_p (src_reg)
1107+ && REGNO (src_reg) != regno
1108+ && try_replace_reg (reg_used, src_reg, insn))
11061109 {
11071110 changed_this_round = changed = 1;
11081111 global_copy_prop_count++;
@@ -1111,7 +1114,7 @@ retry:
11111114 fprintf (dump_file,
11121115 "GLOBAL COPY-PROP: Replacing reg %d in insn %d",
11131116 regno, INSN_UID (insn));
1114- fprintf (dump_file, " with reg %d\n", REGNO (src));
1117+ fprintf (dump_file, " with reg %d\n", REGNO (src_reg));
11151118 }
11161119
11171120 /* The original insn setting reg_used may or may not now be
@@ -1121,12 +1124,10 @@ retry:
11211124 and made things worse. */
11221125 }
11231126 }
1124-
1125- /* If try_replace_reg simplified the insn, the regs found
1126- by find_used_regs may not be valid anymore. Start over. */
1127- if (changed_this_round)
1128- goto retry;
11291127 }
1128+ /* If try_replace_reg simplified the insn, the regs found by find_used_regs
1129+ may not be valid anymore. Start over. */
1130+ while (changed_this_round);
11301131
11311132 if (changed && DEBUG_INSN_P (insn))
11321133 return 0;
@@ -1189,7 +1190,7 @@ do_local_cprop (rtx x, rtx_insn *insn)
11891190 /* Rule out USE instructions and ASM statements as we don't want to
11901191 change the hard registers mentioned. */
11911192 if (REG_P (x)
1192- && (REGNO (x) >= FIRST_PSEUDO_REGISTER
1193+ && (cprop_reg_p (x)
11931194 || (GET_CODE (PATTERN (insn)) != USE
11941195 && asm_noperands (PATTERN (insn)) < 0)))
11951196 {
@@ -1205,7 +1206,7 @@ do_local_cprop (rtx x, rtx_insn *insn)
12051206
12061207 if (cprop_constant_p (this_rtx))
12071208 newcnst = this_rtx;
1208- if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER
1209+ if (cprop_reg_p (this_rtx)
12091210 /* Don't copy propagate if it has attached REG_EQUIV note.
12101211 At this point this only function parameters should have
12111212 REG_EQUIV notes and if the argument slot is used somewhere
@@ -1326,9 +1327,8 @@ implicit_set_cond_p (const_rtx cond)
13261327 if (GET_CODE (cond) != EQ && GET_CODE (cond) != NE)
13271328 return false;
13281329
1329- /* The first operand of COND must be a pseudo-reg. */
1330- if (! REG_P (XEXP (cond, 0))
1331- || HARD_REGISTER_P (XEXP (cond, 0)))
1330+ /* The first operand of COND must be a register we can propagate. */
1331+ if (!cprop_reg_p (XEXP (cond, 0)))
13321332 return false;
13331333
13341334 /* The second operand of COND must be a suitable constant. */
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
1+2015-04-24 Thomas Preud'homme <thomas.preudhomme@arm.com>
2+ Steven Bosscher <steven@gcc.gnu.org>
3+
4+ PR rtl-optimization/34503
5+ * gcc.target/arm/pr64616.c: New file.
6+
17 2015-04-24 Bin Cheng <bin.cheng@arm.com>
28
39 * gcc.target/arm/pr42172-1.c: Check str instead of ldr.
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr64616.c
@@ -0,0 +1,14 @@
1+/* { dg-do compile } */
2+/* { dg-options "-O2" } */
3+
4+int f (int);
5+unsigned int glob;
6+
7+void
8+g ()
9+{
10+ while (f (glob));
11+ glob = 5;
12+}
13+
14+/* { dg-final { scan-assembler-times "ldr" 2 } } */