[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