diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp --- a/llvm/lib/CodeGen/MachineLICM.cpp +++ b/llvm/lib/CodeGen/MachineLICM.cpp @@ -216,7 +216,7 @@ bool IsLICMCandidate(MachineInstr &I); - bool IsLoopInvariantInst(MachineInstr &I); + bool IsLoopInvariantInst(MachineInstr &I, bool &IsSafeToMove); bool HasLoopPHIUse(const MachineInstr *MI) const; @@ -798,11 +798,13 @@ return; SmallVector Candidates; + bool IsSafeToMove = false; for (MachineBasicBlock::instr_iterator I = Preheader->instr_begin(); I != Preheader->instr_end(); ++I) { // We need to ensure that we can safely move this instruction into the loop. // As such, it must not have side-effects, e.g. such as a call has. - if (IsLoopInvariantInst(*I) && !HasLoopPHIUse(&*I)) + if (IsLoopInvariantInst(*I, IsSafeToMove) && IsSafeToMove && + !HasLoopPHIUse(&*I)) Candidates.push_back(&*I); } @@ -1047,10 +1049,16 @@ } /// Returns true if the instruction is loop invariant. -/// I.e., all virtual register operands are defined outside of the loop, -/// physical registers aren't accessed explicitly, and there are no side -/// effects that aren't captured by the operands or other flags. -bool MachineLICMBase::IsLoopInvariantInst(MachineInstr &I) { +/// I.e., all virtual register operands are either defined outside of the loop +/// or rematerializable instructions, physical registers aren't accessed +/// explicitly, and there are no side effects that aren't captured by the +/// operands or other flags. +/// If the instruction is loop invariant, we can indicate that the instruction +/// is safe to be moved by setting IsSafeToMove. For example, if a instruction +/// has an operand defined in same block, it is not safe to move this invariant +/// instruction. +bool MachineLICMBase::IsLoopInvariantInst(MachineInstr &I, bool &IsSafeToMove) { + IsSafeToMove = true; if (!IsLICMCandidate(I)) return false; @@ -1088,13 +1096,17 @@ if (!MO.isUse()) continue; - assert(MRI->getVRegDef(Reg) && - "Machine instr not mapped for this vreg?!"); + MachineInstr* Def = MRI->getVRegDef(Reg); + assert(Def && "Machine instr not mapped for this vreg?!"); - // If the loop contains the definition of an operand, then the instruction - // isn't loop invariant. - if (CurLoop->contains(MRI->getVRegDef(Reg))) - return false; + if (CurLoop->contains(Def)) { + // Can not hoist I to other block since it has operand in current block. + IsSafeToMove = false; + // It this operand is not a rematerializable instruction, I is a loop + // variant variable. + if (!TII->isTriviallyReMaterializable(*Def, AA)) + return false; + } } // If we got this far, the instruction is loop invariant! @@ -1371,7 +1383,9 @@ MBB->insert(Pos, NewMIs[1]); // If unfolding produced a load that wasn't loop-invariant or profitable to // hoist, discard the new instructions and bail. - if (!IsLoopInvariantInst(*NewMIs[0]) || !IsProfitableToHoist(*NewMIs[0])) { + bool IsSafeToMove = false; + if (!IsLoopInvariantInst(*NewMIs[0], IsSafeToMove) || !IsSafeToMove || + !IsProfitableToHoist(*NewMIs[0])) { NewMIs[0]->eraseFromParent(); NewMIs[1]->eraseFromParent(); return nullptr; @@ -1497,8 +1511,10 @@ ++NumNotHoistedDueToHotness; return false; } + bool IsSafeToMove = false; // First check whether we should hoist this instruction. - if (!IsLoopInvariantInst(*MI) || !IsProfitableToHoist(*MI)) { + if (!IsLoopInvariantInst(*MI, IsSafeToMove) || !IsSafeToMove || + !IsProfitableToHoist(*MI)) { // If not, try unfolding a hoistable load. MI = ExtractHoistableLoad(MI); if (!MI) return false;