[LLVMdev] MachineOperand: GlobalAddress vs. ExternalSymbol

Chris Lattner sabre at nondot.org
Fri Jun 18 12:04:02 PDT 2004


On Fri, 18 Jun 2004, Vladimir Prus wrote:
> > actually exist in the LLVM module for the function.  In particular, this
> > would include any functions in a code-generator specific runtime library
> > and malloc/free.  The X86 code generator compiles floating point modulus
> > into fmod calls, and 64-bit integer div/rem into runtime library calls.
>
> And why isn't it possible to just make those functions known to LLVM? After
> all, *I think*, if this function is to be called, it should be declared in
> assembler, and so you have to pass some information abou those function to
> the code printer. (Of course, it's possible to just directly print the
> declarations, but that's scary).

If you wanted to do that, it would be fine.  Be aware that the code
generators are set up as function passes though, so you would have to
insert all function prototypes in the doInitialization(...) method of the
function pass: you can't just do it on the fly from runOn*Function.

The real reason that we aren't doing this currently is that we don't want
code generators to be hacking on the LLVM module.  This greatly interferes
with JIT-style multi-pass optimization and other things.  Unfortunately,
we are a long way from this though, as the lowering passes hack on the
LLVM and other stuff does as well.  Unless you have a good reason to do
so, I would suggest trying to use MO_ExternalFunction just to make future
refactoring easier.

> There's another issue I don't understand. The module consists of functions and
> constants. I'd expect that external function declarations are also constants,
> with appropriate type. However, it seems they are not included in
> [Module::gbegin(), Module::gend()], insteads, they a Function objects with
> isExternal set to true.

Module::gbegin/gend iterate over the global variables, and ::begin/end
iterate over the functions, some of which may be prototypes.  Function
prototypes aren't really any more "constant" than other functions are.
Function prototypes do have correct types on them though.

> To me this seems a bit confusing -- it would be clearer if there we plain
> functions with bodies and everything else were GlobalValue.

The reason that we don't want to do this is that it makes it more
difficult to create a function and then fill in its body.  Currently when
you create a function, you get a prototype.  When you fill in its body,
you now have a defined function.  In your scheme, the function prototype
and defined function objects would be different: to go from one to the
other, you would have to delete the object and reallocate it.

> Anyther question is about SymbolTable. Is it true that it's a mapping from
> name to objects in Module, and than all objects accessible via SymbolsTable
> are either in the list of functions or in the list of global values?

Yup.  There are also function-local symbol tables as well.

I wouldn't recommend depending too much on the names, because LLVM has a
unusual mechanism where it allows objects with different types to have
the same name.  This means you can have:

int %foo(int %X) { ret int %X }
float %foo(float %X) { ret float %X }

In the context of a code generator, you should use the NameMangler
interface to make everything just work.

If you're doing something else and think you need the symbol table, please
let me know.  Clients of the SymbolTable class are extremely rare (by
design).  The SymbolTable class is mostly an internal class that is
automagically used by the system to provide naming invariants and allow
efficient lookup for the rare clients that need it.

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/





More information about the llvm-dev mailing list