/// A ProcResource can have multiple units.
///
- /// For processor resource groups,
- /// this field default to the value of field `ResourceMask`; the number of
- /// bits set is equal to the cardinality of the group. For normal (i.e.
- /// non-group) resources, the number of bits set in this mask is equivalent
- /// to the number of units declared by the processor model (see field
- /// 'NumUnits' in 'ProcResourceUnits').
+ /// For processor resource groups this field is a mask of contained resource
+ /// units. It is obtained from ResourceMask by clearing the highest set bit.
+ /// The number of resource units in a group can be simply computed as the
+ /// population count of this field.
+ ///
+ /// For normal (i.e. non-group) resources, the number of bits set in this mask
+ /// is equivalent to the number of units declared by the processor model (see
+ /// field 'NumUnits' in 'ProcResourceUnits').
uint64_t ResourceSizeMask;
/// A mask of ready units.
#define DEBUG_TYPE "llvm-mca"
ResourceStrategy::~ResourceStrategy() = default;
+// Returns the index of the highest bit set. For resource masks, the position of
+// the highest bit set can be used to construct a resource mask identifier.
+static unsigned getResourceStateIndex(uint64_t Mask) {
+ return std::numeric_limits<uint64_t>::digits - countLeadingZeros(Mask);
+}
+
static uint64_t selectImpl(uint64_t CandidateMask,
uint64_t &NextInSequenceMask) {
- CandidateMask = 1ULL << (countLeadingZeros(CandidateMask) ^
- (std::numeric_limits<uint64_t>::digits - 1));
- NextInSequenceMask &= (CandidateMask ^ (CandidateMask - 1));
+ // The upper bit set in CandidateMask identifies our next candidate resource.
+ CandidateMask = 1ULL << (getResourceStateIndex(CandidateMask) - 1);
+ NextInSequenceMask &= (CandidateMask | (CandidateMask - 1));
return CandidateMask;
}
BufferSize(Desc.BufferSize), IsAGroup(countPopulation(ResourceMask) > 1) {
if (IsAGroup) {
ResourceSizeMask =
- ResourceMask ^ (1ULL << (countLeadingZeros(ResourceMask) ^
- (std::numeric_limits<uint64_t>::digits - 1)));
+ ResourceMask ^ 1ULL << (getResourceStateIndex(ResourceMask) - 1);
} else {
ResourceSizeMask = (1ULL << Desc.NumUnits) - 1;
}
}
#endif
-static unsigned getResourceStateIndex(uint64_t Mask) {
- return std::numeric_limits<uint64_t>::digits - countLeadingZeros(Mask);
-}
-
static std::unique_ptr<ResourceStrategy>
getStrategyFor(const ResourceState &RS) {
if (RS.isAResourceGroup() || RS.getNumUnits() > 1)