[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