summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@intel.com>2015-01-20 14:40:39 +0800
committerZhigang Gong <zhigang.gong@intel.com>2015-01-21 15:00:26 +0800
commit0ef57ef1f12032a3d0525215a7ff3e20569ab16b (patch)
tree1480a21ede8948d8518b7c54de2cd804f64e665b
parent8d96ef5c5fe6b9500abe00a049fbe2b62963b83b (diff)
GBE: fix an ACC register related instruction scheduling bug
Some instructions modify the ACC register in the gen_context stage which's not regonized by current instruction scheduling algorithm. This patch fix this bug by checking all the possible SEL_OPs which may change the ACC implicitly. The corresponding bugzilla link is as below: https://bugs.freedesktop.org/show_bug.cgi?id=88587 Signed-off-by: Zhigang Gong <zhigang.gong@intel.com> Reviewed-by: "Yang, Rong R" <rong.r.yang@intel.com>
-rw-r--r--backend/src/backend/gen_insn_scheduling.cpp4
-rw-r--r--backend/src/backend/gen_insn_selection.cpp14
-rw-r--r--backend/src/backend/gen_insn_selection.hpp2
3 files changed, 18 insertions, 2 deletions
diff --git a/backend/src/backend/gen_insn_scheduling.cpp b/backend/src/backend/gen_insn_scheduling.cpp
index a0a25944..f3ed4b03 100644
--- a/backend/src/backend/gen_insn_scheduling.cpp
+++ b/backend/src/backend/gen_insn_scheduling.cpp
@@ -379,7 +379,7 @@ namespace gbe
}
// Track writes in accumulators
- if (insn.state.accWrEnable) {
+ if (insn.modAcc()) {
const uint32_t index = this->getIndex(GenRegister::acc());
this->nodes[index] = node;
}
@@ -517,7 +517,7 @@ namespace gbe
tracker.addDependency(node, getFlag(insn), WRITE_AFTER_WRITE);
// write-after-write for accumulators
- if (insn.state.accWrEnable)
+ if (insn.modAcc())
tracker.addDependency(node, GenRegister::acc(), WRITE_AFTER_WRITE);
// write-after-write in memory
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 45cd1198..0e33f5d6 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -189,6 +189,20 @@ namespace gbe
this->opcode == SEL_OP_DWORD_GATHER;
}
+ bool SelectionInstruction::modAcc(void) const {
+ return this->opcode == SEL_OP_I64SUB ||
+ this->opcode == SEL_OP_I64ADD ||
+ this->opcode == SEL_OP_MUL_HI ||
+ this->opcode == SEL_OP_HADD ||
+ this->opcode == SEL_OP_RHADD ||
+ this->opcode == SEL_OP_I64MUL ||
+ this->opcode == SEL_OP_I64_MUL_HI ||
+ this->opcode == SEL_OP_I64MADSAT ||
+ this->opcode == SEL_OP_I64DIV ||
+ this->opcode == SEL_OP_I64REM ||
+ this->opcode == SEL_OP_MACH;
+ }
+
bool SelectionInstruction::isWrite(void) const {
return this->opcode == SEL_OP_UNTYPED_WRITE ||
this->opcode == SEL_OP_WRITE64 ||
diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index 7fef11f5..8bffb167 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -77,6 +77,8 @@ namespace gbe
bool isRead(void) const;
/*! Does it write memory? */
bool isWrite(void) const;
+ /*! Does it modify the acc register. */
+ bool modAcc(void) const;
/*! Is it a branch instruction (i.e. modify control flow) */
bool isBranch(void) const;
/*! Is it a label instruction (i.e. change the implicit mask) */