Ada bound checks

Dear Duncan,

Everything worked out with your help. Thanks. I'm now looking at bound
checks that an Ada program has, so I can remove all possible. It seams
that Ada already does some optimization to remove bound checks. Do you
know how are they done, and where?

I tested two codes (below) and the first code did not produce any bound
check and the second produced two bound checks.

Hi Andre,

Everything worked out with your help. Thanks. I'm now looking at bound
checks that an Ada program has, so I can remove all possible. It seams
that Ada already does some optimization to remove bound checks. Do you
know how are they done, and where?

yes, the front-end doesn't generate range checks in cases where it knows
that everything is ok. It tries hard to catch all simple cases, since
range checks are very expensive. I think this basically means that the
array bounds are known constants (they need not be constant in Ada, a
common example is strings), and the index is too. I think this is done
in ada/checks.adb, search for calls to Compile_Time_Known_Value. Also,
I think the front-end can handle simple symbolic cases like:
   for I in A'Range loop ... do something with A(I)... end loop;

By the way, you can see what the front-end is sending to the rest
of gcc by compiling with the -gnatdg flag.
Also, to get all checks required by the language you need to compile
with -gnato. This checks for overflow in all integer computations
(this is off by default because the generated code is so slow).

I tested two codes (below) and the first code did not produce any bound
check

Yes, it is too simple. The LLVM optimizers would almost certainly also
have removed the checks.

and the second produced two bound checks.

You might say four checks, since it does lower and upper bound checks
for each array access.

Ciao,

Duncan.

PS: You might want to take a look at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30911
This is more of a VRP example, but perhaps the kind of pass you have
in mind can help. In theory every call to __gnat_rcheck_12 can be
eliminated, but currently there are 13 calls that llvm fails to remove.
That's mostly because llvm is not informed that Source_First and
Source_Last have values in the range 0 .. 100, and Target_First in the
range 10 .. 20.