LLVM: lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

35using namespace llvm;

36

37#define DEBUG_TYPE "wasm-frame-info"

38

39

40

41

42

43

44

45

46

47

48

49

50

51std::optional

53 int FrameIndex) {

55

56

58 return static_cast<unsigned>(MFI.getObjectOffset(FrameIndex));

59

60

61

64 return std::nullopt;

65

66

67

74

77

78

79 for (EVT ValueVT : ValueVTs)

80 FuncInfo->addLocal(ValueVT.getSimpleVT());

81

82

84 return static_cast<unsigned>(Local);

85}

86

87

88

89

90

91bool WebAssemblyFrameLowering::hasBP(const MachineFunction &MF) const {

92 const auto *RegInfo =

94 return RegInfo->hasStackRealignment(MF);

95}

96

97

98

101

102

103

104

105

106

107

108 bool HasFixedSizedObjects = MFI.getStackSize() > 0;

109 bool NeedsFixedReference = !hasBP(MF) || HasFixedSizedObjects;

110

114}

115

116

117

118

119

120

124}

125

126

127

128bool WebAssemblyFrameLowering::needsSPForLocalFrame(

132

133

134 bool HasExplicitSPUse =

137

138 return MFI.getStackSize() || MFI.adjustsStack() || hasFP(MF) ||

139 HasExplicitSPUse;

140}

141

142

143

144

150}

151

152

153

154

155bool WebAssemblyFrameLowering::needsSP(const MachineFunction &MF) const {

157}

158

159

160

161

162

163bool WebAssemblyFrameLowering::needsSPWriteback(

167

168

169

170

171

172

173

174 bool CanUseRedZone = MFI.getStackSize() <= RedZoneSize && !MFI.hasCalls() &&

176 return needsSPForLocalFrame(MF) && !CanUseRedZone;

177}

178

181 ? WebAssembly::SP64

182 : WebAssembly::SP32;

183}

184

187 ? WebAssembly::FP64

188 : WebAssembly::FP32;

189}

190

191unsigned

194 ? WebAssembly::CONST_I64

195 : WebAssembly::CONST_I32;

196}

197

200 ? WebAssembly::ADD_I64

201 : WebAssembly::ADD_I32;

202}

203

206 ? WebAssembly::SUB_I64

207 : WebAssembly::SUB_I32;

208}

209

212 ? WebAssembly::AND_I64

213 : WebAssembly::AND_I32;

214}

215

216unsigned

219 ? WebAssembly::GLOBAL_GET_I64

220 : WebAssembly::GLOBAL_GET_I32;

221}

222

223unsigned

226 ? WebAssembly::GLOBAL_SET_I64

227 : WebAssembly::GLOBAL_SET_I32;

228}

229

234

235 const char *ES = "__stack_pointer";

237

241}

242

247 assert(I->getOperand(0).getImm() && (hasFP(MF) || hasBP(MF)) &&

248 "Call frame pseudos should only be used for dynamic stack adjustment");

250 const auto *TII = ST.getInstrInfo();

251 if (I->getOpcode() == TII->getCallFrameDestroyOpcode() &&

252 needsSPWriteback(MF)) {

255 }

257}

258

261

263 assert(MFI.getCalleeSavedInfo().empty() &&

264 "WebAssembly should not have callee-saved registers");

265

266 if (!needsSP(MF))

267 return;

268 uint64_t StackSize = MFI.getStackSize();

269

271 const auto *TII = ST.getInstrInfo();

273

275 while (InsertPt != MBB.end() &&

277 ++InsertPt;

279

281 MRI.getTargetRegisterInfo()->getPointerRegClass(MF);

283 if (StackSize)

284 SPReg = MRI.createVirtualRegister(PtrRC);

285

286 const char *ES = "__stack_pointer";

290

291 bool HasBP = hasBP(MF);

292 if (HasBP) {

294 Register BasePtr = MRI.createVirtualRegister(PtrRC);

295 FI->setBasePointerVreg(BasePtr);

296 BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY), BasePtr)

298 }

299 if (StackSize) {

300

301 Register OffsetReg = MRI.createVirtualRegister(PtrRC);

307 }

308 if (HasBP) {

309 Register BitmaskReg = MRI.createVirtualRegister(PtrRC);

310 Align Alignment = MFI.getMaxAlign();

312 .addImm((int64_t) ~(Alignment.value() - 1));

316 }

318

319

320

323 }

324 if (StackSize && needsSPWriteback(MF)) {

326 }

327}

328

332 if (!needsSP(MF) || !needsSPWriteback(MF))

333 return;

335 const auto *TII = ST.getInstrInfo();

339

340 if (InsertPt != MBB.end())

341 DL = InsertPt->getDebugLoc();

342

343

344

345 unsigned SPReg = 0;

347 if (hasBP(MF)) {

349 SPReg = FI->getBasePointerVreg();

350 } else if (StackSize) {

352 MRI.getTargetRegisterInfo()->getPointerRegClass(MF);

353 Register OffsetReg = MRI.createVirtualRegister(PtrRC);

356

357

358

359 SPReg = MRI.createVirtualRegister(PtrRC);

363 } else {

365 }

366

368}

369

372

373

