[llvm] r324582 - [TargetSchedule] Expose sub-units of a ProcResGroup in MCProcResourceDesc.
Andrea Di Biagio via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 26 04:14:11 PST 2018
Ping.
On Mon, Feb 19, 2018 at 5:23 PM, Andrea Di Biagio <andrea.dibiagio at gmail.com
> wrote:
> Hi Clement,
>
> Sorry for the late reply. I have been off sick for a while and I've only
> just seen your commit now I'm back to work.
>
> I am currently working on an LLVM based performance analysis tool which
> reuses the information from the scheduling model, for which I plan to send
> an RFC soon (next week hopefully).
>
> When working on my tool, I had to solve a similar problem to this, and had
> come up with a different fix which doesn't require generating an extra
> table with indices.
>
> My implementation (for which I'm happy to share the patch) uses simple
> bitmasks to solve set membership problems. The idea is that each processor
> resource is associated with a bitmask value (a 64-bit unisigned quantity)
> which can be used as a unique identifier.
>
> Example:
>
> ResourceA 001
> ResourceB 010
> ResourceAB 111
>
> Here, Processor resource units only have one bit set. So we can easily
> tell if a resource is a group or not by simply checking the popcount of the
> bitmask. Resource groups will always have more than one bit set in the
> mask, while normal resources would always have exactly one bit set.
>
> Each mask is unique, and we can use the mask value to quickly check if a
> unit is part of a group. Back to the example, ResourceAB has three bits
> set. If we exclude the most significant bit, the remaining bits describe
> the composition of the set.
> In this case we have that:
> 111 --> 100 U (010 U 001)
>
> There is a precedent for doing things like this. For example, functional
> units in itineraries are uniquely identified by an unsigned value (see for
> example AtomItinerariesFU table in the x86 backend).
>
> The advantage is that:
> a) we don't require an extra table,
> b) we can use the mask both as an identifier, and to quickly solve set
> membership problems (with simple bit manipulation operations), and
> c) (as a consequence of b) we can simplify some of the logic that
> verifies the composition of resource groups (for example, method
> CodeGenSchedModels::verifyProcResourceGroups in CodeGenSchedule.cpp may
> be a good candidate).
>
> Since my approach uses bitmasks, there is a limit in the number of
> resources that can be described. With 64 bits we are obviously limited to
> having 64 resources maximum.
> That being said, the processors with the most resources that I have
> observed in the opensource are Haswell and Broadwell which declare 22
> unique resources each (far below what can be encoded with a 64-bit mask).
>
> I tried to look to see if there is any specific reason why this approach
> was taken in the review, but I couldn't see it there. If there is not a
> specific reason to use the table approach, would you be okay if we adopted
> the bitmask approach?
> To be clear, I am not suggesting that your approach is wrong. However, I
> just want to point out that there may be potentially better approaches.
> The bitmask approach makes the implementation of my tool easier (it would
> make my life easier :-)).
>
> Thanks,
> Andrea
>
> On Fri, Feb 9, 2018 at 8:17 AM, Clement Courbet via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> Yes, thanks for pointing that out.
>>
>> On Thu, Feb 8, 2018 at 7:33 PM, Craig Topper <craig.topper at gmail.com>
>> wrote:
>>
>>> Is this responsible for this warning I'm seeing now
>>>
>>> lib/Target/X86/X86GenSubtargetInfo.inc:52484:39: warning: missing field
>>> 'SubUnitsIdxBegin' initializer [-Wmissing-field-initializers]
>>> {DBGFIELD("InvalidUnit") 0, 0, 0},
>>>
>>> ~Craig
>>>
>>> On Thu, Feb 8, 2018 at 12:46 AM, Clement Courbet via llvm-commits <
>>> llvm-commits at lists.llvm.org> wrote:
>>>
>>>> Author: courbet
>>>> Date: Thu Feb 8 00:46:48 2018
>>>> New Revision: 324582
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=324582&view=rev
>>>> Log:
>>>> [TargetSchedule] Expose sub-units of a ProcResGroup in
>>>> MCProcResourceDesc.
>>>>
>>>> Summary:
>>>> Right now using a ProcResource automatically counts as usage of all
>>>> super ProcResGroups. All this is done during codegen, so there is no
>>>> way for schedulers to get this information at runtime.
>>>>
>>>> This adds the information of which individual ProcRes units are
>>>> contained in a ProcResGroup in MCProcResourceDesc.
>>>>
>>>> Reviewers: gchatelet
>>>>
>>>> Subscribers: llvm-commits
>>>>
>>>> Differential Revision: https://reviews.llvm.org/D43023
>>>>
>>>> Modified:
>>>> llvm/trunk/include/llvm/MC/MCSchedule.h
>>>> llvm/trunk/include/llvm/Target/TargetSchedule.td
>>>> llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
>>>>
>>>> Modified: llvm/trunk/include/llvm/MC/MCSchedule.h
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>> MC/MCSchedule.h?rev=324582&r1=324581&r2=324582&view=diff
>>>> ============================================================
>>>> ==================
>>>> --- llvm/trunk/include/llvm/MC/MCSchedule.h (original)
>>>> +++ llvm/trunk/include/llvm/MC/MCSchedule.h Thu Feb 8 00:46:48 2018
>>>> @@ -44,6 +44,11 @@ struct MCProcResourceDesc {
>>>> // an out-of-order cpus.
>>>> int BufferSize;
>>>>
>>>> + // If the resource has sub-units, a pointer to the first element of
>>>> an array
>>>> + // of `NumUnits` elements containing the ProcResourceIdx of the sub
>>>> units.
>>>> + // nullptr if the resource does not have sub-units.
>>>> + const unsigned *SubUnitsIdxBegin;
>>>> +
>>>> bool operator==(const MCProcResourceDesc &Other) const {
>>>> return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx
>>>> && BufferSize == Other.BufferSize;
>>>>
>>>> Modified: llvm/trunk/include/llvm/Target/TargetSchedule.td
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>> Target/TargetSchedule.td?rev=324582&r1=324581&r2=324582&view=diff
>>>> ============================================================
>>>> ==================
>>>> --- llvm/trunk/include/llvm/Target/TargetSchedule.td (original)
>>>> +++ llvm/trunk/include/llvm/Target/TargetSchedule.td Thu Feb 8
>>>> 00:46:48 2018
>>>> @@ -175,8 +175,7 @@ class ProcResourceKind;
>>>> // BufferSize=1.
>>>> //
>>>> // SchedModel ties these units to a processor for any stand-alone defs
>>>> -// of this class. Instances of subclass ProcResource will be
>>>> automatically
>>>> -// attached to a processor, so SchedModel is not needed.
>>>> +// of this class.
>>>> class ProcResourceUnits<ProcResourceKind kind, int num> {
>>>> ProcResourceKind Kind = kind;
>>>> int NumUnits = num;
>>>>
>>>> Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGe
>>>> n/SubtargetEmitter.cpp?rev=324582&r1=324581&r2=324582&view=diff
>>>> ============================================================
>>>> ==================
>>>> --- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original)
>>>> +++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Thu Feb 8 00:46:48
>>>> 2018
>>>> @@ -92,6 +92,8 @@ class SubtargetEmitter {
>>>> &ProcItinLists);
>>>> void EmitProcessorProp(raw_ostream &OS, const Record *R, StringRef
>>>> Name,
>>>> char Separator);
>>>> + void EmitProcessorResourceSubUnits(const CodeGenProcModel
>>>> &ProcModel,
>>>> + raw_ostream &OS);
>>>> void EmitProcessorResources(const CodeGenProcModel &ProcModel,
>>>> raw_ostream &OS);
>>>> Record *FindWriteResources(const CodeGenSchedRW &SchedWrite,
>>>> @@ -578,24 +580,52 @@ void SubtargetEmitter::EmitProcessorProp
>>>> OS << '\n';
>>>> }
>>>>
>>>> +void SubtargetEmitter::EmitProcessorResourceSubUnits(
>>>> + const CodeGenProcModel &ProcModel, raw_ostream &OS) {
>>>> + OS << "\nstatic const unsigned " << ProcModel.ModelName
>>>> + << "ProcResourceSubUnits[] = {\n"
>>>> + << " 0, // Invalid\n";
>>>> +
>>>> + for (unsigned i = 0, e = ProcModel.ProcResourceDefs.size(); i < e;
>>>> ++i) {
>>>> + Record *PRDef = ProcModel.ProcResourceDefs[i];
>>>> + if (!PRDef->isSubClassOf("ProcResGroup"))
>>>> + continue;
>>>> + RecVec ResUnits = PRDef->getValueAsListOfDefs("Resources");
>>>> + for (Record *RUDef : ResUnits) {
>>>> + Record *const RU =
>>>> + SchedModels.findProcResUnits(RUDef, ProcModel,
>>>> PRDef->getLoc());
>>>> + for (unsigned J = 0; J < RU->getValueAsInt("NumUnits"); ++J) {
>>>> + OS << " " << ProcModel.getProcResourceIdx(RU) << ", ";
>>>> + }
>>>> + }
>>>> + OS << " // " << PRDef->getName() << "\n";
>>>> + }
>>>> + OS << "};\n";
>>>> +}
>>>> +
>>>> void SubtargetEmitter::EmitProcessorResources(const CodeGenProcModel
>>>> &ProcModel,
>>>> raw_ostream &OS) {
>>>> - OS << "\n// {Name, NumUnits, SuperIdx, IsBuffered}\n";
>>>> + EmitProcessorResourceSubUnits(ProcModel, OS);
>>>> +
>>>> + OS << "\n// {Name, NumUnits, SuperIdx, IsBuffered,
>>>> SubUnitsIdxBegin}\n";
>>>> OS << "static const llvm::MCProcResourceDesc "
>>>> << ProcModel.ModelName << "ProcResources" << "[] = {\n"
>>>> << " {DBGFIELD(\"InvalidUnit\") 0, 0, 0},\n";
>>>>
>>>> + unsigned SubUnitsOffset = 1;
>>>> for (unsigned i = 0, e = ProcModel.ProcResourceDefs.size(); i < e;
>>>> ++i) {
>>>> Record *PRDef = ProcModel.ProcResourceDefs[i];
>>>>
>>>> Record *SuperDef = nullptr;
>>>> unsigned SuperIdx = 0;
>>>> unsigned NumUnits = 0;
>>>> + const unsigned SubUnitsBeginOffset = SubUnitsOffset;
>>>> int BufferSize = PRDef->getValueAsInt("BufferSize");
>>>> if (PRDef->isSubClassOf("ProcResGroup")) {
>>>> RecVec ResUnits = PRDef->getValueAsListOfDefs("Resources");
>>>> for (Record *RU : ResUnits) {
>>>> NumUnits += RU->getValueAsInt("NumUnits");
>>>> + SubUnitsOffset += NumUnits;
>>>> }
>>>> }
>>>> else {
>>>> @@ -612,8 +642,14 @@ void SubtargetEmitter::EmitProcessorReso
>>>> OS << " {DBGFIELD(\"" << PRDef->getName() << "\") ";
>>>> if (PRDef->getName().size() < 15)
>>>> OS.indent(15 - PRDef->getName().size());
>>>> - OS << NumUnits << ", " << SuperIdx << ", "
>>>> - << BufferSize << "}, // #" << i+1;
>>>> + OS << NumUnits << ", " << SuperIdx << ", " << BufferSize << ", ";
>>>> + if (SubUnitsBeginOffset != SubUnitsOffset) {
>>>> + OS << ProcModel.ModelName << "ProcResourceSubUnits + "
>>>> + << SubUnitsBeginOffset;
>>>> + } else {
>>>> + OS << "nullptr";
>>>> + }
>>>> + OS << "}, // #" << i+1;
>>>> if (SuperDef)
>>>> OS << ", Super=" << SuperDef->getName();
>>>> OS << "\n";
>>>>
>>>>
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>>
>>>
>>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180226/c5aa5c9c/attachment.html>
More information about the llvm-commits
mailing list