Re: [Beignet] [PATCH] Backend: Fix llvm40 assert about literal structs

2017-05-17 Thread Pan, Xiuli
Ping for review.
If llvm is debug version will cause assert for device enqueue cases.

-Original Message-
From: Pan, Xiuli 
Sent: Tuesday, April 25, 2017 13:27
To: beignet@lists.freedesktop.org
Cc: Pan, Xiuli 
Subject: [PATCH] Backend: Fix llvm40 assert about literal structs

From: Pan Xiuli 

In llvm literal structs have no name, so check it first.

Signed-off-by: Pan Xiuli 
---
 backend/src/llvm/llvm_gen_backend.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/backend/src/llvm/llvm_gen_backend.cpp 
b/backend/src/llvm/llvm_gen_backend.cpp
index 9954021..831666e 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -362,7 +362,8 @@ namespace gbe
 Type *eltTy = dyn_cast(type)->getElementType();
 if (eltTy->isStructTy()) {
   StructType *strTy = dyn_cast(eltTy);
-  if (strTy->getName().data() && strstr(strTy->getName().data(), 
"sampler"))
+  if (!strTy->isLiteral() && strTy->getName().data() &&
+  strstr(strTy->getName().data(), "sampler"))
 type = Type::getInt32Ty(value->getContext());
 }
   }
-- 
2.7.4

___
Beignet mailing list
Beignet@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/beignet


[Beignet] [PATCH] backend: add sqrt-div pattern to instruction select

2017-05-17 Thread rander.wang
there some patterns like:
  sqrt r1, r2;
  load r4, 1.0;   ===> rqrt r3, r2
  div r3, r4, r1;

Signed-off-by: rander.wang 
---
 backend/src/backend/gen_insn_selection.cpp | 71 ++
 1 file changed, 71 insertions(+)

diff --git a/backend/src/backend/gen_insn_selection.cpp 
b/backend/src/backend/gen_insn_selection.cpp
index 822357e..832fbfe 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -3741,6 +3741,76 @@ extern bool OCL_DEBUGINFO; // first defined by calling 
BVAR in program.cpp
 }
   };
 
