Skip to content

Commit

Permalink
Merge pull request #2 from yurydelendik/rustc/frame-pointer
Browse files Browse the repository at this point in the history
[WIP] Encode WebAssembly specific locations in DBG_VALUEs and DW_AT_frame_base
  • Loading branch information
alexcrichton authored Jan 17, 2019
2 parents a27fbee + 0dd13a7 commit 25bfc9f
Show file tree
Hide file tree
Showing 22 changed files with 243 additions and 9 deletions.
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

0 comments on commit 25bfc9f

Please sign in to comment.