aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2019-08-12 08:59:28 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2019-08-12 08:59:28 +0000
commit4e896dad492f7484cc239f105454713a3c4596eb (patch)
treecd09f826db06fdc86d3ce5f01813709dbebd678f /gcc/tree.c
parent5aa76fe17be6f6c222d16d5a51f60ed7755c6ad6 (diff)
downloadgcc-4e896dad492f7484cc239f105454713a3c4596eb.zip
gcc-4e896dad492f7484cc239f105454713a3c4596eb.tar.gz
gcc-4e896dad492f7484cc239f105454713a3c4596eb.tar.bz2
[Ada] Eliminate redundant range checks on conversions
This gets rid of redundant range checks generated in 5 out of the 9 cases of scalar conversions, i.e. (integer, fixed-point, floating-point) converted to (integer, fixed-point, floating-point). The problem is that the Real_Range_Check routine rewrites the conversion node into a conversion to the base type so, when its parent node is analyzed, a new conversion to the subtype may be introduced, depending on the context, giving rise to a second range check against the subtype bounds. This change makes Real_Range_Check rewrite the expression of the conversion node instead of the node, so that the type of the node is preserved and no new conversion is introduced. As a matter of fact, this is exactly what happens in the float-to-float case which goes to the Generate_Range_Check circuit instead and does not suffer from the duplication of range checks. For the following procedure, the compiler must now generate exactly one range check per nested function: procedure P is type I1 is new Integer range -100 .. 100; type I2 is new Integer range -200 .. 200; type D1 is delta 0.5 range -100.0 .. 100.0; type D2 is delta 0.5 range -200.0 .. 200.0; type F1 is new Long_Float range -100.0 .. 100.0; type F2 is new Long_Float range -200.0 .. 200.0; function Conv (A : I2) return I1 is begin return I1 (A); end; function Conv (A : D2) return I1 is begin return I1 (A); end; function Conv (A : F2) return I1 is begin return I1 (A); end; function Conv (A : I2) return D1 is begin return D1 (A); end; function Conv (A : D2) return D1 is begin return D1 (A); end; function Conv (A : F2) return D1 is begin return D1 (A); end; function Conv (A : I2) return F1 is begin return F1 (A); end; function Conv (A : D2) return F1 is begin return F1 (A); end; function Conv (A : F2) return F1 is begin return F1 (A); end; begin null; end; 2019-08-12 Eric Botcazou <ebotcazou@adacore.com> gcc/ada/ * exp_ch4.adb (Real_Range_Check): Do not rewrite the conversion node but its expression instead, after having fetched its current value. Clear the Do_Range_Check flag on entry. Return early for a rewritten float-to-float conversion. Remove redundant local variable. Suppress all checks when inserting the temporary and do not reanalyze the node. From-SVN: r274287
Diffstat (limited to 'gcc/tree.c')
0 files changed, 0 insertions, 0 deletions