[Beignet] [PATCH] Fix the bug of multi deleting of load instruction in lowering
junyan.he at inbox.com
junyan.he at inbox.com
Sun Jan 19 19:28:43 PST 2014
From: Junyan He <junyan.he at linux.intel.com>
When the load instruction has multi-value destinations, the load
instruction in buildConstantPush function will be replaced many
times and which can cause the potential problems.
---
backend/src/ir/instruction.cpp | 9 +++++++++
backend/src/ir/instruction.hpp | 2 ++
backend/src/ir/lowering.cpp | 12 +++++++++---
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp
index 5e3cd84..a3e096f 100644
--- a/backend/src/ir/instruction.cpp
+++ b/backend/src/ir/instruction.cpp
@@ -1442,6 +1442,15 @@ END_FUNCTION(Instruction, Register)
fn.deleteInstruction(this);
}
+ void Instruction::insert(Instruction *prev, Instruction ** new_ins) {
+ Function &fn = prev->getFunction();
+ Instruction *insn = fn.newInstruction(*this);
+ insn->parent = prev->parent;
+ append(insn, prev);
+ if (new_ins)
+ *new_ins = insn;
+ }
+
bool Instruction::hasSideEffect(void) const {
return opcode == OP_STORE ||
opcode == OP_TYPED_WRITE ||
diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp
index c827b9a..696d1d9 100644
--- a/backend/src/ir/instruction.hpp
+++ b/backend/src/ir/instruction.hpp
@@ -170,6 +170,8 @@ namespace ir {
void replace(Instruction *other) const;
/*! Remove the instruction from the instruction stream */
void remove(void);
+ /* Insert the instruction after the previous one. */
+ void insert(Instruction *prev, Instruction ** new_ins = NULL);
/*! Indicates if the instruction belongs to instruction type T. Typically, T
* can be BinaryInstruction, UnaryInstruction, LoadInstruction and so on
*/
diff --git a/backend/src/ir/lowering.cpp b/backend/src/ir/lowering.cpp
index 49b6e06..638b15b 100644
--- a/backend/src/ir/lowering.cpp
+++ b/backend/src/ir/lowering.cpp
@@ -225,6 +225,8 @@ namespace ir {
for (const auto &loadAddImm : seq) {
LoadInstruction *load = cast<LoadInstruction>(loadAddImm.load);
const uint32_t valueNum = load->getValueNum();
+ bool replaced = false;
+ Instruction *ins_after = load; // the instruction to insert after.
for (uint32_t valueID = 0; valueID < valueNum; ++valueID) {
const Type type = load->getValueType();
const RegisterFamily family = getFamily(type);
@@ -249,12 +251,16 @@ namespace ir {
// register is never written. We must however support the register
// replacement in the instruction interface to be able to patch all the
// instruction that uses "reg"
- const Instruction mov = ir::MOV(type, reg, pushed);
- mov.replace(load);
- dead.insert(load);
+ Instruction mov = ir::MOV(type, reg, pushed);
+ mov.insert(ins_after, &ins_after);
+ replaced = true;
}
+
+ if (replaced)
+ dead.insert(load);
}
+ REMOVE_INSN(load)
REMOVE_INSN(add)
REMOVE_INSN(loadImm)
}
--
1.7.9.5
More information about the Beignet
mailing list