Fix the bug of multi deleting of load instruction in lowering
authorJunyan He <junyan.he@linux.intel.com>
Mon, 20 Jan 2014 03:28:43 +0000 (11:28 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Mon, 20 Jan 2014 07:07:03 +0000 (15:07 +0800)
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.

Signed-off-by: Junyan He <junyan.he@linux.intel.com>
Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
backend/src/ir/instruction.cpp
backend/src/ir/instruction.hpp
backend/src/ir/lowering.cpp

index 5e3cd84..a3e096f 100644 (file)
@@ -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 ||
index c827b9a..696d1d9 100644 (file)
@@ -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
      */
index 49b6e06..ad1ea32 100644 (file)
@@ -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)
   }