radeon/compute: Unconditionally inline all functions v2
authorTom Stellard <thomas.stellard@amd.com>
Thu, 14 Nov 2013 02:52:14 +0000 (18:52 -0800)
committerTom Stellard <thomas.stellard@amd.com>
Tue, 26 Nov 2013 04:42:49 +0000 (20:42 -0800)
We need to do this until function calls are supported.

v2:
  - Fix loop conditional

https://bugs.freedesktop.org/show_bug.cgi?id=64225

CC: "10.0" <mesa-stable@lists.freedesktop.org>
src/gallium/drivers/radeon/radeon_llvm_util.c

index f2b3e136d4734d2e2e9c58541e18a5cce5a8f0e8..3ba0acc55bc925aeab7de2d482f7e1353a7f290f 100644 (file)
@@ -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,
@@ -59,9 +60,26 @@ 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;
+       for (fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) {
+               /* 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);