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

66 return Sub == HSub ? HReg : Register();

67

71 return CopiedPReg;

72

73

74 if (Sub)

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

76

77 return 0;

78}

79

80

88 I != E; ++I) {

91 continue;

93 return false;

94

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

97

98

99

100

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

102

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

104 return false;

105

106

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

108

109

110

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

112 return false;

113

114

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

120 return false;

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

123 }

124

125 if (TII.isTriviallyReMaterializable(*MI))

126 return false;

127 }

128 return true;

129}

130

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

134 MachineInstr *MI = MO.getParent();

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

136 return false;

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

138 });

139}

140

143

144 if (Weight < 0)

145 return;

147}

148

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

154 return true;

155 }

156

157 return false;

158}

159

166 float TotalWeight = 0;

167 unsigned NumInstr = 0;

169

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

171

176

177

178

181 }

182

183

185

186 bool IsLocalSplitArtifact = Start && End;

187

188

189 bool ShouldUpdateLI = !IsLocalSplitArtifact;

190

191 if (IsLocalSplitArtifact) {

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

195

196

197

198

199

200

201 TotalWeight +=

203 TotalWeight +=

205

206 NumInstr += 2;

207 }

208

209

210 struct CopyHint {

212 float Weight;

213 CopyHint(Register R, float W) : Reg(R), Weight(W) {}

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

215

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

217 return Reg.isPhysical();

218 if (Weight != Rhs.Weight)

219 return (Weight > Rhs.Weight);

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

221 }

222 };

223

224 bool IsExiting = false;

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

228 E = MRI.reg_instr_nodbg_end();

229 I != E;) {

231

232

233

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

236 continue;

237

238 NumInstr++;

239 bool identityCopy = false;

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

241 if (DestSrc) {

242 const MachineOperand *DestRegOp = DestSrc->Destination;

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

246 }

247

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

249 continue;

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

251 continue;

252

253

254

255 if (TII.isUnspillableTerminator(MI) &&

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

258 return -1.0f;

259 }

260

261

263 if (IsSpillable) {

264

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

266 MBB = MI->getParent();

269 }

270

271

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

275

276

278 Weight *= 3;

279

280 TotalWeight += Weight;

281 }

282

283

284 if (TII.isCopyInstr(*MI))

285 continue;

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

288 Hint[HintReg] += Weight;

289 }

290

291

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

293

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

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

296

297

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

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

301 if (Reg != SkipReg)

303 }

304 sort(RegHints);

305 for (const auto &[Reg, Weight] : RegHints)

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

307

308

309 TotalWeight *= 1.01F;

310 }

311

312

313 if (!IsSpillable)

314 return -1.0;

315

316

317

318

319

320

321

322

323

328 return -1.0;

329 }

330

331

332

333

334

336 TotalWeight *= 0.5F;

337

338 if (IsLocalSplitArtifact)

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

341}

unsigned const MachineRegisterInfo * MRI

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

SmallVector< uint32_t, 0 > Writes

const HexagonInstrInfo * TII

unsigned const TargetRegisterInfo * TRI

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

This file defines the SmallPtrSet class.

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?

unsigned getSize() const

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

void setWeight(float Value)

MachineInstr * getInstructionFromIndex(SlotIndex index) const

Returns the instruction associated with the given index.

SlotIndexes * getSlotIndexes() const

SlotIndex getInstructionIndex(const MachineInstr &Instr) const

Returns the base index of the given instruction.

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

ArrayRef< SlotIndex > getRegMaskSlots() const

Returns a sorted array of slot indices of all instructions with register mask operands.

LiveInterval & getInterval(Register Reg)

bool isLiveOutOfMBB(const LiveRange &LR, const MachineBasicBlock *mbb) const

MachineBasicBlock * getMBBFromIndex(SlotIndex index) const

Result of a LiveRange query.

VNInfo * valueIn() const

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

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.

bool isLoopExiting(const BlockT *BB) const

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

LoopT * getLoopFor(const BlockT *BB) const

Return the inner most loop that BB lives in.

Represents a single loop in the control flow graph.

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

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.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

unsigned getSubReg() const

Register getReg() const

getReg - Returns the register number.

defusechain_iterator - This class provides iterator support for machine operands in the function that...

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

iterator_range< reg_iterator > reg_operands(Register Reg) const

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.

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

virtual const TargetRegisterInfo * getRegisterInfo() const

getRegisterInfo - If register information is available, return it.

virtual const TargetInstrInfo * getInstrInfo() const

VNInfo - Value Number Information.

bool isUnused() const

Returns true if this value is unused.

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 Register copyHint(const MachineInstr *MI, unsigned Reg, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI)

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

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

Helper function for weight calculations.

void calculateSpillWeightsAndHints()

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

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

Weight normalization function.

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

Determine if all values in LI are rematerializable.

void calculateSpillWeightAndHint(LiveInterval &LI)

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

Register getOriginal(Register VirtReg) const

getOriginal - Return the original virtual register that VirtReg descends from through splitting.

MachineRegisterInfo & getRegInfo() const

This is an optimization pass for GlobalISel generic memory operations.

float stack_float_t

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

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)

raw_ostream & dbgs()

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