diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/RegUsageInfoCollector.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/RegUsageInfoCollector.cpp | 124 |
1 files changed, 83 insertions, 41 deletions
diff --git a/contrib/llvm/lib/CodeGen/RegUsageInfoCollector.cpp b/contrib/llvm/lib/CodeGen/RegUsageInfoCollector.cpp index f49ea25bbf35..f1c442ac38ae 100644 --- a/contrib/llvm/lib/CodeGen/RegUsageInfoCollector.cpp +++ b/contrib/llvm/lib/CodeGen/RegUsageInfoCollector.cpp @@ -36,11 +36,8 @@ using namespace llvm; STATISTIC(NumCSROpt, "Number of functions optimized for callee saved registers"); -namespace llvm { -void initializeRegUsageInfoCollectorPass(PassRegistry &); -} - namespace { + class RegUsageInfoCollector : public MachineFunctionPass { public: RegUsageInfoCollector() : MachineFunctionPass(ID) { @@ -52,12 +49,21 @@ public: return "Register Usage Information Collector Pass"; } - void getAnalysisUsage(AnalysisUsage &AU) const override; + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<PhysicalRegisterUsageInfo>(); + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); + } bool runOnMachineFunction(MachineFunction &MF) override; + // Call determineCalleeSaves and then also set the bits for subregs and + // fully saved superregs. + static void computeCalleeSavedRegs(BitVector &SavedRegs, MachineFunction &MF); + static char ID; }; + } // end of anonymous namespace char RegUsageInfoCollector::ID = 0; @@ -72,36 +78,32 @@ FunctionPass *llvm::createRegUsageInfoCollector() { return new RegUsageInfoCollector(); } -void RegUsageInfoCollector::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<PhysicalRegisterUsageInfo>(); - AU.setPreservesAll(); - MachineFunctionPass::getAnalysisUsage(AU); -} - bool RegUsageInfoCollector::runOnMachineFunction(MachineFunction &MF) { MachineRegisterInfo *MRI = &MF.getRegInfo(); const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); const TargetMachine &TM = MF.getTarget(); - DEBUG(dbgs() << " -------------------- " << getPassName() - << " -------------------- \n"); - DEBUG(dbgs() << "Function Name : " << MF.getName() << "\n"); + LLVM_DEBUG(dbgs() << " -------------------- " << getPassName() + << " -------------------- \n"); + LLVM_DEBUG(dbgs() << "Function Name : " << MF.getName() << "\n"); std::vector<uint32_t> RegMask; // Compute the size of the bit vector to represent all the registers. // The bit vector is broken into 32-bit chunks, thus takes the ceil of // the number of registers divided by 32 for the size. - unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32; - RegMask.resize(RegMaskSize, 0xFFFFFFFF); + unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs()); + RegMask.resize(RegMaskSize, ~((uint32_t)0)); const Function &F = MF.getFunction(); - PhysicalRegisterUsageInfo *PRUI = &getAnalysis<PhysicalRegisterUsageInfo>(); + PhysicalRegisterUsageInfo &PRUI = getAnalysis<PhysicalRegisterUsageInfo>(); + PRUI.setTargetMachine(TM); - PRUI->setTargetMachine(&TM); + LLVM_DEBUG(dbgs() << "Clobbered Registers: "); - DEBUG(dbgs() << "Clobbered Registers: "); + BitVector SavedRegs; + computeCalleeSavedRegs(SavedRegs, MF); const BitVector &UsedPhysRegsMask = MRI->getUsedPhysRegsMask(); auto SetRegAsDefined = [&RegMask] (unsigned Reg) { @@ -110,42 +112,82 @@ bool RegUsageInfoCollector::runOnMachineFunction(MachineFunction &MF) { // Scan all the physical registers. When a register is defined in the current // function set it and all the aliasing registers as defined in the regmask. for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) { - // If a register is in the UsedPhysRegsMask set then mark it as defined. - // All it's aliases will also be in the set, so we can skip setting - // as defined all the aliases here. - if (UsedPhysRegsMask.test(PReg)) { - SetRegAsDefined(PReg); + // Don't count registers that are saved and restored. + if (SavedRegs.test(PReg)) continue; - } // If a register is defined by an instruction mark it as defined together - // with all it's aliases. + // with all it's unsaved aliases. if (!MRI->def_empty(PReg)) { for (MCRegAliasIterator AI(PReg, TRI, true); AI.isValid(); ++AI) - SetRegAsDefined(*AI); + if (!SavedRegs.test(*AI)) + SetRegAsDefined(*AI); + continue; } + // If a register is in the UsedPhysRegsMask set then mark it as defined. + // All clobbered aliases will also be in the set, so we can skip setting + // as defined all the aliases here. + if (UsedPhysRegsMask.test(PReg)) + SetRegAsDefined(PReg); } - if (!TargetFrameLowering::isSafeForNoCSROpt(F)) { - const uint32_t *CallPreservedMask = - TRI->getCallPreservedMask(MF, F.getCallingConv()); - if (CallPreservedMask) { - // Set callee saved register as preserved. - for (unsigned i = 0; i < RegMaskSize; ++i) - RegMask[i] = RegMask[i] | CallPreservedMask[i]; - } - } else { + if (TargetFrameLowering::isSafeForNoCSROpt(F)) { ++NumCSROpt; - DEBUG(dbgs() << MF.getName() - << " function optimized for not having CSR.\n"); + LLVM_DEBUG(dbgs() << MF.getName() + << " function optimized for not having CSR.\n"); } for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) if (MachineOperand::clobbersPhysReg(&(RegMask[0]), PReg)) - DEBUG(dbgs() << printReg(PReg, TRI) << " "); + LLVM_DEBUG(dbgs() << printReg(PReg, TRI) << " "); - DEBUG(dbgs() << " \n----------------------------------------\n"); + LLVM_DEBUG(dbgs() << " \n----------------------------------------\n"); - PRUI->storeUpdateRegUsageInfo(&F, std::move(RegMask)); + PRUI.storeUpdateRegUsageInfo(F, RegMask); return false; } + +void RegUsageInfoCollector:: +computeCalleeSavedRegs(BitVector &SavedRegs, MachineFunction &MF) { + const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering(); + const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); + + // Target will return the set of registers that it saves/restores as needed. + SavedRegs.clear(); + TFI.determineCalleeSaves(MF, SavedRegs); + + // Insert subregs. + const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF); + for (unsigned i = 0; CSRegs[i]; ++i) { + unsigned Reg = CSRegs[i]; + if (SavedRegs.test(Reg)) + for (MCSubRegIterator SR(Reg, &TRI, false); SR.isValid(); ++SR) + SavedRegs.set(*SR); + } + + // Insert any register fully saved via subregisters. + for (unsigned PReg = 1, PRegE = TRI.getNumRegs(); PReg < PRegE; ++PReg) { + if (SavedRegs.test(PReg)) + continue; + + // Check if PReg is fully covered by its subregs. + bool CoveredBySubRegs = false; + for (const TargetRegisterClass *RC : TRI.regclasses()) + if (RC->CoveredBySubRegs && RC->contains(PReg)) { + CoveredBySubRegs = true; + break; + } + if (!CoveredBySubRegs) + continue; + + // Add PReg to SavedRegs if all subregs are saved. + bool AllSubRegsSaved = true; + for (MCSubRegIterator SR(PReg, &TRI, false); SR.isValid(); ++SR) + if (!SavedRegs.test(*SR)) { + AllSubRegsSaved = false; + break; + } + if (AllSubRegsSaved) + SavedRegs.set(PReg); + } +} |