Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Encode WebAssembly specific locations in DBG_VALUEs and DW_AT_frame_base #2

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/include/llvm/BinaryFormat/Dwarf.def
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,8 @@ HANDLE_DW_OP(0xa9, reinterpret, 5, DWARF)
// 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(0xed, 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)
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/BinaryFormat/Dwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ enum LLVMConstants : uint32_t {
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.
Expand Down
23 changes: 23 additions & 0 deletions llvm/include/llvm/CodeGen/TargetRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,22 @@ struct RegClassWeight {
unsigned WeightLimit;
};

struct FrameBaseLocation {
enum LocationKind {
Register,
CFA,
TargetIndex
} Kind;
struct TargetIndexInfo {
unsigned Index;
signed Offset;
};
union {
unsigned Reg;
TargetIndexInfo TI;
};
};

/// TargetRegisterInfo base class - We assume that the target defines a static
/// array of TargetRegisterDesc objects that represent all of the machine
/// registers that the target has. As such, we simply have to track a pointer
Expand Down Expand Up @@ -988,6 +1004,13 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// for values allocated in the current stack frame.
virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0;

virtual FrameBaseLocation getFrameBaseLocation(const MachineFunction &MF) const {
FrameBaseLocation Loc;
Loc.Kind = FrameBaseLocation::Register;
Loc.Reg = getFrameRegister(MF);
return Loc;
}

/// Mark a register and all its aliases as reserved in the given set.
void markSuperRegs(BitVector &RegisterSet, unsigned Reg) const;

Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,10 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
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()) {
Expand Down
37 changes: 34 additions & 3 deletions llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -47,12 +60,20 @@ class DebugLocEntry {
: 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,
Expand All @@ -62,17 +83,25 @@ class DebugLocEntry {
const ConstantInt *CIP;
} 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; }
int64_t getInt() const { return Constant.Int; }
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 &);
Expand Down Expand Up @@ -165,6 +194,8 @@ inline bool operator==(const DebugLocEntry::Value &A,
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:
Expand Down
17 changes: 14 additions & 3 deletions llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,24 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {

// Only include DW_AT_frame_base in full debug info
if (!includeMinimalInlineScopes()) {
if (Asm->MF->getTarget().getTargetTriple().isNVPTX()) {
const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo();
auto FBL = RI->getFrameBaseLocation(*Asm->MF);
if (FBL.Kind == FrameBaseLocation::CFA) {
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
} else if (FBL.Kind == FrameBaseLocation::TargetIndex) {
if (FBL.TI.Offset >= 0) {
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
DIExpressionCursor Cursor({});
DwarfExpr.addTargetIndexLocation(FBL.TI.Index, FBL.TI.Offset);
DwarfExpr.addExpression(std::move(Cursor));
addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());
}
} else {
const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo();
MachineLocation Location(RI->getFrameRegister(*Asm->MF));
assert(FBL.Kind == FrameBaseLocation::Register);
MachineLocation Location(FBL.Reg);
if (RI->isPhysicalRegister(Location.getReg()))
addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
}
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,11 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
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())
Expand Down Expand Up @@ -1920,6 +1925,9 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
return;
return DwarfExpr.addExpression(std::move(Cursor));
} else if (Value.isTargetIndexLocation()) {
TargetIndexLocation Loc = Value.getTargetIndexLocation();
DwarfExpr.addTargetIndexLocation(Loc.Index, Loc.Offset);
} else if (Value.isConstantFP()) {
APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt();
DwarfExpr.addUnsignedConstant(RawBytes);
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,3 +437,11 @@ void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {
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);
}
4 changes: 4 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ class DwarfExpression {
/// 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.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ static DescVector getDescriptions() {
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_addrx] = Desc(Op::Dwarf4, Op::SizeLEB);
Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/NVPTX/NVPTXRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ class NVPTXRegisterInfo : public NVPTXGenRegisterInfo {

unsigned getFrameRegister(const MachineFunction &MF) const override;

FrameBaseLocation getFrameBaseLocation(const MachineFunction &MF) const override {
FrameBaseLocation Loc;
Loc.Kind = FrameBaseLocation::CFA;
return Loc;
}

ManagedStringPool *getStrPool() const {
return const_cast<ManagedStringPool *>(&ManagedStrPool);
}
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ void initializeWebAssemblyRegNumberingPass(PassRegistry &);
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
8 changes: 8 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
///
//===----------------------------------------------------------------------===//

#include "WebAssembly.h"
#include "WebAssemblyDebugValueManager.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
Expand Down Expand Up @@ -44,3 +45,10 @@ void WebAssemblyDebugValueManager::clone(MachineInstr *Insert,
MBB->insert(Insert, Clone);
}
}

void WebAssemblyDebugValueManager::replaceWithLocal(unsigned LocalId) {
for (auto *DBI : DbgValues) {
MachineOperand &Op = DBI->getOperand(0);
Op.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL_START, LocalId);
}
}
1 change: 1 addition & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class WebAssemblyDebugValueManager {
void move(MachineInstr *Insert);
void updateReg(unsigned Reg);
void clone(MachineInstr *Insert, unsigned NewReg);
void replaceWithLocal(unsigned LocalId);
};

} // end namespace llvm
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssembly.h"
#include "WebAssemblyDebugValueManager.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblySubtarget.h"
#include "WebAssemblyUtilities.h"
Expand Down Expand Up @@ -262,6 +263,8 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
.addImm(LocalId)
.addReg(MI.getOperand(2).getReg());

