From c5cb2cec9b7c8e4cee016d4c5c485e83dc872d05 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 18 Mar 2020 20:41:19 +0100 Subject: [PATCH] compiler: move NonConstGlobals pass to transform package --- builder/build.go | 2 +- compiler/compiler.go | 11 ----------- transform/globals.go | 13 +++++++++++++ transform/globals_test.go | 7 +++++++ transform/testdata/globals-non-const.ll | 5 +++++ transform/testdata/globals-non-const.out.ll | 5 +++++ 6 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 transform/testdata/globals-non-const.ll create mode 100644 transform/testdata/globals-non-const.out.ll diff --git a/builder/build.go b/builder/build.go index c1d82370..e7029afd 100644 --- a/builder/build.go +++ b/builder/build.go @@ -98,7 +98,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri // pointers are flash and which are in RAM so that pointers can have a // correct address space parameter (address space 1 is for flash). if strings.HasPrefix(config.Triple(), "avr") { - c.NonConstGlobals() + transform.NonConstGlobals(c.Module()) if err := c.Verify(); err != nil { return errors.New("verification error after making all globals non-constant on AVR") } diff --git a/compiler/compiler.go b/compiler/compiler.go index 8556f839..609d57f7 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -2585,17 +2585,6 @@ func (c *Compiler) Verify() error { return llvm.VerifyModule(c.mod, llvm.PrintMessageAction) } -// Turn all global constants into global variables. This works around a -// limitation on Harvard architectures (e.g. AVR), where constant and -// non-constant pointers point to a different address space. -func (c *Compiler) NonConstGlobals() { - global := c.mod.FirstGlobal() - for !global.IsNil() { - global.SetGlobalConstant(false) - global = llvm.NextGlobal(global) - } -} - // Emit object file (.o). func (c *Compiler) EmitObject(path string) error { llvmBuf, err := c.machine.EmitToMemoryBuffer(c.mod, llvm.ObjectFile) diff --git a/transform/globals.go b/transform/globals.go index c142fed8..89386fd8 100644 --- a/transform/globals.go +++ b/transform/globals.go @@ -18,3 +18,16 @@ func ApplyFunctionSections(mod llvm.Module) { llvmFn = llvm.NextFunction(llvmFn) } } + +// NonConstGlobals turns all global constants into global variables. This works +// around a limitation on Harvard architectures (e.g. AVR), where constant and +// non-constant pointers point to a different address space. Normal pointer +// behavior is restored by using the data space only, at the cost of RAM for +// constant global variables. +func NonConstGlobals(mod llvm.Module) { + global := mod.FirstGlobal() + for !global.IsNil() { + global.SetGlobalConstant(false) + global = llvm.NextGlobal(global) + } +} diff --git a/transform/globals_test.go b/transform/globals_test.go index 0dcb0608..14c77e6a 100644 --- a/transform/globals_test.go +++ b/transform/globals_test.go @@ -12,3 +12,10 @@ func TestApplyFunctionSections(t *testing.T) { ApplyFunctionSections(mod) }) } + +func TestNonConstGlobals(t *testing.T) { + t.Parallel() + testTransform(t, "testdata/globals-non-const", func(mod llvm.Module) { + NonConstGlobals(mod) + }) +} diff --git a/transform/testdata/globals-non-const.ll b/transform/testdata/globals-non-const.ll new file mode 100644 index 00000000..5f3c5846 --- /dev/null +++ b/transform/testdata/globals-non-const.ll @@ -0,0 +1,5 @@ +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "armv7em-none-eabi" + +@globalIntConst = constant i32 3 +@globalIntVar = global i32 5 diff --git a/transform/testdata/globals-non-const.out.ll b/transform/testdata/globals-non-const.out.ll new file mode 100644 index 00000000..33b577eb --- /dev/null +++ b/transform/testdata/globals-non-const.out.ll @@ -0,0 +1,5 @@ +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "armv7em-none-eabi" + +@globalIntConst = global i32 3 +@globalIntVar = global i32 5