diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86OptimizeLEAs.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86OptimizeLEAs.cpp | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/llvm/lib/Target/X86/X86OptimizeLEAs.cpp b/llvm/lib/Target/X86/X86OptimizeLEAs.cpp index c8899a85118e..ab4d2bd05772 100644 --- a/llvm/lib/Target/X86/X86OptimizeLEAs.cpp +++ b/llvm/lib/Target/X86/X86OptimizeLEAs.cpp @@ -112,9 +112,9 @@ public: } // end anonymous namespace -/// Provide DenseMapInfo for MemOpKey. namespace llvm { +/// Provide DenseMapInfo for MemOpKey. template <> struct DenseMapInfo<MemOpKey> { using PtrInfo = DenseMapInfo<const MachineOperand *>; @@ -295,8 +295,8 @@ private: /// Replace debug value MI with a new debug value instruction using register /// VReg with an appropriate offset and DIExpression to incorporate the /// address displacement AddrDispShift. Return new debug value instruction. - MachineInstr *replaceDebugValue(MachineInstr &MI, unsigned VReg, - int64_t AddrDispShift); + MachineInstr *replaceDebugValue(MachineInstr &MI, unsigned OldReg, + unsigned NewReg, int64_t AddrDispShift); /// Removes LEAs which calculate similar addresses. bool removeRedundantLEAs(MemOpMap &LEAs); @@ -576,21 +576,50 @@ bool X86OptimizeLEAPass::removeRedundantAddrCalc(MemOpMap &LEAs) { } MachineInstr *X86OptimizeLEAPass::replaceDebugValue(MachineInstr &MI, - unsigned VReg, + unsigned OldReg, + unsigned NewReg, int64_t AddrDispShift) { const DIExpression *Expr = MI.getDebugExpression(); - if (AddrDispShift != 0) - Expr = DIExpression::prepend(Expr, DIExpression::StackValue, AddrDispShift); + if (AddrDispShift != 0) { + if (MI.isNonListDebugValue()) { + Expr = + DIExpression::prepend(Expr, DIExpression::StackValue, AddrDispShift); + } else { + // Update the Expression, appending an offset of `AddrDispShift` to the + // Op corresponding to `OldReg`. + SmallVector<uint64_t, 3> Ops; + DIExpression::appendOffset(Ops, AddrDispShift); + for (MachineOperand &Op : MI.getDebugOperandsForReg(OldReg)) { + unsigned OpIdx = MI.getDebugOperandIndex(&Op); + Expr = DIExpression::appendOpsToArg(Expr, Ops, OpIdx); + } + } + } // Replace DBG_VALUE instruction with modified version. MachineBasicBlock *MBB = MI.getParent(); DebugLoc DL = MI.getDebugLoc(); bool IsIndirect = MI.isIndirectDebugValue(); const MDNode *Var = MI.getDebugVariable(); + unsigned Opcode = MI.isNonListDebugValue() ? TargetOpcode::DBG_VALUE + : TargetOpcode::DBG_VALUE_LIST; if (IsIndirect) - assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset"); - return BuildMI(*MBB, MBB->erase(&MI), DL, TII->get(TargetOpcode::DBG_VALUE), - IsIndirect, VReg, Var, Expr); + assert(MI.getDebugOffset().getImm() == 0 && + "DBG_VALUE with nonzero offset"); + SmallVector<MachineOperand, 4> NewOps; + // If we encounter an operand using the old register, replace it with an + // operand that uses the new register; otherwise keep the old operand. + auto replaceOldReg = [OldReg, NewReg](const MachineOperand &Op) { + if (Op.isReg() && Op.getReg() == OldReg) + return MachineOperand::CreateReg(NewReg, false, false, false, false, + false, false, false, false, 0, + /*IsRenamable*/ true); + return Op; + }; + for (const MachineOperand &Op : MI.debug_operands()) + NewOps.push_back(replaceOldReg(Op)); + return BuildMI(*MBB, MBB->erase(&MI), DL, TII->get(Opcode), IsIndirect, + NewOps, Var, Expr); } // Try to find similar LEAs in the list and replace one with another. @@ -635,7 +664,7 @@ bool X86OptimizeLEAPass::removeRedundantLEAs(MemOpMap &LEAs) { // Replace DBG_VALUE instruction with modified version using the // register from the replacing LEA and the address displacement // between the LEA instructions. - replaceDebugValue(MI, FirstVReg, AddrDispShift); + replaceDebugValue(MI, LastVReg, FirstVReg, AddrDispShift); continue; } |