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

40

41using namespace llvm;

42

43#define DEBUG_TYPE "rename-independent-subregs"

44

45namespace {

46

47class RenameIndependentSubregs {

48public:

49 RenameIndependentSubregs(LiveIntervals *LIS) : LIS(LIS) {}

50

52

53private:

54 struct SubRangeInfo {

57 unsigned Index;

58

60 unsigned Index)

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

62 };

63

64

65 bool renameComponents(LiveInterval &LI) const;

66

67

68

69

73

74

75

79

80

81 void computeMainRangesFixFlags(const IntEqClasses &Classes,

84

85

86 void rewriteOperands(const IntEqClasses &Classes,

89

90

94};

95

97public:

98 static char ID;

101 StringRef getPassName() const override {

102 return "Rename Disconnected Subregister Components";

103 }

104

105 void getAnalysisUsage(AnalysisUsage &AU) const override {

112 }

113};

114

115}

116

117char RenameIndependentSubregsLegacy::ID;

118

120

122 "Rename Independent Subregisters", false, false)

127

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

129

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

131 return false;

132

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

136 return false;

137

138

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

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

147 ++I) {

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

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

152 }

154

155 rewriteOperands(Classes, SubRangeInfos, Intervals);

156 distribute(Classes, SubRangeInfos, Intervals);

157 computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);

158 return true;

159}

160

161bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,

164

165

166 unsigned NumComponents = 0;

167 for (LiveInterval::SubRange &SR : LI.subranges()) {

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

169 ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ;

170

171 unsigned NumSubComponents = ConEQ.Classify(SR);

172 NumComponents += NumSubComponents;

173 }

174

175

176

177 if (SubRangeInfos.size() < 2)

178 return false;

179

180

181

182 const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();

183 Classes.grow(NumComponents);

185 for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {

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

187 continue;

188 unsigned SubRegIdx = MO.getSubReg();

189 LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);

190 unsigned MergedID = ~0u;

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

192 const LiveInterval::SubRange &SR = *SRInfo.SR;

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

194 continue;

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

199 if (VNI == nullptr)

200 continue;

201

202

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

204

205 unsigned ID = LocalID + SRInfo.Index;

206

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

208 }

209 }

210

211

214 return NumClasses > 1;

215}

216

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

218 const SmallVectorImpl &SubRangeInfos,

219 const SmallVectorImpl<LiveInterval*> &Intervals) const {

220 const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();

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

224 MachineOperand &MO = *I++;

226 continue;

227

232 unsigned SubRegIdx = MO.getSubReg();

233 LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);

234

235 unsigned ID = ~0u;

236 for (const SubRangeInfo &SRInfo : SubRangeInfos) {

237 const LiveInterval::SubRange &SR = *SRInfo.SR;

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

239 continue;

241 if (VNI == nullptr)

242 continue;

243

244

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

246

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

248 break;

249 }

250

251 Register VReg = Intervals[ID]->reg();

253

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

255

256

257

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

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

261

262

263 I = MRI->reg_nodbg_begin(Reg);

264 }

265 }

266

267

268

269}

270

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

272 const SmallVectorImpl &SubRangeInfos,

273 const SmallVectorImpl<LiveInterval*> &Intervals) const {

275 SmallVector<unsigned, 8> VNIMapping;

278 for (const SubRangeInfo &SRInfo : SubRangeInfos) {

279 LiveInterval::SubRange &SR = *SRInfo.SR;

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

281 VNIMapping.clear();

282 VNIMapping.reserve(NumValNos);

283 SubRanges.clear();

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

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

286 const VNInfo &VNI = *SR.valnos[I];

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

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

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

292 }

294 }

295}

296

300 return true;

301 }

302 return false;

303}

304

305void RenameIndependentSubregs::computeMainRangesFixFlags(

306 const IntEqClasses &Classes,

307 const SmallVectorImpl &SubRangeInfos,

308 const SmallVectorImpl<LiveInterval*> &Intervals) const {

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

313 LiveInterval &LI = *Intervals[I];

315

317

318

319

320

321 LaneBitmask UsedMask, UnusedMask;

322 for (LiveInterval::SubRange &SR : LI.subranges())

324 SmallVector SubRegIdxs;

325 unsigned Flags = 0;

327

328 if (TRI.getCoveringSubRegIndexes(MRI->getRegClass(Reg), UsedMask,

329 SubRegIdxs) &&

330 SubRegIdxs.size() == 1) {

333 } else {

334 UnusedMask = MRI->getMaxLaneMaskForVReg(Reg) & ~UsedMask;

335 }

336

337

338

339

340 for (const LiveInterval::SubRange &SR : LI.subranges()) {

341

342

343

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

345 const VNInfo &VNI = *SR.valnos[I];

347 continue;

348

349 SlotIndex Def = VNI.def;

352 SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB);

354 continue;

355

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

359 MachineInstrBuilder ImpDef =

363 SlotIndex RegDefIdx = DefIdx.getRegSlot();

364 for (LiveInterval::SubRange &SR : LI.subranges()) {

366 SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI));

