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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

37

38using namespace llvm;

39

40#define DEBUG_TYPE "stack-frame-layout"

41

42namespace {

43

44

45

46

47struct StackFrameLayoutAnalysis {

50

52

53 enum SlotType {

54 Spill,

55 Fixed,

56 VariableSized,

58 Variable,

59 Invalid

60 };

61

62 struct SlotData {

63 int Slot;

67 SlotType SlotTy;

68 bool Scalable;

69

71 const int Idx)

74 SlotTy(Invalid), Scalable(false) {

77 SlotTy = SlotType::Spill;

79 SlotTy = SlotType::Fixed;

81 SlotTy = SlotType::VariableSized;

84 SlotTy = SlotType::StackProtector;

85 else

86 SlotTy = SlotType::Variable;

87 }

88

89 bool isVarSize() const { return SlotTy == SlotType::VariableSized; }

90

91

92

93

94

95

96 bool operator<(const SlotData &Rhs) const {

97 return std::make_tuple(!isVarSize(),

98 Offset.getFixed() + Offset.getScalable(), Slot) >

99 std::make_tuple(!Rhs.isVarSize(),

100 Rhs.Offset.getFixed() + Rhs.Offset.getScalable(),

101 Rhs.Slot);

102 }

103 };

104

106

107

109 return false;

110

112 if (!Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(DEBUG_TYPE))

113 return false;

114

118 Rem << ("\nFunction: " + MF.getName()).str();

119 emitStackFrameLayoutRemarks(MF, Rem);

120 ORE.emit(Rem);

121 return false;

122 }

123

125 switch (Ty) {

126 case SlotType::Spill:

127 return "Spill";

128 case SlotType::Fixed:

129 return "Fixed";

130 case SlotType::VariableSized:

131 return "VariableSized";

132 case SlotType::StackProtector:

133 return "Protector";

134 case SlotType::Variable:

135 return "Variable";

136 default:

138 }

139 }

140

141 void emitStackSlotRemark(const MachineFunction &MF, const SlotData &D,

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171 std::string Prefix =

172 formatv("\nOffset: [SP{0}", (D.Offset.getFixed() < 0) ? "" : "+").str();

173 Rem << Prefix << ore::NV("Offset", D.Offset.getFixed());

174

175 if (D.Offset.getScalable()) {

176 Rem << ((D.Offset.getScalable() < 0) ? "" : "+")

177 << ore::NV("ScalableOffset", D.Offset.getScalable()) << " x vscale";

178 }

179

181 << ", Align: " << ore::NV("Align", D.Align)

183 }

184

187 std::string Loc =

188 formatv("{0} @ {1}:{2}", N->getName(), N->getFilename(), N->getLine())

189 .str();

190 Rem << "\n " << ore::NV("DataLoc", Loc);

191 }

192

196 if (!FI)

198

200 }

201

206 return;

207

209

212

213 std::vector SlotInfo;

214

216 SlotInfo.reserve(NumObj);

217

219 Idx != EndIdx; ++Idx) {

221 continue;

222 SlotInfo.emplace_back(MFI, getStackOffset(MF, MFI, FI, Idx), Idx);

223 }

224

225

227

228 SlotDbgMap SlotMap = genSlotDbgMapping(MF);

229

230 for (const SlotData &Info : SlotInfo) {

231 emitStackSlotRemark(MF, Info, Rem);

233 emitSourceLocRemark(MF, N, Rem);

234 }

235 }

236

237

238

239

241 SlotDbgMap SlotDebugMap;

242

243

246 SlotDebugMap[DI.getStackSlot()].insert(DI.Var);

247

248

252 if (!MO->isStore())

253 continue;

255 MO->getPseudoValue());

256 if (!FI)

257 continue;

258 int FrameIdx = FI->getFrameIndex();

260 MI.collectDebugValues(Dbg);

261

263 SlotDebugMap[FrameIdx].insert(MI->getDebugVariable());

