[Ada] fix overoptimization wrt volatile

Olivier Hainque hainque@adacore.com
Mon Sep 22 11:56:00 GMT 2008


Hello,

gigi's decision about whether an entity may be considered constant for
code generation purposes starts with

  gnat_to_gnu_entity:
  ...
  case E_Variable:
    ...
    object:

        bool const_flag
          = ((kind == E_Constant || kind == E_Variable)
             && Is_True_Constant (gnat_entity)
             && (((Nkind (Declaration_Node (gnat_entity))
                   == N_Object_Declaration)
                  && Present (Expression (Declaration_Node (gnat_entity))))
                 || Present (Renamed_Object (gnat_entity))));

Is_True_Constant conveys information only about explicit assignments
to the object and there is no check against volatileness here.

A visible outcome is a too aggressive optimization of this simple testcase:

   procedure volatile3 is

      v1 : Integer := 0;
      v2 : Integer := 0;
      pragma Volatile (v1);
      pragma Volatile (v2);
   begin
      if v1 /= v2 then
         raise Program_Error;
      end if;
   end;

into

    ada_volatile3:
    .LFB1:
            .cfi_startproc
            .cfi_personality 0x3,__gnat_eh_personality
            ret
            .cfi_endproc
    .LFE1:

on x86_64-linux for instance.

This patch fixes the bug by adding the missing check to the predicate.

Bootstrapped and regression-tested on x86_64-suse-linux.


2008-09-22  Olivier Hainque  <hainque@adacore.com>

        ada/
        * gcc-interface/decl.c (gnat_to_gnu_entity): Even when they
        are never assigned, volatile entities are not constant for code
        generation purposes.

        testsuite/
        * gnat.dg/volatile3.adb: New test.

-------------- next part --------------
Index: ada/gcc-interface/decl.c
===================================================================
*** ada/gcc-interface/decl.c	(revision 140393)
--- ada/gcc-interface/decl.c	(working copy)
*************** gnat_to_gnu_entity (Entity_Id gnat_entit
*** 548,553 ****
--- 548,554 ----
  	bool const_flag
  	  = ((kind == E_Constant || kind == E_Variable)
  	     && Is_True_Constant (gnat_entity)
+ 	     && !Treat_As_Volatile (gnat_entity)
  	     && (((Nkind (Declaration_Node (gnat_entity))
  		   == N_Object_Declaration)
  		  && Present (Expression (Declaration_Node (gnat_entity))))
Index: testsuite/gnat.dg/volatile3.adb
===================================================================
*** testsuite/gnat.dg/volatile3.adb	(revision 0)
--- testsuite/gnat.dg/volatile3.adb	(revision 0)
***************
*** 0 ****
--- 1,16 ----
+ -- { dg-do compile }
+ -- { dg-options "-O2" }
+ 
+ procedure volatile3 is
+ 
+    v1 : Integer := 0;
+    v2 : Integer := 0;
+    pragma Volatile (v1);
+    pragma Volatile (v2);
+ begin
+    if v1 /= v2 then
+       raise Program_Error;
+    end if;
+ end;
+ 
+ -- { dg-final { scan-assembler "__gnat_rcheck" } }


More information about the Gcc-patches mailing list