+/// Hoist - When an instruction is found to use only loop invariant operands
+/// that are safe to hoist, this instruction is called to do the dirty work.
+///
+void MachineLICM::Hoist(MachineInstr &MI) {
+ if (!IsLoopInvariantInst(MI)) return;
+ if (!IsProfitableToHoist(MI)) return;
+
+ // Now move the instructions to the predecessor, inserting it before any
+ // terminator instructions.
+ DEBUG({
+ DOUT << "Hoisting " << MI;
+ if (CurPreheader->getBasicBlock())
+ DOUT << " to MachineBasicBlock "
+ << CurPreheader->getBasicBlock()->getName();
+ if (MI.getParent()->getBasicBlock())
+ DOUT << " from MachineBasicBlock "
+ << MI.getParent()->getBasicBlock()->getName();
+ DOUT << "\n";
+ });
+
+ // Look for opportunity to CSE the hoisted instruction.
+ std::pair<unsigned, unsigned> BBOpcPair =
+ std::make_pair(CurPreheader->getNumber(), MI.getOpcode());
+ DenseMap<std::pair<unsigned, unsigned>,
+ std::vector<const MachineInstr*> >::iterator CI = CSEMap.find(BBOpcPair);
+ bool DoneCSE = false;
+ if (CI != CSEMap.end()) {
+ const MachineInstr *Dup = LookForDuplicate(&MI, CI->second, RegInfo);
+ if (Dup) {
+ DOUT << "CSEing " << MI;
+ DOUT << " with " << *Dup;
+ for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI.getOperand(i);
+ if (MO.isReg() && MO.isDef())
+ RegInfo->replaceRegWith(MO.getReg(), Dup->getOperand(i).getReg());
+ }
+ MI.eraseFromParent();
+ DoneCSE = true;
+ ++NumCSEed;
+ }
+ }