375 return true;

376

378}

379

383 Loc.Kind = DwarfFrameBase::WasmFrameBase;

388 } else {

389

390

392 }

393 return Loc;

394}

unsigned const MachineRegisterInfo * MRI

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

const HexagonInstrInfo * TII

static constexpr Register SPReg

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This class implements WebAssembly-specific bits of TargetFrameLowering class.

This file contains the WebAssembly implementation of the TargetInstrInfo class.

This file provides WebAssembly-specific target descriptions.

This file declares WebAssembly-specific per-machine-function information.

This file declares the WebAssembly-specific subclass of TargetSubtarget.

This file declares the WebAssembly-specific subclass of TargetMachine.

This file contains the declaration of the WebAssembly-specific type parsing utility functions.

This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.

an instruction to allocate memory on the stack

Type * getAllocatedType() const

Return the type that is being allocated by the instruction.

unsigned getAddressSpace() const

Return the address space for the allocation.

bool hasPersonalityFn() const

Check whether this function has a personality function.

bool hasFnAttribute(Attribute::AttrKind Kind) const

Return true if the function has the attribute.

ExceptionHandling getExceptionHandlingType() const

iterator getFirstTerminator()

Returns an iterator to the first terminator instruction of this basic block.

instr_iterator erase(instr_iterator I)

Remove an instruction from the instruction list and delete it.

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

bool hasVarSizedObjects() const

This method may be called any time after instruction selection is complete to determine if the stack ...

uint64_t getStackSize() const

Return the number of bytes that must be allocated to hold all of the fixed size frame objects.

const AllocaInst * getObjectAllocation(int ObjectIdx) const

Return the underlying Alloca of the specified stack object if it exists.

bool hasCalls() const

Return true if the current function has any function calls.

bool isFrameAddressTaken() const

This method may be called any time after instruction selection is complete to determine if there is a...

void setObjectOffset(int ObjectIdx, int64_t SPOffset)

Set the stack frame offset of the specified object.

bool hasPatchPoint() const

This method may be called any time after instruction selection is complete to determine if there is a...

void setObjectSize(int ObjectIdx, int64_t Size)

Change the size of the specified stack object.

void setStackID(int ObjectIdx, uint8_t ID)

bool hasStackMap() const

This method may be called any time after instruction selection is complete to determine if there is a...

uint8_t getStackID(int ObjectIdx) const

int64_t getObjectOffset(int ObjectIdx) const

Return the assigned stack offset of the specified object from the incoming stack pointer.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

const char * createExternalSymbolName(StringRef Name)

Allocate a string and populate it with the given external symbol name.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

const DataLayout & getDataLayout() const

Return the DataLayout attached to the Module associated to this MF.

Function & getFunction()

Return the LLVM function that this machine code represents.

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

MachineOperand class - Representation of each machine instruction operand.

Wrapper class representing virtual and physical registers.

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

bool hasFP(const MachineFunction &MF) const

hasFP - Return true if the specified function should have a dedicated frame pointer register.

virtual bool isSupportedStackID(TargetStackID::Value ID) const

const MCAsmInfo * getMCAsmInfo() const

Return target specific asm information.

static unsigned getOpcAdd(const MachineFunction &MF)

static unsigned getFPReg(const MachineFunction &MF)

bool needsPrologForEH(const MachineFunction &MF) const

static unsigned getOpcGlobSet(const MachineFunction &MF)

bool hasReservedCallFrame(const MachineFunction &MF) const override

Under normal circumstances, when a frame pointer is not required, we reserve argument space for call ...

static unsigned getOpcAnd(const MachineFunction &MF)

static unsigned getSPReg(const MachineFunction &MF)

static unsigned getOpcGlobGet(const MachineFunction &MF)

DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const override

Return the frame base information to be encoded in the DWARF subprogram debug info.

bool isSupportedStackID(TargetStackID::Value ID) const override

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...

static unsigned getOpcConst(const MachineFunction &MF)

bool hasFPImpl(const MachineFunction &MF) const override

Return true if the specified function should have a dedicated frame pointer register.

void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override

These methods insert prolog and epilog code into the function.

void writeSPToGlobal(unsigned SrcReg, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator &InsertStore, const DebugLoc &DL) const

Write SP back to __stack_pointer global.

void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override

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...

static std::optional< unsigned > getLocalForStackObject(MachineFunction &MF, int FrameIndex)

static unsigned getOpcSub(const MachineFunction &MF)

This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...

unsigned getFrameBaseLocal() const

const std::vector< MVT > & getLocals() const

bool isFrameBaseVirtual() const

const std::vector< MVT > & getParams() const

bool isArgument(unsigned Opc)

bool isWasmVarAddressSpace(unsigned AS)

This is an optimization pass for GlobalISel generic memory operations.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

@ Wasm

WebAssembly Exception Handling.

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())

ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...

This struct is a compact representation of a valid (non-zero power of two) alignment.

uint64_t value() const

This is a hole in the type system and should not be abused.

union llvm::TargetFrameLowering::DwarfFrameBase::@248 Location

enum llvm::TargetFrameLowering::DwarfFrameBase::FrameBaseKind Kind

struct WasmFrameBase WasmLoc