aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/X86OptimizeLEAs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/X86OptimizeLEAs.cpp')
-rw-r--r--llvm/lib/Target/X86/X86OptimizeLEAs.cpp49
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;
}