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

1

2

3

4

5

6

7

8

9

10

11

12

13

36#include

37

38using namespace llvm;

39

40#define DEBUG_TYPE "regalloc"

41

44

45namespace {

46 struct CompSpillWeight {

48 return A->weight() < B->weight();

49 }

50 };

51}

52

53namespace {

54

55

56

57

58

62

64

65

66 std::unique_ptr SpillerInstance;

67 std::priority_queue<const LiveInterval *, std::vector<const LiveInterval *>,

68 CompSpillWeight>

70

71

72

74

77

78public:

80

81

83

84

86

88

89 Spiller &spiller() override { return *SpillerInstance; }

90

92

94 if (Queue.empty())

95 return nullptr;

98 return LI;

99 }

100

103

104

106

109 MachineFunctionProperties::Property::NoPHIs);

110 }

111

114 MachineFunctionProperties::Property::IsSSA);

115 }

116

117

118

119

122

123 static char ID;

124};

125

126char RABasic::ID = 0;

127

128}

129

131

133 false, false)

148

149bool RABasic::LRE_CanEraseVirtReg(Register VirtReg) {

150 LiveInterval &LI = LIS->getInterval(VirtReg);

151 if (VRM->hasPhys(VirtReg)) {

152 Matrix->unassign(LI);

153 aboutToRemoveInterval(LI);

154 return true;

155 }

156

157

158

159

161 return false;

162}

163

164void RABasic::LRE_WillShrinkVirtReg(Register VirtReg) {

165 if (!VRM->hasPhys(VirtReg))

166 return;

167

168

169 LiveInterval &LI = LIS->getInterval(VirtReg);

170 Matrix->unassign(LI);

171 enqueue(&LI);

172}

173

176

177void RABasic::getAnalysisUsage(AnalysisUsage &AU) const {

201}

202

203void RABasic::releaseMemory() {

204 SpillerInstance.reset();

205}

206

207

208

209

210

211bool RABasic::spillInterferences(const LiveInterval &VirtReg,

214

215

217

218

219 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {

222 if (!Intf->isSpillable() || Intf->weight() > VirtReg.weight())

223 return false;

225 }

226 }

228 << " interferences with " << VirtReg << "\n");

229 assert(!Intfs.empty() && "expected interference");

230

231

233

234 if (!VRM->hasPhys(Spill->reg()))

235 continue;

236

237

238

239 Matrix->unassign(*Spill);

240

241

242 LiveRangeEdit LRE(Spill, SplitVRegs, *MF, *LIS, VRM, this, &DeadRemats);

243 spiller().spill(LRE);

244 }

245 return true;

246}

247

248

249

250

251

252

253

254

255

256

257

258

259

262

264

265

266 auto Order =

270

271 switch (Matrix->checkInterference(VirtReg, PhysReg)) {

273

274 return PhysReg;

275

277

278 PhysRegSpillCands.push_back(PhysReg);

279 continue;

280

281 default:

282

283 continue;

284 }

285 }

286

287

288 for (MCRegister &PhysReg : PhysRegSpillCands) {

289 if (!spillInterferences(VirtReg, PhysReg, SplitVRegs))

290 continue;

291

292 assert(Matrix->checkInterference(VirtReg, PhysReg) &&

293 "Interference after spill.");

294

295 return PhysReg;

296 }

297

298

299 LLVM_DEBUG(dbgs() << "spilling: " << VirtReg << '\n');

301 return ~0u;

302 LiveRangeEdit LRE(&VirtReg, SplitVRegs, *MF, *LIS, VRM, this, &DeadRemats);

303 spiller().spill(LRE);

304

305

306

307 return 0;

308}

309

311 LLVM_DEBUG(dbgs() << "********** BASIC REGISTER ALLOCATION **********\n"

312 << "********** Function: " << mf.getName() << '\n');

313

314 MF = &mf;

315 auto &MBFI = getAnalysis().getMBFI();