367 }

368 if (!UnusedMask.none()) {

369 LiveInterval::SubRange *SR =

372 }

373 }

374 }

375 }

376

377 for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {

379 continue;

380 unsigned SubRegIdx = MO.getSubReg();

381 if (SubRegIdx == 0)

382 continue;

383

384

385

390 }

395 }

396 }

397

398 if (I == 0)

401

402

403

404

406 }

407}

408

409PreservedAnalyses

413 if (!RenameIndependentSubregs(&LIS).run(MF))

419 return PA;

420}

421

422bool RenameIndependentSubregsLegacy::runOnMachineFunction(MachineFunction &MF) {

423 auto &LIS = getAnalysis().getLIS();

424 return RenameIndependentSubregs(&LIS).run(MF);

425}

426

428

430 if (MRI->subRegLivenessEnabled())

431 return false;

432

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

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

435

437

438

439

440

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

445 continue;

448 continue;

449

450 Changed |= renameComponents(LI);

451 }

452

454}

unsigned const MachineRegisterInfo * MRI

const TargetInstrInfo & TII

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

This file contains helper functions to modify live ranges.

Register const TargetRegisterInfo * TRI

Promote Memory to Register

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

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

Definition RenameIndependentSubregs.cpp:297

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()

AnalysisUsage & addPreserved()

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

LLVM_ABI void setPreservesCFG()

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

Represents analyses that only rely on functions' control flow.

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

LLVM_ABI unsigned Classify(const LiveRange &LR)

Classify the values in LR into connected components.

LLVM_ABI void compress()

compress - Compress equivalence classes by numbering them 0 .

unsigned getNumClasses() const

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

LLVM_ABI unsigned join(unsigned a, unsigned b)

Join the equivalence classes of a and b.

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

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

bool hasInterval(Register Reg) const

SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)

SlotIndexes * getSlotIndexes() const

SlotIndex getInstructionIndex(const MachineInstr &Instr) const

Returns the base index of the given instruction.

VNInfo::Allocator & getVNInfoAllocator()

LiveInterval & getInterval(Register Reg)

LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)

After removing some uses of a register, shrink its live range to just the remaining uses.

LLVM_ABI void constructMainRangeFromSubranges(LiveInterval &LI)

For live interval LI with correct SubRanges construct matching information for the main live range.

LLVM_ABI iterator addSegment(Segment S)

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

bool liveAt(SlotIndex index) const

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

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

iterator_range< pred_iterator > predecessors()

MachineInstrBundleIterator< MachineInstr > iterator

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.

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.

const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register definition operand.

unsigned getSubReg() const

LLVM_ABI 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)

LLVM_ABI 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

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

defusechain_iterator< true, true, true, true, false > reg_nodbg_iterator

reg_nodbg_iterator/reg_nodbg_begin/reg_nodbg_end - Walk all defs and uses of the specified register,...

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

Wrapper class representing virtual and physical registers.

static Register index2VirtReg(unsigned Index)

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

PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)

Definition RenameIndependentSubregs.cpp:410

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.

LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &)

MachineBasicBlock * getMBBFromIndex(SlotIndex index) const

Returns the basic block which the given index falls in.

SlotIndex getMBBEndIdx(unsigned Num) const

Returns the index past the last valid index in the given basic block.

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.

const TargetRegisterInfo & getRegisterInfo() const

virtual const TargetInstrInfo * getInstrInfo() const

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

unsigned ID

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

@ Undef

Value of the register doesn't matter.

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.

AnalysisManager< MachineFunction > MachineFunctionAnalysisManager

LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()

Returns the minimum set of Analyses that all machine function passes must preserve.

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

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

LLVM_ABI raw_ostream & dbgs()

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

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

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

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

BumpPtrAllocatorImpl<> BumpPtrAllocator

The standard BumpPtrAllocator which just uses the default template parameters.

LLVM_ABI char & RenameIndependentSubregsID

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

Definition RenameIndependentSubregs.cpp:119

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

constexpr bool none() const