public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Ada] Improved redundant null check elimination
@ 2013-10-15 11:01 Arnaud Charlet
  0 siblings, 0 replies; only message in thread
From: Arnaud Charlet @ 2013-10-15 11:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Thomas Quinot

[-- Attachment #1: Type: text/plain, Size: 1243 bytes --]

This change improves the circuitry that is responsible for eliminating
checks in the right hand side of short circuit operators, when the left
hand side contains a test that guarantees the check can't fail.

The following test must show no "raise containt_error" nodes in expanded
code:

gcc -c k.adb -gnatG >log
grep constraint_error log

package P is
   type IP is access all Integer;
end P;
with P; use P;
function k (P : IP; I : Integer) return Boolean is
    type New_Bool is new Boolean;
begin
    if P = null or else P.all = 13 then
       return True;
    elsif Boolean'(P = null) or else P.all = 14 then
       return True;
    elsif Boolean (New_Bool (P = null)) or else P.all = 14 then
       return True;
    elsif P /= null and then P.all = 12 then
       return True;
    elsif I = 0 or else 14 / I = 2 then
       return True;
    elsif I /= 0 and then 254 / I = 7 then
       return True;
    else
       return False;
    end if;
end K;

Tested on x86_64-pc-linux-gnu, committed on trunk

2013-10-15  Thomas Quinot  <quinot@adacore.com>

	* checks.adb (Check_Needed): Handle the case where the test in
	the left operand of the short circuit is wrapped in a qualified
	expression, type conversion, or expression with actions.


[-- Attachment #2: difs --]
[-- Type: text/plain, Size: 2861 bytes --]

Index: checks.adb
===================================================================
--- checks.adb	(revision 203568)
+++ checks.adb	(working copy)
@@ -3554,6 +3554,32 @@
       L : Node_Id;
       R : Node_Id;
 
+      function Left_Expression (Op : Node_Id) return Node_Id;
+      --  Return the relevant expression from the left operand of the given
+      --  short circuit form: this is LO itself, except if LO is a qualified
+      --  expression, a type conversion, or an expression with actions, in
+      --  which case this is Left_Expression (Expression (LO)).
+
+      ---------------------
+      -- Left_Expression --
+      ---------------------
+
+      function Left_Expression (Op : Node_Id) return Node_Id is
+         LE : Node_Id := Left_Opnd (Op);
+      begin
+         while Nkind_In (LE,
+                 N_Qualified_Expression,
+                 N_Type_Conversion,
+                 N_Expression_With_Actions)
+         loop
+            LE := Expression (LE);
+         end loop;
+
+         return LE;
+      end Left_Expression;
+
+   --  Start of processing for Check_Needed
+
    begin
       --  Always check if not simple entity
 
@@ -3587,37 +3613,40 @@
 
          elsif K = N_Op_Or then
             exit when N = Right_Opnd (P)
-              and then Nkind (Left_Opnd (P)) = N_Op_Eq;
+              and then Nkind (Left_Expression (P)) = N_Op_Eq;
 
          elsif K = N_Or_Else then
             exit when (N = Right_Opnd (P)
                         or else
                           (Is_List_Member (N)
                              and then List_Containing (N) = Actions (P)))
-              and then Nkind (Left_Opnd (P)) = N_Op_Eq;
+              and then Nkind (Left_Expression (P)) = N_Op_Eq;
 
          --  Similar test for the And/And then case, where the left operand
          --  is an inequality test.
 
          elsif K = N_Op_And then
             exit when N = Right_Opnd (P)
-              and then Nkind (Left_Opnd (P)) = N_Op_Ne;
+              and then Nkind (Left_Expression (P)) = N_Op_Ne;
 
          elsif K = N_And_Then then
             exit when (N = Right_Opnd (P)
                         or else
                           (Is_List_Member (N)
                              and then List_Containing (N) = Actions (P)))
-              and then Nkind (Left_Opnd (P)) = N_Op_Ne;
+              and then Nkind (Left_Expression (P)) = N_Op_Ne;
          end if;
 
          N := P;
       end loop;
 
       --  If we fall through the loop, then we have a conditional with an
-      --  appropriate test as its left operand. So test further.
+      --  appropriate test as its left operand, so look further.
 
-      L := Left_Opnd (P);
+      L := Left_Expression (P);
+
+      --  L is an "=" or "/=" operator: extract its operands
+
       R := Right_Opnd (L);
       L := Left_Opnd (L);
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2013-10-15 10:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-15 11:01 [Ada] Improved redundant null check elimination Arnaud Charlet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).