Remember the minimum cost of the registers in an allocation order and
the number of registers at the end of the allocation order that have the
same cost per use.
This information can be used to limit the search space for
RAGreedy::tryEvict() when looking for a cheaper register.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172280
91177308-0d34-0410-b5e6-
96231b3b80d8
unsigned Tag;
unsigned NumRegs;
bool ProperSubClass;
unsigned Tag;
unsigned NumRegs;
bool ProperSubClass;
+ uint8_t MinCost;
+ uint16_t LastCostChange;
OwningArrayPtr<MCPhysReg> Order;
OwningArrayPtr<MCPhysReg> Order;
- RCInfo() : Tag(0), NumRegs(0), ProperSubClass(false) {}
+ RCInfo()
+ : Tag(0), NumRegs(0), ProperSubClass(false), MinCost(0),
+ LastCostChange(0) {}
+
operator ArrayRef<MCPhysReg>() const {
return makeArrayRef(Order.get(), NumRegs);
}
operator ArrayRef<MCPhysReg>() const {
return makeArrayRef(Order.get(), NumRegs);
}
return CalleeSaved[N-1];
return 0;
}
return CalleeSaved[N-1];
return 0;
}
+
+ /// Get the minimum register cost in RC's allocation order.
+ /// This is the smallest value returned by TRI->getCostPerUse(Reg) for all
+ /// the registers in getOrder(RC).
+ unsigned getMinCost(const TargetRegisterClass *RC) {
+ return get(RC).MinCost;
+ }
+
+ /// Get the position of the last cost change in getOrder(RC).
+ ///
+ /// All registers in getOrder(RC).slice(getLastCostChange(RC)) will have the
+ /// same cost according to TRI->getCostPerUse().
+ unsigned getLastCostChange(const TargetRegisterClass *RC) {
+ return get(RC).LastCostChange;
+ }
};
} // end namespace llvm
};
} // end namespace llvm
unsigned N = 0;
SmallVector<MCPhysReg, 16> CSRAlias;
unsigned N = 0;
SmallVector<MCPhysReg, 16> CSRAlias;
+ unsigned MinCost = 0xff;
+ unsigned LastCost = ~0u;
+ unsigned LastCostChange = 0;
// FIXME: Once targets reserve registers instead of removing them from the
// allocation order, we can simply use begin/end here.
// FIXME: Once targets reserve registers instead of removing them from the
// allocation order, we can simply use begin/end here.
// Remove reserved registers from the allocation order.
if (Reserved.test(PhysReg))
continue;
// Remove reserved registers from the allocation order.
if (Reserved.test(PhysReg))
continue;
+ unsigned Cost = TRI->getCostPerUse(PhysReg);
+ MinCost = std::min(MinCost, Cost);
+
if (CSRNum[PhysReg])
// PhysReg aliases a CSR, save it for later.
CSRAlias.push_back(PhysReg);
if (CSRNum[PhysReg])
// PhysReg aliases a CSR, save it for later.
CSRAlias.push_back(PhysReg);
+ else {
+ if (Cost != LastCost)
+ LastCostChange = N;
RCI.Order[N++] = PhysReg;
RCI.Order[N++] = PhysReg;
}
RCI.NumRegs = N + CSRAlias.size();
assert (RCI.NumRegs <= NumRegs && "Allocation order larger than regclass");
// CSR aliases go after the volatile registers, preserve the target's order.
}
RCI.NumRegs = N + CSRAlias.size();
assert (RCI.NumRegs <= NumRegs && "Allocation order larger than regclass");
// CSR aliases go after the volatile registers, preserve the target's order.
- std::copy(CSRAlias.begin(), CSRAlias.end(), &RCI.Order[N]);
+ for (unsigned i = 0, e = CSRAlias.size(); i != e; ++i) {
+ unsigned PhysReg = CSRAlias[i];
+ unsigned Cost = TRI->getCostPerUse(PhysReg);
+ if (Cost != LastCost)
+ LastCostChange = N;
+ RCI.Order[N++] = PhysReg;
+ LastCost = Cost;
+ }
// Register allocator stress test. Clip register class to N registers.
if (StressRA && RCI.NumRegs > StressRA)
// Register allocator stress test. Clip register class to N registers.
if (StressRA && RCI.NumRegs > StressRA)
if (Super != RC && getNumAllocatableRegs(Super) > RCI.NumRegs)
RCI.ProperSubClass = true;
if (Super != RC && getNumAllocatableRegs(Super) > RCI.NumRegs)
RCI.ProperSubClass = true;
+ RCI.MinCost = uint8_t(MinCost);
+ RCI.LastCostChange = LastCostChange;
+
DEBUG({
dbgs() << "AllocationOrder(" << RC->getName() << ") = [";
for (unsigned I = 0; I != RCI.NumRegs; ++I)
DEBUG({
dbgs() << "AllocationOrder(" << RC->getName() << ") = [";
for (unsigned I = 0; I != RCI.NumRegs; ++I)