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 ||
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
*/
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);
// 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)
}