
Unfortunately, the .rodata section can't be stored in flash. Instead, an explicit .progmem section should be used, which is supported in LLVM as address space 1 but not exposed to normal programs. Eventually a pass should be written that converts trivial const globals of which all loads are visible to be in addrspace 1, to get the benefits of storing those globals directly in ROM.
34 строки
1,1 КиБ
Go
34 строки
1,1 КиБ
Go
package transform
|
|
|
|
import "tinygo.org/x/go-llvm"
|
|
|
|
// This file implements small transformations on globals (functions and global
|
|
// variables) for specific ABIs/architectures.
|
|
|
|
// ApplyFunctionSections puts every function in a separate section. This makes
|
|
// it possible for the linker to remove dead code. It is the equivalent of
|
|
// passing -ffunction-sections to a C compiler.
|
|
func ApplyFunctionSections(mod llvm.Module) {
|
|
llvmFn := mod.FirstFunction()
|
|
for !llvmFn.IsNil() {
|
|
if !llvmFn.IsDeclaration() {
|
|
name := llvmFn.Name()
|
|
llvmFn.SetSection(".text." + name)
|
|
}
|
|
llvmFn = llvm.NextFunction(llvmFn)
|
|
}
|
|
}
|
|
|
|
// DisableTailCalls adds the "disable-tail-calls"="true" function attribute to
|
|
// all functions. This may be necessary, in particular to avoid an error with
|
|
// WebAssembly in LLVM 11.
|
|
func DisableTailCalls(mod llvm.Module) {
|
|
attribute := mod.Context().CreateStringAttribute("disable-tail-calls", "true")
|
|
llvmFn := mod.FirstFunction()
|
|
for !llvmFn.IsNil() {
|
|
if !llvmFn.IsDeclaration() {
|
|
llvmFn.AddFunctionAttr(attribute)
|
|
}
|
|
llvmFn = llvm.NextFunction(llvmFn)
|
|
}
|
|
}
|