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

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

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

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 }

256 return MBB.erase(I);

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

274 auto InsertPt = MBB.begin();

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

277 ++InsertPt;

279

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

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();

337 auto InsertPt = MBB.getFirstTerminator();

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();

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

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static constexpr MCPhysReg SPReg

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

MachineInstrBundleIterator< MachineInstr > iterator

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)

Definition WebAssemblyFrameLowering.cpp:198

static unsigned getFPReg(const MachineFunction &MF)

Definition WebAssemblyFrameLowering.cpp:185

bool needsPrologForEH(const MachineFunction &MF) const

Definition WebAssemblyFrameLowering.cpp:145

static unsigned getOpcGlobSet(const MachineFunction &MF)

Definition WebAssemblyFrameLowering.cpp:224

bool hasReservedCallFrame(const MachineFunction &MF) const override

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

Definition WebAssemblyFrameLowering.cpp:121

static unsigned getOpcAnd(const MachineFunction &MF)

Definition WebAssemblyFrameLowering.cpp:210

static unsigned getSPReg(const MachineFunction &MF)

Definition WebAssemblyFrameLowering.cpp:179

static unsigned getOpcGlobGet(const MachineFunction &MF)

Definition WebAssemblyFrameLowering.cpp:217

DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const override

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

Definition WebAssemblyFrameLowering.cpp:381

bool isSupportedStackID(TargetStackID::Value ID) const override

Definition WebAssemblyFrameLowering.cpp:370

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

Definition WebAssemblyFrameLowering.cpp:244

static unsigned getOpcConst(const MachineFunction &MF)

Definition WebAssemblyFrameLowering.cpp:192

bool hasFPImpl(const MachineFunction &MF) const override

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

Definition WebAssemblyFrameLowering.cpp:99

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

These methods insert prolog and epilog code into the function.

Definition WebAssemblyFrameLowering.cpp:259

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

Write SP back to __stack_pointer global.

Definition WebAssemblyFrameLowering.cpp:230

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

Definition WebAssemblyFrameLowering.cpp:329

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)

Definition WebAssemblyFrameLowering.cpp:52

static unsigned getOpcSub(const MachineFunction &MF)

Definition WebAssemblyFrameLowering.cpp:204

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

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

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.

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

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

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

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

constexpr uint64_t value() const

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