diff options
author | Ayke van Laethem <[email protected]> | 2021-04-05 19:24:25 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2021-04-08 11:40:59 +0200 |
commit | 0b7957d61249ce4b745f78405e36f07245eb8da3 (patch) | |
tree | 73ba364ae47485ff2c03bc361820d49857d0f4e8 /compiler/symbol.go | |
parent | 61243f6c57b4158c28666ebadc6344e143ca02f1 (diff) | |
download | tinygo-0b7957d61249ce4b745f78405e36f07245eb8da3.tar.gz tinygo-0b7957d61249ce4b745f78405e36f07245eb8da3.zip |
compiler: optimize string literals and globals
This commit optimizes string literals and globals by setting the
appropriate alignment and using a nil pointer in zero-length strings.
- Setting the alignment for string values has a surprisingly large
effect, up to around 2% in binary size. I suspect that LLVM will
pick some default alignment for larger byte arrays if no alignment
has been specified and forcing an alignment of 1 will pack all
strings closer together.
- Using nil for zero-length strings also has a positive effect, but
I'm not sure why. Perhaps it makes some optimizations more trivial.
- Always setting the alignment on globals improves code size slightly,
probably for the same reasons setting the alignment of string
literals improves code size. The effect is much smaller, however.
This commit might have an effect on performance, but if it does this
should be tested separately and such a large win in binary size should
definitely not be ignored for small embedded systems.
Diffstat (limited to 'compiler/symbol.go')
-rw-r--r-- | compiler/symbol.go | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/compiler/symbol.go b/compiler/symbol.go index 5b44c20f9..6455fb8f3 100644 --- a/compiler/symbol.go +++ b/compiler/symbol.go @@ -355,16 +355,18 @@ func (c *compilerContext) getGlobal(g *ssa.Global) llvm.Value { // Set alignment from the //go:align comment. var alignInBits uint32 - if info.align < 0 || info.align&(info.align-1) != 0 { + alignment := c.targetData.ABITypeAlignment(llvmType) + if info.align > alignment { + alignment = info.align + } + if alignment <= 0 || alignment&(alignment-1) != 0 { // Check for power-of-two (or 0). // See: https://stackoverflow.com/a/108360 c.addError(g.Pos(), "global variable alignment must be a positive power of two") } else { // Set the alignment only when it is a power of two. - alignInBits = uint32(info.align) ^ uint32(info.align-1) - if info.align > c.targetData.ABITypeAlignment(llvmType) { - llvmGlobal.SetAlignment(info.align) - } + alignInBits = uint32(alignment) ^ uint32(alignment-1) + llvmGlobal.SetAlignment(alignment) } if c.Debug && !info.extern { |