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.
Этот коммит содержится в:
Ayke van Laethem 2019-07-07 14:09:11 +02:00 коммит произвёл Ron Evans
родитель fc9188a298
коммит c66d979ba3

Просмотреть файл

@ -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()) {