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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

39

40using namespace llvm;

41

42#define DEBUG_TYPE "rename-independent-subregs"

43

44namespace {

45

47public:

48 static char ID;

50

52 return "Rename Disconnected Subregister Components";

53 }

54

62 }

63

65

66private:

67 struct SubRangeInfo {

70 unsigned Index;

71

73 unsigned Index)

74 : ConEQ(LIS), SR(&SR), Index(Index) {}

75 };

76

77

78 bool renameComponents(LiveInterval &LI) const;

79

80

81

82

86

87

88

92

93

94 void computeMainRangesFixFlags(const IntEqClasses &Classes,

97

98

99 void rewriteOperands(const IntEqClasses &Classes,

102

103

107};

108

109}

110

111char RenameIndependentSubregs::ID;

112

114

116 "Rename Independent Subregisters", false, false)

121

122bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const {

123

124 if (LI.valnos.size() < 2)

125 return false;

126

129 if (!findComponents(Classes, SubRangeInfos, LI))

130 return false;

131

132

138 << " equivalence classes.\n");

140 for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses;

141 ++I) {

142 Register NewVReg = MRI->createVirtualRegister(RegClass);

143 LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg);

146 }

148

149 rewriteOperands(Classes, SubRangeInfos, Intervals);

150 distribute(Classes, SubRangeInfos, Intervals);

151 computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);

152 return true;

153}

154

155bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,

158

159

160 unsigned NumComponents = 0;

162 SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents));

164

165 unsigned NumSubComponents = ConEQ.Classify(SR);

166 NumComponents += NumSubComponents;

167 }

168

169

170

171 if (SubRangeInfos.size() < 2)

172 return false;

173

174

175

177 Classes.grow(NumComponents);

180 if (!MO.isDef() && !MO.readsReg())

181 continue;

182 unsigned SubRegIdx = MO.getSubReg();

183 LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);

184 unsigned MergedID = ~0u;

185 for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {

187 if ((SR.LaneMask & LaneMask).none())

188 continue;

189 SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());

190 Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())

193 if (VNI == nullptr)

194 continue;

195

196

197 unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);

198

199 unsigned ID = LocalID + SRInfo.Index;

200

201 MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID);

202 }

203 }

204

205

208 return NumClasses > 1;

209}

210

211void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,

215 unsigned Reg = Intervals[0]->reg();

217 E = MRI->reg_nodbg_end(); I != E; ) {

220 continue;

221

223 SlotIndex Pos = LIS->getInstructionIndex(*MI);

226 unsigned SubRegIdx = MO.getSubReg();

227 LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);

228

229 unsigned ID = ~0u;

230 for (const SubRangeInfo &SRInfo : SubRangeInfos) {

232 if ((SR.LaneMask & LaneMask).none())

233 continue;

235 if (VNI == nullptr)

236 continue;

237

238

239 unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);

240

241 ID = Classes[LocalID + SRInfo.Index];

242 break;

243 }

244

245 unsigned VReg = Intervals[ID]->reg();

247

248 if (MO.isTied() && Reg != VReg) {

249

250

251

253 unsigned TiedIdx = MI->findTiedOperandIdx(OperandNo);

254 MI->getOperand(TiedIdx).setReg(VReg);

255

256

257 I = MRI->reg_nodbg_begin(Reg);

258 }

259 }

260

261

262

263}

264

265void RenameIndependentSubregs::distribute(const IntEqClasses &Classes,

272 for (const SubRangeInfo &SRInfo : SubRangeInfos) {

274 unsigned NumValNos = SR.valnos.size();

275 VNIMapping.clear();

276 VNIMapping.reserve(NumValNos);

277 SubRanges.clear();

278 SubRanges.resize(NumClasses-1, nullptr);

279 for (unsigned I = 0; I < NumValNos; ++I) {

281 unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);

282 unsigned ID = Classes[LocalID + SRInfo.Index];

284 if (ID > 0 && SubRanges[ID-1] == nullptr)

285 SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask);

286 }

288 }

289}

290

294 return true;

295 }

296 return false;

297}

298

299void RenameIndependentSubregs::computeMainRangesFixFlags(

304 const SlotIndexes &Indexes = *LIS->getSlotIndexes();

305 for (size_t I = 0, E = Intervals.size(); I < E; ++I) {

308

310

311

312

313

315

316

317

318 for (unsigned I = 0; I < SR.valnos.size(); ++I) {

321 continue;

322

328 continue;

329

332 const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF);

335 SlotIndex DefIdx = LIS->InsertMachineInstrInMaps(*ImpDef);

342 }

343

344 if (Mask.none()) {

347 }

348 }

349 }

350 }

351

354 continue;

355 unsigned SubRegIdx = MO.getSubReg();

356 if (SubRegIdx == 0)

357 continue;

358

359

360

365 }

370 }

371 }

372

