Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit b490116

Browse files
authored
Merge pull request #134 from yurydelendik/originalVars
[WIP] Encode WebAssembly specific locations in DBG_VALUEs and DW_AT_frame_base
2 parents 6923965 + 9c870ef commit b490116

19 files changed

+210
-10
lines changed

include/llvm/BinaryFormat/Dwarf.def

+2
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,8 @@ HANDLE_DW_OP(0xfb, GNU_addr_index, 0, GNU)
627627
HANDLE_DW_OP(0xfc, GNU_const_index, 0, GNU)
628628

629629
// DWARF languages.
630+
// Extensions for WebAssembly.
631+
HANDLE_DW_OP(0xed, WASM_location, 0, WASM)
630632
HANDLE_DW_LANG(0x0001, C89, 2, DWARF)
631633
HANDLE_DW_LANG(0x0002, C, 2, DWARF)
632634
HANDLE_DW_LANG(0x0003, Ada83, 2, DWARF)

include/llvm/BinaryFormat/Dwarf.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ enum LLVMConstants : uint32_t {
5858
DWARF_VENDOR_GNU = 3,
5959
DWARF_VENDOR_GOOGLE = 4,
6060
DWARF_VENDOR_LLVM = 5,
61-
DWARF_VENDOR_MIPS = 6
61+
DWARF_VENDOR_MIPS = 6,
62+
DWARF_VENDOR_WASM = 7
6263
};
6364

6465
/// Constants that define the DWARF format as 32 or 64 bit.

include/llvm/CodeGen/TargetRegisterInfo.h

+23
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,22 @@ struct RegClassWeight {
211211
unsigned WeightLimit;
212212
};
213213

