[LLVMdev] Fibonacci example in OCaml
Gordon Henriksen
gordonhenriksen at mac.com
Mon Nov 26 20:02:55 PST 2007
On 2007-11-26, at 21:12, Jon Harrop wrote:
> Provide a type enumerating the valid terminators and restrict the
> last instruction in a block to be a terminator. Something like this:
>
> type terminator = [ `ret of llvalue | `br of llvalue ]
> type instruction =
> [ terminator
> | `add of llvalue * llvalue
> | `sub of llvalue * llvalue ]
> type block = instruction list * terminator
>
> If you want to avoid having a data structure representing the input
> to LLVM then you can probably achieve the same result using
> combinators, e.g. by having the building functions for terminators
> change an [`incomplete] block into a [`complete] block. However,
> that might make the bindings harder to use.
Intermediate states are important, though they might be invalid. This
is inherited from the underlying object model. I don't think validity
is a concept that can effectively be grafted in through the type
system of a binding.
> Use phantom types to track the type of each llvalue:
>
> type 'a llvalue
This does not cover the full generality of the IR. The first argument
to a call instruction need not be a Function. Rather, the type of the
value must be pointer to function.
Still, those phantom types may be a solution for binding the Value
hierarchy without introducing gratuitous static casts. (The argument
to set_visibility must be a GlobalValue, for instance.) Can you
represent multiple-level inheritance? Value -> GlobalValue ->
GlobalVariable, say.
> I would use polymorphic variants more, particularly for enums and
> types that are only used once (e.g. "linkage" and "visibility"). So
> types would be `i32 rather than i32_type
Types are not enums, they're first-class objects.
> and int_predicate and real_predicate would become overlapping sum
> types, e.g. `ugt is valid for both.
These variant types were set up to have a 1:1 correspondence with the C
++ enums, and I'd prefer to keep that. There's also no overlap for
integer and FP predicates (unsigned greater than is not unordered
greater than).
> I'd also rather see structuring than identifier bloat, e.g.:
>
> module Linkage = struct
> type linkage =
> [ `External
> | ...
> | `Ghost ]
>
> external linkage : llvalue -> linkage = "llvm_linkage"
> end
This is a fair idea for grouping enums.
>> It should be possible for LLVM to perform intra- or interprocedural
>> escape analysis and lower heap allocations to stack allocations,
>> but I don't believe this is implemented. Garbage collection would
>> also complicate it, since LLVM would need to recognize GC allocator
>> functions as such. This would be an excellent project if you are
>> interested in contributing to LLVM itself.
>
> Perhaps such optimizations would be better done at a higher-level,
> above the level of the GC? So that would be ideal for a higher-level
> VM on top of LLVM.
Escape analysis is perfectly practical on the LLVM representation.
Reorganizing data structures is probably best done by the language
front end. A functional language is the ideal host for such
experiments. The closest LLVM does is SROA.
— Gordon
More information about the llvm-dev
mailing list