This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Reassociate X == CST1 || X == CST2 if popcount (CST2 - CST1) == 1 into ((X - CST1) & ~(CST2 - CST1)) == 0
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Zhenqiang Chen <zhenqiang dot chen at arm dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 14 Oct 2013 10:49:01 +0200
- Subject: Re: [PATCH] Reassociate X == CST1 || X == CST2 if popcount (CST2 - CST1) == 1 into ((X - CST1) & ~(CST2 - CST1)) == 0
- Authentication-results: sourceware.org; auth=none
- References: <000001ce91b3$0a947cc0$1fbd7640$ at arm dot com> <20131010111245 dot GE30970 at tucnak dot zalov dot cz> <000001cec6ef$e881b0e0$b98512a0$ at arm dot com> <20131012073934 dot GB30970 at tucnak dot zalov dot cz> <000001cec8ac$6df29e70$49d7db50$ at arm dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Mon, Oct 14, 2013 at 03:10:12PM +0800, Zhenqiang Chen wrote:
@@ -2131,6 +2133,155 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
return true;
}
+/* Optimize X == CST1 || X == CST2
+ if popcount (CST1 ^ CST2) == 1 into
+ (X & ~(CST1 ^ CST2)) == (CST1 & ~(CST1 ^ CST2)).
+ Similarly for ranges. E.g.
+ X != 2 && X != 3 && X != 10 && X != 11
+ will be transformed by the previous optimization into
+ (X - 2U) <= 1U && (X - 10U) <= 1U
+ and this loop can transform that into
+ ((X & ~8) - 2U) <= 1U. */
+
+static bool
+try_transfer_range_tests_1 (enum tree_code opcode, int i, int j, tree type,
+ tree lowi, tree lowj, tree highi, tree highj,
+ vec<operand_entry_t> *ops,
+ struct range_entry *ranges)
The function names are bad, you aren't transfering anything, but optimizing.
Please rename try_transfer_range_tests to optimize_range_tests_1 and
try_transfer_range_tests_{1,2} to optimize_range_tests_{2,3} or perhaps
better yet to optimize_range_tests_{xor,diff}.
Also, perhaps instead of passing ranges and i and j to these two functions
you could pass struct range_entry *range1, struct range_entry *range2
(caller would pass ranges + i, ranges + j).
+/* It does some common checks for function try_transfer_range_tests_1 and
+ try_transfer_range_tests_2.
Please adjust the comment for the renaming. Please change trans_option
to bool optimize_xor.
+ if (trans_option == 1)
+ {
+ if (try_transfer_range_tests_1 (opcode, i, j, type, lowi, lowj,
+ highi, highj, ops, ranges))
+ {
+ any_changes = true;
+ break;
+ }
+ }
+ else if (trans_option == 2)
+ {
+ if (try_transfer_range_tests_2 (opcode, i, j, type, lowi, lowj,
+ highi, highj, ops, ranges))
+ {
+ any_changes = true;
+ break;
+ }
+ }
I'd prefer
if (optimize_xor)
any_changes
= optimize_range_tests_xor (opcode, type, lowi, lowj, highi,
highj, ops, ranges + i, ranges + j);
else
any_changes
= optimize_range_tests_xor (opcode, type, lowi, lowj, highi,
highj, ops, ranges + i, ranges + j);
if (any_changes)
break;
Ok with those changes.
Jakub