214+
struct FrameBaseLocation {
215+
enum LocationKind {
216+
Register,
217+
CFA,
218+
TargetIndex
219+
} Kind;
220+
struct TargetIndexInfo {
221+
unsigned Index;
222+
signed Offset;
223+
};
224+
union {
225+
unsigned Reg;
226+
TargetIndexInfo TI;
227+
};
228+
};
229+
214230
/// TargetRegisterInfo base class - We assume that the target defines a static
215231
/// array of TargetRegisterDesc objects that represent all of the machine
216232
/// registers that the target has. As such, we simply have to track a pointer
@@ -988,6 +1004,13 @@ class TargetRegisterInfo : public MCRegisterInfo {
9881004
/// for values allocated in the current stack frame.
9891005
virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0;
9901006

1007+
virtual FrameBaseLocation getFrameBaseLocation(const MachineFunction &MF) const {
1008+
FrameBaseLocation Loc;
1009+
Loc.Kind = FrameBaseLocation::Register;
1010+
Loc.Reg = getFrameRegister(MF);
1011+
return Loc;
1012+
}
1013+
9911014
/// Mark a register and all its aliases as reserved in the given set.
9921015
void markSuperRegs(BitVector &RegisterSet, unsigned Reg) const;
9931016

lib/CodeGen/AsmPrinter/AsmPrinter.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,10 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
895895
OS << MI->getOperand(0).getImm();
896896
} else if (MI->getOperand(0).isCImm()) {
897897
MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
898+
} else if (MI->getOperand(0).isTargetIndex()) {
899+
auto Op = MI->getOperand(0);
900+
OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";
901+
return true;
898902
} else {
899903
unsigned Reg;
900904
if (MI->getOperand(0).isReg()) {

lib/CodeGen/AsmPrinter/DebugLocEntry.h

+34-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,19 @@
2121
namespace llvm {
2222
class AsmPrinter;
2323

24+
struct TargetIndexLocation {
25+
int Index;
26+
int Offset;
27+
28+
TargetIndexLocation() = default;
29+
TargetIndexLocation(unsigned Idx, int64_t Offset)
30+
: Index(Idx), Offset(Offset) {}
31+
32+
bool operator==(const TargetIndexLocation &Other) const {
33+
return Index == Other.Index && Offset == Other.Offset;
34+
}
35+
};
36+
2437
/// This struct describes location entries emitted in the .debug_loc
2538
/// section.
2639
class DebugLocEntry {
@@ -47,12 +60,20 @@ class DebugLocEntry {
4760
: Expression(Expr), EntryKind(E_Location), Loc(Loc) {
4861
assert(cast<DIExpression>(Expr)->isValid());
4962
}
63+
Value(const DIExpression *Expr, TargetIndexLocation Loc)
64+
: Expression(Expr), EntryKind(E_TargetIndexLocation), TIL(Loc) {}
5065

5166
/// Any complex address location expression for this Value.
5267
const DIExpression *Expression;
5368

5469
/// Type of entry that this represents.
55-
enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
70+
enum EntryType {
71+
E_Location,
72+
E_Integer,
73+
E_ConstantFP,
74+
E_ConstantInt,
75+
E_TargetIndexLocation
76+
};
5677
enum EntryType EntryKind;
5778

5879
/// Either a constant,
@@ -62,17 +83,25 @@ class DebugLocEntry {
6283
const ConstantInt *CIP;
6384
} Constant;
6485

65-
// Or a location in the machine frame.
66-
MachineLocation Loc;
86+
union {
87+
// Or a location in the machine frame.
88+
MachineLocation Loc;
89+
// Or a location from target specific location.
90+
TargetIndexLocation TIL;
91+
};
6792

6893
bool isLocation() const { return EntryKind == E_Location; }
94+
bool isTargetIndexLocation() const {
95+
return EntryKind == E_TargetIndexLocation;
96+
}
6997
bool isInt() const { return EntryKind == E_Integer; }
7098
bool isConstantFP() const { return EntryKind == E_ConstantFP; }
7199
bool isConstantInt() const { return EntryKind == E_ConstantInt; }
72100
int64_t getInt() const { return Constant.Int; }
73101
const ConstantFP *getConstantFP() const { return Constant.CFP; }
74102
const ConstantInt *getConstantInt() const { return Constant.CIP; }
75103
MachineLocation getLoc() const { return Loc; }
104+
TargetIndexLocation getTargetIndexLocation() const { return TIL; }
76105
bool isFragment() const { return getExpression()->isFragment(); }
77106
const DIExpression *getExpression() const { return Expression; }
78107
friend bool operator==(const Value &, const Value &);
@@ -165,6 +194,8 @@ inline bool operator==(const DebugLocEntry::Value &A,
165194
switch (A.EntryKind) {
166195
case DebugLocEntry::Value::E_Location:
167196
return A.Loc == B.Loc;
197+
case DebugLocEntry::Value::E_TargetIndexLocation:
198+
return A.TIL == B.TIL;
168199
case DebugLocEntry::Value::E_Integer:
169200
return A.Constant.Int == B.Constant.Int;
170201
case DebugLocEntry::Value::E_ConstantFP:

lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -340,13 +340,24 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
340340

341341
// Only include DW_AT_frame_base in full debug info
342342
if (!includeMinimalInlineScopes()) {
343-
if (Asm->MF->getTarget().getTargetTriple().isNVPTX()) {
343+
const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo();
344+
auto FBL = RI->getFrameBaseLocation(*Asm->MF);
345+
if (FBL.Kind == FrameBaseLocation::CFA) {
344346
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
345347
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
346348
addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
349+
} else if (FBL.Kind == FrameBaseLocation::TargetIndex) {
350+
if (FBL.TI.Offset >= 0) {
351+
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
352+
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
353+
DIExpressionCursor Cursor({});
354+
DwarfExpr.addTargetIndexLocation(FBL.TI.Index, FBL.TI.Offset);
355+
DwarfExpr.addExpression(std::move(Cursor));
356+
addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());
357+
}
347358
} else {
348-
const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo();
349-
MachineLocation Location(RI->getFrameRegister(*Asm->MF));
359+
assert(FBL.Kind == FrameBaseLocation::Register);
360+
MachineLocation Location(FBL.Reg);
350361
if (RI->isPhysicalRegister(Location.getReg()))
351362
addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
352363
}
@@ -1023,7 +1034,7 @@ void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
10231034

10241035
/// Add an address attribute to a die based on the location provided.
10251036
void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
1026-
const MachineLocation &Location) {
1037+
const MachineLocation &Location) {
10271038
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
10281039
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
10291040
if (Location.isIndirect())

lib/CodeGen/AsmPrinter/DwarfDebug.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,11 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
10601060
MachineLocation MLoc(RegOp.getReg(), Op1.isImm());
10611061
return DebugLocEntry::Value(Expr, MLoc);
10621062
}
1063+
if (MI->getOperand(0).isTargetIndex()) {
1064+
auto Op = MI->getOperand(0);
1065+
return DebugLocEntry::Value(
1066+
Expr, TargetIndexLocation(Op.getIndex(), Op.getOffset()));
1067+
}
10631068
if (MI->getOperand(0).isImm())
10641069
return DebugLocEntry::Value(Expr, MI->getOperand(0).getImm());
10651070
if (MI->getOperand(0).isFPImm())
@@ -1899,6 +1904,9 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
18991904
} else if (Value.isConstantFP()) {
19001905
APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt();
19011906
DwarfExpr.addUnsignedConstant(RawBytes);
1907+
} else if (Value.isTargetIndexLocation()) {
1908+
TargetIndexLocation Loc = Value.getTargetIndexLocation();
1909+
DwarfExpr.addTargetIndexLocation(Loc.Index, Loc.Offset);
19021910
}
19031911
DwarfExpr.addExpression(std::move(ExprCursor));
19041912
}

lib/CodeGen/AsmPrinter/DwarfExpression.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -437,3 +437,11 @@ void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {
437437
addOpPiece(FragmentOffset - OffsetInBits);
438438
OffsetInBits = FragmentOffset;
439439
}
440+
441+
void DwarfExpression::addTargetIndexLocation(unsigned Index, int64_t Offset) {
442+
assert(LocationKind == Implicit || LocationKind == Unknown);
443+
LocationKind = Implicit;
444+
emitOp(dwarf::DW_OP_WASM_location);
445+
emitUnsigned(Index);
446+
emitSigned(Offset);
447+
}

lib/CodeGen/AsmPrinter/DwarfExpression.h

+4
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,10 @@ class DwarfExpression {
248248
/// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
249249
/// the fragment described by \c Expr.
250250
void addFragmentOffset(const DIExpression *Expr);
251+
252+
/// Emit location information expressed via target's index + offset
253+
/// It is an extension for WebAssembly locals, globals and operand stack.
254+
void addTargetIndexLocation(unsigned Index, int64_t Offset);
251255
};
252256

253257
/// DwarfExpression implementation for .debug_loc entries.

lib/DebugInfo/DWARF/DWARFExpression.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ static DescVector getDescriptions() {
9393
Descriptions[DW_OP_implicit_value] =
9494
Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock);
9595
Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3);
96+
Descriptions[DW_OP_WASM_location] =
97+
Desc(Op::Dwarf4, Op::SizeLEB, Op::SignedSizeLEB);
9698
Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
9799
Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB);
98100
Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);

lib/Target/NVPTX/NVPTXRegisterInfo.h

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ class NVPTXRegisterInfo : public NVPTXGenRegisterInfo {
4545

4646
unsigned getFrameRegister(const MachineFunction &MF) const override;
4747

48+
FrameBaseLocation getFrameBaseLocation(const MachineFunction &MF) const override {
49+
FrameBaseLocation Loc;
50+
Loc.Kind = FrameBaseLocation::CFA;
51+
return Loc;
52+
}
53+
4854
ManagedStringPool *getStrPool() const {
4955
return const_cast<ManagedStringPool *>(&ManagedStrPool);
5056
}

lib/Target/WebAssembly/WebAssembly.h

+8
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ void initializeWebAssemblyRegNumberingPass(PassRegistry &);
8282
void initializeWebAssemblyPeepholePass(PassRegistry &);
8383
void initializeWebAssemblyCallIndirectFixupPass(PassRegistry &);
8484

85+
namespace WebAssembly {
86+
enum TargetIndex { TI_LOCAL_START, TI_GLOBAL_START, TI_OPERAND_STACK_START };
87+
} // end namespace WebAssembly
88+
89+
namespace WebAssembly {
90+
enum TargetIndex { TI_LOCAL_START, TI_GLOBAL_START, TI_OPERAND_STACK_START };
91+
} // end namespace WebAssembly
92+
8593
} // end namespace llvm
8694

8795
#endif

lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp

+58
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,45 @@ static MVT typeForRegClass(const TargetRegisterClass *RC) {
164164
llvm_unreachable("unrecognized register class");
165165
}
166166

167+
static void fixupFollowingDebugValues(DenseMap<unsigned, unsigned> &Reg2Local,
168+
MachineRegisterInfo &MRI,
169+
MachineBasicBlock::iterator B,
170+
MachineBasicBlock::iterator E) {
171+
// Scan DBG_VALUE and modify virtual registers with known locals.
172+
// Stop at first non-DBG_VALUE instruction.
173+
for (auto I = B; I != E && I->isDebugInstr();) {
174+
MachineInstr &MI = *I++;
175+
for (MachineOperand &MO : reverse(MI.uses())) {
176+
if (!MO.isReg())
177+
continue;
178+
179+
unsigned OldReg = MO.getReg();
180+
auto I = Reg2Local.find(OldReg);
181+
if (I == Reg2Local.end())
182+
continue;
183+
184+
unsigned LocalId = I->second;
185+
MO.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL_START, LocalId);
186+
}
187+
}
188+
}
189+
190+
static void fixupFollowingDebugValues(unsigned Reg, unsigned LocalId,
191+
MachineRegisterInfo &MRI,
192+
MachineBasicBlock::iterator B,
193+
MachineBasicBlock::iterator E) {
194+
// Scan DBG_VALUE and modify the specified virtual registers with the local.
195+
// Stop at first non-DBG_VALUE instruction.
196+
for (auto I = B; I != E && I->isDebugInstr();) {
197+
MachineInstr &MI = *I++;
198+
for (MachineOperand &MO : reverse(MI.uses())) {
199+
if (!MO.isReg() || MO.getReg() != Reg)
200+
continue;
201+
MO.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL_START, LocalId);
202+
}
203+
}
204+
}
205+
167206
/// Given a MachineOperand of a stackified vreg, return the instruction at the
168207
/// start of the expression tree.
169208
static MachineInstr *findStartOfTree(MachineOperand &MO,
@@ -262,6 +301,11 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
262301
.addImm(LocalId)
263302
.addReg(MI.getOperand(2).getReg());
264303

304+
auto Next = std::next(MachineBasicBlock::iterator(&MI));
305+
fixupFollowingDebugValues(Reg2Local, MRI, Next, MBB.end());
306+
fixupFollowingDebugValues(MI.getOperand(0).getReg(), LocalId, MRI, Next,
307+
MBB.end());
308+
265309
MI.eraseFromParent();
266310
Changed = true;
267311
continue;
@@ -294,13 +338,18 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
294338
BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
295339
.addImm(LocalId)
296340
.addReg(NewReg);
341+
fixupFollowingDebugValues(NewReg, LocalId, MRI, InsertPt,
342+
MBB.end());
297343
}
298344
MI.getOperand(0).setReg(NewReg);
299345
// This register operand is now being used by the inserted drop
300346
// instruction, so make it undead.
301347
MI.getOperand(0).setIsDead(false);
302348
MFI.stackifyVReg(NewReg);
303349
Changed = true;
350+
351+
fixupFollowingDebugValues(Reg2Local, MRI, InsertPt, MBB.end());
352+
304353
}
305354
}
306355

