From c263ee986fc90d8413f444ced7610dfbdfe97be6 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Thu, 17 Jan 2019 12:27:13 -0600 Subject: [PATCH] [WIP] Record WebAssembly specific frame pointer. --- .../include/llvm/CodeGen/TargetRegisterInfo.h | 20 +++++++++++++++++++ .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 17 +++++++++++++--- llvm/lib/Target/NVPTX/NVPTXRegisterInfo.h | 7 +++++++ .../WebAssembly/WebAssemblyExplicitLocals.cpp | 7 +++++++ .../WebAssemblyMachineFunctionInfo.h | 6 +++++- .../WebAssembly/WebAssemblyRegisterInfo.cpp | 10 ++++++++++ .../WebAssembly/WebAssemblyRegisterInfo.h | 3 +++ .../WebAssemblyReplacePhysRegs.cpp | 8 +++++++- 8 files changed, 73 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h index ddbd677b3eaae8..131ceb390f132e 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/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index f0ceba50f1445e..91a52adca131e0 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/Target/NVPTX/NVPTXRegisterInfo.h b/llvm/lib/Target/NVPTX/NVPTXRegisterInfo.h index 9ef6940daf864f..8c43669415c192 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/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp index 8ccc06d346d99c..e755ef17f9e5fc 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -385,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/WebAssemblyMachineFunctionInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h index 4b9ba491dee632..419f21729ccb4c 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 0bfebc32a820e9..9e2f817587ab0a 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 7880eb217dbf39..1112a157a53c5d 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 5eafd6c54e7824..d217c512ad231a 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();