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

Encode WebAssembly specific locations in DBG_VALUEs and DW_AT_frame_base (update) #20

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 @@ -633,6 +633,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)
// The GNU entry value extension.
HANDLE_DW_OP(0xf3, GNU_entry_value, 0, GNU)
// Extensions for Fission proposal.
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 @@ -58,7 +58,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
20 changes: 20 additions & 0 deletions llvm/include/llvm/CodeGen/TargetRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,18 @@ 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 @@ -992,6 +1004,14 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// for values allocated in the current stack frame.
virtual Register 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 @@ -866,6 +866,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 @@ -20,13 +20,32 @@
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;
}
};

/// A single location or constant.
class DbgValueLoc {
/// Any complex address location expression for this DbgValueLoc.
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 @@ -36,8 +55,12 @@ class DbgValueLoc {
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;
};

public:
DbgValueLoc(const DIExpression *Expr, int64_t i)
Expand All @@ -56,15 +79,21 @@ class DbgValueLoc {
: Expression(Expr), EntryKind(E_Location), Loc(Loc) {
assert(cast<DIExpression>(Expr)->isValid());
}
DbgValueLoc(const DIExpression *Expr, TargetIndexLocation Loc)
: Expression(Expr), EntryKind(E_TargetIndexLocation), TIL(Loc) {}

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(); }
bool isEntryVal() const { return getExpression()->isEntryValue(); }
const DIExpression *getExpression() const { return Expression; }
Expand Down Expand Up @@ -162,6 +191,8 @@ inline bool operator==(const DbgValueLoc &A,
switch (A.EntryKind) {
case DbgValueLoc::E_Location:
return A.Loc == B.Loc;
case DbgValueLoc::E_TargetIndexLocation:
return A.TIL == B.TIL;
case DbgValueLoc::E_Integer:
return A.Constant.Int == B.Constant.Int;
case DbgValueLoc::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 @@ -392,13 +392,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 @@ -257,6 +257,11 @@ static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
MachineLocation MLoc(RegOp.getReg(), Op1.isImm());
return DbgValueLoc(Expr, MLoc);
}
if (MI->getOperand(0).isTargetIndex()) {
auto Op = MI->getOperand(0);
return DbgValueLoc(Expr,
TargetIndexLocation(Op.getIndex(), Op.getOffset()));
}
if (MI->getOperand(0).isImm())
return DbgValueLoc(Expr, MI->getOperand(0).getImm());
if (MI->getOperand(0).isFPImm())
Expand Down Expand Up @@ -2027,6 +2032,9 @@ void DwarfDebug::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 @@ -521,3 +521,11 @@ void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
emitUnsigned((1ULL << FromBits) - 1);
emitOp(dwarf::DW_OP_and);
}

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 @@ -295,6 +295,10 @@ class DwarfExpression {

void emitLegacySExt(unsigned FromBits);
void emitLegacyZExt(unsigned FromBits);

/// 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
7 changes: 7 additions & 0 deletions llvm/lib/Target/NVPTX/NVPTXRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ class NVPTXRegisterInfo : public NVPTXGenRegisterInfo {

Register 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 @@ -79,6 +79,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 "WebAssemblyDebugValueManager.h"
#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "llvm/CodeGen/MachineInstr.h"

Expand Down Expand Up @@ -43,3 +44,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 @@ -30,6 +30,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 @@ -17,6 +17,7 @@

#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssembly.h"
#include "WebAssemblyDebugValueManager.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblySubtarget.h"
#include "WebAssemblyUtilities.h"
Expand Down Expand Up @@ -261,6 +262,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 @@ -290,6 +293,9 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
} else {
unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);
unsigned Opc = getLocalSetOpcode(RC);

WebAssemblyDebugValueManager(&MI).replaceWithLocal(LocalId);

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

{
auto RL = Reg2Local.find(MFI.SPVReg);
if (RL != Reg2Local.end()) {
MFI.SPLocal = RL->second;
}
}
yurydelendik marked this conversation as resolved.
Show resolved Hide resolved

#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 @@ -14,6 +14,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 @@ -228,3 +229,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 @@ -16,6 +16,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 @@ -64,6 +65,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
6 changes: 5 additions & 1 deletion llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
bool CFGStackified = false;

public:
explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {}
explicit WebAssemblyFunctionInfo(MachineFunction &MF)
: MF(MF), SPVReg(WebAssembly::NoRegister) {}
~WebAssemblyFunctionInfo() override;
void initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo &YamlMFI);

Expand Down Expand Up @@ -129,6 +130,9 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo {

bool isCFGStackified() const { return CFGStackified; }
void setCFGStackified(bool Value = true) { CFGStackified = Value; }

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 @@ -140,6 +140,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