WebAssemblyDebugValueManager(&MI).replaceWithLocal(LocalId);

MI.eraseFromParent();
Changed = true;
continue;
Expand Down Expand Up @@ -291,6 +294,9 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
} else {
unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);
unsigned Opc = getSetLocalOpcode(RC);

WebAssemblyDebugValueManager(&MI).replaceWithLocal(LocalId);

BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
.addImm(LocalId)
.addReg(NewReg);
Expand Down Expand Up @@ -380,6 +386,13 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
Changed = true;
}

{
auto RL = Reg2Local.find(MFI.SPVReg);
if (RL != Reg2Local.end()) {
MFI.SPLocal = RL->second;
}
}

#ifndef NDEBUG
// Assert that all registers have been stackified at this point.
for (const MachineBasicBlock &MBB : MF) {
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "WebAssemblyInstrInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblySubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
Expand Down Expand Up @@ -198,3 +199,12 @@ bool WebAssemblyInstrInfo::reverseBranchCondition(
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);
}
4 changes: 4 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYINSTRINFO_H

#include "WebAssemblyRegisterInfo.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/CodeGen/TargetInstrInfo.h"

#define GET_INSTRINFO_HEADER
Expand Down Expand Up @@ -56,6 +57,9 @@ class WebAssemblyInstrInfo final : public WebAssemblyGenInstrInfo {
int *BytesAdded = nullptr) const override;
bool
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;

ArrayRef<std::pair<int, const char *>>
getSerializableTargetIndices() const override;
};

} // end namespace llvm
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
unsigned BasePtrVreg = -1U;

public:
explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {}
explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF), SPVReg(WebAssembly::NoRegister) {}
~WebAssemblyFunctionInfo() override;

void addParam(MVT VT) { Params.push_back(VT); }
Expand Down Expand Up @@ -118,6 +118,9 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
assert(Reg & INT32_MIN);
return Reg & INT32_MAX;
}

unsigned SPVReg;
unsigned SPLocal;
};

void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty,
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ WebAssemblyRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
return Regs[TFI->hasFP(MF)][TT.isArch64Bit()];
}

FrameBaseLocation
WebAssemblyRegisterInfo::getFrameBaseLocation(const MachineFunction &MF) const {
const WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
FrameBaseLocation Loc;
Loc.Kind = FrameBaseLocation::TargetIndex;
signed Local = MFI.SPVReg != WebAssembly::NoRegister ? MFI.SPLocal : -1;
Loc.TI = {0, Local};
return Loc;
}

const TargetRegisterClass *
WebAssemblyRegisterInfo::getPointerRegClass(const MachineFunction &MF,
unsigned Kind) const {
Expand Down
Loading