diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h --- a/llvm/lib/Target/WebAssembly/WebAssembly.h +++ b/llvm/lib/Target/WebAssembly/WebAssembly.h @@ -83,6 +83,8 @@ TI_LOCAL, // Followed by an absolute global index (ULEB). DEPRECATED. TI_GLOBAL_FIXED, + // Followed by an index relative to the bottom of the stack + // (for this function). TI_OPERAND_STACK, // Followed by a compilation unit relative global index (uint32_t) // that will have an associated relocation. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp @@ -22,6 +22,7 @@ //===----------------------------------------------------------------------===// #include "WebAssembly.h" +#include "WebAssemblyDebugValueManager.h" #include "WebAssemblyExceptionInfo.h" #include "WebAssemblyMachineFunctionInfo.h" #include "WebAssemblySubtarget.h" @@ -716,8 +717,10 @@ if (!MO.isReg() || Register::isPhysicalRegister(MO.getReg())) continue; if (MachineInstr *Def = MRI.getUniqueVRegDef(MO.getReg())) - if (Def->getParent() == &MBB) + if (Def->getParent() == &MBB) { MFI.unstackifyVReg(MO.getReg()); + WebAssemblyDebugValueManager(Def).replaceWithRegister(MO); + } } } } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h --- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h @@ -16,6 +16,7 @@ #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYDEBUGVALUEMANAGER_H #include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/MachineOperand.h" namespace llvm { @@ -31,6 +32,8 @@ void updateReg(unsigned Reg); void clone(MachineInstr *Insert, unsigned NewReg); void replaceWithLocal(unsigned LocalId); + void replaceWithStackOffset(unsigned StackOffset); + void replaceWithRegister(MachineOperand &MO); }; } // end namespace llvm diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp @@ -14,7 +14,6 @@ #include "WebAssemblyDebugValueManager.h" #include "WebAssembly.h" #include "WebAssemblyMachineFunctionInfo.h" -#include "llvm/CodeGen/MachineInstr.h" using namespace llvm; @@ -51,3 +50,18 @@ Op.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL, LocalId); } } + +void WebAssemblyDebugValueManager::replaceWithStackOffset(unsigned StackOffset) { + for (auto *DBI : DbgValues) { + MachineOperand &Op = DBI->getOperand(0); + Op.ChangeToTargetIndex(llvm::WebAssembly::TI_OPERAND_STACK, StackOffset); + } +} + +void WebAssemblyDebugValueManager::replaceWithRegister(MachineOperand &MO) { + for (auto *DBI : DbgValues) { + MachineOperand &Op = DBI->getOperand(0); + Op.ChangeToRegister(MO.getReg(), MO.isDef(), MO.isImplicit(), MO.isKill(), + MO.isDead(), MO.isUndef(), MO.isDebug()); + } +} diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp @@ -519,7 +519,8 @@ MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, - MachineRegisterInfo &MRI) { + MachineRegisterInfo &MRI, + unsigned StackDepth) { LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump()); WebAssemblyDebugValueManager DefDIs(Def); @@ -554,6 +555,7 @@ LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump()); } + DefDIs.replaceWithStackOffset(StackDepth); imposeStackOrdering(Def); return Def; } @@ -564,7 +566,8 @@ unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, - const WebAssemblyInstrInfo *TII, const WebAssemblyRegisterInfo *TRI) { + const WebAssemblyInstrInfo *TII, const WebAssemblyRegisterInfo *TRI, + unsigned StackDepth) { LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump()); LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump()); @@ -604,6 +607,8 @@ } else { DefDIs.clone(&*Insert, NewReg); } + // DefDIs points to old def, so create a new one. + WebAssemblyDebugValueManager(&*Insert).replaceWithStackOffset(StackDepth); return Clone; } @@ -631,7 +636,8 @@ static MachineInstr *moveAndTeeForMultiUse( unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, - MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII) { + MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII, + unsigned StackDepth) { LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump()); WebAssemblyDebugValueManager DefDIs(Def); @@ -674,6 +680,8 @@ DefDIs.clone(Tee, DefReg); DefDIs.clone(Insert, TeeReg); + // DefDIs points to old def, so create a new one. + WebAssemblyDebugValueManager(&*Insert).replaceWithStackOffset(StackDepth); LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump()); LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump()); @@ -698,6 +706,8 @@ bool done() const { return Worklist.empty(); } + unsigned stackDepth() { return static_cast(Worklist.size()); } + MachineOperand &pop() { RangeTy &Range = Worklist.back(); MachineOperand &Op = *Range.begin(); @@ -896,7 +906,8 @@ isSafeToMove(Def, &Use, Insert, AA, MFI, MRI) && !TreeWalker.isOnStack(Reg); if (CanMove && hasOneUse(Reg, DefI, MRI, MDT, LIS)) { - Insert = moveForSingleUse(Reg, Use, DefI, MBB, Insert, LIS, MFI, MRI); + Insert = moveForSingleUse(Reg, Use, DefI, MBB, Insert, LIS, MFI, MRI, + TreeWalker.stackDepth()); // If we are removing the frame base reg completely, remove the debug // info as well. @@ -906,11 +917,12 @@ } else if (shouldRematerialize(*DefI, AA, TII)) { Insert = rematerializeCheapDef(Reg, Use, *DefI, MBB, Insert->getIterator(), - LIS, MFI, MRI, TII, TRI); + LIS, MFI, MRI, TII, TRI, + TreeWalker.stackDepth()); } else if (CanMove && oneUseDominatesOtherUses(Reg, Use, MBB, MRI, MDT, LIS, MFI)) { Insert = moveAndTeeForMultiUse(Reg, Use, DefI, MBB, Insert, LIS, MFI, - MRI, TII); + MRI, TII, TreeWalker.stackDepth()); } else { // We failed to stackify the operand. If the problem was ordering // constraints, Commuting may be able to help. @@ -935,6 +947,8 @@ if (DefReg != UseReg || !MRI.hasOneUse(DefReg)) break; MFI.stackifyVReg(DefReg); + WebAssemblyDebugValueManager(&*Insert).replaceWithStackOffset( + TreeWalker.stackDepth()); ++SubsequentDef; ++SubsequentUse; }