[Beignet] [PATCH 2/2] GBE: enable llvm5.0 support.

Yang Rong rong.r.yang at intel.com
Wed Sep 20 06:42:20 UTC 2017


1. getOrInsertFunction without nullptr.
2. handle f16 rounding.
3. remove llvm value dump.
4. handle AddrSpaceCastInst when parsing block info.

Signed-off-by: Yang Rong <rong.r.yang at intel.com>
---
 backend/src/llvm/PromoteIntegers.cpp     |  5 +++
 backend/src/llvm/llvm_barrier_nodup.cpp  |  4 ++
 backend/src/llvm/llvm_device_enqueue.cpp | 68 +++++++++++++++++++++++---------
 backend/src/llvm/llvm_gen_backend.cpp    | 41 ++++++++++++++-----
 backend/src/llvm/llvm_profiling.cpp      | 20 ++++++++--
 backend/src/llvm/llvm_sampler_fix.cpp    |  8 ++++
 6 files changed, 114 insertions(+), 32 deletions(-)

diff --git a/backend/src/llvm/PromoteIntegers.cpp b/backend/src/llvm/PromoteIntegers.cpp
index a500311..d433771 100644
--- a/backend/src/llvm/PromoteIntegers.cpp
+++ b/backend/src/llvm/PromoteIntegers.cpp
@@ -605,8 +605,13 @@ static void convertInstruction(Instruction *Inst, ConversionState &State) {
     for (SwitchInst::CaseIt I = Switch->case_begin(),
              E = Switch->case_end();
          I != E; ++I) {
+#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50
+      NewInst->addCase(cast<ConstantInt>(convertConstant(I->getCaseValue())),
+                       I->getCaseSuccessor());
+#else
       NewInst->addCase(cast<ConstantInt>(convertConstant(I.getCaseValue())),
                        I.getCaseSuccessor());
+#endif
     }
     Switch->eraseFromParent();
   } else {
diff --git a/backend/src/llvm/llvm_barrier_nodup.cpp b/backend/src/llvm/llvm_barrier_nodup.cpp
index a7d0d1a..b8ffdf4 100644
--- a/backend/src/llvm/llvm_barrier_nodup.cpp
+++ b/backend/src/llvm/llvm_barrier_nodup.cpp
@@ -74,7 +74,11 @@ namespace gbe {
               if (F.hasFnAttribute(Attribute::NoDuplicate)) {
                 auto attrs = F.getAttributes();
                 F.setAttributes(attrs.removeAttribute(M.getContext(),
+#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50
+                                AttributeList::FunctionIndex,
+#else
                                 AttributeSet::FunctionIndex,
+#endif
                                 Attribute::NoDuplicate));
                 changed = true;
               }
diff --git a/backend/src/llvm/llvm_device_enqueue.cpp b/backend/src/llvm/llvm_device_enqueue.cpp
index 9a0fb46..1e94b75 100644
--- a/backend/src/llvm/llvm_device_enqueue.cpp
+++ b/backend/src/llvm/llvm_device_enqueue.cpp
@@ -29,6 +29,7 @@ namespace gbe {
     BitCastInst* bt = dyn_cast<BitCastInst>(I);
     if (bt == NULL)
       return NULL;
+//bt->dump();
 
     Type* type = bt->getOperand(0)->getType();
     if(!type->isPointerTy())
@@ -112,7 +113,8 @@ namespace gbe {
     ValueToValueMapTy VMap;
     for (Function::arg_iterator I = Fn->arg_begin(), E = Fn->arg_end(); I != E; ++I) {
       PointerType *ty = dyn_cast<PointerType>(I->getType());
-      if(ty && ty->getAddressSpace() == 0) //Foce set the address space to global
+      //Foce set the address space to global
+      if(ty && (ty->getAddressSpace() == 0 || ty->getAddressSpace() == 4))
         ty = PointerType::get(ty->getPointerElementType(), 1);
       ParamTys.push_back(ty);
     }
@@ -252,12 +254,23 @@ namespace gbe {
             if(gep == NULL)
               continue;
 
-            BitCastInst* fnPointer = dyn_cast<BitCastInst>(gep->getOperand(0));
-            if(fnPointer == NULL)
+            Value *fnPointer = gep->getOperand(0);
+            if (isa<AddrSpaceCastInst>(fnPointer)) {
+              fnPointer = (dyn_cast<AddrSpaceCastInst>(fnPointer))->getOperand(0);
+            }
+
+            if (isa<BitCastInst>(fnPointer)) {
+              fnPointer = (dyn_cast<BitCastInst>(fnPointer))->getOperand(0);
+            }
+
+            if(fnPointer == gep->getOperand(0))
               continue;
 
-            if(BitCastInst* bt = dyn_cast<BitCastInst>(fnPointer->getOperand(0))) {
-              std::string fnName = blocks[bt->getOperand(0)];
+            if (isa<BitCastInst>(fnPointer)) {
+              fnPointer = (dyn_cast<BitCastInst>(fnPointer))->getOperand(0);
+            }
+            if(blocks.find(fnPointer) != blocks.end()) {
+              std::string fnName = blocks[fnPointer];
               Function* f = mod->getFunction(fnName);
               CallInst *newCI = builder.CreateCall(f, args);
               CI->replaceAllUsesWith(newCI);
@@ -266,7 +279,7 @@ namespace gbe {
             }
 
             //the function is global variable
-            if(GlobalVariable* gv = dyn_cast<GlobalVariable>(fnPointer->getOperand(0))) {
+            if(GlobalVariable* gv = dyn_cast<GlobalVariable>(fnPointer)) {
               Constant *c = gv->getInitializer();
               ConstantExpr *expr = dyn_cast<ConstantExpr>(c->getOperand(3));
               BitCastInst *bt = dyn_cast<BitCastInst>(expr->getAsInstruction());
@@ -277,7 +290,7 @@ namespace gbe {
               continue;
             }
 
-            ld = dyn_cast<LoadInst>(fnPointer->getOperand(0));
+            ld = dyn_cast<LoadInst>(fnPointer);
             if(ld == NULL)
               continue;
 
@@ -304,9 +317,13 @@ namespace gbe {
                 User *theUser = iter->getUser();
 #endif
                 if(StoreInst *st = dyn_cast<StoreInst>(theUser)) {
-                  bt = dyn_cast<BitCastInst>(st->getValueOperand());
-                  if(bt)
-                    v = bt->getOperand(0);
+                  v = st->getValueOperand();
+                  if (isa<AddrSpaceCastInst>(v)) {
+                    v = (dyn_cast<AddrSpaceCastInst>(v))->getOperand(0);
+                  }
+                  if (isa<BitCastInst>(v)) {
+                    v = (dyn_cast<BitCastInst>(v))->getOperand(0);
+                  }
                 }
               }
               if(blocks.find(v) == blocks.end()) {
@@ -340,8 +357,12 @@ namespace gbe {
             if(type->isIntegerTy())
                 block_index = 6;
             Value *block = CI->getArgOperand(block_index);
-            while(isa<BitCastInst>(block))
-               block = dyn_cast<BitCastInst>(block)->getOperand(0);
+            while(isa<BitCastInst>(block) || isa<AddrSpaceCastInst>(block)) {
+               if (isa<BitCastInst>(block))
+                 block = dyn_cast<BitCastInst>(block)->getOperand(0);
+               if (isa<AddrSpaceCastInst>(block))
+                 block = dyn_cast<AddrSpaceCastInst>(block)->getOperand(0);
+             }
             LoadInst *ld = dyn_cast<LoadInst>(block);
             Value *v = NULL;
             if(ld) {
@@ -353,9 +374,13 @@ namespace gbe {
                 User *theUser = iter->getUser();
 #endif
                 if(StoreInst *st = dyn_cast<StoreInst>(theUser)) {
-                  BitCastInst *bt = dyn_cast<BitCastInst>(st->getValueOperand());
-                  if(bt)
-                    v = bt->getOperand(0);
+                  v = st->getValueOperand();
+                  if (isa<AddrSpaceCastInst>(v)) {
+                    v = (dyn_cast<AddrSpaceCastInst>(v))->getOperand(0);
+                  }
+                  if (isa<BitCastInst>(v)) {
+                    v = (dyn_cast<BitCastInst>(v))->getOperand(0);
+                  }
                 }
               }
               if(blocks.find(v) == blocks.end()) {
@@ -378,15 +403,20 @@ namespace gbe {
             if( fn->isVarArg() ) {
               //enqueue function with slm, convert to __gen_enqueue_kernel_slm call
               //store the slm information to a alloca address.
-              int start = block_index + 1;
+              int start = block_index + 1 + 1;  //the first is count, skip
               int count = CI->getNumArgOperands() - start;
               Type *intTy = IntegerType::get(mod->getContext(), 32);
+              Type *int64Ty = IntegerType::get(mod->getContext(), 64);
 
               AllocaInst *AI = builder.CreateAlloca(intTy, ConstantInt::get(intTy, count));
 
               for(uint32_t i = start; i < CI->getNumArgOperands(); i++) {
                 Value *ptr = builder.CreateGEP(AI, ConstantInt::get(intTy, i-start));
-                builder.CreateStore(CI->getArgOperand(i), ptr);
+                Value *argSize = CI->getArgOperand(i);
+                if (argSize->getType() == int64Ty) {
+                  argSize = builder.CreateTrunc(argSize, intTy);
+                }
+                builder.CreateStore(argSize, ptr);
               }
               SmallVector<Value*, 16> args(CI->op_begin(), CI->op_begin() + 3);
               args.push_back(CI->getArgOperand(block_index));
@@ -394,8 +424,8 @@ namespace gbe {
               args.push_back(AI);
 
               std::vector<Type *> ParamTys;
-              for (Value** I = args.begin(); I != args.end(); ++I)
-                ParamTys.push_back((*I)->getType());
+              for (Value** iter = args.begin(); iter != args.end(); ++iter)
+                ParamTys.push_back((*iter)->getType());
               CallInst* newCI = builder.CreateCall(cast<llvm::Function>(mod->getOrInsertFunction(
                               "__gen_enqueue_kernel_slm", FunctionType::get(intTy, ParamTys, false))), args);
               CI->replaceAllUsesWith(newCI);
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index a9df652..c552c91 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -740,6 +740,8 @@ namespace gbe
     DECL_VISIT_FN(AtomicCmpXchgInst, AtomicCmpXchgInst);
 #undef DECL_VISIT_FN
 
+    // Emit rounding instructions from gen native function
+    void emitRoundingCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode);
     // Emit unary instructions from gen native function
     void emitUnaryCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode, ir::Type = ir::TYPE_FLOAT);
     // Emit unary instructions from gen native function
@@ -973,7 +975,7 @@ namespace gbe
             CallInst *ci = dyn_cast<CallInst>(theUser);
             pointer = ci ? ci->getArgOperand(0) : NULL;
           } else {
-            theUser->dump();
+            //theUser->dump();
             GBE_ASSERT(0 && "Unknown instruction operating on pointers\n");
           }
 
@@ -1121,7 +1123,7 @@ namespace gbe
           pointerBaseMap.insert(std::make_pair(ptr, basePhi));
           return basePhi;
       } else {
-        ptr->dump();
+        //ptr->dump();
         GBE_ASSERT(0 && "Unhandled instruction in getPointerBase\n");
         return ptr;
       }
@@ -1202,7 +1204,7 @@ namespace gbe
           BtiValueMap.insert(std::make_pair(Val, btiPhi));
           return btiPhi;
         } else {
-          Val->dump();
+          //Val->dump();
           GBE_ASSERT(0 && "Unhandled instruction in getBtiRegister\n");
           return Val;
         }
@@ -1656,7 +1658,7 @@ namespace gbe
         }
       default:
         {
-          c->dump();
+          //c->dump();
           NOT_IMPLEMENTED;
         }
     }
@@ -1908,7 +1910,7 @@ namespace gbe
   ir::ImmediateIndex GenWriter::processConstantImmIndex(Constant *CPV, int32_t index) {
     if (dyn_cast<ConstantExpr>(CPV) == NULL)
       return processConstantImmIndexImpl(CPV, index);
-    CPV->dump();
+    //CPV->dump();
     GBE_ASSERT(0 && "unsupported constant.\n");
     return ctx.newImmediate((uint32_t)0);
   }
@@ -4172,6 +4174,21 @@ namespace gbe
     };
   }
 
+  void GenWriter::emitRoundingCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode) {
+    if (I.getType()->isHalfTy()) {
+      const ir::Register src = this->getRegister(I.getOperand(0));
+      const ir::Register srcFloat = ctx.reg(ir::FAMILY_DWORD);
+      const ir::Register dstFloat = ctx.reg(ir::FAMILY_DWORD);
+      const ir::Register dst = this->getRegister(&I);
+      ctx.F16TO32(ir::TYPE_FLOAT, ir::TYPE_U16, srcFloat, src);
+      ctx.ALU1(opcode, ir::TYPE_FLOAT, dstFloat, srcFloat);
+      ctx.F32TO16(ir::TYPE_U16, ir::TYPE_FLOAT, dst, dstFloat);
+    } else {
+      GBE_ASSERT(I.getType()->isFloatTy());
+      this->emitUnaryCallInst(I,CS,opcode);
+    }
+  }
+
   void GenWriter::emitUnaryCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode, ir::Type type) {
     CallSite::arg_iterator AI = CS.arg_begin();
 #if GBE_DEBUG
@@ -4838,10 +4855,10 @@ namespace gbe
           }
           break;
           case Intrinsic::sqrt: this->emitUnaryCallInst(I,CS,ir::OP_SQR); break;
-          case Intrinsic::ceil: this->emitUnaryCallInst(I,CS,ir::OP_RNDU); break;
-          case Intrinsic::trunc: this->emitUnaryCallInst(I,CS,ir::OP_RNDZ); break;
-          case Intrinsic::rint: this->emitUnaryCallInst(I,CS,ir::OP_RNDE); break;
-          case Intrinsic::floor: this->emitUnaryCallInst(I,CS,ir::OP_RNDD); break;
+          case Intrinsic::ceil: this->emitRoundingCallInst(I,CS,ir::OP_RNDU); break;
+          case Intrinsic::trunc: this->emitRoundingCallInst(I,CS,ir::OP_RNDZ); break;
+          case Intrinsic::rint: this->emitRoundingCallInst(I,CS,ir::OP_RNDE); break;
+          case Intrinsic::floor: this->emitRoundingCallInst(I,CS,ir::OP_RNDD); break;
           case Intrinsic::sin: this->emitUnaryCallInst(I,CS,ir::OP_SIN); break;
           case Intrinsic::cos: this->emitUnaryCallInst(I,CS,ir::OP_COS); break;
           case Intrinsic::log2: this->emitUnaryCallInst(I,CS,ir::OP_LOG); break;
@@ -5698,9 +5715,13 @@ namespace gbe
           case GEN_OCL_ENQUEUE_SET_NDRANGE_INFO:
           {
             GBE_ASSERT(AI != AE);
+            Value *dstValue;
+            if(I.hasStructRetAttr())
+              dstValue = *AI++;
+            else
+              dstValue = &I;
             Value *srcValue = *AI;
             ++AI;
-            Value *dstValue = &I;
             regTranslator.newValueProxy(srcValue, dstValue);
             break;
           }
diff --git a/backend/src/llvm/llvm_profiling.cpp b/backend/src/llvm/llvm_profiling.cpp
index f7e4cc5..2d2ee11 100644
--- a/backend/src/llvm/llvm_profiling.cpp
+++ b/backend/src/llvm/llvm_profiling.cpp
@@ -162,12 +162,19 @@ namespace gbe
       /* Add the timestamp store function call. */
       // __gen_ocl_store_timestamp(int nth, int type);
       Value *Args[2] = {ConstantInt::get(intTy, pointNum++), ConstantInt::get(intTy, profilingType)};
+#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50
       builder->CreateCall(cast<llvm::Function>(module->getOrInsertFunction(
               "__gen_ocl_calc_timestamp", Type::getVoidTy(module->getContext()),
               IntegerType::getInt32Ty(module->getContext()),
+              IntegerType::getInt32Ty(module->getContext()))),
+              ArrayRef<Value*>(Args));
+#else
+      builder->CreateCall(cast<llvm::Function>(module->getOrInsertFunction(
+              "__gen_ocl_calc_timestamp", Type::getVoidTy(module->getContext()),
               IntegerType::getInt32Ty(module->getContext()),
-              NULL)),
+              IntegerType::getInt32Ty(module->getContext()), nullptr)),
               ArrayRef<Value*>(Args));
+#endif
     }
     /* We insert one store_profiling at the end of the last block to hold the place. */
     llvm::Function::iterator BE = F.end();
@@ -177,12 +184,19 @@ namespace gbe
     builder->SetInsertPoint(&*retInst);
     Value *Args2[2] = {profilingBuf, ConstantInt::get(intTy, profilingType)};
 
+#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50
     builder->CreateCall(cast<llvm::Function>(module->getOrInsertFunction(
             "__gen_ocl_store_profiling", Type::getVoidTy(module->getContext()),
             ptrTy,
-            IntegerType::getInt32Ty(module->getContext()),
-            NULL)),
+            IntegerType::getInt32Ty(module->getContext()))),
             ArrayRef<Value*>(Args2));
