diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def index b0f78d0fd61ff..086e702c44879 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -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. diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h index 76d9c365c0a85..c46b824109821 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.h +++ b/llvm/include/llvm/BinaryFormat/Dwarf.h @@ -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. diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h index ddbd677b3eaae..131ceb390f132 100644 --- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h @@ -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 @@ -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; diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 7adc59d096fee..f4346003bef5b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -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()) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h index 17e39b3d3268f..3213fc7427491 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -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, @@ -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) @@ -56,8 +79,13 @@ class DbgValueLoc { : Expression(Expr), EntryKind(E_Location), Loc(Loc) { assert(cast(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; } @@ -65,6 +93,7 @@ class DbgValueLoc { 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; } @@ -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: diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index f0ceba50f1445..91a52adca131e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -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); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 71bb2b0858cc6..b967e3f37c8c2 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -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()) @@ -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); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index 2858afaa1cf19..57c438c30ac52 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -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); +} diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h index ec2ef6e575f77..1ad009ca7fc08 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -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. diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp index 470d4b5364b47..b18269282ead8 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -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); diff --git a/llvm/lib/Target/NVPTX/NVPTXRegisterInfo.h b/llvm/lib/Target/NVPTX/NVPTXRegisterInfo.h index 9ef6940daf864..8c43669415c19 100644 --- a/llvm/lib/Target/NVPTX/NVPTXRegisterInfo.h +++ b/llvm/lib/Target/NVPTX/NVPTXRegisterInfo.h @@ -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(&ManagedStrPool); } diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h index fcbd0a5082ffe..fcd48e0096b61 100644 --- a/llvm/lib/Target/WebAssembly/WebAssembly.h +++ b/llvm/lib/Target/WebAssembly/WebAssembly.h @@ -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 diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp index 579377c9a5d75..114a50a3055d7 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "WebAssemblyDebugValueManager.h" +#include "WebAssembly.h" #include "WebAssemblyMachineFunctionInfo.h" #include "llvm/CodeGen/MachineInstr.h" @@ -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); + } +} diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h index 06e8805b5ad08..7eae3cb5febd8 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h @@ -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 diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp index 5343697527445..e755ef17f9e5f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -17,6 +17,7 @@ #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" #include "WebAssembly.h" +#include "WebAssemblyDebugValueManager.h" #include "WebAssemblyMachineFunctionInfo.h" #include "WebAssemblySubtarget.h" #include "WebAssemblyUtilities.h" @@ -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; @@ -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); @@ -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; + } + } + #ifndef NDEBUG // Assert that all registers have been stackified at this point. for (const MachineBasicBlock &MBB : MF) { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp index ee6981135526b..b4e1f888acb6d 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp @@ -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" @@ -228,3 +229,12 @@ bool WebAssemblyInstrInfo::reverseBranchCondition( Cond.front() = MachineOperand::CreateImm(!Cond.front().getImm()); return false; } + +ArrayRef> +WebAssemblyInstrInfo::getSerializableTargetIndices() const { + static const std::pair 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); +} diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h index df1051b4f42cf..6afbfceaca7fa 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h @@ -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 @@ -64,6 +65,9 @@ class WebAssemblyInstrInfo final : public WebAssemblyGenInstrInfo { int *BytesAdded = nullptr) const override; bool reverseBranchCondition(SmallVectorImpl &Cond) const override; + + ArrayRef> + getSerializableTargetIndices() const override; }; } // end namespace llvm diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h index 4b9ba491dee63..419f21729ccb4 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h @@ -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); @@ -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, diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp index 0bfebc32a820e..9e2f817587ab0 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp @@ -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(); + 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 { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h index 7880eb217dbf3..1112a157a53c5 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h @@ -41,6 +41,9 @@ class WebAssemblyRegisterInfo final : public WebAssemblyGenRegisterInfo { // Debug information queries. Register getFrameRegister(const MachineFunction &MF) const override; + FrameBaseLocation + getFrameBaseLocation(const MachineFunction &MF) const override; + const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind = 0) const override; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp index 5eafd6c54e782..d217c512ad231 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp @@ -88,8 +88,14 @@ bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) { for (auto I = MRI.reg_begin(PReg), E = MRI.reg_end(); I != E;) { MachineOperand &MO = *I++; if (!MO.isImplicit()) { - if (VReg == WebAssembly::NoRegister) + if (VReg == WebAssembly::NoRegister) { VReg = MRI.createVirtualRegister(RC); + if (PReg == WebAssembly::SP32) { + WebAssemblyFunctionInfo &MFI = + *MF.getInfo(); + MFI.SPVReg = VReg; + } + } MO.setReg(VReg); if (MO.getParent()->isDebugValue()) MO.setIsDebug(); diff --git a/llvm/test/DebugInfo/WebAssembly/dbg-value-ti.ll b/llvm/test/DebugInfo/WebAssembly/dbg-value-ti.ll new file mode 100644 index 0000000000000..a99ca2d43cb3d --- /dev/null +++ b/llvm/test/DebugInfo/WebAssembly/dbg-value-ti.ll @@ -0,0 +1,74 @@ +; RUN: llc < %s -stop-after=wasm-explicit-locals | FileCheck %s + +; Checks if DBG_VALUEs that correspond to new `local.{tee,set}` are +; using `target-index(wasm-local-start)` operands. + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown-wasm" + +define hidden i32 @fib(i32 %n) local_unnamed_addr #0 !dbg !7 { +; CHECK: body: +entry: + +; CHECK: %[[REG1:.*]]:i32 = CONST_I32 1, +; CHECK: LOCAL_SET_I32 [[LOOP_LOCAL:.*]], %[[REG1]], +; CHECK: DBG_VALUE 1, $noreg, + call void @llvm.dbg.value(metadata i32 1, metadata !16, metadata !DIExpression()), !dbg !19 + %cmp8 = icmp sgt i32 %n, 0, !dbg !21 + br i1 %cmp8, label %for.body, label %for.end, !dbg !24 + +for.body: ; preds = %entry, %for.body + %b.011 = phi i32 [ %add, %for.body ], [ 1, %entry ] + %a.010 = phi i32 [ %b.011, %for.body ], [ 0, %entry ] + %i.09 = phi i32 [ %inc, %for.body ], [ 0, %entry ] + +; CHECK: %[[REG2:.*]]:i32 = LOCAL_GET_I32 [[LOOP_LOCAL]], +; CHECK: %[[REG3:.*]]:i32 = LOCAL_TEE_I32 [[TMP_LOCAL:.*]], %[[REG2]], +; CHECK: DBG_VALUE target-index(wasm-local-start) + [[TMP_LOCAL]], $noreg, + call void @llvm.dbg.value(metadata i32 %b.011, metadata !16, metadata !DIExpression()), !dbg !19 + +; CHECK: %[[REG4:.*]]:i32 = nsw ADD_I32 +; CHECK: LOCAL_SET_I32 [[LOOP_LOCAL]], %[[REG4]], +; CHECK: DBG_VALUE target-index(wasm-local-start) + [[LOOP_LOCAL]], $noreg, + %add = add nsw i32 %b.011, %a.010, !dbg !26 + %inc = add nuw nsw i32 %i.09, 1, !dbg !28 + call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !19 + %exitcond = icmp eq i32 %inc, %n, !dbg !21 + br i1 %exitcond, label %for.end, label %for.body, !dbg !24, !llvm.loop !29 + +for.end: ; preds = %for.body, %entry + %b.0.lcssa = phi i32 [ 1, %entry ], [ %add, %for.body ], !dbg !31 + call void @llvm.dbg.value(metadata i32 %b.0.lcssa, metadata !16, metadata !DIExpression()), !dbg !19 + ret i32 %b.0.lcssa, !dbg !32 +} + +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!4} +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "", directory: "") +!2 = !{} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!7 = distinct !DISubprogram(name: "fib", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!16} +!16 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 2, type: !10) +!17 = !DILocation(line: 1, column: 13, scope: !7) +!18 = !DILocation(line: 2, column: 13, scope: !7) +!19 = !DILocation(line: 2, column: 20, scope: !7) +!20 = !DILocation(line: 2, column: 7, scope: !7) +!21 = !DILocation(line: 3, column: 17, scope: !22) +!22 = distinct !DILexicalBlock(scope: !23, file: !1, line: 3, column: 3) +!23 = distinct !DILexicalBlock(scope: !7, file: !1, line: 3, column: 3) +!24 = !DILocation(line: 3, column: 3, scope: !23) +!25 = !DILocation(line: 2, column: 10, scope: !7) +!26 = !DILocation(line: 6, column: 7, scope: !27) +!27 = distinct !DILexicalBlock(scope: !22, file: !1, line: 3, column: 27) +!28 = !DILocation(line: 3, column: 23, scope: !22) +!29 = distinct !{!29, !24, !30} +!30 = !DILocation(line: 7, column: 3, scope: !23) +!31 = !DILocation(line: 0, scope: !7) +!32 = !DILocation(line: 8, column: 3, scope: !7)