[Beignet] [PATCH] backend: add sqrt-div pattern to instruction select
Pan, Xiuli
xiuli.pan at intel.com
Fri May 19 06:16:07 UTC 2017
I discuss with Yang Rong, and found you can do more merge for
sqrt r1, r2;
load r4, 2.0; ===> rqrt r5, r2
div r3, r4, r1; mul r3, r5, 2.0
To get less loadi.
-----Original Message-----
From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of rander.wang
Sent: Friday, May 19, 2017 14:10
To: beignet at freedesktop.org
Cc: Wang, Rander <rander.wang at intel.com>
Subject: [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 <rander.wang at intel.com>
---
backend/src/backend/gen_insn_selection.cpp | 68 ++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 822357e..cbad103 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -3741,6 +3741,73 @@ 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<ir::BinaryInstruction>(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<ir::UnaryInstruction>(child1->insn).getType() == TYPE_FLOAT);
+ GenRegister srcSQR = sel.selReg(child1->insn.getSrc(0), TYPE_FLOAT);
+ const GenRegister tmp = sel.selReg(sel.reg(ir::FAMILY_DWORD), ir::TYPE_FLOAT);
+ const GenRegister src0 = sel.selReg(insn.getSrc(0), TYPE_FLOAT);
+ float val = 0.0f;
+
+ if(child0 && child0->insn.getOpcode() == OP_LOADI)
+ {
+ const auto &loadimm = cast<LoadImmInstruction>(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);
+ if (child1->child[0]) child1->child[0]->isRoot = 1;
+ }
+ else
+ {
+ sel.MATH(tmp, GEN_MATH_FUNCTION_RSQ, srcSQR);
+ sel.MUL(dst, src0, tmp);
+ if (child1->child[0]) child1->child[0]->isRoot = 1;
+ if (child0) child0->isRoot = 1;
+ }
+ sel.pop();
+
+ return true;
+ }
+ return false;
+ }
+ };
+
/*! sel.{le,l,ge...} like patterns */
class SelectModifierInstructionPattern : public SelectionPattern
{
@@ -8078,6 +8145,7 @@ extern bool OCL_DEBUGINFO; // first defined by calling BVAR in program.cpp
SelectionLibrary::SelectionLibrary(void) {
this->insert<UnaryInstructionPattern>();
+ this->insert<SqrtDivInstructionPattern>();
this->insert<BinaryInstructionPattern>();
this->insert<TypedWriteInstructionPattern>();
this->insert<SyncInstructionPattern>();
--
2.7.4
_______________________________________________
Beignet mailing list
Beignet at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/beignet
More information about the Beignet
mailing list