mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-07 03:16:05 +03:00
Support GC closures with alignment > 16
Tested by tests/dmd/runnable/test16098.d.
This commit is contained in:
parent
56785d41a8
commit
ef8ba481e3
3 changed files with 22 additions and 17 deletions
|
@ -207,17 +207,6 @@ llvm::AllocaInst *DtoRawAlloca(LLType *lltype, size_t alignment,
|
||||||
return ai;
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue *DtoGcMalloc(const Loc &loc, LLType *lltype, const char *name) {
|
|
||||||
// get runtime function
|
|
||||||
llvm::Function *fn = getRuntimeFunction(loc, gIR->module, "_d_allocmemory");
|
|
||||||
// parameters
|
|
||||||
LLValue *size = DtoConstSize_t(getTypeAllocSize(lltype));
|
|
||||||
// call runtime allocator
|
|
||||||
LLValue *mem = gIR->CreateCallOrInvoke(fn, size, name);
|
|
||||||
// cast
|
|
||||||
return DtoBitCast(mem, getPtrToType(lltype), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
LLValue *DtoAllocaDump(DValue *val, const char *name) {
|
LLValue *DtoAllocaDump(DValue *val, const char *name) {
|
||||||
return DtoAllocaDump(val, val->type, name);
|
return DtoAllocaDump(val, val->type, name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,6 @@ llvm::AllocaInst *DtoArrayAlloca(Type *type, unsigned arraysize,
|
||||||
const char *name = "");
|
const char *name = "");
|
||||||
llvm::AllocaInst *DtoRawAlloca(LLType *lltype, size_t alignment,
|
llvm::AllocaInst *DtoRawAlloca(LLType *lltype, size_t alignment,
|
||||||
const char *name = "");
|
const char *name = "");
|
||||||
LLValue *DtoGcMalloc(const Loc &loc, LLType *lltype, const char *name = "");
|
|
||||||
|
|
||||||
LLValue *DtoAllocaDump(DValue *val, const char *name = "");
|
LLValue *DtoAllocaDump(DValue *val, const char *name = "");
|
||||||
LLValue *DtoAllocaDump(DValue *val, int alignment, const char *name = "");
|
LLValue *DtoAllocaDump(DValue *val, int alignment, const char *name = "");
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/llvmhelpers.h"
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
|
#include "gen/runtime.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
#include "ir/irfunction.h"
|
#include "ir/irfunction.h"
|
||||||
#include "ir/irtypeaggr.h"
|
#include "ir/irtypeaggr.h"
|
||||||
|
@ -488,17 +489,33 @@ void DtoCreateNestedContext(FuncGenState &funcGen) {
|
||||||
auto &irFunc = funcGen.irFunc;
|
auto &irFunc = funcGen.irFunc;
|
||||||
unsigned depth = irFunc.depth;
|
unsigned depth = irFunc.depth;
|
||||||
LLStructType *frameType = irFunc.frameType;
|
LLStructType *frameType = irFunc.frameType;
|
||||||
|
const unsigned frameAlignment =
|
||||||
|
std::max(getABITypeAlign(frameType), irFunc.frameTypeAlignment);
|
||||||
|
|
||||||
// Create frame for current function and append to frames list
|
// Create frame for current function and append to frames list
|
||||||
LLValue *frame = nullptr;
|
LLValue *frame = nullptr;
|
||||||
bool needsClosure = fd->needsClosure();
|
bool needsClosure = fd->needsClosure();
|
||||||
IF_LOG Logger::println("Needs closure (GC) flag: %d", (int)needsClosure);
|
IF_LOG Logger::println("Needs closure (GC) flag: %d", (int)needsClosure);
|
||||||
if (needsClosure) {
|
if (needsClosure) {
|
||||||
// FIXME: alignment ?
|
LLFunction *fn =
|
||||||
frame = DtoGcMalloc(fd->loc, frameType, ".frame");
|
getRuntimeFunction(fd->loc, gIR->module, "_d_allocmemory");
|
||||||
|
auto size = getTypeAllocSize(frameType);
|
||||||
|
if (frameAlignment > 16) // GC guarantees an alignment of 16
|
||||||
|
size += frameAlignment - 16;
|
||||||
|
LLValue *mem =
|
||||||
|
gIR->CreateCallOrInvoke(fn, DtoConstSize_t(size), ".gc_frame");
|
||||||
|
if (frameAlignment <= 16) {
|
||||||
|
frame = DtoBitCast(mem, frameType->getPointerTo(), ".frame");
|
||||||
|
} else {
|
||||||
|
const uint64_t mask = frameAlignment - 1;
|
||||||
|
mem = gIR->ir->CreatePtrToInt(mem, DtoSize_t());
|
||||||
|
mem = gIR->ir->CreateAdd(mem, DtoConstSize_t(mask));
|
||||||
|
mem = gIR->ir->CreateAnd(mem, DtoConstSize_t(~mask));
|
||||||
|
frame =
|
||||||
|
gIR->ir->CreateIntToPtr(mem, frameType->getPointerTo(), ".frame");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
unsigned alignment =
|
frame = DtoRawAlloca(frameType, frameAlignment, ".frame");
|
||||||
std::max(getABITypeAlign(frameType), irFunc.frameTypeAlignment);
|
|
||||||
frame = DtoRawAlloca(frameType, alignment, ".frame");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy parent frames into beginning
|
// copy parent frames into beginning
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue