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

1

2

3

4

5

6

7

8

26#include

27#include

28

29using namespace llvm;

30

31#define DEBUG_TYPE "calcspillweights"

32

34 LLVM_DEBUG(dbgs() << "********** Compute Spill Weights **********\n"

35 << "********** Function: " << MF.getName() << '\n');

36

38 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {

40 if (MRI.reg_nodbg_empty(Reg))

41 continue;

43 }

44}

45

46

50 unsigned Sub, HSub;

52 if (MI->getOperand(0).getReg() == Reg) {

53 Sub = MI->getOperand(0).getSubReg();

54 HReg = MI->getOperand(1).getReg();

55 HSub = MI->getOperand(1).getSubReg();

56 } else {

57 Sub = MI->getOperand(1).getSubReg();

58 HReg = MI->getOperand(0).getReg();

59 HSub = MI->getOperand(0).getSubReg();

60 }

61

62 if (!HReg)

63 return 0;

64

67

71 return CopiedPReg;

72

73

75 return TRI.getMatchingSuperReg(CopiedPReg, Sub, RC);

76

78}

79

80

87 Register Original = VRM.getOriginal(Reg);

90 I != E; ++I) {

92 const VNInfo *OrigVNI = VNI;

94 continue;

96 return false;

97

99 assert(MI && "Dead valno in interval");

100

101

102

103

104 while (TII.isFullCopyInstr(*MI)) {

105

106 if (MI->getOperand(0).getReg() != Reg)

107 return false;

108

109

110 Reg = MI->getOperand(1).getReg();

111

112

113

114 if (!Reg.isVirtual() || VRM.getOriginal(Reg) != Original)

115 return false;

116

117

118 const LiveInterval &SrcLI = LIS.getInterval(Reg);

121 assert(VNI && "Copy from non-existing value");

123 return false;

124 MI = LIS.getInstructionFromIndex(VNI->def);

125 assert(MI && "Dead valno in interval");

126 }

127

128 if (TII.isReMaterializable(*MI))

129 return false;

130

131 VNIDefs[OrigVNI->id] = MI;

132 }

133

134

135

137 if (!MO.readsReg())

138 continue;

139 SlotIndex UseIdx = LIS.getInstructionIndex(*MO.getParent());

141 assert(Def && "Use with no def");

143 return false;

144 }

145

146 return true;

147}

148

155 UseIdx = std::max(UseIdx, UseIdx.getRegSlot(true));

157 if (!MO.isReg() || !MO.getReg() || !MO.readsReg())

158 continue;

159

160

161

162 if (MO.getReg().isPhysical()) {

163 if (MRI.isConstantPhysReg(MO.getReg()) || TII.isIgnorableUse(MO))

164 continue;

165 return false;

166 }

167

168 const LiveInterval &li = LIS.getInterval(MO.getReg());

170 if (!OVNI)

171 continue;

172

173

174

175

177 return false;

178

180 return false;

181

182

185 unsigned SubReg = MO.getSubReg();

187 : MRI.getMaxLaneMaskForVReg(MO.getReg());

189 if ((SR.LaneMask & LM).none())

190 continue;

191 if (!SR.liveAt(UseIdx))

192 return false;

193

194 LM &= ~SR.LaneMask;

195 if (LM.none())

196 break;

197 }

198 }

199 }

200 return true;

201}

202

203bool VirtRegAuxInfo::isLiveAtStatepointVarArg(LiveInterval &LI) {

206 MachineInstr *MI = MO.getParent();

207 if (MI->getOpcode() != TargetOpcode::STATEPOINT)

208 return false;

209 return StatepointOpers(MI).getVarIdx() <= MO.getOperandNo();

210 });

211}

212

215

216 if (Weight < 0)

217 return;

219}

220

225 if (MI->isInlineAsm() && MI->mayFoldInlineAsmRegOp(MI->getOperandNo(&MO)))

226 return true;

227 }

228

229 return false;

230}

231

238 float TotalWeight = 0;

239 unsigned NumInstr = 0;

241

242 std::pair<unsigned, Register> TargetHint = MRI.getRegAllocationHint(LI.reg());

243

246 Register Original = VRM.getOriginal(Reg);

247 const LiveInterval &OrigInt = LIS.getInterval(Original);

248

249

250

253 }

254

255

257

258 bool IsLocalSplitArtifact = Start && End;

259

260

261 bool ShouldUpdateLI = !IsLocalSplitArtifact;

262

263 if (IsLocalSplitArtifact) {

265 assert(LocalMBB == LIS.getMBBFromIndex(*Start) &&

266 "start and end are expected to be in the same basic block");

267

268

269

270

271

272

273 TotalWeight +=

275 TotalWeight +=

277

278 NumInstr += 2;

279 }

280

281

282 struct CopyHint {

284 float Weight;

285 bool IsCSR;

286 CopyHint(Register R, float W, bool IsCSR)

287 : Reg(R), Weight(W), IsCSR(IsCSR) {}

288 bool operator<(const CopyHint &Rhs) const {

289

290 if (Reg.isPhysical() != Rhs.Reg.isPhysical())

291 return Reg.isPhysical();

292 if (Weight != Rhs.Weight)

293 return (Weight > Rhs.Weight);

294

295 if (Reg.isPhysical() && IsCSR != Rhs.IsCSR)

296 return !IsCSR;

297 return Reg.id() < Rhs.Reg.id();

298 }

299 };

300

301 bool IsExiting = false;

304 I = MRI.reg_instr_nodbg_begin(LI.reg()),

305 E = MRI.reg_instr_nodbg_end();

306 I != E;) {

308

309

310

312 if (IsLocalSplitArtifact && ((SI < *Start) || (SI > *End)))

313 continue;

314

315 NumInstr++;

316 bool identityCopy = false;

317 auto DestSrc = TII.isCopyInstr(*MI);

318 if (DestSrc) {

319 const MachineOperand *DestRegOp = DestSrc->Destination;

321 identityCopy = DestRegOp->getReg() == SrcRegOp->getReg() &&

323 }

324

325 if (identityCopy || MI->isImplicitDef())

326 continue;

327 if (!Visited.insert(MI).second)

328 continue;

329

330

331

332 if (TII.isUnspillableTerminator(MI) &&

333 MI->definesRegister(LI.reg(), nullptr)) {

335 return -1.0f;

336 }

337

338

340 if (IsSpillable) {

341

342 if (MI->getParent() != MBB) {

343 MBB = MI->getParent();

346 }

347

348

349 bool Reads, Writes;

350 std::tie(Reads, Writes) = MI->readsWritesVirtualRegister(LI.reg());

352

353

354 if (Writes && IsExiting && LIS.isLiveOutOfMBB(LI, MBB))

355 Weight *= 3;

356

357 TotalWeight += Weight;

358 }

359

360

361 if (TII.isCopyInstr(*MI))

362 continue;

364 if (HintReg && (HintReg.isVirtual() || MRI.isAllocatable(HintReg)))

365 Hint[HintReg] += Weight;

366 }

367

368

369 if (ShouldUpdateLI && Hint.size()) {

370

371 if (TargetHint.first == 0 && TargetHint.second)

372 MRI.clearSimpleHint(LI.reg());

373

374

375 Register SkipReg = TargetHint.first != 0 ? TargetHint.second : Register();

377 for (const auto &[Reg, Weight] : Hint) {

378 if (Reg != SkipReg)

380 Reg, Weight,

381 Reg.isPhysical() ? TRI.isCalleeSavedPhysReg(Reg, MF) : false);

382 }

383 sort(RegHints);

384 for (const auto &[Reg, _, __] : RegHints)

385 MRI.addRegAllocationHint(LI.reg(), Reg);

386

387

388 TotalWeight *= 1.01F;

389 }

390

391

392 if (!IsSpillable)

393 return -1.0;

394

395

396

397

398

399

400

401

402

403 if (ShouldUpdateLI && LI.isZeroLength(LIS.getSlotIndexes()) &&

407 return -1.0;

408 }

409

410

411

412

413

415 TotalWeight *= 0.5F;

416

417

419 TotalWeight *= TRI.getSpillWeightScaleFactor(RC);

420

421 if (IsLocalSplitArtifact)

422 return normalize(TotalWeight, Start->distance(*End), NumInstr);

424}

unsigned const MachineRegisterInfo * MRI

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

const TargetInstrInfo & TII

static bool canMemFoldInlineAsm(LiveInterval &LI, const MachineRegisterInfo &MRI)

Definition CalcSpillWeights.cpp:221

