This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix bug in predictive commoning
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 15 Apr 2008 15:58:49 +0200
- Subject: [PATCH] Fix bug in predictive commoning
This is a regression present on the mainline and 4.3 branch:
eric@linux:~/build/gcc/native32> gcc/xgcc -Bgcc -S -O3 p.adb
p.adb: In function 'P.Create':
p.adb:3: error: statement marked for throw in middle of block
# VUSE <SMT.166_294(ab)> { SMT.166 }
D.613_124 = VIEW_CONVERT_EXPR<struct
p__create__TmS___C_PAD[D.431:D.433]>(*SR.31_153)[i_125]{lb: i_4 sz:
12}.F.length;
p.adb:3: error: statement marked for throw, but doesn't
D.615_129 = SR.31__I__FSR.31__I_I__lengthSR.31__I__F.190_272;
p.adb:3: error: statement marked for throw, but doesn't
D.617_133 = SR.31__I__FSR.31__I_I__lengthSR.31__I__F.190_272;
p.adb:3: error: statement marked for throw, but doesn't
D.620_140 = SR.31__I__FSR.31__I_I__lengthSR.31__I__F.190_272;
+===========================GNAT BUG DETECTED==============================+
| 4.4.0 20080414 (experimental) [trunk revision 134253] (i586-suse-linux-gnu)
GCC error:|
| verify_stmts failed
The predictive commoning pass performs load hoisting on an expression that can
throw, thus breaking the CFG; of course this is -fnon-call-exceptions at work.
The proposed fix is to do what LIM does, i.e. to punt on these expressions.
Tested on i586-suse-linux, OK for mainline and 4.3 branch?
2008-04-15 Eric Botcazou <ebotcazou@adacore.com>
* tree-predcom.c (suitable_reference_p): Return false if the
reference can throw.
2008-04-15 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/loop_optimization1.ad[sb]: New test.
--
Eric Botcazou
Index: tree-predcom.c
===================================================================
--- tree-predcom.c (revision 134253)
+++ tree-predcom.c (working copy)
@@ -590,7 +590,8 @@ suitable_reference_p (struct data_refere
tree ref = DR_REF (a), step = DR_STEP (a);
if (!step
- || !is_gimple_reg_type (TREE_TYPE (ref)))
+ || !is_gimple_reg_type (TREE_TYPE (ref))
+ || tree_could_throw_p (ref))
return false;
if (integer_zerop (step))
package Loop_Optimization1 is
type Number is range 0 .. 127;
type Group_List is array (Positive range <>) of Number;
subtype Index is Natural range 1 .. 5;
function Groups (T : Integer) return Group_List;
pragma Import (Ada, Groups);
type Group_Chain (Length : Index := 1) is record
Groups : Group_List(1 .. Length);
end record;
type Group_Chain_List is array (Positive range <>) of Group_Chain;
function Group_Chains (T : Integer) return Group_Chain_List;
pragma Import (Ada, Group_Chains);
type R (I : Boolean) is null record;
type R_Access is access R;
type R_List is array (Positive range <>) of R_Access;
type R_List_Access is access R_List;
type D is record
L : R_List_Access;
end record;
procedure Create (A : in out D; Val : Integer);
end Loop_Optimization1;
-- { dg-do compile }
-- { dg-options "-O3" }
package body Loop_Optimization1 is
procedure Create (A : in out D; Val : Integer) is
M : constant Group_Chain_List := Group_Chains(Val);
G : constant Group_List := Groups(Val);
function Is_Visible (Group : Number) return Boolean is
begin
for I in M'Range loop
if Group = M(I).Groups(M(I).Length) then
return True;
end if;
end loop;
return False;
end;
begin
for I in A.L'Range loop
A.L(I) := new R(Is_Visible(G(I)));
end loop;
end;
end Loop_Optimization1;