373 if (I == 0)

375 LIS->constructMainRangeFromSubranges(LI);

376

377

378

379

380 LIS->shrinkToUses(&LI);

381 }

382}

383

384bool RenameIndependentSubregs::runOnMachineFunction(MachineFunction &MF) {

385

387 if (MRI->subRegLivenessEnabled())

388 return false;

389

390 LLVM_DEBUG(dbgs() << "Renaming independent subregister live ranges in "

391 << MF.getName() << '\n');

392

393 LIS = &getAnalysis().getLIS();

395

396

397

398

399 bool Changed = false;

400 for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) {

402 if (!LIS->hasInterval(Reg))

403 continue;

406 continue;

407

408 Changed |= renameComponents(LI);

409 }

410

411 return Changed;

412}

unsigned const MachineRegisterInfo * MRI

const HexagonInstrInfo * TII

This file contains helper functions to modify live ranges.

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)

Rename Independent Subregisters

static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos)

Represent the analysis usage information of a pass.

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:

Allocate memory in an ever growing pool, as if by bump-pointer.

ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a LiveInterval into equivalence cl...

unsigned Classify(const LiveRange &LR)

Classify the values in LR into connected components.

void compress()

compress - Compress equivalence classes by numbering them 0 .

unsigned getNumClasses() const

getNumClasses - Return the number of equivalence classes after compress() was called.

unsigned join(unsigned a, unsigned b)

Join the equivalence classes of a and b.

void grow(unsigned N)

grow - Increase capacity to hold 0 .

A live range for subregisters.

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

void removeEmptySubRanges()

Removes all subranges without any segments (subranges without segments are not considered valid and s...

bool hasSubRanges() const

Returns true if subregister liveness information is available.

iterator_range< subrange_iterator > subranges()

SubRange * createSubRange(BumpPtrAllocator &Allocator, LaneBitmask LaneMask)

Creates a new empty subregister live range.

iterator addSegment(Segment S)

Add the specified Segment to this range, merging segments as appropriate.

bool liveAt(SlotIndex index) const

VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)

createDeadDef - Make sure the range has a value defined at Def.

VNInfo * getNextValue(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator)

getNextValue - Create a new value number and return it.

VNInfo * getVNInfoAt(SlotIndex Idx) const

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

Describe properties that are true of each instruction in the target description file.

iterator_range< pred_iterator > predecessors()

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.

virtual bool runOnMachineFunction(MachineFunction &MF)=0

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

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.

MachineOperand class - Representation of each machine instruction operand.

unsigned getSubReg() const

unsigned getOperandNo() const

Returns the index of this operand in the instruction that it belongs to.

bool readsReg() const

readsReg - Returns true if this operand reads the previous value of its register.

void setIsDead(bool Val=true)

void setReg(Register Reg)

Change the register this operand corresponds to.

MachineInstr * getParent()

getParent - Return the instruction that this operand belongs to.

void setIsUndef(bool Val=true)

bool isEarlyClobber() const

reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...

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

virtual StringRef getPassName() const

getPassName - Return a nice clean name for a pass.

Wrapper class representing virtual and physical registers.

static Register index2VirtReg(unsigned Index)

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

SlotIndex - An opaque wrapper around machine indexes.

SlotIndex getDeadSlot() const

Returns the dead def kill slot for the current instruction.

SlotIndex getBaseIndex() const

Returns the base index for associated with this index.

SlotIndex getPrevSlot() const

Returns the previous slot in the index list.

SlotIndex getRegSlot(bool EC=false) const

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

MachineBasicBlock * getMBBFromIndex(SlotIndex index) const

Returns the basic block which the given index falls in.

SlotIndex getMBBEndIdx(unsigned Num) const

Returns the last index in the given basic block number.

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

void reserve(size_type N)

void push_back(const T &Elt)

pointer data()

Return a pointer to the vector's buffer, even if empty().

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.

TargetInstrInfo - Interface to description of machine instruction set.

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

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

constexpr std::underlying_type_t< E > Mask()

Get a bitmask with 1s in all places up to the high-order bit of E's largest value.

unsigned ID

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

Reg

All possible values of the reg field in the ModR/M byte.

NodeAddr< DefNode * > Def

This is an optimization pass for GlobalISel generic memory operations.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

static void DistributeRange(LiveRangeT &LR, LiveRangeT *SplitLRs[], EqClassesT VNIClasses)

Helper function that distributes live range value numbers and the corresponding segments of a primary...

raw_ostream & dbgs()

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

MachineBasicBlock::iterator findPHICopyInsertPoint(MachineBasicBlock *MBB, MachineBasicBlock *SuccMBB, unsigned SrcReg)

findPHICopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg when following the CFG...

char & RenameIndependentSubregsID

This pass detects subregister lanes in a virtual register that are used independently of other lanes ...

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 represents a simple continuous liveness interval for a value.