Register const TargetRegisterInfo * TRI

Promote Memory to Register

This file defines the SmallPtrSet class.

A live range for subregisters.

LiveInterval - This class represents the liveness of a register, or stack slot.

void markNotSpillable()

markNotSpillable - Mark interval as not spillable

bool isSpillable() const

isSpillable - Can this interval be spilled?

bool hasSubRanges() const

Returns true if subregister liveness information is available.

LLVM_ABI unsigned getSize() const

getSize - Returns the sum of sizes of all the LiveRange's.

iterator_range< subrange_iterator > subranges()

void setWeight(float Value)

static LLVM_ABI float getSpillWeight(bool isDef, bool isUse, const MachineBlockFrequencyInfo *MBFI, const MachineInstr &MI, ProfileSummaryInfo *PSI=nullptr)

Calculate the spill weight to assign to a single instruction.

Result of a LiveRange query.

VNInfo * valueIn() const

Return the value that is live-in to the instruction.

LLVM_ABI bool isLiveAtIndexes(ArrayRef< SlotIndex > Slots) const

bool isZeroLength(SlotIndexes *Indexes) const

Returns true if the live range is zero length, i.e.

LiveQueryResult Query(SlotIndex Idx) const

Query Liveness at Idx.

VNInfoList::const_iterator const_vni_iterator

VNInfo * getVNInfoAt(SlotIndex Idx) const

getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.

bool isLoopExiting(const BlockT *BB) const

True if terminator in the block can branch to another block that is outside of the current loop.

Represents a single loop in the control flow graph.

Wrapper class representing physical registers. Should be passed by value.

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

unsigned getSubReg() const

Register getReg() const

getReg - Returns the register number.

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

iterator_range< reg_iterator > reg_operands(Register Reg) const

defusechain_instr_iterator< true, true, true, true > reg_instr_nodbg_iterator

reg_instr_nodbg_iterator/reg_instr_nodbg_begin/reg_instr_nodbg_end - Walk all defs and uses of the sp...

Wrapper class representing virtual and physical registers.

static Register index2VirtReg(unsigned Index)

Convert a 0-based index to a virtual register number.

MCRegister asMCReg() const

Utility to check-convert this value to a MCRegister.

constexpr bool isVirtual() const

Return true if the specified register number is in the virtual register namespace.

SlotIndex - An opaque wrapper around machine indexes.

static bool isSameInstr(SlotIndex A, SlotIndex B)

isSameInstr - Return true if A and B refer to the same instruction.

SlotIndex getRegSlot(bool EC=false) const

Returns the register use/def slot in the current instruction for a normal or early-clobber def.

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

reference emplace_back(ArgTypes &&... Args)

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

TargetInstrInfo - Interface to description of machine instruction set.

bool contains(Register Reg) const

Return true if the specified register is included in this register class.

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

VNInfo - Value Number Information.

bool isUnused() const

Returns true if this value is unused.

unsigned id

The ID number of this value.

SlotIndex def

The index of the defining instruction.

bool isPHIDef() const

Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...

static bool allUsesAvailableAt(const MachineInstr *MI, SlotIndex UseIdx, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)

Definition CalcSpillWeights.cpp:149

float weightCalcHelper(LiveInterval &LI, SlotIndex *Start=nullptr, SlotIndex *End=nullptr)

Helper function for weight calculations.

Definition CalcSpillWeights.cpp:232

void calculateSpillWeightsAndHints()

Compute spill weights and allocation hints for all virtual register live intervals.

Definition CalcSpillWeights.cpp:33

static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, const VirtRegMap &VRM, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)

Determine if all values in LI are rematerializable.

Definition CalcSpillWeights.cpp:81

virtual float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr)

Weight normalization function.

static Register copyHint(const MachineInstr *MI, Register Reg, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI)

Return the preferred allocation register for reg, given a COPY instruction.

Definition CalcSpillWeights.cpp:47

void calculateSpillWeightAndHint(LiveInterval &LI)

(re)compute li's spill weight and allocation hint.

Definition CalcSpillWeights.cpp:213

MachineRegisterInfo & getRegInfo() const

This is an optimization pass for GlobalISel generic memory operations.

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

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 sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

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

@ Sub

Subtraction of integers.

float stack_float_t

Type to force float point values onto the stack, so that x86 doesn't add hidden precision,...

constexpr bool none() const