> Does anyone know what is the difference on 'service reload' in using
> compiler option: optimize in IBM OS/VS COBOL?
>
> I have encountered a OS/VS COBOL program which behaves differently
> when nooptimize is used (while optimize is used in production run).
> In the program, there are some arithimetics on BLL cells such as
> adding the length of some table entries so as to access the next table
>
> element. Then it execute a 'service reload' after several cobol
> statements of accessing the table entries.
> By inspecting the procedure map listing, it seems that the BLL in TGT
> is updated by 'service reload' when 'optimize' is used. But for
> 'nooptimize', BLL in TGT is updated in COBOL ADD statement.
I think I've been down this road, but in a different
forum. During optimization, the compiler decides that it
doesn't need to reload the base registers (ie:
BLL's) everytime it encounters the source code
SERVICE RELOAD. It's similar to the old:
"compute wrk-1 = 1 + 2" which a really good optimizer
would reduce to "move 3 to wrk-1". In your case,
the BLL is usually static for "batch" but not so with
CICS, so compiler assumes it is using "batch" and
deletes the RELOAD after arithmetics on the table
references. As I recall the SERVICE RELOAD is
loading registers from word values held somewhere in
program storage area.
The compiler obviously can not follow, or anticipate
the exact program flow of pseudo-conversational, so
your only option is to turn off the optimiziation and
code-efficiently as possible.
My understanding is that in non-optimised code, the base registers for
the relevant field(s) are loaded into hardware registers (from the TGT)
before each generated statement. As the optimiser removes redundant
register loads in a block of code, it can happen that the address of a
field is updated in mid-block (by a called routine, like the ones CICS
uses, for example). Obviously the "old" address (as held in a register)
is no longer valid and must be updated. My understanding is that the
addresses in the TGT get updated by CICS, and the register must be
re-loaded - so one of us has this the wrong way round :-) However,
consider the difficulty involved (for CICS) in predicting which register
holds the offending address..... I think I'm right.
A similar thing happens, BTW, if you read a variable-length item
containing it's own occurs ... depending on (ODO) object is read (under
VS COBOL only). The ODO cell will not be updated, so you have to move the
ODO object to itself, forcing a re-calculation of the length of the
object.
All good clean fun and two of the reasons why writers of interactive
debugging tools flourish :-)
Pete
As some of the other posters have stated, the optimize option tells the
compiler not to reload the BLL (BASE LOCATOR LINKAGE) registers before each
access to a linkage data item. OS/VS COBOL uses a limited (I think 3, but
I am not sure, and don't have a listing handy) number of general registers
as base locator registers for generated code. As you have seen from the
DMAP, your storage assignments are associated with BL registers (BLL for
linkage or BLW for working-storage) stored as fullwords in the TGT.
Normally, the compiler will try to load the BLL cell address before each
reference to a variable. This is the 'NOOPTIMIZE' option behavior. Many
of these storage-to-register moves are redundent, especially if you are
following good coding behavior and keeping locality of reference. Within a
paragraph, COBOL knows the path your code is following, so it knows when a
register reload is redundant. Similarly, if you have a paragraph header
which is not referred to by a GO TO or PERFORM, COBOL knows that you will
not enter from somewhere else at that point. Therefore, once a base
register is loaded with the correct address for a given BLL within a
paragraph, or a string of paragraphs which are executed in line, it need
not be reloaded for the duration of that code string, unless COBOL runs out
of physical registers to use and overlays it.
To take advantage of this, the compiler has the 'OPTIMIZE' option, which
tells COBOL to remove redundant reloads of the physical general purpose
registers from the BLL cells. COBOL will only generate the first load of a
base register after a paragraph header referred to as an entry, or after it
needs to reuse a physical register. A number of third party products
(e.g., CA-Optimizer) also do this sort of modification. The compiler
option causes the compiler to not generate the moves in the first place.
The third party products scan the object code after it is generated, but
before it goes to the link editor, removing the redundant moves, and
realigning the resultant addresses in each CSECT. This difference is
important to what the SERVICE RELOAD does.
A number of things you can do in the program can modify the effective
address which should be in a BLL cell. LINKAGE section entries have a
separate BLL cell for each 01 level. Programmers will typically mess with
these by moving a value to the associated BLL cell, or by accessing some
other system (eg., CICS) which will modify it. This 'moves' the DSECT
window associated with the data structure in the 01 level. In any case,
COBOL cannot know that the cell has been modified, so *if you access
storage which is addressed by that BLL cell within that code string after
the BLL cell change*, and you have the optimize option on, COBOL will not
know that it must reload the BLL cell to the general purpose register.
Without the reload, the generated code will operate on the wrong address,
with 'unpredicable results'. This is the fundamental problem which SERVICE
RELOAD is designed to address.
These techniques are usually associated with CICS programs, because of the
way linkage sections are used, and the addressibility of BLL cells. Even
the OS/VS COBOL manual refers to CICS programs, and the CICS Application
Programmer's Guide. However, I have worked with production programs in
batch which use assembler stubs (e.g., Consco Accounting Information
System) to give addressiblity to BLL cells, so it is not just a CICS thing.
If your program has any way of modifying BLL cells then you could run into
this sort of addressibility problem.
The "SERVICE RELOAD variable name" statement is actually a compiler
directive which says, in effect, "The BLL cell for 01 level item 'variable
name' has been modified, so the next time you reference anything
subordinate to that 01 level, generate the code to reload the appropriate
base register from the BLL cell". It is effective only from that point
until the end of the code string, since even with OPTIMIZE on, the compiler
would generate a reload in the next paragraph which can be jumped to by a
PERFORM or GO TO. The safest course is to put the RELOAD in whether you
are accessing the data items or not, since someone else may later come
along and add a reference. To quote the manual, "The SERVICE RELOAD
statement must be used following each statement which modifies
addressibility to an area defined in the LINKAGE section, that is ,
whenever the contents of a BLL cell is changed in any way." There is no
lost efficiency if you don't have a reference, since the RELOAD itself does
not generate any code, only the references to the linkage data item.
If more than one cell was modified, then you need more than one SERVICE
RELOAD. Also, if you modified the pointer to the BLL cell table, (which
could happen), then you need a reload for each and every BLL cell to
linkage (since thay are all implicitly modified). As the BLL cell table
pointer is modified by CICS when your program is first entered, you need a
SERVICE RELOAD for the BLL cell list itself as your first statement.
A special case, noted in the CICS Application Programmer's Reference is
when HANDLE CONDITION or HANDLE AID statements are used. Since these can
cause CICS to reenter a program at a different point than where it left,
and COBOL will have no clue, the paragraph referred to in the HANDLE
CONDITION/AID must have a SERVICE RELOAD for each 01 level whose BLL cell
was modified anywhere *in the execution path* between where the HANDLE
CONDITION/AID was coded, and *any* CICS command which might cause that
HANDLE to be invoked. Needless to say, this can be a real pain to figure
out. The safe route is, put a SERVICE RELOAD in for every 01 level which
gets modified anywhere after the header for each paragraph referred to in a
HANDLE.
Getting back to an earlier point, the SERVICE RELOAD tells COBOL what to
generate, but being a compiler directive it is invisible to third party
optimizers which operate on the object code after it is generated. These
products cannot know that you have been messing with BLL cells, nor that
you tried to tell the compiler about it, nor where a HANDLE CONDITION/AID
might cause a change in execution path, so they can really wreak havoc on
your code. Between this, and the possibility that a coder does not put in
all the SERVICE RELOADS they need, it is understandable that some shops
have odd rules for CICS coding like, "Just don't run any sort of optimize
on any CICS programs," or "Don't use HANDLE CONDITION or HANDLE AID in any
program." I've even seen "Put a SERVICE RELOAD for each BLL after each
paragraph header," which is not only overkill, but which still probably
will not solve the problem by anyway.
My primary reference for this unconscionably long lecture was CICS/VS
Application Programmer's Reference Manual (Command Level) SC33-0077-4, page
22. Please refer to the current version (whatever it is) for more
information.
--
"There's a big difference between mostly dead, and all dead. Please, open
his mouth."
Miracle Max, "The Princess Bride"
--
***********************************************
* Jim Van Sickle <mailto:jim...@ibm.net> *
* Manager, Operations and Tech Support *
* United Retail, Inc. *
*---------------------------------------------*
* visit my meager web site at: *
* <http://mypage.ihost.com/jimswebsite/> *
***********************************************
>Might I make a suggestion?
>Migrate your program to COBOL II and let the OS worry about BLL cells and
>SERVICE RELOADS!
>Seriously, I'm a strong proponent of understanding what goes on behind the
>scenes, but to depend on your average just-off-the-turnip-truck developer (which
>I was not that many moons ago so *back off*) to code SERVICE RELOADS when
>necessary is asking too much.
>Just my $0.02
>Cheers :-)
My job is to migrate this program to VS COBOL II. Usually the
migration is performed by a third party translator but the migrated
copy does not work properly in testing. The original program is full
of GO TOs and all the datasets are accessed by locate mode. Sometimes
it changes the content of a BLL cell, GO TO another paragraph, perform
a sequence of instructions and then service reload the updated BLL
cell.
But anyway, I have solved the problem and thank for all your opinions.