[Info-vax] The Road to V9.0

Dave Froble davef at tsoft-inc.com
Sun Oct 13 15:18:50 EDT 2019


On 10/12/2019 11:06 PM, John Reagan wrote:
> Since Clair mentioned that EDT and DIFF were held up by compiler issues, I'll give another one of my exciting episodes of
>
> "Adventures in compiler bugs with static initialization"
>
> As we are compiling a wider variety of BLISS code we had a rash of 3 BLISS bugs all in a week.  As background, the interface from the compiler frontends to GEM is a very PSECT-oriented interfaces.  Frontend says "put these bytes at offset N in PSECT P" and "associated global name A with PSECT offset N".  By contrast, the LLVM notion is that "variables can be placed into sections", "variables have initial values", and the early LLVM we're using for the cross-compilers has limited support for aliased symbols.  [Newer LLVMs have better support and we will switch to that when we get there.]
>
> [Short interlude for a free BLISS Tip O' The Week...
>
> In BLISS, the construct PLIT stands for Pure LITeral.  It is how you define a readonly literal of any sequence of bytes, words, longwords, strings, etc.  PLITs also have a magic count that proceeds the data.  By contrast UPLIT (Uncounted Pure LITeral) omits the count.  UPLIT is by far the most common form.  You only see PLITs in places where tables are built by BLISS macros and you want the compiler to count the number of things placed in the readonly memory.
>
> We now return you to the bug report already in progress...]
>
> Bug #1
>
> There was code in EDT that defined a constant that was shared with multiple modules.
>
> GLOBAL BIND TBL = UPLIT (1,2,3);
>
> [I simplified it for this discussion.]  The BLISS frontend created two symbols.  An anonymous symbol named P.AAA and a global symbol TBL.  As mentioned before, the frontend also said "put literals 1,2,3 into the PLIT PSECT at offset N".  It also said "associate global symbol TBL with PLIT PSECT at offset N".
>
> The GEM-to-LLVM converter (ie, G2L) got confused and told LLVM about the variable named P.AAA with the initial values and also about a separate variable named TBL with an initial value of all zeros.  We needed extra code to propagate the initial values from P.AAA to TBL; to generate only a single LLVM variable; and to map references from both P.AAA and TBL to that single symbol.
>
> We already did the right thing with non-global BINDs, but GLOBAL BINDs need extra work (GLOBAL BINDs get extra work in the BLISS frontend already).
>
> Bug #2
>
> There was a variable that was being initialized with a sequence of 5 byte elements.  A byte followed by a pointer to a counted string with something like
>
> GLOBAL TBL2 = BLOCK[100,BYTE] INITIAL (UPLIT BYTE(1,%ASCIC 'ONE', 2, %ASCIC 'TWO'))
>
> and so on.
>
> As I mentioned earlier, GEM would just want to put those values into the underlying PSECT and also associate the name TBL2 with that same offset.  LLVM wants a structured constants.  So we have to look at the initializers and invent some type that would match the shape of the initializer in spite of BLISS having no such type.  We ended up with a
>
> struct {byte, long, byte, long}
>
> and so forth.  BLISS wants those to be byte packed and generated code to match.  However, we messed up the inferred type we used to describe the initializer and it ended up with alignment padding between the 'byte' and 'long' fields.  The initializer put the bytes in the wrong spot and actually ran over the end putting bytes into subsequent variables.  There are 'packing' knobs and 'alignment' knobs in LLVM to support things like __attribute__((packed)) and __attribute__((aligned)) that you can use in clang (and gcc).  We just needed to tell LLVM exactly what we wanted and not accept the defaults.
>
> Bug #3
>
> Remember the PLIT I talked about earlier?  That is implemented by the BLISS frontend generating TWO symbols.  One, the P.AAA, is the data bytes.  And another symbol, carefully placed just before P.AAA in the PSECT, that is initialized with the count.
>
> The G2L converter didn't do all the symbols in increasing offset order due to the BLISS frontend not filling in a particular flag in that "preceding count" symbol and it was placed somewhere else.  So code that does
>
> INCR I FROM 0 TO (.TBL[-1] - 1) DO
>
> would fetch something that wasn't the count and use that as the loop's termination value.  You'd get something that wasn't quite an infinite loop, but instead of being INCR I FROM 0 TO 3, it would be some very large value.
>

Question for you John ...

Are these problems you're correcting actual poor / bad coding?  I'm 
getting the impression that for most it's just in the conversion to LLVM.

Will the modified code still work on VAX / Alpha / itanic, or is it not 
backward compatible?

You have reported some bugs in the past.  The reversed operands in the 
Macro-32 example was such.

-- 
David Froble                       Tel: 724-529-0450
Dave Froble Enterprises, Inc.      E-Mail: davef at tsoft-inc.com
DFE Ultralights, Inc.
170 Grimplin Road
Vanderbilt, PA  15486



More information about the Info-vax mailing list