forked from OSchip/llvm-project
[TargetRegisterInfo] Make the heuristic to skip region split overridable by the target
RegAllocGreedy uses a fairly compile time intensive splitting heuristic called region splitting. This heuristic was disabled via another heuristic when it is likely that it won't be worth the compile time. The only way to control this other heuristic was via a command line option (huge-size-for-split). This commit gives more control on this heuristic by making it overridable by the target using a target hook in TargetRegisterInfo called shouldRegionSplitForVirtReg. The default implementation of this hook keeps the heuristic as it was before this patch.
This commit is contained in:
parent
221c5af4e4
commit
f26ff8c9df
|
@ -40,6 +40,7 @@ class MachineInstr;
|
|||
class RegScavenger;
|
||||
class VirtRegMap;
|
||||
class LiveIntervals;
|
||||
class LiveInterval;
|
||||
|
||||
class TargetRegisterClass {
|
||||
public:
|
||||
|
@ -952,6 +953,12 @@ public:
|
|||
LiveIntervals &LIS) const
|
||||
{ return true; }
|
||||
|
||||
/// Region split has a high compile time cost especially for large live range.
|
||||
/// This method is used to decide whether or not \p VirtReg should
|
||||
/// go through this expensive splitting heuristic.
|
||||
virtual bool shouldRegionSplitForVirtReg(const MachineFunction &MF,
|
||||
const LiveInterval &VirtReg) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// Debug information queries.
|
||||
|
||||
|
|
|
@ -124,12 +124,6 @@ static cl::opt<bool> EnableDeferredSpilling(
|
|||
"variable because of other evicted variables."),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
HugeSizeForSplit("huge-size-for-split", cl::Hidden,
|
||||
cl::desc("A threshold of live range size which may cause "
|
||||
"high compile time cost in global splitting."),
|
||||
cl::init(5000));
|
||||
|
||||
// FIXME: Find a good default for this flag and remove the flag.
|
||||
static cl::opt<unsigned>
|
||||
CSRFirstTimeCost("regalloc-csr-first-time-cost",
|
||||
|
@ -486,7 +480,6 @@ private:
|
|||
const SmallVirtRegSet&);
|
||||
unsigned tryRegionSplit(LiveInterval&, AllocationOrder&,
|
||||
SmallVectorImpl<unsigned>&);
|
||||
unsigned isSplitBenefitWorthCost(LiveInterval &VirtReg);
|
||||
/// Calculate cost of region splitting.
|
||||
unsigned calculateRegionSplitCost(LiveInterval &VirtReg,
|
||||
AllocationOrder &Order,
|
||||
|
@ -1815,20 +1808,9 @@ void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
|
|||
MF->verify(this, "After splitting live range around region");
|
||||
}
|
||||
|
||||
// Global split has high compile time cost especially for large live range.
|
||||
// Return false for the case here where the potential benefit will never
|
||||
// worth the cost.
|
||||
unsigned RAGreedy::isSplitBenefitWorthCost(LiveInterval &VirtReg) {
|
||||
MachineInstr *MI = MRI->getUniqueVRegDef(VirtReg.reg);
|
||||
if (MI && TII->isTriviallyReMaterializable(*MI, AA) &&
|
||||
VirtReg.size() > HugeSizeForSplit)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
||||
SmallVectorImpl<unsigned> &NewVRegs) {
|
||||
if (!isSplitBenefitWorthCost(VirtReg))
|
||||
if (!TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
|
||||
return 0;
|
||||
unsigned NumCands = 0;
|
||||
BlockFrequency SpillCost = calcSpillCost();
|
||||
|
|
|
@ -13,19 +13,22 @@
|
|||
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/LiveInterval.h"
|
||||
#include "llvm/CodeGen/TargetFrameLowering.h"
|
||||
#include "llvm/CodeGen/TargetInstrInfo.h"
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
#include "llvm/CodeGen/VirtRegMap.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/MachineValueType.h"
|
||||
|
@ -39,6 +42,12 @@
|
|||
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<unsigned>
|
||||
HugeSizeForSplit("huge-size-for-split", cl::Hidden,
|
||||
cl::desc("A threshold of live range size which may cause "
|
||||
"high compile time cost in global splitting."),
|
||||
cl::init(5000));
|
||||
|
||||
TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
|
||||
regclass_iterator RCB, regclass_iterator RCE,
|
||||
const char *const *SRINames,
|
||||
|
@ -55,6 +64,17 @@ TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
|
|||
|
||||
TargetRegisterInfo::~TargetRegisterInfo() = default;
|
||||
|
||||
bool TargetRegisterInfo::shouldRegionSplitForVirtReg(
|
||||
const MachineFunction &MF, const LiveInterval &VirtReg) const {
|
||||
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
MachineInstr *MI = MRI.getUniqueVRegDef(VirtReg.reg);
|
||||
if (MI && TII->isTriviallyReMaterializable(*MI) &&
|
||||
VirtReg.size() > HugeSizeForSplit)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void TargetRegisterInfo::markSuperRegs(BitVector &RegisterSet, unsigned Reg)
|
||||
const {
|
||||
for (MCSuperRegIterator AI(Reg, this, true); AI.isValid(); ++AI)
|
||||
|
|
Loading…
Reference in New Issue