Top-level constants in the LLVM backend
jiribenes opened this issue · comments
Motivation
The LLVM backend currently does not support top-level let bindings of any kind.
As a first step, it would be nice to at least support top-level bindings of literals that don't use any capabilities (what I'll call "top-level constants" here), like for example:
val myString = "Hello, world!"
// ^^^
// [error] Toplevel def and let bindings not yet supported: Let(myString,Literal(Hello, world!,Data(String,List())))
def main() = {
println(myString)
}
Existing use in the standard library
We even use top-level constants in the standard library in the string
module:
effekt/libraries/common/string.effekt
Lines 206 to 227 in acbec87
which are then used by the test
module:
effekt/libraries/common/test.effekt
Line 79 in acbec87
Unfortunately since the LLVM backend doesn't support these top-level constants, one may use neither ANSI escape codes nor, by transitivity, the test
module. :(
Implementation details
Based on my Clang-based testing, I think it should be enough to do the following to declare a top-level Pos
constant:
@topLevelPos = constant %struct.Pos { i64 42, ptr null }, align 8
The biggest problem might be that we'd need to add these top-level constants to the Machine representation as that's where the current error is being thrown from:
effekt/effekt/shared/src/main/scala/effekt/machine/Transformer.scala
Lines 39 to 47 in acbec87
(One could start by pattern-matching on something like
(rest, lifted.Definition.Let(constantName, lit@Literal(_, _)))
...)
Technically, we should also be able to instead inline all of these top-level constants wherever they appear, but that's quite ad-hoc.