Last active
January 20, 2019 05:13
-
-
Save yurydelendik/3242da58878ceb96ba778cf3f26d7c9a to your computer and use it in GitHub Desktop.
Attept to extend DBG_VALUE functionality
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: include/llvm/BinaryFormat/Dwarf.def | |
=================================================================== | |
diff --git a/llvm/trunk/include/llvm/BinaryFormat/Dwarf.def b/llvm/trunk/include/llvm/BinaryFormat/Dwarf.def | |
--- a/llvm/trunk/include/llvm/BinaryFormat/Dwarf.def (revision 336356) | |
+++ b/llvm/trunk/include/llvm/BinaryFormat/Dwarf.def (working copy) | |
@@ -617,6 +617,8 @@ | |
// Vendor extensions: | |
// Extensions for GNU-style thread-local storage. | |
HANDLE_DW_OP(0xe0, GNU_push_tls_address, 0, GNU) | |
+// Extensions for WebAssembly. | |
+HANDLE_DW_OP(0xF6, WASM_location, 0, WASM) | |
// Extensions for Fission proposal. | |
HANDLE_DW_OP(0xfb, GNU_addr_index, 0, GNU) | |
HANDLE_DW_OP(0xfc, GNU_const_index, 0, GNU) | |
Index: include/llvm/BinaryFormat/Dwarf.h | |
=================================================================== | |
diff --git a/llvm/trunk/include/llvm/BinaryFormat/Dwarf.h b/llvm/trunk/include/llvm/BinaryFormat/Dwarf.h | |
--- a/llvm/trunk/include/llvm/BinaryFormat/Dwarf.h (revision 336356) | |
+++ b/llvm/trunk/include/llvm/BinaryFormat/Dwarf.h (working copy) | |
@@ -58,7 +58,8 @@ | |
DWARF_VENDOR_GNU = 3, | |
DWARF_VENDOR_GOOGLE = 4, | |
DWARF_VENDOR_LLVM = 5, | |
- DWARF_VENDOR_MIPS = 6 | |
+ DWARF_VENDOR_MIPS = 6, | |
+ DWARF_VENDOR_WASM = 7 | |
}; | |
/// Constants that define the DWARF format as 32 or 64 bit. | |
Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp | |
=================================================================== | |
diff --git a/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | |
--- a/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (revision 336356) | |
+++ b/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (working copy) | |
@@ -880,6 +880,10 @@ | |
OS << MI->getOperand(0).getImm(); | |
} else if (MI->getOperand(0).isCImm()) { | |
MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/); | |
+ } else if (MI->getOperand(0).isTargetIndex()) { | |
+ auto Op = MI->getOperand(0); | |
+ OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")"; | |
+ return true; | |
} else { | |
unsigned Reg; | |
if (MI->getOperand(0).isReg()) { | |
Index: lib/CodeGen/AsmPrinter/DebugLocEntry.h | |
=================================================================== | |
diff --git a/llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h | |
--- a/llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h (revision 336356) | |
+++ b/llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h (working copy) | |
@@ -21,6 +21,19 @@ | |
namespace llvm { | |
class AsmPrinter; | |
+struct TargetIndexLocation { | |
+ int Index; | |
+ int Offset; | |
+ | |
+ TargetIndexLocation() = default; | |
+ TargetIndexLocation(unsigned Idx, int64_t Offset) | |
+ : Index(Idx), Offset(Offset) {} | |
+ | |
+ bool operator==(const TargetIndexLocation &Other) const { | |
+ return Index == Other.Index && Offset == Other.Offset; | |
+ } | |
+}; | |
+ | |
/// This struct describes location entries emitted in the .debug_loc | |
/// section. | |
class DebugLocEntry { | |
@@ -47,12 +60,20 @@ | |
: Expression(Expr), EntryKind(E_Location), Loc(Loc) { | |
assert(cast<DIExpression>(Expr)->isValid()); | |
} | |
+ Value(const DIExpression *Expr, TargetIndexLocation Loc) | |
+ : Expression(Expr), EntryKind(E_TargetIndexLocation), TIL(Loc) {} | |
/// Any complex address location expression for this Value. | |
const DIExpression *Expression; | |
/// Type of entry that this represents. | |
- enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt }; | |
+ enum EntryType { | |
+ E_Location, | |
+ E_Integer, | |
+ E_ConstantFP, | |
+ E_ConstantInt, | |
+ E_TargetIndexLocation | |
+ }; | |
enum EntryType EntryKind; | |
/// Either a constant, | |
@@ -60,12 +81,20 @@ | |
int64_t Int; | |
const ConstantFP *CFP; | |
const ConstantInt *CIP; | |
+ TargetIndexLocation TIL; | |
} Constant; | |
- // Or a location in the machine frame. | |
- MachineLocation Loc; | |
+ union { | |
+ // Or a location in the machine frame. | |
+ MachineLocation Loc; | |
+ // Or a location from target specific location. | |
+ TargetIndexLocation TIL; | |
+ }; | |
bool isLocation() const { return EntryKind == E_Location; } | |
+ bool isTargetIndexLocation() const { | |
+ return EntryKind == E_TargetIndexLocation; | |
+ } | |
bool isInt() const { return EntryKind == E_Integer; } | |
bool isConstantFP() const { return EntryKind == E_ConstantFP; } | |
bool isConstantInt() const { return EntryKind == E_ConstantInt; } | |
@@ -73,6 +102,7 @@ | |
const ConstantFP *getConstantFP() const { return Constant.CFP; } | |
const ConstantInt *getConstantInt() const { return Constant.CIP; } | |
MachineLocation getLoc() const { return Loc; } | |
+ TargetIndexLocation getTargetIndexLocation() const { return TIL; } | |
bool isFragment() const { return getExpression()->isFragment(); } | |
const DIExpression *getExpression() const { return Expression; } | |
friend bool operator==(const Value &, const Value &); | |
@@ -165,6 +195,8 @@ | |
switch (A.EntryKind) { | |
case DebugLocEntry::Value::E_Location: | |
return A.Loc == B.Loc; | |
+ case DebugLocEntry::Value::E_TargetIndexLocation: | |
+ return A.TIL == B.TIL; | |
case DebugLocEntry::Value::E_Integer: | |
return A.Constant.Int == B.Constant.Int; | |
case DebugLocEntry::Value::E_ConstantFP: | |
Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp | |
=================================================================== | |
diff --git a/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | |
--- a/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (revision 336356) | |
+++ b/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (working copy) | |
@@ -945,6 +945,11 @@ | |
MachineLocation MLoc(RegOp.getReg(), Op1.isImm()); | |
return DebugLocEntry::Value(Expr, MLoc); | |
} | |
+ if (MI->getOperand(0).isTargetIndex()) { | |
+ auto Op = MI->getOperand(0); | |
+ return DebugLocEntry::Value( | |
+ Expr, TargetIndexLocation(Op.getIndex(), Op.getOffset())); | |
+ } | |
if (MI->getOperand(0).isImm()) | |
return DebugLocEntry::Value(Expr, MI->getOperand(0).getImm()); | |
if (MI->getOperand(0).isFPImm()) | |
@@ -1717,6 +1722,9 @@ | |
} else if (Value.isConstantFP()) { | |
APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt(); | |
DwarfExpr.addUnsignedConstant(RawBytes); | |
+ } else if (Value.isTargetIndexLocation()) { | |
+ TargetIndexLocation Loc = Value.getTargetIndexLocation(); | |
+ DwarfExpr.addTargetIndexLocation(Loc.Index, Loc.Offset); | |
} | |
DwarfExpr.addExpression(std::move(ExprCursor)); | |
} | |
Index: lib/CodeGen/AsmPrinter/DwarfExpression.cpp | |
=================================================================== | |
diff --git a/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | |
--- a/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp (revision 336356) | |
+++ b/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp (working copy) | |
@@ -425,3 +425,11 @@ | |
addOpPiece(FragmentOffset - OffsetInBits); | |
OffsetInBits = FragmentOffset; | |
} | |
+ | |
+void DwarfExpression::addTargetIndexLocation(unsigned Index, int64_t Offset) { | |
+ assert(LocationKind == Implicit || LocationKind == Unknown); | |
+ LocationKind = Implicit; | |
+ emitOp(dwarf::DW_OP_WASM_location); | |
+ emitUnsigned(Index); | |
+ emitSigned(Offset); | |
+} | |
Index: lib/CodeGen/AsmPrinter/DwarfExpression.h | |
=================================================================== | |
diff --git a/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h | |
--- a/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h (revision 336356) | |
+++ b/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h (working copy) | |
@@ -245,6 +245,10 @@ | |
/// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to | |
/// the fragment described by \c Expr. | |
void addFragmentOffset(const DIExpression *Expr); | |
+ | |
+ /// Emit location information expressed via target's index + offset | |
+ /// It is an extension for WebAssembly locals, globals and operand stack. | |
+ void addTargetIndexLocation(unsigned Index, int64_t Offset); | |
}; | |
/// DwarfExpression implementation for .debug_loc entries. | |
Index: lib/CodeGen/LiveInterval.cpp | |
=================================================================== | |
diff --git a/llvm/trunk/lib/CodeGen/LiveInterval.cpp b/llvm/trunk/lib/CodeGen/LiveInterval.cpp | |
--- a/llvm/trunk/lib/CodeGen/LiveInterval.cpp (revision 336356) | |
+++ b/llvm/trunk/lib/CodeGen/LiveInterval.cpp (working copy) | |
@@ -1311,16 +1311,20 @@ | |
MachineInstr *MI = RI->getParent(); | |
++RI; | |
// DBG_VALUE instructions don't have slot indexes, so get the index of the | |
- // instruction before them. | |
+ // instruction before them. The value is defined there too. | |
// Normally, DBG_VALUE instructions are removed before this function is | |
// called, but it is not a requirement. | |
SlotIndex Idx; | |
- if (MI->isDebugValue()) | |
+ bool ValueIn; // TODO(yd) land in D48994 | |
+ if (MI->isDebugValue()) { | |
Idx = LIS.getSlotIndexes()->getIndexBefore(*MI); | |
- else | |
+ ValueIn = false; | |
+ } else { | |
Idx = LIS.getInstructionIndex(*MI); | |
+ ValueIn = MO.readsReg(); | |
+ } | |
LiveQueryResult LRQ = LI.Query(Idx); | |
- const VNInfo *VNI = MO.readsReg() ? LRQ.valueIn() : LRQ.valueDefined(); | |
+ const VNInfo *VNI = ValueIn ? LRQ.valueIn() : LRQ.valueDefined(); | |
// In the case of an <undef> use that isn't tied to any def, VNI will be | |
// NULL. If the use is tied to a def, VNI will be the defined value. | |
if (!VNI) | |
Index: lib/DebugInfo/DWARF/DWARFExpression.cpp | |
=================================================================== | |
diff --git a/llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp | |
--- a/llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp (revision 336356) | |
+++ b/llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp (working copy) | |
@@ -93,6 +93,8 @@ | |
Descriptions[DW_OP_implicit_value] = | |
Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock); | |
Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3); | |
+ Descriptions[DW_OP_WASM_location] = | |
+ Desc(Op::Dwarf4, Op::SizeLEB, Op::SignedSizeLEB); | |
Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3); | |
Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB); | |
Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB); | |
Index: lib/Target/WebAssembly/WebAssembly.h | |
=================================================================== | |
diff --git a/llvm/trunk/lib/Target/WebAssembly/WebAssembly.h b/llvm/trunk/lib/Target/WebAssembly/WebAssembly.h | |
--- a/llvm/trunk/lib/Target/WebAssembly/WebAssembly.h (revision 336356) | |
+++ b/llvm/trunk/lib/Target/WebAssembly/WebAssembly.h (working copy) | |
@@ -78,6 +78,10 @@ | |
void initializeWebAssemblyPeepholePass(PassRegistry &); | |
void initializeWebAssemblyCallIndirectFixupPass(PassRegistry &); | |
+namespace WebAssembly { | |
+enum TargetIndex { TI_LOCAL_START, TI_GLOBAL_START, TI_OPERAND_STACK_START }; | |
+} // end namespace WebAssembly | |
+ | |
} // end namespace llvm | |
#endif | |
Index: lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp | |
=================================================================== | |
diff --git a/llvm/trunk/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/trunk/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp | |
--- a/llvm/trunk/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp (revision 336356) | |
+++ b/llvm/trunk/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp (working copy) | |
@@ -160,6 +160,45 @@ | |
llvm_unreachable("unrecognized register class"); | |
} | |
+static void fixupFollowingDebugValues(DenseMap<unsigned, unsigned> &Reg2Local, | |
+ MachineRegisterInfo &MRI, | |
+ MachineBasicBlock::iterator B, | |
+ MachineBasicBlock::iterator E) { | |
+ // Scan DBG_VALUE and modify virtual registers with known locals. | |
+ // Stop at first non-DBG_VALUE instruction. | |
+ for (auto I = B; I != E && I->isDebugInstr();) { | |
+ MachineInstr &MI = *I++; | |
+ for (MachineOperand &MO : reverse(MI.uses())) { | |
+ if (!MO.isReg()) | |
+ continue; | |
+ | |
+ unsigned OldReg = MO.getReg(); | |
+ auto I = Reg2Local.find(OldReg); | |
+ if (I == Reg2Local.end()) | |
+ continue; | |
+ | |
+ unsigned LocalId = I->second; | |
+ MO.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL_START, LocalId); | |
+ } | |
+ } | |
+} | |
+ | |
+static void fixupFollowingDebugValues(unsigned Reg, unsigned LocalId, | |
+ MachineRegisterInfo &MRI, | |
+ MachineBasicBlock::iterator B, | |
+ MachineBasicBlock::iterator E) { | |
+ // Scan DBG_VALUE and modify the specified virtual registers with the local. | |
+ // Stop at first non-DBG_VALUE instruction. | |
+ for (auto I = B; I != E && I->isDebugInstr();) { | |
+ MachineInstr &MI = *I++; | |
+ for (MachineOperand &MO : reverse(MI.uses())) { | |
+ if (!MO.isReg() || MO.getReg() != Reg) | |
+ continue; | |
+ MO.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL_START, LocalId); | |
+ } | |
+ } | |
+} | |
+ | |
/// Given a MachineOperand of a stackified vreg, return the instruction at the | |
/// start of the expression tree. | |
static MachineInstr *FindStartOfTree(MachineOperand &MO, | |
@@ -263,6 +302,11 @@ | |
.addImm(LocalId) | |
.addReg(MI.getOperand(2).getReg()); | |
+ auto Next = std::next(MachineBasicBlock::iterator(&MI)); | |
+ fixupFollowingDebugValues(Reg2Local, MRI, Next, MBB.end()); | |
+ fixupFollowingDebugValues(MI.getOperand(0).getReg(), LocalId, MRI, Next, | |
+ MBB.end()); | |
+ | |
MI.eraseFromParent(); | |
Changed = true; | |
continue; | |
@@ -295,6 +339,8 @@ | |
BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc)) | |
.addImm(LocalId) | |
.addReg(NewReg); | |
+ fixupFollowingDebugValues(NewReg, LocalId, MRI, InsertPt, | |
+ MBB.end()); | |
} | |
MI.getOperand(0).setReg(NewReg); | |
// This register operand is now being used by the inserted drop | |
@@ -301,6 +347,9 @@ | |
// instruction, so make it undead. | |
MI.getOperand(0).setIsDead(false); | |
MFI.stackifyVReg(NewReg); | |
+ | |
+ fixupFollowingDebugValues(Reg2Local, MRI, InsertPt, MBB.end()); | |
+ | |
Changed = true; | |
} | |
} | |
@@ -350,6 +399,8 @@ | |
.addImm(LocalId); | |
MO.setReg(NewReg); | |
MFI.stackifyVReg(NewReg); | |
+ | |
+ fixupFollowingDebugValues(OldReg, LocalId, MRI, InsertPt, MBB.end()); | |
Changed = true; | |
} | |
Index: lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp | |
=================================================================== | |
diff --git a/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp | |
--- a/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp (revision 336356) | |
+++ b/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp (working copy) | |
@@ -201,3 +201,12 @@ | |
Cond.front() = MachineOperand::CreateImm(!Cond.front().getImm()); | |
return false; | |
} | |
+ | |
+ArrayRef<std::pair<int, const char *>> | |
+WebAssemblyInstrInfo::getSerializableTargetIndices() const { | |
+ static const std::pair<int, const char *> TargetIndices[] = { | |
+ {WebAssembly::TI_LOCAL_START, "wasm-local-start"}, | |
+ {WebAssembly::TI_GLOBAL_START, "wasm-global-start"}, | |
+ {WebAssembly::TI_OPERAND_STACK_START, "wasm-operator-stack-start"}}; | |
+ return makeArrayRef(TargetIndices); | |
+} | |
Index: lib/Target/WebAssembly/WebAssemblyInstrInfo.h | |
=================================================================== | |
diff --git a/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.h b/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.h | |
--- a/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.h (revision 336356) | |
+++ b/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.h (working copy) | |
@@ -16,7 +16,9 @@ | |
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYINSTRINFO_H | |
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYINSTRINFO_H | |
+#include "WebAssembly.h" | |
#include "WebAssemblyRegisterInfo.h" | |
+#include "llvm/ADT/ArrayRef.h" | |
#include "llvm/CodeGen/TargetInstrInfo.h" | |
#define GET_INSTRINFO_HEADER | |
@@ -56,6 +58,9 @@ | |
int *BytesAdded = nullptr) const override; | |
bool | |
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; | |
+ | |
+ ArrayRef<std::pair<int, const char *>> | |
+ getSerializableTargetIndices() const override; | |
}; | |
} // end namespace llvm | |
Index: lib/Target/WebAssembly/WebAssemblyRegStackify.cpp | |
=================================================================== | |
diff --git a/llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp b/llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp | |
--- a/llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp (revision 336356) | |
+++ b/llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp (working copy) | |
@@ -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" | |
@@ -464,6 +465,32 @@ | |
} | |
} | |
+static void MoveDebugValues(unsigned Reg, MachineInstr *Insert, | |
+ MachineBasicBlock &MBB, MachineRegisterInfo &MRI) { | |
+ for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Reg), | |
+ RE = MRI.reg_end(); | |
+ RI != RE; ++RI) { | |
+ MachineInstr *MI = RI->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 (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Reg), | |
+ RE = MRI.reg_end(); | |
+ RI != RE; ++RI) { | |
+ MachineOperand &MO = *RI; | |
+ MachineInstr *MI = RI->getParent(); | |
+ assert(MI != nullptr); | |
+ if (MI->isDebugValue() && MI->getParent() == &MBB) | |
+ MO.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 +502,7 @@ | |
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 +527,8 @@ | |
MFI.stackifyVReg(NewReg); | |
+ UpdateDebugValuesReg(Reg, NewReg, MBB, MRI); | |
+ | |
LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump()); | |
} | |
@@ -506,6 +536,31 @@ | |
return Def; | |
} | |
+static void CloneDebugValues(unsigned Reg, MachineInstr *Insert, | |
+ unsigned TargetReg, MachineBasicBlock &MBB, | |
+ MachineRegisterInfo &MRI, | |
+ const WebAssemblyInstrInfo *TII) { | |
+ SmallPtrSet<MachineInstr *, 4> Instrs; | |
+ for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Reg), | |
+ RE = MRI.reg_end(); | |
+ RI != RE; ++RI) { | |
+ MachineInstr *MI = RI->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 +591,7 @@ | |
} | |
// 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 +599,11 @@ | |
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 +653,8 @@ | |
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 +671,9 @@ | |
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; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Moved to https://reviews.llvm.org/D52634