gallivm,ac: add function attributes at call sites instead of declarations

They can vary at call sites if the intrinsic is NOT a legacy SI intrinsic.
We need this to force readnone or inaccessiblememonly on some amdgcn
intrinsics.

This is only used with LLVM 4.0 and later. Intrinsics only used with
LLVM <= 3.9 don't need the LEGACY flag.

gallivm and ac code is in the same patch, because splitting would be
more complicated with all the LEGACY uses all over the place.

v2: don't change the prototype of lp_add_function_attr.

Reviewed-by: Jose Fonseca <jfonseca@vmware.com> (v1)
This commit is contained in:
Marek Olšák
2017-02-22 02:29:12 +01:00
parent 408f370710
commit 940da36a65
8 changed files with 177 additions and 102 deletions

View File

@@ -24,7 +24,7 @@
*/
/* based on pieces from si_pipe.c and radeon_llvm_emit.c */
#include "ac_llvm_util.h"
#include "util/bitscan.h"
#include <llvm-c/Core.h>
#include "c11/threads.h"
@@ -180,12 +180,10 @@ static const char *attr_to_str(enum ac_func_attr attr)
#endif
void
ac_add_function_attr(LLVMValueRef function,
int attr_idx,
enum ac_func_attr attr)
static void
ac_add_function_attr(LLVMContextRef ctx, LLVMValueRef function,
int attr_idx, enum ac_func_attr attr)
{
#if HAVE_LLVM < 0x0400
LLVMAttribute llvm_attr = ac_attr_to_llvm_attr(attr);
if (attr_idx == -1) {
@@ -194,15 +192,30 @@ ac_add_function_attr(LLVMValueRef function,
LLVMAddAttribute(LLVMGetParam(function, attr_idx - 1), llvm_attr);
}
#else
LLVMContextRef context = LLVMGetModuleContext(LLVMGetGlobalParent(function));
const char *attr_name = attr_to_str(attr);
unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name,
strlen(attr_name));
LLVMAttributeRef llvm_attr = LLVMCreateEnumAttribute(context, kind_id, 0);
LLVMAddAttributeAtIndex(function, attr_idx, llvm_attr);
LLVMAttributeRef llvm_attr = LLVMCreateEnumAttribute(ctx, kind_id, 0);
if (LLVMIsAFunction(function))
LLVMAddAttributeAtIndex(function, attr_idx, llvm_attr);
else
LLVMAddCallSiteAttribute(function, attr_idx, llvm_attr);
#endif
}
void ac_add_func_attributes(LLVMContextRef ctx, LLVMValueRef function,
unsigned attrib_mask)
{
attrib_mask |= AC_FUNC_ATTR_NOUNWIND;
attrib_mask &= ~AC_FUNC_ATTR_LEGACY;
while (attrib_mask) {
enum ac_func_attr attr = 1u << u_bit_scan(&attrib_mask);
ac_add_function_attr(ctx, function, -1, attr);
}
}
void
ac_dump_module(LLVMModuleRef module)
{