003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/CodeGen
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
CodeGen
/
📁
..
📄
AggressiveAntiDepBreaker.cpp
(37.23 KB)
📄
AggressiveAntiDepBreaker.h
(6.8 KB)
📄
AllocationOrder.cpp
(1.96 KB)
📄
AllocationOrder.h
(2.96 KB)
📄
Analysis.cpp
(32.62 KB)
📁
AsmPrinter
📄
AtomicExpandPass.cpp
(71.86 KB)
📄
BBSectionsPrepare.cpp
(18.8 KB)
📄
BasicTargetTransformInfo.cpp
(1.53 KB)
📄
BranchFolding.cpp
(77.92 KB)
📄
BranchFolding.h
(7.36 KB)
📄
BranchRelaxation.cpp
(19.45 KB)
📄
BreakFalseDeps.cpp
(9.79 KB)
📄
BuiltinGCs.cpp
(4.88 KB)
📄
CFGuardLongjmp.cpp
(3.73 KB)
📄
CFIInstrInserter.cpp
(17.53 KB)
📄
CalcSpillWeights.cpp
(10.22 KB)
📄
CallingConvLower.cpp
(10.4 KB)
📄
CodeGen.cpp
(5.28 KB)
📄
CodeGenPrepare.cpp
(295.01 KB)
📄
CommandFlags.cpp
(24.89 KB)
📄
CriticalAntiDepBreaker.cpp
(27.91 KB)
📄
CriticalAntiDepBreaker.h
(4.22 KB)
📄
DFAPacketizer.cpp
(10.91 KB)
📄
DeadMachineInstructionElim.cpp
(6.52 KB)
📄
DetectDeadLanes.cpp
(20.74 KB)
📄
DwarfEHPrepare.cpp
(9.01 KB)
📄
EarlyIfConversion.cpp
(37.51 KB)
📄
EdgeBundles.cpp
(3.21 KB)
📄
ExecutionDomainFix.cpp
(14.67 KB)
📄
ExpandMemCmp.cpp
(33.66 KB)
📄
ExpandPostRAPseudos.cpp
(7.28 KB)
📄
ExpandReductions.cpp
(7.23 KB)
📄
FEntryInserter.cpp
(1.81 KB)
📄
FaultMaps.cpp
(4.99 KB)
📄
FinalizeISel.cpp
(2.65 KB)
📄
FixupStatepointCallerSaved.cpp
(11.06 KB)
📄
FuncletLayout.cpp
(2.21 KB)
📄
GCMetadata.cpp
(5.1 KB)
📄
GCMetadataPrinter.cpp
(748 B)
📄
GCRootLowering.cpp
(11.46 KB)
📄
GCStrategy.cpp
(708 B)
📁
GlobalISel
📄
GlobalMerge.cpp
(24.52 KB)
📄
HardwareLoops.cpp
(18.44 KB)
📄
IfConversion.cpp
(89.43 KB)
📄
ImplicitNullChecks.cpp
(25.14 KB)
📄
IndirectBrExpandPass.cpp
(7.79 KB)
📄
InlineSpiller.cpp
(58.24 KB)
📄
InterferenceCache.cpp
(8.83 KB)
📄
InterferenceCache.h
(7.22 KB)
📄
InterleavedAccessPass.cpp
(16.59 KB)
📄
InterleavedLoadCombinePass.cpp
(42.35 KB)
📄
IntrinsicLowering.cpp
(17.08 KB)
📄
LLVMTargetMachine.cpp
(10.25 KB)
📄
LatencyPriorityQueue.cpp
(5.64 KB)
📄
LazyMachineBlockFrequencyInfo.cpp
(3.36 KB)
📄
LexicalScopes.cpp
(12.16 KB)
📄
LiveDebugValues.cpp
(78.98 KB)
📄
LiveDebugVariables.cpp
(51.79 KB)
📄
LiveDebugVariables.h
(2.15 KB)
📄
LiveInterval.cpp
(46.67 KB)
📄
LiveIntervalCalc.cpp
(7.62 KB)
📄
LiveIntervalUnion.cpp
(6.36 KB)
📄
LiveIntervals.cpp
(64.59 KB)
📄
LivePhysRegs.cpp
(11.08 KB)
📄
LiveRangeCalc.cpp
(15.72 KB)
📄
LiveRangeEdit.cpp
(17.03 KB)
📄
LiveRangeShrink.cpp
(8.69 KB)
📄
LiveRangeUtils.h
(2.12 KB)
📄
LiveRegMatrix.cpp
(7.47 KB)
📄
LiveRegUnits.cpp
(4.72 KB)
📄
LiveStacks.cpp
(2.95 KB)
📄
LiveVariables.cpp
(30.26 KB)
📄
LocalStackSlotAllocation.cpp
(17.26 KB)
📄
LoopTraversal.cpp
(2.89 KB)
📄
LowLevelType.cpp
(1.93 KB)
📄
LowerEmuTLS.cpp
(5.66 KB)
📄
MBFIWrapper.cpp
(1.57 KB)
📄
MIRCanonicalizerPass.cpp
(12.46 KB)
📄
MIRNamerPass.cpp
(2.16 KB)
📁
MIRParser
📄
MIRPrinter.cpp
(32.67 KB)
📄
MIRPrintingPass.cpp
(1.99 KB)
📄
MIRVRegNamerUtils.cpp
(6.04 KB)
📄
MIRVRegNamerUtils.h
(3.25 KB)
📄
MachineBasicBlock.cpp
(50.47 KB)
📄
MachineBlockFrequencyInfo.cpp
(10.13 KB)
📄
MachineBlockPlacement.cpp
(137.61 KB)
📄
MachineBranchProbabilityInfo.cpp
(3.5 KB)
📄
MachineCSE.cpp
(31.82 KB)
📄
MachineCombiner.cpp
(28.13 KB)
📄
MachineCopyPropagation.cpp
(29.21 KB)
📄
MachineDebugify.cpp
(6.47 KB)
📄
MachineDominanceFrontier.cpp
(1.83 KB)
📄
MachineDominators.cpp
(4.86 KB)
📄
MachineFrameInfo.cpp
(9.77 KB)
📄
MachineFunction.cpp
(42.97 KB)
📄
MachineFunctionPass.cpp
(4.78 KB)
📄
MachineFunctionPrinterPass.cpp
(2.3 KB)
📄
MachineInstr.cpp
(76.39 KB)
📄
MachineInstrBundle.cpp
(11.49 KB)
📄
MachineLICM.cpp
(57.05 KB)
📄
MachineLoopInfo.cpp
(4.98 KB)
📄
MachineLoopUtils.cpp
(5.16 KB)
📄
MachineModuleInfo.cpp
(9.9 KB)
📄
MachineModuleInfoImpls.cpp
(1.5 KB)
📄
MachineOperand.cpp
(39.6 KB)
📄
MachineOptimizationRemarkEmitter.cpp
(3.29 KB)
📄
MachineOutliner.cpp
(42.13 KB)
📄
MachinePipeliner.cpp
(111.33 KB)
📄
MachinePostDominators.cpp
(2.42 KB)
📄
MachineRegionInfo.cpp
(4.75 KB)
📄
MachineRegisterInfo.cpp
(22.97 KB)
📄
MachineSSAUpdater.cpp
(12.99 KB)
📄
MachineScheduler.cpp
(136.89 KB)
📄
MachineSink.cpp
(51.94 KB)
📄
MachineSizeOpts.cpp
(8.76 KB)
📄
MachineStripDebug.cpp
(3.76 KB)
📄
MachineTraceMetrics.cpp
(49.58 KB)
📄
MachineVerifier.cpp
(107.98 KB)
📄
MacroFusion.cpp
(7.55 KB)
📄
ModuloSchedule.cpp
(85.09 KB)
📄
NonRelocatableStringpool.cpp
(1.65 KB)
📄
OptimizePHIs.cpp
(6.7 KB)
📄
PHIElimination.cpp
(27.73 KB)
📄
PHIEliminationUtils.cpp
(2.56 KB)
📄
PHIEliminationUtils.h
(972 B)
📄
ParallelCG.cpp
(3.71 KB)
📄
PatchableFunction.cpp
(3.44 KB)
📄
PeepholeOptimizer.cpp
(78.41 KB)
📄
PostRAHazardRecognizer.cpp
(3.5 KB)
📄
PostRASchedulerList.cpp
(24.31 KB)
📄
PreISelIntrinsicLowering.cpp
(7.91 KB)
📄
ProcessImplicitDefs.cpp
(5.4 KB)
📄
PrologEpilogInserter.cpp
(50.45 KB)
📄
PseudoSourceValue.cpp
(4.71 KB)
📄
RDFGraph.cpp
(58.39 KB)
📄
RDFLiveness.cpp
(40.7 KB)
📄
RDFRegisters.cpp
(11.29 KB)
📄
ReachingDefAnalysis.cpp
(21.74 KB)
📄
RegAllocBase.cpp
(6.31 KB)
📄
RegAllocBase.h
(4.63 KB)
📄
RegAllocBasic.cpp
(11.33 KB)
📄
RegAllocFast.cpp
(45.78 KB)
📄
RegAllocGreedy.cpp
(123.32 KB)
📄
RegAllocPBQP.cpp
(33.14 KB)
📄
RegUsageInfoCollector.cpp
(7.39 KB)
📄
RegUsageInfoPropagate.cpp
(5.07 KB)
📄
RegisterClassInfo.cpp
(6.62 KB)
📄
RegisterCoalescer.cpp
(151.71 KB)
📄
RegisterCoalescer.h
(4.04 KB)
📄
RegisterPressure.cpp
(48.86 KB)
📄
RegisterScavenging.cpp
(27.48 KB)
📄
RegisterUsageInfo.cpp
(3.18 KB)
📄
RenameIndependentSubregs.cpp
(14.79 KB)
📄
ResetMachineFunctionPass.cpp
(3.48 KB)
📄
SafeStack.cpp
(34.12 KB)
📄
SafeStackLayout.cpp
(5.3 KB)
📄
SafeStackLayout.h
(2.41 KB)
📄
ScalarizeMaskedMemIntrin.cpp
(31.46 KB)
📄
ScheduleDAG.cpp
(21.34 KB)
📄
ScheduleDAGInstrs.cpp
(54.59 KB)
📄
ScheduleDAGPrinter.cpp
(3.21 KB)
📄
ScoreboardHazardRecognizer.cpp
(7.96 KB)
📁
SelectionDAG
📄
ShadowStackGCLowering.cpp
(14.16 KB)
📄
ShrinkWrap.cpp
(23.03 KB)
📄
SjLjEHPrepare.cpp
(18.93 KB)
📄
SlotIndexes.cpp
(9.35 KB)
📄
SpillPlacement.cpp
(12.58 KB)
📄
SpillPlacement.h
(6.67 KB)
📄
SplitKit.cpp
(66.39 KB)
📄
SplitKit.h
(23.7 KB)
📄
StackColoring.cpp
(49.03 KB)
📄
StackMapLivenessAnalysis.cpp
(6.16 KB)
📄
StackMaps.cpp
(19.74 KB)
📄
StackProtector.cpp
(22.94 KB)
📄
StackSlotColoring.cpp
(17.12 KB)
📄
SwiftErrorValueTracking.cpp
(11.37 KB)
📄
SwitchLoweringUtils.cpp
(18.33 KB)
📄
TailDuplication.cpp
(3.32 KB)
📄
TailDuplicator.cpp
(38.29 KB)
📄
TargetFrameLoweringImpl.cpp
(6.24 KB)
📄
TargetInstrInfo.cpp
(51.1 KB)
📄
TargetLoweringBase.cpp
(82.53 KB)
📄
TargetLoweringObjectFileImpl.cpp
(80.52 KB)
📄
TargetOptionsImpl.cpp
(2 KB)
📄
TargetPassConfig.cpp
(48.89 KB)
📄
TargetRegisterInfo.cpp
(19.15 KB)
📄
TargetSchedule.cpp
(13.16 KB)
📄
TargetSubtargetInfo.cpp
(1.89 KB)
📄
TwoAddressInstructionPass.cpp
(62.08 KB)
📄
TypePromotion.cpp
(32.46 KB)
📄
UnreachableBlockElim.cpp
(7.48 KB)
📄
ValueTypes.cpp
(19.87 KB)
📄
VirtRegMap.cpp
(21.4 KB)
📄
WasmEHPrepare.cpp
(17.48 KB)
📄
WinEHPrepare.cpp
(51.16 KB)
📄
XRayInstrumentation.cpp
(9.66 KB)
Editing: RenameIndependentSubregs.cpp
//===-- RenameIndependentSubregs.cpp - Live Interval Analysis -------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // /// Rename independent subregisters looks for virtual registers with /// independently used subregisters and renames them to new virtual registers. /// Example: In the following: /// %0:sub0<read-undef> = ... /// %0:sub1 = ... /// use %0:sub0 /// %0:sub0 = ... /// use %0:sub0 /// use %0:sub1 /// sub0 and sub1 are never used together, and we have two independent sub0 /// definitions. This pass will rename to: /// %0:sub0<read-undef> = ... /// %1:sub1<read-undef> = ... /// use %1:sub1 /// %2:sub1<read-undef> = ... /// use %2:sub1 /// use %0:sub0 // //===----------------------------------------------------------------------===// #include "LiveRangeUtils.h" #include "PHIEliminationUtils.h" #include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/InitializePasses.h" using namespace llvm; #define DEBUG_TYPE "rename-independent-subregs" namespace { class RenameIndependentSubregs : public MachineFunctionPass { public: static char ID; RenameIndependentSubregs() : MachineFunctionPass(ID) {} StringRef getPassName() const override { return "Rename Disconnected Subregister Components"; } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); AU.addRequired<LiveIntervals>(); AU.addPreserved<LiveIntervals>(); AU.addRequired<SlotIndexes>(); AU.addPreserved<SlotIndexes>(); MachineFunctionPass::getAnalysisUsage(AU); } bool runOnMachineFunction(MachineFunction &MF) override; private: struct SubRangeInfo { ConnectedVNInfoEqClasses ConEQ; LiveInterval::SubRange *SR; unsigned Index; SubRangeInfo(LiveIntervals &LIS, LiveInterval::SubRange &SR, unsigned Index) : ConEQ(LIS), SR(&SR), Index(Index) {} }; /// Split unrelated subregister components and rename them to new vregs. bool renameComponents(LiveInterval &LI) const; /// Build a vector of SubRange infos and a union find set of /// equivalence classes. /// Returns true if more than 1 equivalence class was found. bool findComponents(IntEqClasses &Classes, SmallVectorImpl<SubRangeInfo> &SubRangeInfos, LiveInterval &LI) const; /// Distribute the LiveInterval segments into the new LiveIntervals /// belonging to their class. void distribute(const IntEqClasses &Classes, const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, const SmallVectorImpl<LiveInterval*> &Intervals) const; /// Constructs main liverange and add missing undef+dead flags. void computeMainRangesFixFlags(const IntEqClasses &Classes, const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, const SmallVectorImpl<LiveInterval*> &Intervals) const; /// Rewrite Machine Operands to use the new vreg belonging to their class. void rewriteOperands(const IntEqClasses &Classes, const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, const SmallVectorImpl<LiveInterval*> &Intervals) const; LiveIntervals *LIS; MachineRegisterInfo *MRI; const TargetInstrInfo *TII; }; } // end anonymous namespace char RenameIndependentSubregs::ID; char &llvm::RenameIndependentSubregsID = RenameIndependentSubregs::ID; INITIALIZE_PASS_BEGIN(RenameIndependentSubregs, DEBUG_TYPE, "Rename Independent Subregisters", false, false) INITIALIZE_PASS_DEPENDENCY(SlotIndexes) INITIALIZE_PASS_DEPENDENCY(LiveIntervals) INITIALIZE_PASS_END(RenameIndependentSubregs, DEBUG_TYPE, "Rename Independent Subregisters", false, false) bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const { // Shortcut: We cannot have split components with a single definition. if (LI.valnos.size() < 2) return false; SmallVector<SubRangeInfo, 4> SubRangeInfos; IntEqClasses Classes; if (!findComponents(Classes, SubRangeInfos, LI)) return false; // Create a new VReg for each class. unsigned Reg = LI.reg; const TargetRegisterClass *RegClass = MRI->getRegClass(Reg); SmallVector<LiveInterval*, 4> Intervals; Intervals.push_back(&LI); LLVM_DEBUG(dbgs() << printReg(Reg) << ": Found " << Classes.getNumClasses() << " equivalence classes.\n"); LLVM_DEBUG(dbgs() << printReg(Reg) << ": Splitting into newly created:"); for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses; ++I) { Register NewVReg = MRI->createVirtualRegister(RegClass); LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg); Intervals.push_back(&NewLI); LLVM_DEBUG(dbgs() << ' ' << printReg(NewVReg)); } LLVM_DEBUG(dbgs() << '\n'); rewriteOperands(Classes, SubRangeInfos, Intervals); distribute(Classes, SubRangeInfos, Intervals); computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals); return true; } bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes, SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> &SubRangeInfos, LiveInterval &LI) const { // First step: Create connected components for the VNInfos inside the // subranges and count the global number of such components. unsigned NumComponents = 0; for (LiveInterval::SubRange &SR : LI.subranges()) { SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents)); ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ; unsigned NumSubComponents = ConEQ.Classify(SR); NumComponents += NumSubComponents; } // Shortcut: With only 1 subrange, the normal separate component tests are // enough and we do not need to perform the union-find on the subregister // segments. if (SubRangeInfos.size() < 2) return false; // Next step: Build union-find structure over all subranges and merge classes // across subranges when they are affected by the same MachineOperand. const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); Classes.grow(NumComponents); unsigned Reg = LI.reg; for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) { if (!MO.isDef() && !MO.readsReg()) continue; unsigned SubRegIdx = MO.getSubReg(); LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx); unsigned MergedID = ~0u; for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) { const LiveInterval::SubRange &SR = *SRInfo.SR; if ((SR.LaneMask & LaneMask).none()) continue; SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()); Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber()) : Pos.getBaseIndex(); const VNInfo *VNI = SR.getVNInfoAt(Pos); if (VNI == nullptr) continue; // Map to local representant ID. unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI); // Global ID unsigned ID = LocalID + SRInfo.Index; // Merge other sets MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID); } } // Early exit if we ended up with a single equivalence class. Classes.compress(); unsigned NumClasses = Classes.getNumClasses(); return NumClasses > 1; } void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes, const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, const SmallVectorImpl<LiveInterval*> &Intervals) const { const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); unsigned Reg = Intervals[0]->reg; for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg), E = MRI->reg_nodbg_end(); I != E; ) { MachineOperand &MO = *I++; if (!MO.isDef() && !MO.readsReg()) continue; auto *MI = MO.getParent(); SlotIndex Pos = LIS->getInstructionIndex(*MI); Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber()) : Pos.getBaseIndex(); unsigned SubRegIdx = MO.getSubReg(); LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx); unsigned ID = ~0u; for (const SubRangeInfo &SRInfo : SubRangeInfos) { const LiveInterval::SubRange &SR = *SRInfo.SR; if ((SR.LaneMask & LaneMask).none()) continue; const VNInfo *VNI = SR.getVNInfoAt(Pos); if (VNI == nullptr) continue; // Map to local representant ID. unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI); // Global ID ID = Classes[LocalID + SRInfo.Index]; break; } unsigned VReg = Intervals[ID]->reg; MO.setReg(VReg); if (MO.isTied() && Reg != VReg) { /// Undef use operands are not tracked in the equivalence class, /// but need to be updated if they are tied; take care to only /// update the tied operand. unsigned OperandNo = MI->getOperandNo(&MO); unsigned TiedIdx = MI->findTiedOperandIdx(OperandNo); MI->getOperand(TiedIdx).setReg(VReg); // above substitution breaks the iterator, so restart. I = MRI->reg_nodbg_begin(Reg); } } // TODO: We could attempt to recompute new register classes while visiting // the operands: Some of the split register may be fine with less constraint // classes than the original vreg. } void RenameIndependentSubregs::distribute(const IntEqClasses &Classes, const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, const SmallVectorImpl<LiveInterval*> &Intervals) const { unsigned NumClasses = Classes.getNumClasses(); SmallVector<unsigned, 8> VNIMapping; SmallVector<LiveInterval::SubRange*, 8> SubRanges; BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator(); for (const SubRangeInfo &SRInfo : SubRangeInfos) { LiveInterval::SubRange &SR = *SRInfo.SR; unsigned NumValNos = SR.valnos.size(); VNIMapping.clear(); VNIMapping.reserve(NumValNos); SubRanges.clear(); SubRanges.resize(NumClasses-1, nullptr); for (unsigned I = 0; I < NumValNos; ++I) { const VNInfo &VNI = *SR.valnos[I]; unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI); unsigned ID = Classes[LocalID + SRInfo.Index]; VNIMapping.push_back(ID); if (ID > 0 && SubRanges[ID-1] == nullptr) SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask); } DistributeRange(SR, SubRanges.data(), VNIMapping); } } static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) { for (const LiveInterval::SubRange &SR : LI.subranges()) { if (SR.liveAt(Pos)) return true; } return false; } void RenameIndependentSubregs::computeMainRangesFixFlags( const IntEqClasses &Classes, const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, const SmallVectorImpl<LiveInterval*> &Intervals) const { BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator(); const SlotIndexes &Indexes = *LIS->getSlotIndexes(); for (size_t I = 0, E = Intervals.size(); I < E; ++I) { LiveInterval &LI = *Intervals[I]; unsigned Reg = LI.reg; LI.removeEmptySubRanges(); // There must be a def (or live-in) before every use. Splitting vregs may // violate this principle as the splitted vreg may not have a definition on // every path. Fix this by creating IMPLICIT_DEF instruction as necessary. for (const LiveInterval::SubRange &SR : LI.subranges()) { // Search for "PHI" value numbers in the subranges. We must find a live // value in each predecessor block, add an IMPLICIT_DEF where it is // missing. for (unsigned I = 0; I < SR.valnos.size(); ++I) { const VNInfo &VNI = *SR.valnos[I]; if (VNI.isUnused() || !VNI.isPHIDef()) continue; SlotIndex Def = VNI.def; MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(Def); for (MachineBasicBlock *PredMBB : MBB.predecessors()) { SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB); if (subRangeLiveAt(LI, PredEnd.getPrevSlot())) continue; MachineBasicBlock::iterator InsertPos = llvm::findPHICopyInsertPoint(PredMBB, &MBB, Reg); const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF); MachineInstrBuilder ImpDef = BuildMI(*PredMBB, InsertPos, DebugLoc(), MCDesc, Reg); SlotIndex DefIdx = LIS->InsertMachineInstrInMaps(*ImpDef); SlotIndex RegDefIdx = DefIdx.getRegSlot(); for (LiveInterval::SubRange &SR : LI.subranges()) { VNInfo *SRVNI = SR.getNextValue(RegDefIdx, Allocator); SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI)); } } } } for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) { if (!MO.isDef()) continue; unsigned SubRegIdx = MO.getSubReg(); if (SubRegIdx == 0) continue; // After assigning the new vreg we may not have any other sublanes living // in and out of the instruction anymore. We need to add new dead and // undef flags in these cases. if (!MO.isUndef()) { SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()); if (!subRangeLiveAt(LI, Pos)) MO.setIsUndef(); } if (!MO.isDead()) { SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()).getDeadSlot(); if (!subRangeLiveAt(LI, Pos)) MO.setIsDead(); } } if (I == 0) LI.clear(); LIS->constructMainRangeFromSubranges(LI); // A def of a subregister may be a use of other register lanes. Replacing // such a def with a def of a different register will eliminate the use, // and may cause the recorded live range to be larger than the actual // liveness in the program IR. LIS->shrinkToUses(&LI); } } bool RenameIndependentSubregs::runOnMachineFunction(MachineFunction &MF) { // Skip renaming if liveness of subregister is not tracked. MRI = &MF.getRegInfo(); if (!MRI->subRegLivenessEnabled()) return false; LLVM_DEBUG(dbgs() << "Renaming independent subregister live ranges in " << MF.getName() << '\n'); LIS = &getAnalysis<LiveIntervals>(); TII = MF.getSubtarget().getInstrInfo(); // Iterate over all vregs. Note that we query getNumVirtRegs() the newly // created vregs end up with higher numbers but do not need to be visited as // there can't be any further splitting. bool Changed = false; for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) { unsigned Reg = Register::index2VirtReg(I); if (!LIS->hasInterval(Reg)) continue; LiveInterval &LI = LIS->getInterval(Reg); if (!LI.hasSubRanges()) continue; Changed |= renameComponents(LI); } return Changed; }
Upload File
Create Folder