[Mesa-dev] [PATCH] radeon/compute: Unconditionally inline all functions
Aaron Watry
awatry at gmail.com
Thu Nov 14 09:38:06 PST 2013
On Thu, Nov 14, 2013 at 10:29 AM, Tom Stellard <tom at stellard.net> wrote:
> From: Tom Stellard <thomas.stellard at amd.com>
>
> We need to do this until function calls are supported.
>
> https://bugs.freedesktop.org/show_bug.cgi?id=64225
>
> CC: "10.0" <mesa-stable at lists.freedesktop.org>
> ---
> src/gallium/drivers/radeon/radeon_llvm_util.c | 24 ++++++++++++++++++++++--
> 1 file changed, 22 insertions(+), 2 deletions(-)
>
> diff --git a/src/gallium/drivers/radeon/radeon_llvm_util.c b/src/gallium/drivers/radeon/radeon_llvm_util.c
> index 7192dee..02a11b5 100644
> --- a/src/gallium/drivers/radeon/radeon_llvm_util.c
> +++ b/src/gallium/drivers/radeon/radeon_llvm_util.c
> @@ -30,6 +30,7 @@
> #include <llvm-c/BitReader.h>
> #include <llvm-c/Core.h>
> #include <llvm-c/Target.h>
> +#include <llvm-c/Transforms/IPO.h>
> #include <llvm-c/Transforms/PassManagerBuilder.h>
>
> LLVMModuleRef radeon_llvm_parse_bitcode(const unsigned char * bitcode,
> @@ -58,9 +59,28 @@ static void radeon_llvm_optimize(LLVMModuleRef mod)
> LLVMTargetDataRef TD = LLVMCreateTargetData(data_layout);
> LLVMPassManagerBuilderRef builder = LLVMPassManagerBuilderCreate();
> LLVMPassManagerRef pass_manager = LLVMCreatePassManager();
> - LLVMAddTargetData(TD, pass_manager);
>
> - LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 1000000000);
> + /* Functions calls are not supported yet, so we need to inline
> + * everything. The most efficient way to do this is to add
> + * the always_inline attribute to all non-kernel functions
> + * and then run the Always Inline pass. The Always Inline
> + * pass will automaically inline functions with this attribute
> + * and does not perform the expensive cost analysis that the normal
> + * inliner does.
> + */
> +
> + LLVMValueRef fn;
> + LLVMValueRef last_fn = LLVMGetLastFunction(mod);
> + for (fn = LLVMGetFirstFunction(mod); fn != last_fn;
> + fn = LLVMGetNextFunction(fn)) {
Will this actually run for the last function? Is there reason to
believe that the last function isn't affected?
Consider:
int testFn(int4 arg);
kernel void testKernel(global int* data){
int4 input;
.... stuff ....
int val = testFn(input);
}
int testFn(int4 arg){
return 0;
}
I'm assuming that functions will exist in the order that they were
defined (not declared) when looping over the functions in the module.
Given that LLVMGetNextFunction returns 0 when it hits the end of the
list, couldn't we just check that?
--Aaron
> + /* All the non-kernel functions have internal linkage */
> + if (LLVMGetLinkage(fn) == LLVMInternalLinkage) {
> + LLVMAddFunctionAttr(fn, LLVMAlwaysInlineAttribute);
> + }
> + }
> +
> + LLVMAddTargetData(TD, pass_manager);
> + LLVMAddAlwaysInlinerPass(pass_manager);
> LLVMPassManagerBuilderPopulateModulePassManager(builder, pass_manager);
>
> LLVMRunPassManager(pass_manager, mod);
> --
> 1.8.1.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list