[M3devel] [M3commit] [modula3/cm3] 90b335: Fix special-case passing of static link parameter.

Rodney M. Bates rodney_bates at lcwb.coop
Mon Aug 28 21:10:37 CEST 2017

On 08/27/2017 09:56 PM, Hosking, Antony L wrote:
> Rodney,
> Can you give a summary of the status of the LLVM backend?

Status of the Cm3 llvm backend.  2017-08-28

The llvm backend passes all of the compiler p tests in m3-sys/m3tests
that the m3cc backend passes.  This has been tried only for

One of these (p004) complains of compile-time output different from
what it expects, but this is only a different order of the same list
of warning messages, no doubt due to the fact that these two backends
request different orderings of unnesting of nested procedures.  It's
the same front end.

Another (p140) is passing with llvm and not with m3cc.

I thought I recalled once using the llvm backend to rebuild the
compiler and core libraries twice, converging to same-sized
executables and libraries.  But more recently, this process failed in
the second rebuild.

m3llvm uses llvm version 3.6.1.  The llvm project has just tagged a
release candidate 5.0.0-rc3.  They continue in very rapid development,
and it is probably hard to track.  Particularly painful is the
production of bindings so our m3llvm pass can call into llvm to build
its IR.  This is extremely tedious and error prone.  I would love it
if I never had to do it again.  The interface for debug info has
changed significantly since the binding I created for 3.6.1.  It would
be very desirable if this could be automated.  This may be already

Llvm in-memory IR has complex hierarchies of subclasses.  Types in
each such hierarchy are entirely lost by bindings, pointers being
passed in and out statically typed as the top of the hierarchy.  They
receive the C++ equivalent of a NARROW when passed back in, which
turns what could have been compile-time errors into runtime errors.
It would be very desirable for this info to survive inter-language

The llvm backend requires a local build of llvm, using some of its
libraries and executables.  Figuring out which ones to link to and in
what order is tedious, and failure messages give little clue to what
is needed.  There are currently no modifications to the llvm code, but
a few are needed and look to be difficult to avoid. I have made no
attempt to integrate building llvm into the cm3 build process.  I
guess I need to write some instructions for doing it.  However, the
process of compiling using llvm, given an installed llvm, is fully
integrated into Cm3.

Llvm is large, and time-consuming to build.  Also, it compiles
noticeably slower than m3cc, but this is probably to be expected,
given its emphasis on optimization.  No doubt different optimization
levels are involved here.

Generation of Dwarf debug info suffers some compile-time segfaults,
and I have this disabled for now.  The result is no debug info at all,
so both gdb and m3gdb are limited to things like examining registers,
disassembling machine code, etc.  I have been able to get some use
from even this.  Most of the code for Dwarf production is present.  It
just needs some work.  Maybe not too much.

Once Dwarf is produced, it will probably not create a very Modula3-
like debugging experience without considerable work in m3gdb, which
now uses a greatly kludged extension of stabs.  But even stock gcc
will probably be better than it is now with stabs, perhaps quite a

The current scheme for handling up-level references is not very nice.
It uses a variation on the old display scheme.  It works for compiled
code, but will not support up-level references made from a debugger to
variables that are not already up-level referenced by the code itself.
What is needed to get the displacements of locals through llvm is
unclear.  There was something added to a later llvm that might help.

There still needs to be some thought given to who (CG or llvm) takes
care of memory layout tasks.  As with m3cc, the front end has lowered
some things farther than llvm's IR is designed to expect.  One llvm
developer once said he would never let llvm do memory layout, but I am
far from clear on the options and their consequences, particularly to

Most of the llvm back end is in package m3-sys/m3llvm3.6.1.  This
compiles to an executable named 'm3llvm', a separate pass that reads
Cm3' binary IR (*.ic, *.mc files) and writes llvm binary IR files
(*.ib, *.mb).  It makes calls on various llvm libraries through
bindings found in package m3-sys/llvmbindings.  Ignore packages llvm
and llvmgen.  They are old development stuff.  Cm3 invokes m3llvm, llc
(an llvm executable that reads llvm IR and produces assembly code) and
as to assemble it.  To compile using llvm, add the line:


to your cm3.cfg file to.

> — Tony

Rodney Bates
rodney.m.bates at acm.org

More information about the M3devel mailing list