[PATCH] D98976: [CodeGen] Use ProcResGroup information in SchedBoundary

David Penry via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 15 11:33:41 PDT 2021


dpenry added a comment.

OK, I think we are in agreement about what they're supposed to allow/disallow when ResourceCycles is uniform.  I'd like to make a stab at making this work in the general cases of SchedWriteRes you mentioned before as well:

1. //Resource is member of multiple resource groups//: there's nothing conceptually too difficult about it; just a matter of coding it up.
2. //Mixed latencies//:  In the code below, in the cycle after an instruction with UnevenWideWrite issues, should it be possible to issue one or two MyNarrowWrites?  I'm inclined to say it should be one.... only X is actually available for use in that cycle.
3. //Leftover group time//: If I've understood what you've remarked on before, after issuing OverWideWrite nothing else in the group can issue for this or the following cycle.  After issuing OverNarrowWrite, only one NarrowWrite can issue in this cycle or the next cycle.

  def X : ProcResource<1>;
  def Y : ProcResource<1>;
  def A : ProcResGroup<[X, Y]>;
  
  def UnevenWideWrite : SchedWriteRes<[X,Y]> {
    let ResourceCycles = [1,2];
  }
  def MyNarrowWrite : SchedWriteRes<[A]> {
    let ResourceCycles = [1];
  }
  def OverWideWrite : SchedWriteRes<[X,Y,A]> {
    let ResourceCycles = [1,1,1];
  }
  def OverNarrowWrite : SchedWriteRes<[X,A]> {
    let ResourceCycles = [1,1];
  }

As an algorithmic detail, though there's logically one instance of a ProcResGroup, the subtarget emitter actually reports it to have as many instances as the total instances of its members.  There seem to be a few options for dealing with groups:

1. Continue to instantiate that many instances in the scheduler and use them to track how many members of the group have been spoken for in each cycle.  This will support all of the general cases and carries the most flavor of what I've tried to do before.
2. Instantiate only one instance of the processor resource group, but don't track how many members have been spoken for (because tracking would be effectively the same thing as the previous option but with more changes to the code).
  1. Only mark it as in use if there is leftover group time.  This will not permit dual issue of OverNarrowWrite with anything else from the group, as the group will have been marked used.
  2. OR mark it as in use if there is leftover group time and all members are used.  In this case, we lose the extra time in which OverNarrowWrite prevents a dual-issue of NarrowWrite.
3. Don't instantiate the processor resource group at all and assign the leftover time to some chosen victim.
4. Don't instantiate the processor resource group at all and declare that leftover time gets ignored during hazarding (but is still part of pressure calculations) for BufferSize = 0.

Use of the second, third, or fourth alternative will require some means of choosing which member is the victim; first-available, LRU, or plugin are all viable options.

At this point, #4 is the way I'm leaning; it's clean and simple -- a resource group is fully used (and thus prevents further issue) when all its members are used.  No extra tracking is required.  It is also fairly simple to state what model features are not being handled -- write resources which mix the members and the group and for which the group has BufferSize = 0.  #2 and #3 just seem like half-solutions that will sometimes work and sometimes not work.  #1 will leave code very similar to what you see now (without dividing cycles by units used, but still requiring requests for multiple instances).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98976/new/

https://reviews.llvm.org/D98976



More information about the llvm-commits mailing list