From c66d979ba310feb94bee49e264a1af9d9981127b Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 7 Jul 2019 14:09:11 +0200 Subject: [PATCH] compiler: avoid some stack frames when this is unnecessary Some instructions do not create new values, they transform existing values in some way (bitcast, getelementptr, etc.). Do not store them in the stack object. This lowers the size of the repulsion demo from 100kB to 98kB (with a baseline of 72kB for the leaking GC). That's a useful reduction in file size. --- compiler/gc.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/compiler/gc.go b/compiler/gc.go index bb6633df..1af142b8 100644 --- a/compiler/gc.go +++ b/compiler/gc.go @@ -187,9 +187,29 @@ func (c *Compiler) makeGCStackSlots() bool { } // Some trivial optimizations. - if ptr.IsAInstruction().IsNil() || !ptr.IsAPHINode().IsNil() { + if ptr.IsAInstruction().IsNil() { continue } + switch ptr.InstructionOpcode() { + case llvm.PHI, llvm.GetElementPtr: + // These values do not create new values: the values already + // existed locally in this function so must have been tracked + // already. + continue + case llvm.ExtractValue, llvm.BitCast: + // These instructions do not create new values, but their + // original value may not be tracked. So keep tracking them for + // now. + // With more analysis, it should be possible to optimize a + // significant chunk of these away. + case llvm.Call, llvm.Load, llvm.IntToPtr: + // These create new values so must be stored locally. But + // perhaps some of these can be fused when they actually refer + // to the same value. + default: + // Ambiguous. These instructions are uncommon, but perhaps could + // be optimized if needed. + } if !ptr.IsAAllocaInst().IsNil() { if typeHasPointers(ptr.Type().ElementType()) {