[Info-vax] The Road to V9.0

John Reagan xyzzy1959 at gmail.com
Mon Oct 14 13:42:52 EDT 2019


On Sunday, October 13, 2019 at 3:18:14 PM UTC-4, Dave Froble wrote:
> 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

Just the differences in GEM vs LLVM.  Nothing more.  Not related to pointer sizes, descriptors, Linux, the Illuminati, etc 

LLVM's model is that "variables live in sections", "variables have initial values".  GEM's model is "data lives in PSECTs" and "variables are associated with offsets into PSECTs".  

When you get to ELF, that is exactly the model.  Data lives in ELF sections.  The ELF symbol table defines names (and sizes and 'data vs procedure') that point to ELF sections plus an offset.  The same ELF on OpenVMS and on Linux.  No difference.

Just plain and simple bugs in our G2L code that maps between GEM and LLVM.  I was just trying to point out that while we did lots of testing and prototyping, these class of bugs are hard to spot but easy to fix.  (I changed about 20 lines to fix all 3 bugs).



More information about the Info-vax mailing list