+#else
+    builder->CreateCall(cast<llvm::Function>(module->getOrInsertFunction(
+            "__gen_ocl_store_profiling", Type::getVoidTy(module->getContext()),
+            ptrTy,
+            IntegerType::getInt32Ty(module->getContext()), nullptr)),
+            ArrayRef<Value*>(Args2));
+#endif
 
     delete builder;
     return changed;
diff --git a/backend/src/llvm/llvm_sampler_fix.cpp b/backend/src/llvm/llvm_sampler_fix.cpp
index c249755..c9ec817 100644
--- a/backend/src/llvm/llvm_sampler_fix.cpp
+++ b/backend/src/llvm/llvm_sampler_fix.cpp
@@ -81,7 +81,11 @@ namespace gbe {
 
 #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 40
           Module *M = I->getParent()->getParent()->getParent();
+#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50
+          Value* samplerCvt = M->getOrInsertFunction("__gen_ocl_sampler_to_int", i32Ty, I->getOperand(0)->getType());
+#else
           Value* samplerCvt = M->getOrInsertFunction("__gen_ocl_sampler_to_int", i32Ty, I->getOperand(0)->getType(), nullptr);
+#endif
           Value *samplerVal = Builder.CreateCall(samplerCvt, {I->getOperand(0)});
 #else
           Value *samplerVal = I->getOperand(0);
@@ -119,7 +123,11 @@ namespace gbe {
           Builder.SetInsertPoint(I);
 #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 40
           Module *M = I->getParent()->getParent()->getParent();
+#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 50
+          Value* samplerCvt = M->getOrInsertFunction("__gen_ocl_sampler_to_int", i32Ty, I->getOperand(0)->getType());
+#else
           Value* samplerCvt = M->getOrInsertFunction("__gen_ocl_sampler_to_int", i32Ty, I->getOperand(0)->getType(), nullptr);
+#endif
           Value *samplerVal = Builder.CreateCall(samplerCvt, {I->getOperand(0)});
 #else
           Value *samplerVal = I->getOperand(0);
-- 
2.7.4



More information about the Beignet mailing list