316 auto &LiveStks = getAnalysis().getLS();

317 auto &MDT = getAnalysis().getDomTree();

318

320 getAnalysis().getLIS(),

321 getAnalysis().getLRM());

323 getAnalysis().getLI(), MBFI,

324 &getAnalysis().getPSI());

325 VRAI.calculateSpillWeightsAndHints();

326

327 SpillerInstance.reset(

329

330 allocatePhysRegs();

331 postOptimization();

332

333

334 LLVM_DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << *VRM << "\n");

335

336 releaseMemory();

337 return true;

338}

339

341 return new RABasic();

342}

343

345 return new RABasic(F);

346}

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

unsigned const TargetRegisterInfo * TRI

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

static RegisterRegAlloc basicRegAlloc("basic", "basic register allocator", createBasicRegisterAllocator)

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

A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.

static AllocationOrder create(unsigned VirtReg, const VirtRegMap &VRM, const RegisterClassInfo &RegClassInfo, const LiveRegMatrix *Matrix)

Create a new AllocationOrder for VirtReg.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequiredID(const void *ID)

AnalysisUsage & addPreservedID(const void *ID)

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

void setPreservesCFG()

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

FunctionPass class - This class is used to implement most global optimizations.

Query interferences between a single live virtual register and a live interval union.

const SmallVectorImpl< const LiveInterval * > & interferingVRegs(unsigned MaxInterferingRegs=std::numeric_limits< unsigned >::max())

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

bool isSpillable() const

isSpillable - Can this interval be spilled?

Callback methods for LiveRangeEdit owners.

virtual bool LRE_CanEraseVirtReg(Register)

Called when a virtual register is no longer used.

virtual void LRE_WillShrinkVirtReg(Register)

Called before shrinking the live range of a virtual register.

@ IK_VirtReg

Virtual register interference.

@ IK_Free

No interference, go ahead and assign.

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

constexpr bool isValid() const

Analysis pass which computes a MachineDominatorTree.

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

virtual MachineFunctionProperties getClearedProperties() const

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

virtual bool runOnMachineFunction(MachineFunction &MF)=0

runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...

virtual MachineFunctionProperties getRequiredProperties() const

Properties which a MachineFunction may have at a given point in time.

MachineFunctionProperties & set(Property P)

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

virtual StringRef getPassName() const

getPassName - Return a nice clean name for a pass.

virtual void releaseMemory()

releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...

An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.

RegAllocBase provides the register allocation driver and interface that can be extended to add intere...

virtual MCRegister selectOrSplit(const LiveInterval &VirtReg, SmallVectorImpl< Register > &splitLVRs)=0

void init(VirtRegMap &vrm, LiveIntervals &lis, LiveRegMatrix &mat)

virtual Spiller & spiller()=0

virtual const LiveInterval * dequeue()=0

dequeue - Return the next unassigned register, or NULL.

virtual void enqueueImpl(const LiveInterval *LI)=0

enqueue - Add VirtReg to the priority queue of unassigned registers.

Wrapper class representing virtual and physical registers.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

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

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

Calculate auxiliary information for a virtual register such as its spill weight and allocation hint.

unsigned ID

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

This is an optimization pass for GlobalISel generic memory operations.

std::function< bool(const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, const Register Reg)> RegAllocFilterFunc

Filter function for register classes during regalloc.

char & MachineDominatorsID

MachineDominators - This pass is a machine dominators analysis pass.

auto reverse(ContainerTy &&C)

raw_ostream & dbgs()

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

Spiller * createInlineSpiller(const Spiller::RequiredAnalyses &Analyses, MachineFunction &MF, VirtRegMap &VRM, VirtRegAuxInfo &VRAI)

Create and return a spiller that will insert spill code directly instead of deferring though VirtRegM...

FunctionPass * createBasicRegisterAllocator()

BasicRegisterAllocation Pass - This pass implements a degenerate global register allocator using the ...

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.

char & RABasicID

Basic register allocator.