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] [PATCH] backend: add sqrt-div pattern to instruction select
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
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
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
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