aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
index e6d02a5..5b6a91d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
@@ -25,6 +25,7 @@
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblySubtarget.h"
#include "WebAssemblyUtilities.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
@@ -465,6 +466,27 @@ static void ShrinkToUses(LiveInterval &LI, LiveIntervals &LIS) {
}
}
+static void MoveDebugValues(unsigned Reg, MachineInstr *Insert,
+ MachineBasicBlock &MBB, MachineRegisterInfo &MRI) {
+ for (auto &Op : MRI.reg_operands(Reg)) {
+ MachineInstr *MI = Op.getParent();
+ assert(MI != nullptr);
+ if (MI->isDebugValue() && MI->getParent() == &MBB)
+ MBB.splice(Insert, &MBB, MI);
+ }
+}
+
+static void UpdateDebugValuesReg(unsigned Reg, unsigned NewReg,
+ MachineBasicBlock &MBB,
+ MachineRegisterInfo &MRI) {
+ for (auto &Op : MRI.reg_operands(Reg)) {
+ MachineInstr *MI = Op.getParent();
+ assert(MI != nullptr);
+ if (MI->isDebugValue() && MI->getParent() == &MBB)
+ Op.setReg(NewReg);
+ }
+}
+
/// A single-use def in the same block with no intervening memory or register
/// dependencies; move the def down and nest it with the current instruction.
static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
@@ -475,6 +497,7 @@ static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
MBB.splice(Insert, &MBB, Def);
+ MoveDebugValues(Reg, Insert, MBB, MRI);
LIS.handleMove(*Def);
if (MRI.hasOneDef(Reg) && MRI.hasOneUse(Reg)) {
@@ -499,6 +522,8 @@ static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
MFI.stackifyVReg(NewReg);
+ UpdateDebugValuesReg(Reg, NewReg, MBB, MRI);
+
LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
}
@@ -506,6 +531,29 @@ static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
return Def;
}
+static void CloneDebugValues(unsigned Reg, MachineInstr *Insert,
+ unsigned TargetReg, MachineBasicBlock &MBB,
+ MachineRegisterInfo &MRI,
+ const WebAssemblyInstrInfo *TII) {
+ SmallPtrSet<MachineInstr *, 4> Instrs;
+ for (auto &Op : MRI.reg_operands(Reg)) {
+ MachineInstr *MI = Op.getParent();
+ assert(MI != nullptr);
+ if (MI->isDebugValue() && MI->getParent() == &MBB &&
+ Instrs.find(MI) == Instrs.end())
+ Instrs.insert(MI);
+ }
+ for (const auto &MI : Instrs) {
+ MachineInstr &Clone = TII->duplicate(MBB, Insert, *MI);
+ for (unsigned i = 0, e = Clone.getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = Clone.getOperand(i);
+ if (MO.isReg() && MO.getReg() == Reg)
+ MO.setReg(TargetReg);
+ }
+ LLVM_DEBUG(dbgs() << " - - Cloned DBG_VALUE: "; Clone.dump());
+ }
+}
+
/// A trivially cloneable instruction; clone it and nest the new copy with the
/// current instruction.
static MachineInstr *RematerializeCheapDef(
@@ -536,6 +584,7 @@ static MachineInstr *RematerializeCheapDef(
}
// If that was the last use of the original, delete the original.
+ // Move or clone corresponding DBG_VALUEs to the 'Insert' location.
if (IsDead) {
LLVM_DEBUG(dbgs() << " - Deleting original\n");
SlotIndex Idx = LIS.getInstructionIndex(Def).getRegSlot();
@@ -543,6 +592,11 @@ static MachineInstr *RematerializeCheapDef(
LIS.removeInterval(Reg);
LIS.RemoveMachineInstrFromMaps(Def);
Def.eraseFromParent();
+
+ MoveDebugValues(Reg, &*Insert, MBB, MRI);
+ UpdateDebugValuesReg(Reg, NewReg, MBB, MRI);
+ } else {
+ CloneDebugValues(Reg, &*Insert, NewReg, MBB, MRI, TII);
}
return Clone;
@@ -592,6 +646,8 @@ static MachineInstr *MoveAndTeeForMultiUse(
SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot();
SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot();
+ MoveDebugValues(Reg, Insert, MBB, MRI);
+
// Tell LiveIntervals we moved the original vreg def from Def to Tee.
LiveInterval &LI = LIS.getInterval(Reg);
LiveInterval::iterator I = LI.FindSegmentContaining(DefIdx);
@@ -608,6 +664,9 @@ static MachineInstr *MoveAndTeeForMultiUse(
ImposeStackOrdering(Def);
ImposeStackOrdering(Tee);
+ CloneDebugValues(Reg, Tee, DefReg, MBB, MRI, TII);
+ CloneDebugValues(Reg, Insert, TeeReg, MBB, MRI, TII);
+
LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump());
return Def;