Skip to content

Commit ecc6d16

Browse files
aykevldeadprogram
authored andcommitted
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.
1 parent 5f252b3 commit ecc6d16

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

builder/sizes_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func TestBinarySize(t *testing.T) {
4343
// microcontrollers
4444
{"hifive1b", "examples/echo", 4600, 280, 0, 2268},
4545
{"microbit", "examples/serial", 2908, 388, 8, 2272},
46-
{"wioterminal", "examples/pininterrupt", 6140, 1484, 116, 6832},
46+
{"wioterminal", "examples/pininterrupt", 6140, 1484, 116, 6824},
4747

4848
// TODO: also check wasm. Right now this is difficult, because
4949
// wasm binaries are run through wasm-opt and therefore the

interp/interpreter.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,17 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
287287
// Get the object layout, if it is available.
288288
llvmLayoutType := r.getLLVMTypeFromLayout(operands[2])
289289

290+
// Get the alignment of the memory to be allocated.
291+
alignment := 0 // use default alignment if unset
292+
alignAttr := inst.llvmInst.GetCallSiteEnumAttribute(0, llvm.AttributeKindID("align"))
293+
if !alignAttr.IsNil() {
294+
alignment = int(alignAttr.GetEnumValue())
295+
}
296+
290297
// Create the object.
291298
alloc := object{
292299
globalName: r.pkgName + "$alloc",
300+
align: alignment,
293301
llvmLayoutType: llvmLayoutType,
294302
buffer: newRawValue(uint32(size)),
295303
size: uint32(size),
@@ -646,6 +654,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
646654
globalName: r.pkgName + "$alloca",
647655
buffer: newRawValue(uint32(size)),
648656
size: uint32(size),
657+
align: inst.llvmInst.Alignment(),
649658
}
650659
index := len(r.objects)
651660
r.objects = append(r.objects, alloca)

interp/memory.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type object struct {
4242
globalName string // name, if not yet created (not guaranteed to be the final name)
4343
buffer value // buffer with value as given by interp, nil if external
4444
size uint32 // must match buffer.len(), if available
45+
align int // alignment of the object (may be 0 if unknown)
4546
constant bool // true if this is a constant global
4647
marked uint8 // 0 means unmarked, 1 means external read, 2 means external write
4748
}
@@ -593,6 +594,12 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val
593594
// runtime.alloc.
594595
// First allocate a new global for this object.
595596
obj := mem.get(v.index())
597+
alignment := obj.align
598+
if alignment == 0 {
599+
// Unknown alignment, perhaps from a direct call to runtime.alloc in
600+
// the runtime. Use a conservative default instead.
601+
alignment = mem.r.maxAlign
602+
}
596603
if obj.llvmType.IsNil() && obj.llvmLayoutType.IsNil() {
597604
// Create an initializer without knowing the global type.
598605
// 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
603610
globalType := initializer.Type()
604611
llvmValue = llvm.AddGlobal(mem.r.mod, globalType, obj.globalName)
605612
llvmValue.SetInitializer(initializer)
606-
llvmValue.SetAlignment(mem.r.maxAlign)
613+
llvmValue.SetAlignment(alignment)
607614
obj.llvmGlobal = llvmValue
608615
mem.put(v.index(), obj)
609616
} else {
@@ -642,11 +649,7 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val
642649
return llvm.Value{}, errors.New("interp: allocated value does not match allocated type")
643650
}
644651
llvmValue.SetInitializer(initializer)
645-
if obj.llvmType.IsNil() {
646-
// The exact type isn't known (only the layout), so use the
647-
// alignment that would normally be expected from runtime.alloc.
648-
llvmValue.SetAlignment(mem.r.maxAlign)
649-
}
652+
llvmValue.SetAlignment(alignment)
650653
}
651654

652655
// It should be included in r.globals because otherwise markExternal

0 commit comments

Comments
 (0)