diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index b3dbb9c9704..53fa7ca7167 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -689,6 +689,11 @@ public: /// debugging downstream codegen failures exposed by regalloc. virtual bool mayOverrideLocalAssignment() const { return true; } + /// Allow the target to override the cost of using a callee-saved register for + /// the first time. Default value of 0 means we will use a callee-saved + /// register if it is available. + virtual unsigned getCSRFirstUseCost() const { return 0; } + /// requiresRegisterScavenging - returns true if the target requires (and can /// make use of) the register scavenger. virtual bool requiresRegisterScavenging(const MachineFunction &MF) const { diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index 0eb91ab2927..6a623b82002 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -2123,7 +2123,10 @@ unsigned RAGreedy::tryAssignCSRFirstTime(LiveInterval &VirtReg, unsigned PhysReg, unsigned &CostPerUseLimit, SmallVectorImpl &NewVRegs) { - BlockFrequency CSRCost(CSRFirstTimeCost); + // We use the larger one out of the command-line option and the value report + // by TRI. + BlockFrequency CSRCost(std::max((unsigned)CSRFirstTimeCost, + TRI->getCSRFirstUseCost())); if (getStage(VirtReg) == RS_Spill && VirtReg.isSpillable()) { // We choose spill over using the CSR for the first time if the spill cost // is lower than CSRCost. @@ -2172,7 +2175,8 @@ unsigned RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg, // When NewVRegs is not empty, we may have made decisions such as evicting // a virtual register, go with the earlier decisions and use the physical // register. - if (CSRFirstTimeCost > 0 && CSRFirstUse && NewVRegs.empty()) { + if ((CSRFirstTimeCost || TRI->getCSRFirstUseCost()) && + CSRFirstUse && NewVRegs.empty()) { unsigned CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg, CostPerUseLimit, NewVRegs); if (CSRReg || !NewVRegs.empty())