Skip to content

Commit ef8ba48

Browse files
committed
Support GC closures with alignment > 16
Tested by tests/dmd/runnable/test16098.d.
1 parent 56785d4 commit ef8ba48

File tree

3 files changed

+22
-17
lines changed

3 files changed

+22
-17
lines changed

gen/llvmhelpers.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,17 +207,6 @@ llvm::AllocaInst *DtoRawAlloca(LLType *lltype, size_t alignment,
207207
return ai;
208208
}
209209

210-
LLValue *DtoGcMalloc(const Loc &loc, LLType *lltype, const char *name) {
211-
// get runtime function
212-
llvm::Function *fn = getRuntimeFunction(loc, gIR->module, "_d_allocmemory");
213-
// parameters
214-
LLValue *size = DtoConstSize_t(getTypeAllocSize(lltype));
215-
// call runtime allocator
216-
LLValue *mem = gIR->CreateCallOrInvoke(fn, size, name);
217-
// cast
218-
return DtoBitCast(mem, getPtrToType(lltype), name);
219-
}
220-
221210
LLValue *DtoAllocaDump(DValue *val, const char *name) {
222211
return DtoAllocaDump(val, val->type, name);
223212
}

gen/llvmhelpers.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ llvm::AllocaInst *DtoArrayAlloca(Type *type, unsigned arraysize,
4747
const char *name = "");
4848
llvm::AllocaInst *DtoRawAlloca(LLType *lltype, size_t alignment,
4949
const char *name = "");
50-
LLValue *DtoGcMalloc(const Loc &loc, LLType *lltype, const char *name = "");
5150

5251
LLValue *DtoAllocaDump(DValue *val, const char *name = "");
5352
LLValue *DtoAllocaDump(DValue *val, int alignment, const char *name = "");

gen/nested.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "gen/irstate.h"
1818
#include "gen/llvmhelpers.h"
1919
#include "gen/logger.h"
20+
#include "gen/runtime.h"
2021
#include "gen/tollvm.h"
2122
#include "ir/irfunction.h"
2223
#include "ir/irtypeaggr.h"
@@ -488,17 +489,33 @@ void DtoCreateNestedContext(FuncGenState &funcGen) {
488489
auto &irFunc = funcGen.irFunc;
489490
unsigned depth = irFunc.depth;
490491
LLStructType *frameType = irFunc.frameType;
492+
const unsigned frameAlignment =
493+
std::max(getABITypeAlign(frameType), irFunc.frameTypeAlignment);
494+
491495
// Create frame for current function and append to frames list
492496
LLValue *frame = nullptr;
493497
bool needsClosure = fd->needsClosure();
494498
IF_LOG Logger::println("Needs closure (GC) flag: %d", (int)needsClosure);
495499
if (needsClosure) {
496-
// FIXME: alignment ?
497-
frame = DtoGcMalloc(fd->loc, frameType, ".frame");
500+
LLFunction *fn =
501+
getRuntimeFunction(fd->loc, gIR->module, "_d_allocmemory");
502+
auto size = getTypeAllocSize(frameType);
503+
if (frameAlignment > 16) // GC guarantees an alignment of 16
504+
size += frameAlignment - 16;
505+
LLValue *mem =
506+
gIR->CreateCallOrInvoke(fn, DtoConstSize_t(size), ".gc_frame");
507+
if (frameAlignment <= 16) {
508+
frame = DtoBitCast(mem, frameType->getPointerTo(), ".frame");
509+
} else {
510+
const uint64_t mask = frameAlignment - 1;
511+
mem = gIR->ir->CreatePtrToInt(mem, DtoSize_t());
512+
mem = gIR->ir->CreateAdd(mem, DtoConstSize_t(mask));
513+
mem = gIR->ir->CreateAnd(mem, DtoConstSize_t(~mask));
514+
frame =
515+
gIR->ir->CreateIntToPtr(mem, frameType->getPointerTo(), ".frame");
516+
}
498517
} else {
499-
unsigned alignment =
500-
std::max(getABITypeAlign(frameType), irFunc.frameTypeAlignment);
501-
frame = DtoRawAlloca(frameType, alignment, ".frame");
518+
frame = DtoRawAlloca(frameType, frameAlignment, ".frame");
502519
}
503520

504521
// copy parent frames into beginning

0 commit comments

Comments
 (0)