+/*! there some patterns like:
+  sqrt r1, r2;
+  load r4, 1.0;   ===> rqrt r3, r2
+  div r3, r4, r1; */
+  class SqrtDivInstructionPattern : public SelectionPattern
+  {
+  public:
+/*! Register the pattern for all opcodes of the family */
+SqrtDivInstructionPattern(void) : SelectionPattern(1, 1) {
+   this->opcodes.push_back(ir::OP_DIV);
+}
+
+/*! Implements base class */
+virtual bool emit(Selection::Opaque  &sel, SelectionDAG &dag) const
+{
+  using namespace ir;
+
+  // We are good to try. We need a MUL for one of the two sources
+  const ir::BinaryInstruction &insn = 
cast(dag.insn);
+  if (insn.getType() != TYPE_FLOAT)
+return false;
+  SelectionDAG *child0 = dag.child[0];
+  SelectionDAG *child1 = dag.child[1];
+  const GenRegister dst = sel.selReg(insn.getDst(0), TYPE_FLOAT);
+
+  if (child1 && child1->insn.getOpcode() == OP_SQR) {
+GBE_ASSERT(cast(child1->insn).getType() == 
TYPE_FLOAT);
+GenRegister srcSQR = sel.selReg(child1->insn.getSrc(0), TYPE_FLOAT);
+const GenRegister dstSQR = sel.selReg(child1->insn.getDst(0), 
TYPE_FLOAT);
+const GenRegister src0 = sel.selReg(insn.getSrc(0), TYPE_FLOAT);
+const GenRegister src1 = sel.selReg(insn.getSrc(1), TYPE_FLOAT);
+float val = 0.0f;
+
+if(child0 && child0->insn.getOpcode() == OP_LOADI)
+{
+  const auto &loadimm = cast(child0->insn);
+  const Immediate imm = loadimm.getImmediate();
+  const Type type = imm.getType();
+  if(type == TYPE_FLOAT)
+val = imm.getFloatValue();
+  else if(type == TYPE_S32)
+val = imm.getIntegerValue();
+}
+
+sel.push();
+if (sel.isScalarReg(insn.getDst(0)))
+  sel.curr.execWidth = 1;
+
+if(val == 1.0f)
+{
+  sel.MATH(dst, GEN_MATH_FUNCTION_RSQ, srcSQR);
+  child0->isRoot = 1;
+  child1->isRoot = 1;
+}
+else
+{
+  sel.MATH(dstSQR, GEN_MATH_FUNCTION_RSQ, srcSQR);
+  sel.MUL(dst, src0, src1);
+  sel.pop();
+  if (child1->child[0]) child1->child[0]->isRoot = 1;
+  if (child1->child[1]) child1->child[1]->isRoot = 1;
+  if (child0) child0->isRoot = 1;
+}
+
+return true;
+  }
+  return false;
+}
+  };
+
   /*! sel.{le,l,ge...} like patterns */
   class SelectModifierInstructionPattern : public SelectionPattern
   {
@@ -8078,6 +8148,7 @@ extern bool OCL_DEBUGINFO; // first defined by calling 
BVAR in program.cpp
 
   SelectionLibrary::SelectionLibrary(void) {
 this->insert();
+this->insert();
 this->insert();
 this->insert();
 this->insert();
-- 
2.7.4

___
Beignet mailing list
Beignet@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/beignet


[Beignet] [PATCH 1/2] Backend: Add optimization for negtive modifier

2017-05-17 Thread rander.wang
 LLVM transform Mad(a, -b, c) to
 Add b, -b, 0
 Mad val, a, b, c

 pow(a,-b) and other buildin math function to the same instruction 
sequence like above

 for Gen support negtive modifier, mad(a, -b, c) is native suppoted.
 Do it just like a:  mov b, -b, so it is a Mov operation like 
LocalCopyPropagation

Signed-off-by: rander.wang 
---
 .../src/backend/gen_insn_selection_optimize.cpp| 35 +++---
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/backend/src/backend/gen_insn_selection_optimize.cpp 
b/backend/src/backend/gen_insn_selection_optimize.cpp
index 512a5bd..d1c302d 100644
--- a/backend/src/backend/gen_insn_selection_optimize.cpp
+++ b/backend/src/backend/gen_insn_selection_optimize.cpp
@@ -74,8 +74,7 @@ namespace gbe
   const GenRegister& replacement) :
   insn(insn), intermedia(intermedia), replacement(replacement)
   {
-assert(insn.opcode == SEL_OP_MOV);
-assert(&(insn.src(0)) == &replacement);
+assert(insn.opcode == SEL_OP_MOV || insn.opcode == SEL_OP_ADD);
 assert(&(insn.dst(0)) == &intermedia);
 this->elements = CalculateElements(intermedia, insn.state.execWidth);
 replacementOverwritten = false;
@@ -102,6 +101,7 @@ namespace gbe
 void doReplacement(ReplaceInfo* info);
 bool CanBeReplaced(const ReplaceInfo* info, const SelectionInstruction& 
insn, const GenRegister& var);
 void cleanReplaceInfoMap();
+void doNegAddOptimization(SelectionInstruction& insn);
 
 SelectionBlock &bb;
 const ir::Liveness::LiveOut& liveout;
@@ -159,8 +159,14 @@ namespace gbe
 
   void SelBasicBlockOptimizer::addToReplaceInfoMap(SelectionInstruction& insn)
   {
-assert(insn.opcode == SEL_OP_MOV);
-const GenRegister& src = insn.src(0);
+assert(insn.opcode == SEL_OP_MOV || insn.opcode == SEL_OP_ADD);
+GenRegister& src = insn.src(0);
+if(insn.opcode == SEL_OP_ADD)
+{
+  if(src.file == GEN_IMMEDIATE_VALUE)
+src = insn.src(1);
+}
+
 const GenRegister& dst = insn.dst(0);
 if (src.type != dst.type || src.file != dst.file || src.hstride != 
dst.hstride)
   return;
@@ -246,10 +252,31 @@ namespace gbe
 
   if (insn.opcode == SEL_OP_MOV)
 addToReplaceInfoMap(insn);
+
+  doNegAddOptimization(insn);
 }
 cleanReplaceInfoMap();
   }
 
+  /* LLVM transform Mad(a, -b, c) to
+ Add b, -b, 0
+ Mad val, a, b, c
+ for Gen support negtive modifier, mad(a, -b, c) is native suppoted.
+ Also it can be used for the same like instruction sequence.
+ Do it just like a:  mov b, -b, so it is a Mov operation like 
LocalCopyPropagation
+  */
+  void SelBasicBlockOptimizer::doNegAddOptimization(SelectionInstruction& insn)
+  {
+  if(insn.opcode == SEL_OP_ADD)
+  {
+  GenRegister src0 = insn.src(0);
+  GenRegister src1 = insn.src(1);
+  if((src0.negation && src1.file == GEN_IMMEDIATE_VALUE && 
src1.value.f == 0.0f) ||
+  (src1.negation && src0.file == GEN_IMMEDIATE_VALUE && 
src0.value.f == 0.0f))
+  addToReplaceInfoMap(insn);
+  }
+  }
+
   void SelBasicBlockOptimizer::run()
   {
 for (size_t i = 0; i < MaxTries; ++i) {
-- 
2.7.4

___
Beignet mailing list
Beignet@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/beignet


[Beignet] [PATCH V2] Backend: Fix performance regression with sampler refine fro LLVM40

2017-05-17 Thread Xiuli Pan
From: Pan Xiuli 

After the refine we can not know if a sampler is a constant initialized
or not. Then the compiler optimization for constant sampler will break
and we will runtime decide which SAMPLE instruction will use.
Now fix the sampler refine for LLVM40 to enable the constant check.
V2: Fix a typo of function __gen_ocl_sampler_to_int type.

Signed-off-by: Pan Xiuli 
---
 backend/src/libocl/src/ocl_image.cl   |  9 
 backend/src/llvm/llvm_sampler_fix.cpp | 41 +++
 2 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/backend/src/libocl/src/ocl_image.cl 
b/backend/src/libocl/src/ocl_image.cl
index e66aa15..2febfda 100644
--- a/backend/src/libocl/src/ocl_image.cl
+++ b/backend/src/libocl/src/ocl_image.cl
@@ -295,18 +295,17 @@ GEN_VALIDATE_ARRAY_INDEX(int, read_write image1d_buffer_t)
 // The work around is to use a LD message instead of normal sample message.
 ///
 
-bool __gen_ocl_sampler_need_fix(int);
-bool __gen_ocl_sampler_need_rounding_fix(int);
-int __gen_ocl_sampler_to_int(sampler_t);
+bool __gen_ocl_sampler_need_fix(sampler_t);
+bool __gen_ocl_sampler_need_rounding_fix(sampler_t);
 
 bool __gen_sampler_need_fix(const sampler_t sampler)
 {
-  return __gen_ocl_sampler_need_fix(__gen_ocl_sampler_to_int(sampler));
+  return __gen_ocl_sampler_need_fix(sampler);
 }
 
 bool __gen_sampler_need_rounding_fix(const sampler_t sampler)
 {
-  return 
__gen_ocl_sampler_need_rounding_fix(__gen_ocl_sampler_to_int(sampler));
+  return __gen_ocl_sampler_need_rounding_fix(sampler);
 }
 
 INLINE_OVERLOADABLE float __gen_fixup_float_coord(float tmpCoord)
diff --git a/backend/src/llvm/llvm_sampler_fix.cpp 
b/backend/src/llvm/llvm_sampler_fix.cpp
index 2e8bcf9..c249755 100644
--- a/backend/src/llvm/llvm_sampler_fix.cpp
+++ b/backend/src/llvm/llvm_sampler_fix.cpp
@@ -55,9 +55,17 @@ namespace gbe {
 //  ((sampler & __CLK_FILTER_MASK) == CLK_FILTER_NEAREST));
 bool needFix = true;
 Value *needFixVal;
+#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 40
+CallInst *init = dyn_cast(I->getOperand(0));
+if (init && 
init->getCalledValue()->getName().compare("__translate_sampler_initializer"))
+{
+  const ConstantInt *ci = dyn_cast(init->getOperand(0));
+  uint32_t samplerInt = ci->getZExtValue();
+#else
 if (dyn_cast(I->getOperand(0))) {
   const ConstantInt *ci = dyn_cast(I->getOperand(0));
   uint32_t samplerInt = ci->getZExtValue();
+#endif
   needFix = ((samplerInt & __CLK_ADDRESS_MASK) == CLK_ADDRESS_CLAMP &&
  (samplerInt & __CLK_FILTER_MASK) == CLK_FILTER_NEAREST);
   needFixVal = ConstantInt::get(boolTy, needFix);
@@ -65,14 +73,24 @@ namespace gbe {
   IRBuilder<> Builder(I->getParent());
 
   Builder.SetInsertPoint(I);
+
   Value *addressMask = ConstantInt::get(i32Ty, __CLK_ADDRESS_MASK);
-  Value *addressMode = Builder.CreateAnd(I->getOperand(0), 
addressMask);
   Value *clampInt =  ConstantInt::get(i32Ty, CLK_ADDRESS_CLAMP);
-  Value *isClampMode = Builder.CreateICmpEQ(addressMode, clampInt);
   Value *filterMask = ConstantInt::get(i32Ty, __CLK_FILTER_MASK);
-  Value *filterMode = Builder.CreateAnd(I->getOperand(0), filterMask);
   Value *nearestInt = ConstantInt::get(i32Ty, CLK_FILTER_NEAREST);
+
+#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 40
+  Module *M = I->getParent()->getParent()->getParent();
+  Value* samplerCvt = 
M->getOrInsertFunction("__gen_ocl_sampler_to_int", i32Ty, 
I->getOperand(0)->getType(), nullptr);
+  Value *samplerVal = Builder.CreateCall(samplerCvt, 
{I->getOperand(0)});
+#else
+  Value *samplerVal = I->getOperand(0);
+#endif
+  Value *addressMode = Builder.CreateAnd(samplerVal, addressMask);
+  Value *isClampMode = Builder.CreateICmpEQ(addressMode, clampInt);
+  Value *filterMode = Builder.CreateAnd(samplerVal, filterMask);
   Value *isNearestMode = Builder.CreateICmpEQ(filterMode, nearestInt);
+
   needFixVal = Builder.CreateAnd(isClampMode, isNearestMode);
 }
 
@@ -83,16 +101,31 @@ namespace gbe {
 //  return ((sampler & CLK_NORMALIZED_COORDS_TRUE) == 0);
 bool needFix = true;
 Value *needFixVal;
+ #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 40
+CallInst *init = dyn_cast(I->getOperand(0));
+if (init && 
init->getCalledValue()->getName().compare("__translate_sampler_initializer"))
+{
+  const ConstantInt *ci = dyn_cast(init->getOperand(0));
+  uint32_t samplerInt = ci->getZExtValue();
+#else
 if (dyn_cast(I->getOperand(0))) {
   const ConstantInt *ci = dyn_cast(I->getOperand(0));
   uint32_t samplerInt = ci->getZExtValue();
+#endif
   needFix = samplerInt & CLK_NORMALIZED_CO

Re: [Beignet] [PATCH] Backend: Fix llvm40 assert about literal structs

2017-05-17 Thread Guo, Yejun
Looks fine to me, thanks.

-Original Message-
From: Beignet [mailto:beignet-boun...@lists.freedesktop.org] On Behalf Of Pan, 
Xiuli
Sent: Wednesday, May 17, 2017 3:15 PM
To: beignet@lists.freedesktop.org
Subject: Re: [Beignet] [PATCH] Backend: Fix llvm40 assert about literal structs

Ping for review.
If llvm is debug version will cause assert for device enqueue cases.

-Original Message-
From: Pan, Xiuli 
Sent: Tuesday, April 25, 2017 13:27
To: beignet@lists.freedesktop.org
Cc: Pan, Xiuli 
Subject: [PATCH] Backend: Fix llvm40 assert about literal structs

From: Pan Xiuli 

In llvm literal structs have no name, so check it first.

Signed-off-by: Pan Xiuli 
---
 backend/src/llvm/llvm_gen_backend.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/backend/src/llvm/llvm_gen_backend.cpp 
b/backend/src/llvm/llvm_gen_backend.cpp
index 9954021..831666e 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -362,7 +362,8 @@ namespace gbe
 Type *eltTy = dyn_cast(type)->getElementType();
 if (eltTy->isStructTy()) {
   StructType *strTy = dyn_cast(eltTy);
-  if (strTy->getName().data() && strstr(strTy->getName().data(), 
"sampler"))
+  if (!strTy->isLiteral() && strTy->getName().data() &&
+  strstr(strTy->getName().data(), "sampler"))
 type = Type::getInt32Ty(value->getContext());
 }
   }
-- 
2.7.4

___
Beignet mailing list
Beignet@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/beignet
___
Beignet mailing list
Beignet@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/beignet