264 }

265 }

266 }

267

268 return SlotDebugMap;

269 }

270};

271

273public:

274 static char ID;

275

277

278 StringRef getPassName() const override {

279 return "Stack Frame Layout Analysis";

280 }

281

282 void getAnalysisUsage(AnalysisUsage &AU) const override {

286 }

287

288 bool runOnMachineFunction(MachineFunction &MF) override {

289 auto &ORE = getAnalysis().getORE();

290 return StackFrameLayoutAnalysis(ORE).run(MF);

291 }

292};

293

294char StackFrameLayoutAnalysisLegacy::ID = 0;

295}

296

301 StackFrameLayoutAnalysis(ORE).run(MF);

303}

304

307 "Stack Frame Layout", false, false)

308

309

311 return new StackFrameLayoutAnalysisLegacy();

312}

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

Analysis containing CSE Info

static std::string getTypeString(Type *T)

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

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

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

void setPreservesAll()

Set by analyses that do not transform their input at all.

static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)

DISubprogram * getSubprogram() const

Get the attached subprogram.

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

This is an important class for using LLVM in a threaded context.

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

bool hasScalableStackID(int ObjectIdx) const

int getStackProtectorIndex() const

Return the index for the stack protector object.

Align getObjectAlign(int ObjectIdx) const

Return the alignment of the specified stack object.

bool isSpillSlotObjectIndex(int ObjectIdx) const

Returns true if the specified index corresponds to a spill slot.

int64_t getObjectSize(int ObjectIdx) const

Return the size of the specified object.

unsigned getNumObjects() const

Return the number of objects.

bool isVariableSizedObjectIndex(int ObjectIdx) const

Returns true if the specified index corresponds to a variable sized object.

int getObjectIndexEnd() const

Return one past the maximum frame object index.

bool hasStackProtectorIndex() const

bool hasStackObjects() const

Return true if there are any stack objects in this function.

int64_t getObjectOffset(int ObjectIdx) const

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

bool isFixedObjectIndex(int ObjectIdx) const

Returns true if the specified index corresponds to a fixed stack object.

int getObjectIndexBegin() const

Return the minimum frame object index.

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.

Description of the location of a variable whose Address is valid and unchanging during function execu...

const TargetSubtargetInfo & getSubtarget() const

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

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

MachineFrameInfo & getFrameInfo()

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

auto getInStackSlotVariableDbgInfo()

Returns the collection of variables for which we have debug info and that have been assigned a stack ...

Function & getFunction()

Return the LLVM function that this machine code represents.

const MachineBasicBlock & front() const

Representation of each machine instruction.

A description of a memory reference used in the backend.

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.

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

PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)

Definition StackFrameLayoutAnalysisPass.cpp:298

StackOffset holds a fixed and a scalable offset in bytes.

int64_t getFixed() const

Returns the fixed component of the stack.

StringRef - Represent a constant reference to a string, i.e.

Information about stack frame layout on the target.

virtual StackOffset getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI) const

getFrameIndexReferenceFromSP - This method returns the offset from the stack pointer to the slot of t...

virtual const TargetFrameLowering * getFrameLowering() const

#define llvm_unreachable(msg)

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

unsigned ID

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

DiagnosticInfoOptimizationBase::Argument NV

This is an optimization pass for GlobalISel generic memory operations.

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

LLVM_ABI MachineFunctionPass * createStackFrameLayoutAnalysisPass()

StackFramePrinter pass - This pass prints out the machine function's stack frame to the given stream ...

AnalysisManager< MachineFunction > MachineFunctionAnalysisManager

auto dyn_cast_or_null(const Y &Val)

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

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

bool isFunctionInPrintList(StringRef FunctionName)

LLVM_ABI char & StackFrameLayoutAnalysisPassID

StackFramePrinter - This pass prints the stack frame layout and variable mappings.

Definition StackFrameLayoutAnalysisPass.cpp:305

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.