@@ -353,6 +402,8 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
353402
MO.setReg(NewReg);
354403
MFI.stackifyVReg(NewReg);
355404
Changed = true;
405+
406+
fixupFollowingDebugValues(OldReg, LocalId, MRI, InsertPt, MBB.end());
356407
}
357408

358409
// Coalesce and eliminate COPY instructions.
@@ -379,6 +430,13 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
379430
Changed = true;
380431
}
381432

433+
{
434+
auto RL = Reg2Local.find(MFI.SPVReg);
435+
if (RL != Reg2Local.end()) {
436+
MFI.SPLocal = RL->second;
437+
}
438+
}
439+
382440
#ifndef NDEBUG
383441
// Assert that all registers have been stackified at this point.
384442
for (const MachineBasicBlock &MBB : MF) {

lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,12 @@ bool WebAssemblyInstrInfo::reverseBranchCondition(
198198
Cond.front() = MachineOperand::CreateImm(!Cond.front().getImm());
199199
return false;
200200
}
201+
202+
ArrayRef<std::pair<int, const char *>>
203+
WebAssemblyInstrInfo::getSerializableTargetIndices() const {
204+
static const std::pair<int, const char *> TargetIndices[] = {
205+
{WebAssembly::TI_LOCAL_START, "wasm-local-start"},
206+
{WebAssembly::TI_GLOBAL_START, "wasm-global-start"},
207+
{WebAssembly::TI_OPERAND_STACK_START, "wasm-operator-stack-start"}};
208+
return makeArrayRef(TargetIndices);
209+
}

lib/Target/WebAssembly/WebAssemblyInstrInfo.h

+5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYINSTRINFO_H
1717
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYINSTRINFO_H
1818

19+
#include "WebAssembly.h"
1920
#include "WebAssemblyRegisterInfo.h"
21+
#include "llvm/ADT/ArrayRef.h"
2022
#include "llvm/CodeGen/TargetInstrInfo.h"
2123

2224
#define GET_INSTRINFO_HEADER
@@ -56,6 +58,9 @@ class WebAssemblyInstrInfo final : public WebAssemblyGenInstrInfo {
5658
int *BytesAdded = nullptr) const override;
5759
bool
5860
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
61+
62+
ArrayRef<std::pair<int, const char *>>
63+
getSerializableTargetIndices() const override;
5964
};
6065

6166
} // end namespace llvm

0 commit comments

Comments
 (0)