aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/CodeGen/RegUsageInfoCollector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/CodeGen/RegUsageInfoCollector.cpp')
-rw-r--r--contrib/llvm/lib/CodeGen/RegUsageInfoCollector.cpp124
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);
+ }
+}