yaxunl updated this revision to Diff 169864.
yaxunl retitled this revision from "[OpenCL] Mark load of block invoke function 
as invariant" to "Mark store and load of block invoke function as 
invariant.group".
yaxunl edited the summary of this revision.
yaxunl added a comment.
Herald added a subscriber: Prazek.

mark store and load of block invoke function as invariant.group.


https://reviews.llvm.org/D53295

Files:
  lib/CodeGen/CGBlocks.cpp
  test/CodeGenOpenCL/blocks-indirect-call.cl

Index: test/CodeGenOpenCL/blocks-indirect-call.cl
===================================================================
--- /dev/null
+++ test/CodeGenOpenCL/blocks-indirect-call.cl
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple amdgcn-amd-amdhsa | FileCheck -check-prefixes=COMMON,NOOPT %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple amdgcn-amd-amdhsa | FileCheck -check-prefixes=COMMON,OPT %s
+
+// Check invariant.group MD are emitted at -O0 and indirect function calls
+// are eliminated at default optimization level.
+
+// COMMON-LABEL: define {{.*}} @blockInLoopCondition
+// NOOPT: store {{.*}}@__blockInLoopCondition_block_invoke{{.*}} !invariant.group
+// NOOPT: %[[INV:.*]] = getelementptr {{.*}}%block.literal, i32 0, i32 2
+// NOOPT: load {{.*}}%[[INV]]{{.*}}, !invariant.group
+// ToDo: Fix LLVM optimizations to lower indirect function call
+// OPT: %[[INV:.*]] = phi {{.*}}[ @__blockInLoopCondition_block_invoke, %entry ]
+// OPT: call i32 %[[INV]]
+
+// OPT-NOT: load {{.*}}!invariant.group
+void blockInLoopCondition(int* res, int tid, int multiplier) {
+  int (^kernelBlock)(int) = ^(int num) {
+    return num * multiplier;
+  };
+  res[tid] = 39;
+  for(int i=0; i<kernelBlock(13); i++) {
+    res[tid]--;
+  }
+}
+
+// COMMON-LABEL: define {{.*}} @blockInLoopBody
+// NOOPT: store {{.*}}@__blockInLoopBody_block_invoke{{.*}} !invariant.group
+// NOOPT: %[[INV:.*]] = getelementptr {{.*}}%block.literal, i32 0, i32 2
+// NOOPT: load {{.*}}%[[INV]]{{.*}}, !invariant.group
+// OPT: call i32 @__blockInLoopBody_block_invoke
+// OPT-NOT: load {{.*}}!invariant.group
+void blockInLoopBody(int* res, int tid, int multiplier) {
+  res[tid] = 39;
+  for(int i=0; i<1000; i++) {
+    int (^kernelBlock)(int) = ^(int num) {
+      return num * multiplier;
+    };
+    res[tid]=kernelBlock(tid);
+  }
+}
+
Index: lib/CodeGen/CGBlocks.cpp
===================================================================
--- lib/CodeGen/CGBlocks.cpp
+++ lib/CodeGen/CGBlocks.cpp
@@ -976,23 +976,25 @@
     [&](unsigned index, CharUnits offset, const Twine &name) -> Address {
       return Builder.CreateStructGEP(blockAddr, index, offset, name);
     };
-  auto storeField =
-    [&](llvm::Value *value, unsigned index, CharUnits offset,
-        const Twine &name) {
-      Builder.CreateStore(value, projectField(index, offset, name));
-    };
+  auto storeField = [&](llvm::Value *value, unsigned index, CharUnits offset,
+                        const Twine &name, bool IsInvariant) {
+    auto *ST = Builder.CreateStore(value, projectField(index, offset, name));
+    if (IsInvariant)
+      ST->setMetadata(CGM.getModule().getMDKindID("invariant.group"),
+                      llvm::MDNode::get(getLLVMContext(), None));
+  };
 
   // Initialize the block header.
   {
     // We assume all the header fields are densely packed.
     unsigned index = 0;
     CharUnits offset;
-    auto addHeaderField =
-      [&](llvm::Value *value, CharUnits size, const Twine &name) {
-        storeField(value, index, offset, name);
-        offset += size;
-        index++;
-      };
+    auto addHeaderField = [&](llvm::Value *value, CharUnits size,
+                              const Twine &name, bool IsInvariant = false) {
+      storeField(value, index, offset, name, IsInvariant);
+      offset += size;
+      index++;
+    };
 
     if (!IsOpenCL) {
       addHeaderField(isa, getPointerSize(), "block.isa");
@@ -1008,7 +1010,8 @@
           llvm::ConstantInt::get(IntTy, blockInfo.BlockAlign.getQuantity()),
           getIntSize(), "block.align");
     }
-    addHeaderField(blockFn, GenVoidPtrSize, "block.invoke");
+    addHeaderField(blockFn, GenVoidPtrSize, "block.invoke",
+                   /*IsInvariant=*/true);
     if (!IsOpenCL)
       addHeaderField(descriptor, getPointerSize(), "block.descriptor");
     else if (auto *Helper =
@@ -1302,6 +1305,9 @@
 
   // Load the function.
   llvm::Value *Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
+  cast<llvm::LoadInst>(Func)->setMetadata(
+      CGM.getModule().getMDKindID("invariant.group"),
+      llvm::MDNode::get(getLLVMContext(), None));
 
   const FunctionType *FuncTy = FnType->castAs<FunctionType>();
   const CGFunctionInfo &FnInfo =
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to