mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-01 07:30:43 +03:00
Support generic ldc.attributes.llvmAttr UDAs for function parameters
This commit is contained in:
parent
1fdf330346
commit
cc336d6df1
5 changed files with 96 additions and 51 deletions
|
@ -603,6 +603,11 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
|
|||
// add func to IRFunc
|
||||
irFunc->setLLVMFunc(func);
|
||||
|
||||
// First apply the TargetMachine attributes, such that they can be overridden
|
||||
// by UDAs.
|
||||
applyTargetMachineAttributes(*func, *gTargetMachine);
|
||||
applyFuncDeclUDAs(fdecl, irFunc);
|
||||
|
||||
// parameter attributes
|
||||
if (!DtoIsIntrinsic(fdecl)) {
|
||||
applyParamAttrsToLLFunc(f, getIrFunc(fdecl)->irFty, func);
|
||||
|
@ -611,11 +616,6 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
|
|||
}
|
||||
}
|
||||
|
||||
// First apply the TargetMachine attributes, such that they can be overridden
|
||||
// by UDAs.
|
||||
applyTargetMachineAttributes(*func, *gTargetMachine);
|
||||
applyFuncDeclUDAs(fdecl, irFunc);
|
||||
|
||||
if(irFunc->isDynamicCompiled()) {
|
||||
declareDynamicCompiledFunction(gIR, irFunc);
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ static void addExplicitArguments(std::vector<LLValue *> &args, AttrSet &attrs,
|
|||
const size_t formalLLArgCount = irFty.args.size();
|
||||
|
||||
// Number of formal arguments in the D call expression (excluding varargs).
|
||||
const int formalDArgCount = Parameter::dim(formalParams);
|
||||
const size_t formalDArgCount = Parameter::dim(formalParams);
|
||||
|
||||
// The number of explicit arguments in the D call expression (including
|
||||
// varargs), not all of which necessarily generate a LLVM argument.
|
||||
|
@ -167,9 +167,11 @@ static void addExplicitArguments(std::vector<LLValue *> &args, AttrSet &attrs,
|
|||
|
||||
// Make sure to evaluate argument expressions for which there's no LL
|
||||
// parameter (e.g., empty structs for some ABIs).
|
||||
if (irArg->parametersIdx < formalDArgCount) {
|
||||
for (; dArgIndex < irArg->parametersIdx; ++dArgIndex) {
|
||||
toElem(argexps[dArgIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
Expression *const argexp = argexps[dArgIndex];
|
||||
Parameter *const formalParam =
|
||||
|
|
53
gen/uda.cpp
53
gen/uda.cpp
|
@ -207,19 +207,19 @@ void applyAttrAllocSize(StructLiteralExp *sle, IrFunction *irFunc) {
|
|||
|
||||
// @llvmAttr("key", "value")
|
||||
// @llvmAttr("key")
|
||||
void applyAttrLLVMAttr(StructLiteralExp *sle, llvm::Function *func) {
|
||||
void applyAttrLLVMAttr(StructLiteralExp *sle, llvm::AttrBuilder &attrs) {
|
||||
checkStructElems(sle, {Type::tstring, Type::tstring});
|
||||
llvm::StringRef key = getStringElem(sle, 0);
|
||||
llvm::StringRef value = getStringElem(sle, 1);
|
||||
if (value.empty()) {
|
||||
const auto kind = llvm::getAttrKindFromName(key);
|
||||
if (kind != llvm::Attribute::None) {
|
||||
func->addFnAttr(kind);
|
||||
attrs.addAttribute(kind);
|
||||
} else {
|
||||
func->addFnAttr(key);
|
||||
attrs.addAttribute(key);
|
||||
}
|
||||
} else {
|
||||
func->addFnAttr(key, value);
|
||||
attrs.addAttribute(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,9 +407,8 @@ void applyVarDeclUDAs(VarDeclaration *decl, llvm::GlobalVariable *gvar) {
|
|||
}
|
||||
|
||||
void applyFuncDeclUDAs(FuncDeclaration *decl, IrFunction *irFunc) {
|
||||
if (!decl->userAttribDecl)
|
||||
return;
|
||||
|
||||
// function UDAs
|
||||
if (decl->userAttribDecl) {
|
||||
llvm::Function *func = irFunc->getLLVMFunc();
|
||||
assert(func);
|
||||
|
||||
|
@ -424,7 +423,15 @@ void applyFuncDeclUDAs(FuncDeclaration *decl, IrFunction *irFunc) {
|
|||
if (ident == Id::udaAllocSize) {
|
||||
applyAttrAllocSize(sle, irFunc);
|
||||
} else if (ident == Id::udaLLVMAttr) {
|
||||
applyAttrLLVMAttr(sle, func);
|
||||
llvm::AttrBuilder attrs;
|
||||
applyAttrLLVMAttr(sle, attrs);
|
||||
#if LDC_LLVM_VER >= 500
|
||||
func->addAttributes(LLAttributeSet::FunctionIndex, attrs);
|
||||
#else
|
||||
AttrSet attrSet;
|
||||
attrSet.addToFunction(attrs);
|
||||
func->addAttributes(LLAttributeSet::FunctionIndex, attrSet);
|
||||
#endif
|
||||
} else if (ident == Id::udaLLVMFastMathFlag) {
|
||||
applyAttrLLVMFastMathFlag(sle, irFunc);
|
||||
} else if (ident == Id::udaOptStrategy) {
|
||||
|
@ -453,6 +460,36 @@ void applyFuncDeclUDAs(FuncDeclaration *decl, IrFunction *irFunc) {
|
|||
}
|
||||
}
|
||||
|
||||
// parameter UDAs
|
||||
auto parameterList = irFunc->type->parameterList;
|
||||
for (auto arg : irFunc->irFty.args) {
|
||||
if (arg->parametersIdx >= parameterList.length())
|
||||
continue;
|
||||
|
||||
auto param =
|
||||
Parameter::getNth(parameterList.parameters, arg->parametersIdx);
|
||||
if (!param->userAttribDecl)
|
||||
continue;
|
||||
|
||||
Expressions *attrs = param->userAttribDecl->getAttributes();
|
||||
expandTuples(attrs);
|
||||
for (auto &attr : *attrs) {
|
||||
auto sle = getLdcAttributesStruct(attr);
|
||||
if (!sle)
|
||||
continue;
|
||||
|
||||
auto ident = sle->sd->ident;
|
||||
if (ident == Id::udaLLVMAttr) {
|
||||
applyAttrLLVMAttr(sle, arg->attrs);
|
||||
} else {
|
||||
sle->warning("Ignoring unrecognized special parameter attribute "
|
||||
"`ldc.attributes.%s`",
|
||||
ident->toChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks whether 'sym' has the @ldc.attributes._weak() UDA applied.
|
||||
bool hasWeakUDA(Dsymbol *sym) {
|
||||
auto sle = getMagicAttribute(sym, Id::udaWeak, Id::attributes);
|
||||
|
|
|
@ -46,7 +46,7 @@ struct IrFuncTyArg {
|
|||
|
||||
/// The index of the declaration in the FuncDeclaration::parameters array
|
||||
/// corresponding to this argument.
|
||||
size_t parametersIdx = 0;
|
||||
size_t parametersIdx = -1;
|
||||
|
||||
/// This is the final LLVM Type used for the parameter/return value type
|
||||
llvm::Type *ltype = nullptr;
|
||||
|
|
6
tests/codegen/attr_param.d
Normal file
6
tests/codegen/attr_param.d
Normal file
|
@ -0,0 +1,6 @@
|
|||
// RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
|
||||
|
||||
import ldc.attributes;
|
||||
|
||||
// CHECK: define{{.*}} @{{.*}}3foo{{.*}}(i8* noalias %p_arg)
|
||||
void foo(@llvmAttr("noalias") void* p) {}
|
Loading…
Add table
Add a link
Reference in a new issue