In a perform varying identifer-1 from identifier-2 when identifier-1 is the same than identifier-2 as below
PERFORM varying FLD-2 FROM FLD-2 BY -1 UNTIL FLD-2 = 0
gnucobol generates the initialization of identifier-1 by itself
/* Line: 10 : PERFORM : tstperf.cbl */
memmove (b_17, b_17, 8);
In this case we could avoid the memmove generation
I agree. Do you want to have a look in the code yourself on this or should we inspect together?
Last edit: Simon Sobisch 2024-04-21
Hi Simon
I will try to find the solution by digging in the code and propose a patch.
I will surely have questions ;-)
I guess it's there in codegen.c
We have to check that from and name are different to output_move
Yes, in this case we can do that directly here to just not generate that internal MOVE. In the function itself we can do something similar, but only if IBM move is not active (may be handled outside already) and then output a no_op call instead.
Simon
Here is a patch proposal
It passes all the test (make check , make test)
I add a test program
The patch
Thank you for investigating it! That looks very promising - but you can improve the test (same test) to also check the debug item; and for this to work you need the
is_same_reference
only around theoutput_move
, not also for the debug handling.For the new function - just add it to the local functions (no need for the extra declaration) and shorten it:
... but: is that actually correct? I think hashval is not the hash for the reference but the hash-entry for the word-table, no?
In this case the check has to be made more complicated (maybe getting field founder and offset + size [see overlapping check in typeck.c])? Doing that would also have the benefit of not doing a move if there was a simple redefine; but then again we'd need to check for the same usage as well.
I do wonder if we should add that inline (if it is small) function also in typeck.c
cb_build_move_copy()
and use this for all but the cb_move_ibm case.Hi Simon
Here is a second patch proposal including the associated tests.
This patch allows the compiler not to generate a move if and only the name of the two variables are identical
All tests are ok (make check and make test)
In a second I would try to deal with the fact that both variables are "redefines", but I need to increase my level of knowledge of GnuCobol for that ;-)
But the current patch allows, in my opinion, to cover the majority of cases
Thank you for this second iteration.
Please adjust the test title - "DHR" is not that well, possibly just "MOVE to same field"?
Is there a reason to not have a single test? Each test can also contain multiple programs (prog1.cob, prog2.cob, ....). I think the
DEBUG-ITEM
test (please add that in the keywords) can be combined with another one - either you haveCOB_SET_DEBUG=1
set or not.Please add a short comment (either in COBOL or with
#
outside) what is special about each test program (at least from a very quick glance it wasn't easy to spot).If you really want to test that the moves are not generated: add
--save-temps
to the compile command, then$GREP
for all moves (or similar).For adjusting this place, there is no need for
cob_nop
as we still (should) have the codegen of the statement. So something likeFor
is_same_var
: that possibly breaks forFROM level78constant
orFROM FUNCTION NUMVAL (VAR)
.Best seems to be something like:
then comparing if the
ref->value
(= the COBOL field) as well as thesubs
are identical. The current approach ignoresVAR1 (A) FROM VAR1(B)
. In other places (like the normalMOVE
) we'd have to also check theoffset
andlength
, but we only allow numeric items here so that doesn't apply (if you rename the function to something likeis_same_numeric_reference
)friendly ping @dhugonnard
Hi Simon
I have been very busy with my job and also wanted to find a solution that really satisfied me for the cob_decimal_pow function. The previous patch that I sent wasn't yet good enough for my taste.
I think I achieved what I wanted for this feature.
Attached you will find the patch which contains the source code as well as all the associated test programs
The principles of the modifications are as follows:
0) to calculate a^b we immediately transform a into mpt_t type to use the mpf_pow_ui function
1) before calculating a^b, we check that b*ln(a) is not greater than 38. If the result is greater than 38 we raise an exception to generate a 'SIZE ERROR'.
3) for a^b if b is negative and integer we calculate the absolute value of b and 1/a THEN we test if 'abs(b) fits_ulong'.
I was also interested in the optimization of logarithm calculations by creating a proof concept to calculate ln with the CORDIC algorithm.
You will find the test program in the attachment.
To use it :
I will now work again on optimization #470
Dennis
OK i'll do that this week
Denis