From 57dd570730249ec0e2ee1bcd7f3ac24f0a7eef4d Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Thu, 10 Jan 2019 16:30:19 -0600 Subject: [PATCH 1/2] Add DBG_VALUE with local operands location in WebAssemblyExplicitLocals pass https://reviews.llvm.org/D52634 --- include/llvm/BinaryFormat/Dwarf.def | 2 + include/llvm/BinaryFormat/Dwarf.h | 3 +- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 4 ++ lib/CodeGen/AsmPrinter/DebugLocEntry.h | 37 ++++++++++++-- lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 8 +++ lib/CodeGen/AsmPrinter/DwarfExpression.h | 4 ++ lib/DebugInfo/DWARF/DWARFExpression.cpp | 2 + lib/Target/WebAssembly/WebAssembly.h | 4 ++ .../WebAssembly/WebAssemblyExplicitLocals.cpp | 51 +++++++++++++++++++ .../WebAssembly/WebAssemblyInstrInfo.cpp | 9 ++++ lib/Target/WebAssembly/WebAssemblyInstrInfo.h | 5 ++ 11 files changed, 125 insertions(+), 4 deletions(-) diff --git a/include/llvm/BinaryFormat/Dwarf.def b/include/llvm/BinaryFormat/Dwarf.def index 512cc64926db..0643fc21a057 100644 --- a/include/llvm/BinaryFormat/Dwarf.def +++ b/include/llvm/BinaryFormat/Dwarf.def @@ -627,6 +627,8 @@ HANDLE_DW_OP(0xfb, GNU_addr_index, 0, GNU) HANDLE_DW_OP(0xfc, GNU_const_index, 0, GNU) // DWARF languages. +// Extensions for WebAssembly. +HANDLE_DW_OP(0xed, WASM_location, 0, WASM) HANDLE_DW_LANG(0x0001, C89, 2, DWARF) HANDLE_DW_LANG(0x0002, C, 2, DWARF) HANDLE_DW_LANG(0x0003, Ada83, 2, DWARF) diff --git a/include/llvm/BinaryFormat/Dwarf.h b/include/llvm/BinaryFormat/Dwarf.h index 330e31cffae6..3bbea5589f39 100644 --- a/include/llvm/BinaryFormat/Dwarf.h +++ b/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/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 526f7ce30831..23bcc10bc4e3 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -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()) { diff --git a/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/lib/CodeGen/AsmPrinter/DebugLocEntry.h index befa4b941c8d..7582e06e5bff 100644 --- a/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -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 { @@ -47,12 +60,20 @@ class DebugLocEntry { : Expression(Expr), EntryKind(E_Location), Loc(Loc) { assert(cast(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, @@ -62,10 +83,17 @@ 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; } @@ -73,6 +101,7 @@ class DebugLocEntry { 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 &); @@ -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: diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index 19c350afbf17..5c1f27bf7e16 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -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); +} diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.h b/lib/CodeGen/AsmPrinter/DwarfExpression.h index d47c4d1d2969..ef7236a118f3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -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. diff --git a/lib/DebugInfo/DWARF/DWARFExpression.cpp b/lib/DebugInfo/DWARF/DWARFExpression.cpp index 2df4456053fb..a9d200637fde 100644 --- a/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/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/lib/Target/WebAssembly/WebAssembly.h b/lib/Target/WebAssembly/WebAssembly.h index 87975cad02a8..3285898a4b1f 100644 --- a/lib/Target/WebAssembly/WebAssembly.h +++ b/lib/Target/WebAssembly/WebAssembly.h @@ -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 diff --git a/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp index 384c0d60db53..45131f71b5b6 100644 --- a/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -164,6 +164,45 @@ static MVT typeForRegClass(const TargetRegisterClass *RC) { llvm_unreachable("unrecognized register class"); } +static void fixupFollowingDebugValues(DenseMap &Reg2Local, + MachineRegisterInfo &MRI, + MachineBasicBlock::iterator B, + MachineBasicBlock::iterator E) { + // Scan DBG_VALUE and modify virtual registers with known locals. + // Stop at first non-DBG_VALUE instruction. + for (auto I = B; I != E && I->isDebugInstr();) { + MachineInstr &MI = *I++; + for (MachineOperand &MO : reverse(MI.uses())) { + if (!MO.isReg()) + continue; + + unsigned OldReg = MO.getReg(); + auto I = Reg2Local.find(OldReg); + if (I == Reg2Local.end()) + continue; + + unsigned LocalId = I->second; + MO.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL_START, LocalId); + } + } +} + +static void fixupFollowingDebugValues(unsigned Reg, unsigned LocalId, + MachineRegisterInfo &MRI, + MachineBasicBlock::iterator B, + MachineBasicBlock::iterator E) { + // Scan DBG_VALUE and modify the specified virtual registers with the local. + // Stop at first non-DBG_VALUE instruction. + for (auto I = B; I != E && I->isDebugInstr();) { + MachineInstr &MI = *I++; + for (MachineOperand &MO : reverse(MI.uses())) { + if (!MO.isReg() || MO.getReg() != Reg) + continue; + MO.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL_START, LocalId); + } + } +} + /// Given a MachineOperand of a stackified vreg, return the instruction at the /// start of the expression tree. static MachineInstr *findStartOfTree(MachineOperand &MO, @@ -262,6 +301,11 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { .addImm(LocalId) .addReg(MI.getOperand(2).getReg()); + auto Next = std::next(MachineBasicBlock::iterator(&MI)); + fixupFollowingDebugValues(Reg2Local, MRI, Next, MBB.end()); + fixupFollowingDebugValues(MI.getOperand(0).getReg(), LocalId, MRI, Next, + MBB.end()); + MI.eraseFromParent(); Changed = true; continue; @@ -294,6 +338,8 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc)) .addImm(LocalId) .addReg(NewReg); + fixupFollowingDebugValues(NewReg, LocalId, MRI, InsertPt, + MBB.end()); } MI.getOperand(0).setReg(NewReg); // This register operand is now being used by the inserted drop @@ -301,6 +347,9 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { MI.getOperand(0).setIsDead(false); MFI.stackifyVReg(NewReg); Changed = true; + + fixupFollowingDebugValues(Reg2Local, MRI, InsertPt, MBB.end()); + } } @@ -353,6 +402,8 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { MO.setReg(NewReg); MFI.stackifyVReg(NewReg); Changed = true; + + fixupFollowingDebugValues(OldReg, LocalId, MRI, InsertPt, MBB.end()); } // Coalesce and eliminate COPY instructions. diff --git a/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp index 5efff32d6167..57cdd7c4c619 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp +++ b/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp @@ -198,3 +198,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/lib/Target/WebAssembly/WebAssemblyInstrInfo.h b/lib/Target/WebAssembly/WebAssemblyInstrInfo.h index 4a3763c345b0..66bdbf97dd1c 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrInfo.h +++ b/lib/Target/WebAssembly/WebAssemblyInstrInfo.h @@ -16,7 +16,9 @@ #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYINSTRINFO_H #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYINSTRINFO_H +#include "WebAssembly.h" #include "WebAssemblyRegisterInfo.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/CodeGen/TargetInstrInfo.h" #define GET_INSTRINFO_HEADER @@ -56,6 +58,9 @@ class WebAssemblyInstrInfo final : public WebAssemblyGenInstrInfo { int *BytesAdded = nullptr) const override; bool reverseBranchCondition(SmallVectorImpl &Cond) const override; + + ArrayRef> + getSerializableTargetIndices() const override; }; } // end namespace llvm From 9c870ef82e43d3b0edc5a558f6962db9191c6438 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Thu, 10 Jan 2019 17:20:11 -0600 Subject: [PATCH 2/2] Record Wasm specific frame pointer. --- include/llvm/CodeGen/TargetRegisterInfo.h | 23 +++++++++++++++++++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 19 +++++++++++---- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 8 +++++++ lib/Target/NVPTX/NVPTXRegisterInfo.h | 6 +++++ lib/Target/WebAssembly/WebAssembly.h | 4 ++++ .../WebAssembly/WebAssemblyExplicitLocals.cpp | 7 ++++++ .../WebAssemblyMachineFunctionInfo.h | 5 +++- .../WebAssembly/WebAssemblyRegisterInfo.cpp | 10 ++++++++ .../WebAssembly/WebAssemblyRegisterInfo.h | 2 ++ .../WebAssemblyReplacePhysRegs.cpp | 7 +++++- 10 files changed, 85 insertions(+), 6 deletions(-) diff --git a/include/llvm/CodeGen/TargetRegisterInfo.h b/include/llvm/CodeGen/TargetRegisterInfo.h index 0fbff3137653..2c3e8fcaf9c0 100644 --- a/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/include/llvm/CodeGen/TargetRegisterInfo.h @@ -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 @@ -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; diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index d93c7f6c8459..943b55f19505 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -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); } @@ -1023,7 +1034,7 @@ void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, /// Add an address attribute to a die based on the location provided. void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, - const MachineLocation &Location) { + const MachineLocation &Location) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); if (Location.isIndirect()) diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 5d50f34d77d9..3d38b6ee33b5 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1060,6 +1060,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()) @@ -1899,6 +1904,9 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, } else if (Value.isConstantFP()) { APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt(); DwarfExpr.addUnsignedConstant(RawBytes); + } else if (Value.isTargetIndexLocation()) { + TargetIndexLocation Loc = Value.getTargetIndexLocation(); + DwarfExpr.addTargetIndexLocation(Loc.Index, Loc.Offset); } DwarfExpr.addExpression(std::move(ExprCursor)); } diff --git a/lib/Target/NVPTX/NVPTXRegisterInfo.h b/lib/Target/NVPTX/NVPTXRegisterInfo.h index 6185a0b54cac..d4aa873cda33 100644 --- a/lib/Target/NVPTX/NVPTXRegisterInfo.h +++ b/lib/Target/NVPTX/NVPTXRegisterInfo.h @@ -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(&ManagedStrPool); } diff --git a/lib/Target/WebAssembly/WebAssembly.h b/lib/Target/WebAssembly/WebAssembly.h index 3285898a4b1f..4a0fa27c1bca 100644 --- a/lib/Target/WebAssembly/WebAssembly.h +++ b/lib/Target/WebAssembly/WebAssembly.h @@ -86,6 +86,10 @@ namespace WebAssembly { enum TargetIndex { TI_LOCAL_START, TI_GLOBAL_START, TI_OPERAND_STACK_START }; } // end namespace WebAssembly +namespace WebAssembly { +enum TargetIndex { TI_LOCAL_START, TI_GLOBAL_START, TI_OPERAND_STACK_START }; +} // end namespace WebAssembly + } // end namespace llvm #endif diff --git a/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp index 45131f71b5b6..909348fd8494 100644 --- a/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -430,6 +430,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/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h index cde44d24599a..9509c60cf3e4 100644 --- a/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ b/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h @@ -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); } @@ -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, diff --git a/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp b/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp index 1f0870865b06..c7d96749a104 100644 --- a/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp +++ b/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp @@ -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(); + 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/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h b/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h index 2a73dfd4b065..2f7158081054 100644 --- a/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h +++ b/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h @@ -42,6 +42,8 @@ class WebAssemblyRegisterInfo final : public WebAssemblyGenRegisterInfo { // Debug information queries. unsigned 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/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp b/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp index e5a3e47a3bcd..39117757adcf 100644 --- a/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp +++ b/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp @@ -89,8 +89,13 @@ 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();