35 #define DEBUG_TYPE "wasm-frame-info"
44 bool WebAssemblyFrameLowering::hasBP(
48 return RegInfo->needsStackRealignment(MF);
63 bool NeedsFixedReference = !hasBP(MF) || HasFixedSizedObjects;
92 bool WebAssemblyFrameLowering::needsSPWriteback(
104 const char *ES =
"__stack_pointer";
112 BuildMI(MBB, InsertAddr, DL,
TII->get(WebAssembly::CONST_I32),
Zero)
117 BuildMI(MBB, InsertStore, DL,
TII->get(WebAssembly::STORE_I32))
129 assert(!I->getOperand(0).getImm() && (
hasFP(MF) || hasBP(MF)) &&
130 "Call frame pseudos should only be used for dynamic stack adjustment");
132 if (I->getOpcode() ==
TII->getCallFrameDestroyOpcode() &&
145 "WebAssembly should not have callee-saved registers");
147 if (!needsSP(MF, MFI))
return;
153 auto InsertPt = MBB.
begin();
157 MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
158 unsigned Zero =
MRI.createVirtualRegister(PtrRC);
159 unsigned SPReg = WebAssembly::SP32;
161 SPReg =
MRI.createVirtualRegister(PtrRC);
162 const char *ES =
"__stack_pointer";
164 BuildMI(MBB, InsertPt, DL,
TII->get(WebAssembly::CONST_I32),
Zero)
170 BuildMI(MBB, InsertPt, DL,
TII->get(WebAssembly::LOAD_I32), SPReg)
176 bool HasBP = hasBP(MF);
179 unsigned BasePtr =
MRI.createVirtualRegister(PtrRC);
180 FI->setBasePointerVreg(BasePtr);
181 BuildMI(MBB, InsertPt, DL,
TII->get(WebAssembly::COPY), BasePtr)
186 unsigned OffsetReg =
MRI.createVirtualRegister(PtrRC);
187 BuildMI(MBB, InsertPt, DL,
TII->get(WebAssembly::CONST_I32), OffsetReg)
189 BuildMI(MBB, InsertPt, DL,
TII->get(WebAssembly::SUB_I32),
195 unsigned BitmaskReg =
MRI.createVirtualRegister(PtrRC);
198 "Alignment must be a power of 2");
199 BuildMI(MBB, InsertPt, DL,
TII->get(WebAssembly::CONST_I32), BitmaskReg)
200 .addImm((
int)~(Alignment - 1));
201 BuildMI(MBB, InsertPt, DL,
TII->get(WebAssembly::AND_I32),
203 .addReg(WebAssembly::SP32)
210 BuildMI(MBB, InsertPt, DL,
TII->get(WebAssembly::COPY),
212 .addReg(WebAssembly::SP32);
214 if (StackSize && needsSPWriteback(MF, MFI)) {
223 if (!needsSP(MF, MFI) || !needsSPWriteback(MF, MFI))
return;
229 if (InsertPt != MBB.
end())
230 DL = InsertPt->getDebugLoc();
238 SPReg = FI->getBasePointerVreg();
239 }
else if (StackSize) {
241 MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
242 unsigned OffsetReg =
MRI.createVirtualRegister(PtrRC);
244 BuildMI(MBB, InsertPt, DL,
TII->get(WebAssembly::CONST_I32), OffsetReg)
248 SPReg =
MRI.createVirtualRegister(PtrRC);
249 BuildMI(MBB, InsertPt, DL,
TII->get(WebAssembly::ADD_I32), SPReg)
250 .addReg(
hasFP(MF) ? WebAssembly::FP32 : WebAssembly::SP32)
253 SPReg =
hasFP(MF) ? WebAssembly::FP32 : WebAssembly::SP32;
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
These methods insert prolog and epilog code into the function.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
bool hasFP(const MachineFunction &MF) const override
Return true if the specified function should have a dedicated frame pointer register.
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const HexagonInstrInfo * TII
const TargetRegisterInfo * getTargetRegisterInfo() const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
This file declares the WebAssembly-specific subclass of TargetMachine.
PseudoSourceValueManager & getPSVManager() const
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool hasStackMap() const
This method may be called any time after instruction selection is complete to determine if there is a...
unsigned const MachineRegisterInfo * MRI
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
const PseudoSourceValue * getExternalSymbolCallEntry(const char *ES)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
This file provides WebAssembly-specific target descriptions.
static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator &InsertAddr, MachineBasicBlock::iterator &InsertStore, const DebugLoc &DL)
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
This class contains a discriminated union of information about pointers in memory operands...
const char * createExternalSymbolName(StringRef Name)
Allocate a string and populate it with the given external symbol name.
The memory access writes data.
bool hasCalls() const
Return true if the current function has any function calls.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
This file contains the WebAssembly implementation of the TargetInstrInfo class.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SynchronizationScope SynchScope=CrossThread, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
bool hasPatchPoint() const
This method may be called any time after instruction selection is complete to determine if there is a...
This class implements WebAssembly-specific bits of TargetFrameLowering class.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
static const size_t RedZoneSize
Size of the red zone for the user stack (leaf functions can use this much space below the stack point...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool hasReservedCallFrame(const MachineFunction &MF) const override
Under normal circumstances, when a frame pointer is not required, we reserve argument space for call ...
This file declares WebAssembly-specific per-machine-function information.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.