mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-21 12:59:04 +00:00
interp: align created globals
Use the alignment from the align attribute of the runtime.alloc call. This is going to be a more accurate alignment, and is typically smaller than the default.
This commit is contained in:
committed by
Ron Evans
parent
5f252b3e16
commit
ecc6d16f22
@@ -43,7 +43,7 @@ func TestBinarySize(t *testing.T) {
|
|||||||
// microcontrollers
|
// microcontrollers
|
||||||
{"hifive1b", "examples/echo", 4600, 280, 0, 2268},
|
{"hifive1b", "examples/echo", 4600, 280, 0, 2268},
|
||||||
{"microbit", "examples/serial", 2908, 388, 8, 2272},
|
{"microbit", "examples/serial", 2908, 388, 8, 2272},
|
||||||
{"wioterminal", "examples/pininterrupt", 6140, 1484, 116, 6832},
|
{"wioterminal", "examples/pininterrupt", 6140, 1484, 116, 6824},
|
||||||
|
|
||||||
// TODO: also check wasm. Right now this is difficult, because
|
// TODO: also check wasm. Right now this is difficult, because
|
||||||
// wasm binaries are run through wasm-opt and therefore the
|
// wasm binaries are run through wasm-opt and therefore the
|
||||||
|
|||||||
@@ -287,9 +287,17 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
|||||||
// Get the object layout, if it is available.
|
// Get the object layout, if it is available.
|
||||||
llvmLayoutType := r.getLLVMTypeFromLayout(operands[2])
|
llvmLayoutType := r.getLLVMTypeFromLayout(operands[2])
|
||||||
|
|
||||||
|
// Get the alignment of the memory to be allocated.
|
||||||
|
alignment := 0 // use default alignment if unset
|
||||||
|
alignAttr := inst.llvmInst.GetCallSiteEnumAttribute(0, llvm.AttributeKindID("align"))
|
||||||
|
if !alignAttr.IsNil() {
|
||||||
|
alignment = int(alignAttr.GetEnumValue())
|
||||||
|
}
|
||||||
|
|
||||||
// Create the object.
|
// Create the object.
|
||||||
alloc := object{
|
alloc := object{
|
||||||
globalName: r.pkgName + "$alloc",
|
globalName: r.pkgName + "$alloc",
|
||||||
|
align: alignment,
|
||||||
llvmLayoutType: llvmLayoutType,
|
llvmLayoutType: llvmLayoutType,
|
||||||
buffer: newRawValue(uint32(size)),
|
buffer: newRawValue(uint32(size)),
|
||||||
size: uint32(size),
|
size: uint32(size),
|
||||||
@@ -646,6 +654,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
|||||||
globalName: r.pkgName + "$alloca",
|
globalName: r.pkgName + "$alloca",
|
||||||
buffer: newRawValue(uint32(size)),
|
buffer: newRawValue(uint32(size)),
|
||||||
size: uint32(size),
|
size: uint32(size),
|
||||||
|
align: inst.llvmInst.Alignment(),
|
||||||
}
|
}
|
||||||
index := len(r.objects)
|
index := len(r.objects)
|
||||||
r.objects = append(r.objects, alloca)
|
r.objects = append(r.objects, alloca)
|
||||||
|
|||||||
+9
-6
@@ -42,6 +42,7 @@ type object struct {
|
|||||||
globalName string // name, if not yet created (not guaranteed to be the final name)
|
globalName string // name, if not yet created (not guaranteed to be the final name)
|
||||||
buffer value // buffer with value as given by interp, nil if external
|
buffer value // buffer with value as given by interp, nil if external
|
||||||
size uint32 // must match buffer.len(), if available
|
size uint32 // must match buffer.len(), if available
|
||||||
|
align int // alignment of the object (may be 0 if unknown)
|
||||||
constant bool // true if this is a constant global
|
constant bool // true if this is a constant global
|
||||||
marked uint8 // 0 means unmarked, 1 means external read, 2 means external write
|
marked uint8 // 0 means unmarked, 1 means external read, 2 means external write
|
||||||
}
|
}
|
||||||
@@ -593,6 +594,12 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val
|
|||||||
// runtime.alloc.
|
// runtime.alloc.
|
||||||
// First allocate a new global for this object.
|
// First allocate a new global for this object.
|
||||||
obj := mem.get(v.index())
|
obj := mem.get(v.index())
|
||||||
|
alignment := obj.align
|
||||||
|
if alignment == 0 {
|
||||||
|
// Unknown alignment, perhaps from a direct call to runtime.alloc in
|
||||||
|
// the runtime. Use a conservative default instead.
|
||||||
|
alignment = mem.r.maxAlign
|
||||||
|
}
|
||||||
if obj.llvmType.IsNil() && obj.llvmLayoutType.IsNil() {
|
if obj.llvmType.IsNil() && obj.llvmLayoutType.IsNil() {
|
||||||
// Create an initializer without knowing the global type.
|
// Create an initializer without knowing the global type.
|
||||||
// This is probably the result of a runtime.alloc call.
|
// This is probably the result of a runtime.alloc call.
|
||||||
@@ -603,7 +610,7 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val
|
|||||||
globalType := initializer.Type()
|
globalType := initializer.Type()
|
||||||
llvmValue = llvm.AddGlobal(mem.r.mod, globalType, obj.globalName)
|
llvmValue = llvm.AddGlobal(mem.r.mod, globalType, obj.globalName)
|
||||||
llvmValue.SetInitializer(initializer)
|
llvmValue.SetInitializer(initializer)
|
||||||
llvmValue.SetAlignment(mem.r.maxAlign)
|
llvmValue.SetAlignment(alignment)
|
||||||
obj.llvmGlobal = llvmValue
|
obj.llvmGlobal = llvmValue
|
||||||
mem.put(v.index(), obj)
|
mem.put(v.index(), obj)
|
||||||
} else {
|
} else {
|
||||||
@@ -642,11 +649,7 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val
|
|||||||
return llvm.Value{}, errors.New("interp: allocated value does not match allocated type")
|
return llvm.Value{}, errors.New("interp: allocated value does not match allocated type")
|
||||||
}
|
}
|
||||||
llvmValue.SetInitializer(initializer)
|
llvmValue.SetInitializer(initializer)
|
||||||
if obj.llvmType.IsNil() {
|
llvmValue.SetAlignment(alignment)
|
||||||
// The exact type isn't known (only the layout), so use the
|
|
||||||
// alignment that would normally be expected from runtime.alloc.
|
|
||||||
llvmValue.SetAlignment(mem.r.maxAlign)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// It should be included in r.globals because otherwise markExternal
|
// It should be included in r.globals because otherwise markExternal
|
||||||
|
|||||||
Reference in New Issue
Block a user