[Ada] Implement -fpreserve-control-flow in front end

Arnaud Charlet charlet@adacore.com
Mon Apr 20 09:04:00 GMT 2009


This switch is primarily a back end switch to preserve control
flow for object level coverage analysis. This patch implements
the switch in the front end to deal with suppressing a couple
of cases where the front end would otherwise do improper
control flow optimizations.

The following test program:

function Cflow (X : Boolean) return Boolean is
begin
   if X then
      return True;
   else
      return False;
   end if;
end;

compiled with -gnatG -O2 -fpreserve-control-flow (with a back-end that
implements this switch) must generate:

Source recreated from tree for Cflow (body)
-------------------------------------------


function cflow (x : boolean) return boolean is
begin
   if x then
      return true;
   else
      return false;
   end if;
end cflow;

In the absence of this patch, the front end yielded:

function cflow (x : boolean) return boolean is
begin
   return x;
end cflow;

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

2009-04-20  Robert Dewar  <dewar@adacore.com>

	* exp_ch5.adb, usage.adb, back_end.adb, opt.ads: Implement
	front-end part of -fpreserve-control-flow switch.

-------------- next part --------------
Index: exp_ch5.adb
===================================================================
--- exp_ch5.adb	(revision 146367)
+++ exp_ch5.adb	(working copy)
@@ -3272,9 +3272,12 @@ package body Exp_Ch5 is
 
       --     return not (expression);
 
-      --  Only do these optimizations if we are at least at -O1 level
+      --  Only do these optimizations if we are at least at -O1 level and
+      --  do not do them if control flow optimizations are suppressed.
 
-      if Optimization_Level > 0 then
+      if Optimization_Level > 0
+        and then not Opt.Suppress_Control_Flow_Optimizations
+      then
          if Nkind (N) = N_If_Statement
            and then No (Elsif_Parts (N))
            and then Present (Else_Statements (N))
Index: usage.adb
===================================================================
--- usage.adb	(revision 146367)
+++ usage.adb	(working copy)
@@ -99,6 +99,9 @@ begin
 
       Write_Switch_Char ("fno-inline   ", "");
       Write_Line ("Inhibit all inlining (makes executable smaller)");
+
+      Write_Switch_Char ("fpreserve-control-flow ", "");
+      Write_Line ("Preserve control flow for coverage analysis");
    end if;
 
    --  Common switches available to both GCC and JGNAT
Index: back_end.adb
===================================================================
--- back_end.adb	(revision 146367)
+++ back_end.adb	(working copy)
@@ -219,6 +219,13 @@ package body Back_End is
 
             if Switch_Chars (First .. Last) = "fno-inline" then
                Opt.Suppress_All_Inlining := True;
+
+            --  Another special check, the switch -fpreserve-control-flow
+            --  which is also a back end switch sets the front end flag
+            --  that inhibits improper control flow transformations.
+
+            elsif Switch_Chars (First .. Last) = "fpreserve-control-flow" then
+               Opt.Suppress_Control_Flow_Optimizations := True;
             end if;
          end if;
       end Scan_Back_End_Switches;
Index: opt.ads
===================================================================
--- opt.ads	(revision 146371)
+++ opt.ads	(working copy)
@@ -1061,6 +1061,11 @@ package Opt is
    --  Set by -fno-inline. Suppresses all inlining, both front end and back end
    --  regardless of any other switches that are set.
 
+   Suppress_Control_Flow_Optimizations : Boolean := False;
+   --  GNAT
+   --  Set by -fpreserve-control-flow. Suppresses control flow optimizations
+   --  that interfere with coverage analysis based on the object code.
+
    System_Extend_Pragma_Arg : Node_Id := Empty;
    --  GNAT
    --  Set non-empty if and only if a correct Extend_System pragma was present


More information about the Gcc-patches mailing list