mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-29 06:30:39 +03:00
Refactor code to hide direct IrFunction->func usage and add convenient functions (#1911)
This commit is contained in:
parent
09cef87178
commit
a26bfc1223
17 changed files with 158 additions and 73 deletions
|
@ -90,7 +90,7 @@ DValue *DtoNewClass(Loc &loc, TypeClass *tc, NewExp *newexp) {
|
|||
// custom allocator
|
||||
else if (newexp->allocator) {
|
||||
DtoResolveFunction(newexp->allocator);
|
||||
DFuncValue dfn(newexp->allocator, getIrFunc(newexp->allocator)->func);
|
||||
DFuncValue dfn(newexp->allocator, DtoCallee(newexp->allocator));
|
||||
DValue *res = DtoCallFunction(newexp->loc, nullptr, &dfn, newexp->newargs);
|
||||
mem = DtoBitCast(DtoRVal(res), DtoType(tc), ".newclass_custom");
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ DValue *DtoNewClass(Loc &loc, TypeClass *tc, NewExp *newexp) {
|
|||
Logger::println("Calling constructor");
|
||||
assert(newexp->arguments != NULL);
|
||||
DtoResolveFunction(newexp->member);
|
||||
DFuncValue dfn(newexp->member, getIrFunc(newexp->member)->func, mem);
|
||||
DFuncValue dfn(newexp->member, DtoCallee(newexp->member), mem);
|
||||
return DtoCallFunction(newexp->loc, tc, &dfn, newexp->arguments);
|
||||
}
|
||||
|
||||
|
@ -485,7 +485,7 @@ static LLConstant *build_class_dtor(ClassDeclaration *cd) {
|
|||
|
||||
DtoResolveFunction(dtor);
|
||||
return llvm::ConstantExpr::getBitCast(
|
||||
getIrFunc(dtor)->func, getPtrToType(LLType::getInt8Ty(gIR->context())));
|
||||
DtoCallee(dtor), getPtrToType(LLType::getInt8Ty(gIR->context())));
|
||||
}
|
||||
|
||||
static ClassFlags::Type build_classinfo_flags(ClassDeclaration *cd) {
|
||||
|
|
|
@ -828,7 +828,7 @@ ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
|
|||
auto SP = DBuilder.createFunction(
|
||||
CU, // context
|
||||
fd->toPrettyChars(), // name
|
||||
getIrFunc(fd)->func->getName(), // linkage name
|
||||
getIrFunc(fd)->getLLVMFuncName(), // linkage name
|
||||
file, // file
|
||||
fd->loc.linnum, // line no
|
||||
DIFnType, // type
|
||||
|
@ -839,12 +839,12 @@ ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
|
|||
isOptimizationEnabled() // isOptimized
|
||||
#if LDC_LLVM_VER < 308
|
||||
,
|
||||
getIrFunc(fd)->func
|
||||
DtoFunction(fd)
|
||||
#endif
|
||||
);
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (fd->fbody)
|
||||
getIrFunc(fd)->func->setSubprogram(SP);
|
||||
DtoFunction(fd)->setSubprogram(SP);
|
||||
#endif
|
||||
return SP;
|
||||
}
|
||||
|
@ -888,12 +888,12 @@ ldc::DISubprogram ldc::DIBuilder::EmitThunk(llvm::Function *Thunk,
|
|||
isOptimizationEnabled() // isOptimized
|
||||
#if LDC_LLVM_VER < 308
|
||||
,
|
||||
getIrFunc(fd)->func
|
||||
DtoFunction(fd)
|
||||
#endif
|
||||
);
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (fd->fbody)
|
||||
getIrFunc(fd)->func->setSubprogram(SP);
|
||||
DtoFunction(fd)->setSubprogram(SP);
|
||||
#endif
|
||||
return SP;
|
||||
}
|
||||
|
|
|
@ -323,7 +323,7 @@ static llvm::Function *DtoDeclareVaFunction(FuncDeclaration *fdecl) {
|
|||
}
|
||||
assert(func);
|
||||
|
||||
getIrFunc(fdecl)->func = func;
|
||||
getIrFunc(fdecl)->setLLVMFunc(func);
|
||||
return func;
|
||||
}
|
||||
|
||||
|
@ -548,7 +548,7 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
|
|||
IF_LOG Logger::cout() << "func = " << *func << std::endl;
|
||||
|
||||
// add func to IRFunc
|
||||
irFunc->func = func;
|
||||
irFunc->setLLVMFunc(func);
|
||||
|
||||
// parameter attributes
|
||||
if (!DtoIsIntrinsic(fdecl)) {
|
||||
|
@ -781,12 +781,14 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
}
|
||||
|
||||
if (fd->ir->isDefined()) {
|
||||
llvm::Function *func = getIrFunc(fd)->getLLVMFunc();
|
||||
assert(nullptr != func);
|
||||
if (!linkageAvailableExternally &&
|
||||
(getIrFunc(fd)->func->getLinkage() ==
|
||||
(func->getLinkage() ==
|
||||
llvm::GlobalValue::AvailableExternallyLinkage)) {
|
||||
// Fix linkage
|
||||
const auto lwc = lowerFuncLinkage(fd);
|
||||
setLinkage(lwc, getIrFunc(fd)->func);
|
||||
setLinkage(lwc, func);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -917,7 +919,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
|
||||
const auto f = static_cast<TypeFunction *>(fd->type->toBasetype());
|
||||
IrFuncTy &irFty = irFunc->irFty;
|
||||
llvm::Function *func = irFunc->func;
|
||||
llvm::Function *func = irFunc->getLLVMFunc();
|
||||
|
||||
const auto lwc = lowerFuncLinkage(fd);
|
||||
if (linkageAvailableExternally) {
|
||||
|
@ -1027,7 +1029,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
defineParameters(irFty, *fd->parameters);
|
||||
|
||||
// Initialize PGO state for this function
|
||||
funcGen.pgo.assignRegionCounters(fd, irFunc->func);
|
||||
funcGen.pgo.assignRegionCounters(fd, func);
|
||||
|
||||
DtoCreateNestedContext(funcGen);
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ IrFunction *IRState::func() {
|
|||
}
|
||||
|
||||
llvm::Function *IRState::topfunc() {
|
||||
return func()->func;
|
||||
return func()->getLLVMFunc();
|
||||
}
|
||||
|
||||
llvm::Instruction *IRState::topallocapoint() {
|
||||
|
@ -126,6 +126,11 @@ LLCallSite IRState::CreateCallOrInvoke(LLValue *Callee, LLValue *Arg1,
|
|||
return funcGen().callOrInvoke(Callee, args, Name);
|
||||
}
|
||||
|
||||
bool IRState::isMainFunc(const IrFunction *func) const {
|
||||
assert(func != nullptr);
|
||||
return func->getLLVMFunc() == mainFunc;
|
||||
}
|
||||
|
||||
bool IRState::emitArrayBoundsChecks() {
|
||||
if (global.params.useArrayBounds != BOUNDSCHECKsafeonly) {
|
||||
return global.params.useArrayBounds == BOUNDSCHECKon;
|
||||
|
|
|
@ -161,6 +161,8 @@ struct IRState {
|
|||
LLValue *Arg2, LLValue *Arg3, LLValue *Arg4,
|
||||
const char *Name = "");
|
||||
|
||||
bool isMainFunc(const IrFunction *func) const;
|
||||
|
||||
// this holds the array being indexed or sliced so $ will work
|
||||
// might be a better way but it works. problem is I only get a
|
||||
// VarDeclaration for __dollar, but I can't see how to get the
|
||||
|
|
|
@ -1383,7 +1383,7 @@ void callPostblit(Loc &loc, Expression *exp, LLValue *val) {
|
|||
}
|
||||
DtoResolveFunction(fd);
|
||||
Expressions args;
|
||||
DFuncValue dfn(fd, getIrFunc(fd)->func, val);
|
||||
DFuncValue dfn(fd, DtoCallee(fd), val);
|
||||
DtoCallFunction(loc, Type::basic[Tvoid], &dfn, &args);
|
||||
}
|
||||
}
|
||||
|
@ -1588,9 +1588,9 @@ DValue *DtoSymbolAddress(Loc &loc, Type *type, Declaration *decl) {
|
|||
// We need to codegen the function here, because literals are not added
|
||||
// to the module member list.
|
||||
DtoDefineFunction(flitdecl);
|
||||
assert(getIrFunc(flitdecl)->func);
|
||||
assert(DtoCallee(flitdecl));
|
||||
|
||||
return new DFuncValue(flitdecl, getIrFunc(flitdecl)->func);
|
||||
return new DFuncValue(flitdecl, DtoCallee(flitdecl));
|
||||
}
|
||||
|
||||
if (FuncDeclaration *fdecl = decl->isFuncDeclaration()) {
|
||||
|
@ -1607,7 +1607,7 @@ DValue *DtoSymbolAddress(Loc &loc, Type *type, Declaration *decl) {
|
|||
}
|
||||
DtoResolveFunction(fdecl);
|
||||
return new DFuncValue(fdecl, fdecl->llvmInternal != LLVMva_arg
|
||||
? getIrFunc(fdecl)->func
|
||||
? DtoCallee(fdecl)
|
||||
: nullptr);
|
||||
}
|
||||
|
||||
|
@ -1661,7 +1661,7 @@ llvm::Constant *DtoConstSymbolAddress(Loc &loc, Declaration *decl) {
|
|||
// static function
|
||||
if (FuncDeclaration *fd = decl->isFuncDeclaration()) {
|
||||
DtoResolveFunction(fd);
|
||||
return getIrFunc(fd)->func;
|
||||
return DtoCallee(fd);
|
||||
}
|
||||
|
||||
llvm_unreachable("Taking constant address not implemented.");
|
||||
|
|
|
@ -48,7 +48,7 @@ llvm::Function *buildForwarderFunction(
|
|||
}
|
||||
|
||||
if (funcs.size() == 1) {
|
||||
return getIrFunc(funcs.front())->func;
|
||||
return DtoCallee(funcs.front());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ llvm::Function *buildForwarderFunction(
|
|||
|
||||
// ... calling the given functions, and...
|
||||
for (auto func : funcs) {
|
||||
const auto f = getIrFunc(func)->func;
|
||||
const auto f = DtoCallee(func);
|
||||
#if LDC_LLVM_VER < 307
|
||||
const auto call = builder.CreateCall(f, "");
|
||||
const auto ft = call->getCalledFunction()->getFunctionType();
|
||||
|
|
|
@ -602,7 +602,7 @@ void addCoverageAnalysis(Module *m) {
|
|||
FuncDeclaration::genCfunc(nullptr, Type::tvoid, ctorname.c_str());
|
||||
fd->linkage = LINKd;
|
||||
IrFunction *irfunc = getIrFunc(fd, true);
|
||||
irfunc->func = ctor;
|
||||
irfunc->setLLVMFunc(ctor);
|
||||
getIrModule(m)->sharedCtors.push_back(fd);
|
||||
}
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ void RTTIBuilder::push_size_as_vp(uint64_t s) {
|
|||
void RTTIBuilder::push_funcptr(FuncDeclaration *fd, Type *castto) {
|
||||
if (fd) {
|
||||
DtoResolveFunction(fd);
|
||||
LLConstant *F = getIrFunc(fd)->func;
|
||||
LLConstant *F = DtoCallee(fd);
|
||||
if (castto) {
|
||||
F = DtoBitCast(F, DtoType(castto));
|
||||
}
|
||||
|
|
|
@ -132,14 +132,14 @@ public:
|
|||
auto &funcGen = irs->funcGen();
|
||||
IrFunction *const f = &funcGen.irFunc;
|
||||
FuncDeclaration *const fd = f->decl;
|
||||
LLFunction *const llFunc = f->func;
|
||||
llvm::FunctionType *funcType = f->getLLVMFuncType();
|
||||
|
||||
emitInstrumentationFnLeave(fd);
|
||||
|
||||
// is there a return value expression?
|
||||
if (stmt->exp || (!stmt->exp && (llFunc == irs->mainFunc))) {
|
||||
if (stmt->exp || (!stmt->exp && irs->isMainFunc(f))) {
|
||||
// if the function's return type is void, it uses sret
|
||||
if (llFunc->getReturnType() == LLType::getVoidTy(irs->context())) {
|
||||
if (funcType->getReturnType() == LLType::getVoidTy(irs->context())) {
|
||||
assert(!f->type->isref);
|
||||
|
||||
LLValue *sretPointer = getIrFunc(fd)->sretArg;
|
||||
|
@ -181,7 +181,7 @@ public:
|
|||
}
|
||||
} else {
|
||||
// the return type is not void, so this is a normal "register" return
|
||||
if (!stmt->exp && (llFunc == irs->mainFunc)) {
|
||||
if (!stmt->exp && irs->isMainFunc(f)) {
|
||||
returnValue =
|
||||
LLConstant::getNullValue(irs->mainFunc->getReturnType());
|
||||
} else {
|
||||
|
@ -207,7 +207,7 @@ public:
|
|||
// If the function returns a struct or a static array, and the return
|
||||
// value is a pointer to a struct or a static array, load from it
|
||||
// before returning.
|
||||
if (returnValue->getType() != llFunc->getReturnType() &&
|
||||
if (returnValue->getType() != funcType->getReturnType() &&
|
||||
DtoIsInMemoryOnly(f->type->next) &&
|
||||
isaPointer(returnValue->getType())) {
|
||||
Logger::println("Loading value for return");
|
||||
|
@ -215,18 +215,18 @@ public:
|
|||
}
|
||||
|
||||
// can happen for classes and void main
|
||||
if (returnValue->getType() != llFunc->getReturnType()) {
|
||||
if (returnValue->getType() != funcType->getReturnType()) {
|
||||
// for the main function this only happens if it is declared as void
|
||||
// and then contains a return (exp); statement. Since the actual
|
||||
// return type remains i32, we just throw away the exp value
|
||||
// and return 0 instead
|
||||
// if we're not in main, just bitcast
|
||||
if (llFunc == irs->mainFunc) {
|
||||
if (irs->isMainFunc(f)) {
|
||||
returnValue =
|
||||
LLConstant::getNullValue(irs->mainFunc->getReturnType());
|
||||
} else {
|
||||
returnValue =
|
||||
irs->ir->CreateBitCast(returnValue, llFunc->getReturnType());
|
||||
irs->ir->CreateBitCast(returnValue, funcType->getReturnType());
|
||||
}
|
||||
|
||||
IF_LOG Logger::cout() << "return value after cast: " << *returnValue
|
||||
|
@ -235,7 +235,7 @@ public:
|
|||
}
|
||||
} else {
|
||||
// no return value expression means it's a void function.
|
||||
assert(llFunc->getReturnType() == LLType::getVoidTy(irs->context()));
|
||||
assert(funcType->getReturnType() == LLType::getVoidTy(irs->context()));
|
||||
}
|
||||
|
||||
// If there are no cleanups to run, we try to keep the IR simple and
|
||||
|
|
|
@ -508,9 +508,9 @@ public:
|
|||
// added
|
||||
// to the module member list.
|
||||
Declaration_codegen(fd, p);
|
||||
assert(getIrFunc(fd)->func);
|
||||
assert(DtoCallee(fd));
|
||||
|
||||
result = getIrFunc(fd)->func;
|
||||
result = DtoCallee(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
20
gen/toir.cpp
20
gen/toir.cpp
|
@ -703,7 +703,7 @@ public:
|
|||
FuncDeclaration *fdecl = dve->var->isFuncDeclaration();
|
||||
assert(fdecl);
|
||||
DtoDeclareFunction(fdecl);
|
||||
fnval = new DFuncValue(fdecl, getIrFunc(fdecl)->func, DtoRVal(dve->e1));
|
||||
fnval = new DFuncValue(fdecl, DtoCallee(fdecl), DtoRVal(dve->e1));
|
||||
} else {
|
||||
fnval = toElem(e->e1);
|
||||
}
|
||||
|
@ -852,7 +852,7 @@ public:
|
|||
FuncDeclaration *fd = fv->func;
|
||||
assert(fd);
|
||||
DtoResolveFunction(fd);
|
||||
result = new DFuncValue(fd, getIrFunc(fd)->func);
|
||||
result = new DFuncValue(fd, DtoCallee(fd));
|
||||
return;
|
||||
}
|
||||
if (v->isIm()) {
|
||||
|
@ -961,7 +961,7 @@ public:
|
|||
if (nonFinal) {
|
||||
funcval = DtoVirtualFunctionPointer(l, fdecl, e->toChars());
|
||||
} else {
|
||||
funcval = getIrFunc(fdecl)->func;
|
||||
funcval = DtoCallee(fdecl);
|
||||
}
|
||||
assert(funcval);
|
||||
|
||||
|
@ -1478,7 +1478,7 @@ public:
|
|||
if (e->allocator) {
|
||||
// custom allocator
|
||||
DtoResolveFunction(e->allocator);
|
||||
DFuncValue dfn(e->allocator, getIrFunc(e->allocator)->func);
|
||||
DFuncValue dfn(e->allocator, DtoCallee(e->allocator));
|
||||
DValue *res = DtoCallFunction(e->loc, nullptr, &dfn, e->newargs);
|
||||
mem = DtoBitCast(DtoRVal(res), DtoType(ntype->pointerTo()),
|
||||
".newstruct_custom");
|
||||
|
@ -1507,7 +1507,7 @@ public:
|
|||
IF_LOG Logger::println("Calling constructor");
|
||||
assert(e->arguments != NULL);
|
||||
DtoResolveFunction(e->member);
|
||||
DFuncValue dfn(e->member, getIrFunc(e->member)->func, mem);
|
||||
DFuncValue dfn(e->member, DtoCallee(e->member), mem);
|
||||
DtoCallFunction(e->loc, ts, &dfn, e->arguments);
|
||||
}
|
||||
}
|
||||
|
@ -1694,7 +1694,7 @@ public:
|
|||
->sym->inv) != nullptr) {
|
||||
Logger::print("calling struct invariant");
|
||||
DtoResolveFunction(invdecl);
|
||||
DFuncValue invfunc(invdecl, getIrFunc(invdecl)->func, DtoRVal(cond));
|
||||
DFuncValue invfunc(invdecl, DtoCallee(invdecl), DtoRVal(cond));
|
||||
DtoCallFunction(e->loc, nullptr, &invfunc, nullptr);
|
||||
}
|
||||
}
|
||||
|
@ -1917,7 +1917,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
castfptr = getIrFunc(e->func)->func;
|
||||
castfptr = DtoCallee(e->func);
|
||||
}
|
||||
|
||||
castfptr = DtoBitCast(castfptr, dgty->getContainedType(1));
|
||||
|
@ -2166,7 +2166,7 @@ public:
|
|||
DtoDeclareFunction(fd);
|
||||
assert(!fd->isNested());
|
||||
}
|
||||
assert(getIrFunc(fd)->func);
|
||||
assert(DtoCallee(fd));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2210,12 +2210,12 @@ public:
|
|||
cval = DtoBitCast(cval, dgty->getContainedType(0));
|
||||
|
||||
LLValue *castfptr =
|
||||
DtoBitCast(getIrFunc(fd)->func, dgty->getContainedType(1));
|
||||
DtoBitCast(DtoCallee(fd), dgty->getContainedType(1));
|
||||
|
||||
result = new DImValue(e->type, DtoAggrPair(cval, castfptr, ".func"));
|
||||
|
||||
} else {
|
||||
result = new DFuncValue(e->type, fd, getIrFunc(fd)->func);
|
||||
result = new DFuncValue(e->type, fd, DtoCallee(fd));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -256,11 +256,10 @@ void TryCatchScope::emitCatchBodiesMSVC(IRState &irs, llvm::Value *) {
|
|||
// if no landing pad is created, the catch blocks are unused, but
|
||||
// the verifier complains if there are catchpads without personality
|
||||
// so we can just set it unconditionally
|
||||
if (!irs.func()->func->hasPersonalityFn()) {
|
||||
if (!irs.func()->hasLLVMPersonalityFn()) {
|
||||
const char *personality = "__CxxFrameHandler3";
|
||||
LLFunction *personalityFn =
|
||||
getRuntimeFunction(Loc(), irs.module, personality);
|
||||
irs.func()->func->setPersonalityFn(personalityFn);
|
||||
irs.func()->setLLVMPersonalityFn(
|
||||
getRuntimeFunction(Loc(), irs.module, personality));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -623,11 +622,9 @@ llvm::LandingPadInst *createLandingPadInst(IRState &irs) {
|
|||
LLStructType::get(LLType::getInt8PtrTy(irs.context()),
|
||||
LLType::getInt32Ty(irs.context()), nullptr);
|
||||
#if LDC_LLVM_VER >= 307
|
||||
LLFunction *currentFunction = irs.func()->func;
|
||||
if (!currentFunction->hasPersonalityFn()) {
|
||||
LLFunction *personalityFn =
|
||||
getRuntimeFunction(Loc(), irs.module, "_d_eh_personality");
|
||||
currentFunction->setPersonalityFn(personalityFn);
|
||||
if (!irs.func()->hasLLVMPersonalityFn()) {
|
||||
irs.func()->setLLVMPersonalityFn(
|
||||
getRuntimeFunction(Loc(), irs.module, "_d_eh_personality"));
|
||||
}
|
||||
return irs.ir->CreateLandingPad(retType, 0);
|
||||
#else
|
||||
|
@ -753,12 +750,10 @@ llvm::BasicBlock *TryCatchFinallyScopes::getOrCreateResumeUnwindBlock() {
|
|||
#if LDC_LLVM_VER >= 308
|
||||
llvm::BasicBlock *
|
||||
TryCatchFinallyScopes::emitLandingPadMSVC(CleanupCursor cleanupScope) {
|
||||
LLFunction *currentFunction = irs.func()->func;
|
||||
if (!currentFunction->hasPersonalityFn()) {
|
||||
if (!irs.func()->hasLLVMPersonalityFn()) {
|
||||
const char *personality = "__CxxFrameHandler3";
|
||||
LLFunction *personalityFn =
|
||||
getRuntimeFunction(Loc(), irs.module, personality);
|
||||
currentFunction->setPersonalityFn(personalityFn);
|
||||
irs.func()->setLLVMPersonalityFn(
|
||||
getRuntimeFunction(Loc(), irs.module, personality));
|
||||
}
|
||||
|
||||
if (cleanupScope == 0)
|
||||
|
|
11
gen/uda.cpp
11
gen/uda.cpp
|
@ -134,7 +134,7 @@ const char *getFirstElemString(StructLiteralExp *sle) {
|
|||
// @allocSize(1)
|
||||
// @allocSize(0,2)
|
||||
void applyAttrAllocSize(StructLiteralExp *sle, IrFunction *irFunc) {
|
||||
llvm::Function *func = irFunc->func;
|
||||
llvm::Function *func = irFunc->getLLVMFunc();
|
||||
|
||||
checkStructElems(sle, {Type::tint32, Type::tint32});
|
||||
auto sizeArgIdx = getIntElem(sle, 0);
|
||||
|
@ -236,6 +236,7 @@ void applyAttrOptStrategy(StructLiteralExp *sle, IrFunction *irFunc) {
|
|||
checkStructElems(sle, {Type::tstring});
|
||||
llvm::StringRef value = getStringElem(sle, 0);
|
||||
|
||||
llvm::Function *func = irFunc->getLLVMFunc();
|
||||
if (value == "none") {
|
||||
if (irFunc->decl->inlining == PINLINEalways) {
|
||||
sle->error("cannot combine '@ldc.attributes.%s(\"none\")' with "
|
||||
|
@ -244,11 +245,11 @@ void applyAttrOptStrategy(StructLiteralExp *sle, IrFunction *irFunc) {
|
|||
return;
|
||||
}
|
||||
irFunc->decl->inlining = PINLINEnever;
|
||||
irFunc->func->addFnAttr(llvm::Attribute::OptimizeNone);
|
||||
func->addFnAttr(llvm::Attribute::OptimizeNone);
|
||||
} else if (value == "optsize") {
|
||||
irFunc->func->addFnAttr(llvm::Attribute::OptimizeForSize);
|
||||
func->addFnAttr(llvm::Attribute::OptimizeForSize);
|
||||
} else if (value == "minsize") {
|
||||
irFunc->func->addFnAttr(llvm::Attribute::MinSize);
|
||||
func->addFnAttr(llvm::Attribute::MinSize);
|
||||
} else {
|
||||
sle->warning(
|
||||
"ignoring unrecognized parameter '%s' for '@ldc.attributes.%s'",
|
||||
|
@ -359,7 +360,7 @@ void applyFuncDeclUDAs(FuncDeclaration *decl, IrFunction *irFunc) {
|
|||
if (!decl->userAttribDecl)
|
||||
return;
|
||||
|
||||
llvm::Function *func = irFunc->func;
|
||||
llvm::Function *func = irFunc->getLLVMFunc();
|
||||
assert(func);
|
||||
|
||||
Expressions *attrs = decl->userAttribDecl->getAttributes();
|
||||
|
|
|
@ -200,7 +200,7 @@ LLConstant *IrAggr::getVtblInit() {
|
|||
|
||||
DtoResolveFunction(fd);
|
||||
assert(isIrFuncCreated(fd) && "invalid vtbl function");
|
||||
c = DtoBitCast(getIrFunc(fd)->func, voidPtrType);
|
||||
c = DtoBitCast(DtoCallee(fd), voidPtrType);
|
||||
|
||||
if (cd->isFuncHidden(fd)) {
|
||||
// fd is hidden from the view of this class. If fd overlaps with any
|
||||
|
@ -328,7 +328,7 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
|
|||
if (fd->interfaceVirtual)
|
||||
thunkOffset -= fd->interfaceVirtual->offset;
|
||||
if (thunkOffset == 0) {
|
||||
constants.push_back(DtoBitCast(irFunc->func, voidPtrTy));
|
||||
constants.push_back(DtoBitCast(irFunc->getLLVMCallee(), voidPtrTy));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -344,11 +344,12 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
|
|||
if (!thunk) {
|
||||
const LinkageWithCOMDAT lwc(LLGlobalValue::LinkOnceODRLinkage,
|
||||
supportsCOMDAT());
|
||||
const auto callee = irFunc->getLLVMCallee();
|
||||
thunk = LLFunction::Create(
|
||||
isaFunction(irFunc->func->getType()->getContainedType(0)), lwc.first,
|
||||
isaFunction(callee->getType()->getContainedType(0)), lwc.first,
|
||||
thunkName, &gIR->module);
|
||||
setLinkage(lwc, thunk);
|
||||
thunk->copyAttributesFrom(irFunc->func);
|
||||
thunk->copyAttributesFrom(callee);
|
||||
|
||||
// Thunks themselves don't have an identity, only the target
|
||||
// function has.
|
||||
|
@ -375,7 +376,7 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
|
|||
sizeof(FuncDeclaration)));
|
||||
thunkFd->ir = new IrDsymbol();
|
||||
auto thunkFunc = getIrFunc(thunkFd, true); // create the IrFunction
|
||||
thunkFunc->func = thunk;
|
||||
thunkFunc->setLLVMFunc(thunk);
|
||||
thunkFunc->type = irFunc->type;
|
||||
gIR->funcGenStates.emplace_back(new FuncGenState(*thunkFunc, *gIR));
|
||||
|
||||
|
@ -394,7 +395,7 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
|
|||
// latter being just for IR readablilty).
|
||||
std::vector<LLValue *> args;
|
||||
llvm::Function::arg_iterator thunkArg = thunk->arg_begin();
|
||||
llvm::Function::arg_iterator origArg = irFunc->func->arg_begin();
|
||||
llvm::Function::arg_iterator origArg = callee->arg_begin();
|
||||
for (; thunkArg != thunk->arg_end(); ++thunkArg, ++origArg) {
|
||||
thunkArg->setName(origArg->getName());
|
||||
args.push_back(&(*thunkArg));
|
||||
|
@ -416,8 +417,8 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
|
|||
gIR->DBuilder.EmitStopPoint(fd->loc);
|
||||
|
||||
// call the real vtbl function.
|
||||
llvm::CallInst *call = gIR->ir->CreateCall(irFunc->func, args);
|
||||
call->setCallingConv(irFunc->func->getCallingConv());
|
||||
llvm::CallInst *call = gIR->ir->CreateCall(callee, args);
|
||||
call->setCallingConv(irFunc->getCallingConv());
|
||||
call->setTailCallKind(llvm::CallInst::TCK_Tail);
|
||||
|
||||
// return from the thunk
|
||||
|
|
|
@ -38,6 +38,47 @@ void IrFunction::setAlwaysInline() {
|
|||
func->addFnAttr(llvm::Attribute::AlwaysInline);
|
||||
}
|
||||
|
||||
void IrFunction::setLLVMFunc(llvm::Function *function) {
|
||||
assert(function != nullptr);
|
||||
func = function;
|
||||
}
|
||||
|
||||
llvm::Function *IrFunction::getLLVMFunc() const {
|
||||
return func;
|
||||
}
|
||||
|
||||
llvm::CallingConv::ID IrFunction::getCallingConv() const {
|
||||
assert(func != nullptr);
|
||||
return func->getCallingConv();
|
||||
}
|
||||
|
||||
llvm::FunctionType *IrFunction::getLLVMFuncType() const {
|
||||
assert(func != nullptr);
|
||||
return func->getFunctionType();
|
||||
}
|
||||
|
||||
#if LDC_LLVM_VER >= 307
|
||||
bool IrFunction::hasLLVMPersonalityFn() const {
|
||||
assert(func != nullptr);
|
||||
return func->hasPersonalityFn();
|
||||
}
|
||||
|
||||
void IrFunction::setLLVMPersonalityFn(llvm::Constant *personality) {
|
||||
assert(func != nullptr);
|
||||
func->setPersonalityFn(personality);
|
||||
}
|
||||
#endif
|
||||
|
||||
llvm::StringRef IrFunction::getLLVMFuncName() const {
|
||||
assert(func != nullptr);
|
||||
return func->getName();
|
||||
}
|
||||
|
||||
llvm::Function *IrFunction::getLLVMCallee() const {
|
||||
assert(func != nullptr);
|
||||
return func;
|
||||
}
|
||||
|
||||
IrFunction *getIrFunc(FuncDeclaration *decl, bool create) {
|
||||
if (!isIrFuncCreated(decl) && create) {
|
||||
assert(decl->ir->irFunc == NULL);
|
||||
|
@ -55,3 +96,13 @@ bool isIrFuncCreated(FuncDeclaration *decl) {
|
|||
assert(t == IrDsymbol::FuncType || t == IrDsymbol::NotSet);
|
||||
return t == IrDsymbol::FuncType;
|
||||
}
|
||||
|
||||
llvm::Function *DtoFunction(FuncDeclaration *decl, bool create) {
|
||||
assert(decl != nullptr);
|
||||
return getIrFunc(decl, create)->getLLVMFunc();
|
||||
}
|
||||
|
||||
llvm::Function *DtoCallee(FuncDeclaration *decl, bool create) {
|
||||
assert(decl != nullptr);
|
||||
return getIrFunc(decl, create)->getLLVMCallee();
|
||||
}
|
||||
|
|
|
@ -34,7 +34,24 @@ struct IrFunction {
|
|||
void setNeverInline();
|
||||
void setAlwaysInline();
|
||||
|
||||
llvm::Function *func = nullptr;
|
||||
void setLLVMFunc(llvm::Function *function);
|
||||
|
||||
/// Returns the associated LLVM function.
|
||||
/// Use getLLVMCallee() for the LLVM function to be used for calls.
|
||||
llvm::Function *getLLVMFunc() const;
|
||||
llvm::CallingConv::ID getCallingConv() const;
|
||||
llvm::FunctionType *getLLVMFuncType() const;
|
||||
llvm::StringRef getLLVMFuncName() const;
|
||||
|
||||
#if LDC_LLVM_VER >= 307
|
||||
bool hasLLVMPersonalityFn() const;
|
||||
void setLLVMPersonalityFn(llvm::Constant *personality);
|
||||
#endif
|
||||
|
||||
/// Returns the associated LLVM function to be used for calls (potentially
|
||||
/// some sort of wrapper, e.g., a JIT wrapper).
|
||||
llvm::Function *getLLVMCallee() const;
|
||||
|
||||
FuncDeclaration *decl = nullptr;
|
||||
TypeFunction *type = nullptr;
|
||||
|
||||
|
@ -71,9 +88,20 @@ struct IrFunction {
|
|||
/// Stores the FastMath options for this functions.
|
||||
/// These are set e.g. by math related UDA's from ldc.attributes.
|
||||
llvm::FastMathFlags FMF;
|
||||
|
||||
private:
|
||||
llvm::Function *func = nullptr;
|
||||
};
|
||||
|
||||
IrFunction *getIrFunc(FuncDeclaration *decl, bool create = false);
|
||||
bool isIrFuncCreated(FuncDeclaration *decl);
|
||||
|
||||
/// Returns the associated LLVM function.
|
||||
/// Use DtoCallee() for the LLVM function to be used for calls.
|
||||
llvm::Function *DtoFunction(FuncDeclaration *decl, bool create = false);
|
||||
|
||||
/// Returns the associated LLVM function to be used for calls (potentially
|
||||
/// some sort of wrapper, e.g., a JIT wrapper).
|
||||
llvm::Function *DtoCallee(FuncDeclaration *decl, bool create = false);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue