LLVM: lib/CodeGen/LocalStackSlotAllocation.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

36#include

37#include

38#include

39#include

40

41using namespace llvm;

42

43#define DEBUG_TYPE "localstackalloc"

44

45STATISTIC(NumAllocations, "Number of frame indices allocated into local block");

46STATISTIC(NumBaseRegisters, "Number of virtual frame base registers allocated");

47STATISTIC(NumReplacements, "Number of frame indices references replaced");

48

49namespace {

50

51 class FrameRef {

53 int64_t LocalOffset;

54 int FrameIdx;

55

56

57

58

59 unsigned Order;

60

61 public:

63 MI(I), LocalOffset(Offset), FrameIdx(Idx), Order(Ord) {}

64

66 return std::tie(LocalOffset, FrameIdx, Order) <

67 std::tie(RHS.LocalOffset, RHS.FrameIdx, RHS.Order);

68 }

69

71 int64_t getLocalOffset() const { return LocalOffset; }

72 int getFrameIndex() const { return FrameIdx; }

73 };

74

75 class LocalStackSlotImpl {

77

78

79 using StackObjSet = SmallSetVector<int, 8>;

80

82 bool StackGrowsDown, Align &MaxAlign);

84 SmallSet<int, 16> &ProtectedObjs,

85 MachineFrameInfo &MFI, bool StackGrowsDown,

86 int64_t &Offset, Align &MaxAlign);

87 void calculateFrameObjectOffsets(MachineFunction &Fn);

88 bool insertFrameReferenceRegisters(MachineFunction &Fn);

89

90 public:

91 bool runOnMachineFunction(MachineFunction &MF);

92 };

93

95 public:

96 static char ID;

97

98 explicit LocalStackSlotPass() : MachineFunctionPass(ID) {

100 }

101

102 bool runOnMachineFunction(MachineFunction &MF) override {

103 return LocalStackSlotImpl().runOnMachineFunction(MF);

104 }

105

106 void getAnalysisUsage(AnalysisUsage &AU) const override {

109 }

110 };

111

112}

113

117 bool Changed = LocalStackSlotImpl().runOnMachineFunction(MF);

122 return PA;

123}

124

125char LocalStackSlotPass::ID = 0;

126

129 "Local Stack Slot Allocation", false, false)

130

135

136

137

138 if (LocalObjectCount == 0 || TRI->requiresVirtualBaseRegisters(MF))

139 return false;

140

141

143

144

145 calculateFrameObjectOffsets(MF);

146

147

148 bool UsedBaseRegs = insertFrameReferenceRegisters(MF);

149

150

151

152

153

154

156

157 return true;

158}

159

160

161void LocalStackSlotImpl::AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx,

162 int64_t &Offset, bool StackGrowsDown,

163 Align &MaxAlign) {

164

165 if (StackGrowsDown)

167

169

170

171

172 MaxAlign = std::max(MaxAlign, Alignment);

173

174

176

177 int64_t LocalOffset = StackGrowsDown ? -Offset : Offset;

178 LLVM_DEBUG(dbgs() << "Allocate FI(" << FrameIdx << ") to local offset "

179 << LocalOffset << "\n");

180

181 LocalOffsets[FrameIdx] = LocalOffset;

182

184

185 if (!StackGrowsDown)

187

188 ++NumAllocations;

189}

190

191

192

193void LocalStackSlotImpl::AssignProtectedObjSet(

196 Align &MaxAlign) {

197 for (int i : UnassignedObjs) {

199 ProtectedObjs.insert(i);

200 }

201}

202

203

204

205void LocalStackSlotImpl::calculateFrameObjectOffsets(MachineFunction &Fn) {

206

209 bool StackGrowsDown =

213

214

215

219

220

221

222

223

225 "Stack protector pre-allocated in LocalStackSlotAllocation");

226

230

231

232

235 MaxAlign);

236

237

240 continue;

241 if (StackProtectorFI == (int)i)

242 continue;

244 continue;

245

248 continue;

250 SmallArrayObjs.insert(i);

251 continue;

253 AddrOfObjs.insert(i);

254 continue;

256 LargeArrayObjs.insert(i);

257 continue;

258 }

260 }

261

268 }

269

270

271

274 continue;

276 continue;

277 if (ProtectedObjs.count(i))

278 continue;

280 continue;

281

283 }

284

285

288}

289

291 int64_t FrameSizeAdjust,

292 int64_t LocalFrameOffset,

295

296

297 int64_t Offset = FrameSizeAdjust + LocalFrameOffset - BaseOffset;

298 return TRI->isFrameOffsetLegal(&MI, BaseReg, Offset);

299}

300

301bool LocalStackSlotImpl::insertFrameReferenceRegisters(MachineFunction &Fn) {

302

303

304

305

306

307

308

312 bool StackGrowsDown =

314

315

316

317

318

320

321 unsigned Order = 0;

322

325

326

327 if (MI.isDebugInstr() || MI.getOpcode() == TargetOpcode::STATEPOINT ||

328 MI.getOpcode() == TargetOpcode::STACKMAP ||

329 MI.getOpcode() == TargetOpcode::PATCHPOINT)

330 continue;

331

332

333

334

335

336

337

339

340

341 if (MO.isFI()) {

342

344 break;

345 int Idx = MO.getIndex();

346 int64_t LocalOffset = LocalOffsets[Idx];

347 if (TRI->needsFrameBaseReg(&MI, LocalOffset))

348 break;

349 FrameReferenceInsns.push_back(FrameRef(&MI, LocalOffset, Idx, Order++));

350 break;

351 }

352 }

353 }

354 }

355

356

357

359

361

363 int64_t BaseOffset = 0;

364

365

366 for (int ref = 0, e = FrameReferenceInsns.size(); ref < e ; ++ref) {

367 FrameRef &FR = FrameReferenceInsns[ref];

369 int64_t LocalOffset = FR.getLocalOffset();

370 int FrameIdx = FR.getFrameIndex();

372 "Only pre-allocated locals expected!");

373

374

375

376

377

380 continue;

381

383

384 unsigned idx = 0;

385 for (unsigned f = MI.getNumOperands(); idx != f; ++idx) {

386 if (MI.getOperand(idx).isFI())

387 continue;

388

389 if (FrameIdx == MI.getOperand(idx).getIndex())

390 break;

391 }

392

393 assert(idx < MI.getNumOperands() && "Cannot find FI operand");

394

396 int64_t FrameSizeAdjust = StackGrowsDown ? MFI.getLocalFrameSize() : 0;

397

399

400

401

402

403

404

407 LocalOffset, MI, TRI)) {

409 << "\n");

410

411 Offset = FrameSizeAdjust + LocalOffset - BaseOffset;

412 } else {

413

414 int64_t InstrOffset = TRI->getFrameIndexInstrOffset(&MI, idx);

415

416 int64_t CandBaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset;

417

418

419

420

421

422

423 if (ref + 1 >= e ||

425 BaseReg, CandBaseOffset, FrameSizeAdjust,

426 FrameReferenceInsns[ref + 1].getLocalOffset(),

428 continue;

429

430

431 BaseOffset = CandBaseOffset;

432

433

434

435

436 BaseReg = TRI->materializeFrameBaseRegister(Entry, FrameIdx, InstrOffset);

437

438 LLVM_DEBUG(dbgs() << " Materialized base register at frame local offset "

439 << LocalOffset + InstrOffset

440 << " into " << printReg(BaseReg, TRI) << '\n');

441

442

443

444

445 Offset = -InstrOffset;

446

447 ++NumBaseRegisters;

448 }

449 assert(BaseReg && "Unable to allocate virtual base register!");

450

451

452

453 TRI->resolveFrameIndex(MI, BaseReg, Offset);

455

456 ++NumReplacements;

457 }

458

459 return BaseReg.isValid();

460}

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

static MachineInstr * getMachineInstr(MachineInstr *MI)

static bool lookupCandidateBaseReg(Register BaseReg, int64_t BaseOffset, int64_t FrameSizeAdjust, int64_t LocalFrameOffset, const MachineInstr &MI, const TargetRegisterInfo *TRI)

Definition LocalStackSlotAllocation.cpp:290

Register const TargetRegisterInfo * TRI

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

static void AssignProtectedObjSet(const StackObjSet &UnassignedObjs, SmallSet< int, 16 > &ProtectedObjs, MachineFrameInfo &MFI, bool StackGrowsDown, int64_t &Offset, Align &MaxAlign)

AssignProtectedObjSet - Helper function to assign large stack objects (i.e., those required to be clo...

static void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, Align &MaxAlign)

AdjustStackOffset - Helper function used to adjust the stack frame offset.

SmallSetVector< int, 8 > StackObjSet

StackObjSet - A set of stack object indexes.

This file implements a set that has insertion order iteration characteristics.

This file defines the SmallSet class.

This file defines the SmallVector class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

LLVM_ABI void setPreservesCFG()

This function should be called by the pass, iff they do not:

Represents analyses that only rely on functions' control flow.

PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &)

Definition LocalStackSlotAllocation.cpp:115

MachineInstrBundleIterator< MachineInstr > iterator

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

SSPLayoutKind getObjectSSPLayout(int ObjectIdx) const

bool isObjectPreAllocated(int ObjectIdx) const

Return true if the object was pre-allocated into the local block.

void setUseLocalStackAllocationBlock(bool v)

setUseLocalStackAllocationBlock - Set whether the local allocation blob should be allocated together ...

void setLocalFrameSize(int64_t sz)

Set the size of the local object blob.

@ SSPLK_SmallArray

Array or nested array < SSP-buffer-size.

@ SSPLK_LargeArray

Array or nested array >= SSP-buffer-size.

@ SSPLK_AddrOf

The address of this allocation is exposed and triggered protection.

@ SSPLK_None

Did not trigger a stack protector.

void setLocalFrameMaxAlign(Align Alignment)

Required alignment of the local object blob, which is the strictest alignment of any object in it.

int getStackProtectorIndex() const

Return the index for the stack protector object.

Align getObjectAlign(int ObjectIdx) const

Return the alignment of the specified stack object.

void mapLocalFrameObject(int ObjectIndex, int64_t Offset)

Map a frame index into the local object block.

int64_t getObjectSize(int ObjectIdx) const

Return the size of the specified object.

int64_t getLocalFrameSize() const

Get the size of the local object blob.

int getObjectIndexEnd() const

Return one past the maximum frame object index.

bool hasStackProtectorIndex() const

uint8_t getStackID(int ObjectIdx) const

bool isDeadObjectIndex(int ObjectIdx) const

Returns true if the specified index corresponds to a dead object.

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

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.

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

static LLVM_ABI PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

Wrapper class representing virtual and physical registers.

bool insert(const value_type &X)

Insert a new element into the SetVector.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

size_type count(const T &V) const

count - Return 1 if the element is in the set, 0 otherwise.

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

void push_back(const T &Elt)

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

Information about stack frame layout on the target.

virtual bool isStackIdSafeForLocalArea(unsigned StackId) const

This method returns whether or not it is safe for an object with the given stack id to be bundled int...

StackDirection getStackGrowthDirection() const

getStackGrowthDirection - Return the direction the stack grows

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

virtual const TargetFrameLowering * getFrameLowering() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

BaseReg

Stack frame base register. Bit 0 of FREInfo.Info.

This is an optimization pass for GlobalISel generic memory operations.

bool operator<(int64_t V1, const APSInt &V2)

AnalysisManager< MachineFunction > MachineFunctionAnalysisManager

LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()

Returns the minimum set of Analyses that all machine function passes must preserve.

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI void initializeLocalStackSlotPassPass(PassRegistry &)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

LLVM_ABI char & LocalStackSlotAllocationID

LocalStackSlotAllocation - This pass assigns local frame indices to stack slots relative to one anoth...

Definition LocalStackSlotAllocation.cpp:127

LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)

Prints virtual and physical registers with or without a TRI instance.

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