[PATCH] D108750: [PowerPC] common chains to reuse offsets to reduce register pressure

Jinsong Ji via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 21 08:32:51 PDT 2021


jsji added inline comments.


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:67
+//    A1_new = p + base1 // chain 1
+//    B1_new = p + base2 // chain 2, now inside the loop, offset is reused.
+//
----------------
`offset is reused` ? common offset is re-used?


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:71
+//      unsigned long x1 = *(unsigned long *)(A1_new + i);
+//      unsigned long x2 = *(unsigned long *)(A1_new + offset + i);
+//      unsigned long x3 = *(unsigned long *)(B1_new + i);
----------------
Should we use `((A1_new + i) + offset )` to be clearer?


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:422
+// use that start as a chain separator.
+static bool isValidChainCommoningCandidate(const SCEV *LSCEV) {
+  const SCEVAddRecExpr *ARSCEV = cast<SCEVAddRecExpr>(LSCEV);
----------------
`isChainCommoningCandidate` , to be aligned with `isDSFormCandidate` etc.


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:488
+  // Reach the limit.
+  if (Buckets.size() > MaxBucketNum)
+    return;
----------------
Why we have this limit check here, but not in `addOneCandidate`?

Also we should at least emit some debug log if we are really discarding candidate due to bucket limit here.


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:491
+
+  if (!isValidChainCommoningCandidate(LSCEV))
+    return;
----------------
This should be checked in collectCandiate, as `isValidCandidate`.


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:500
+    const SCEV *Diff = SE->getMinusSCEV(LSCEV, B.BaseSCEV);
+    if (isValidChainCommoningDiff(Diff)) {
+      B.Elements.push_back(BucketElement(Diff, MemI));
----------------
Can we also abstract this check so that we can also reuse `addOneCandidate` to do this.

Something like:

```
 for (auto &B : Buckets) {
    const SCEV *Diff = SE->getMinusSCEV(LSCEV, B.BaseSCEV);
    if ( const auto *Diff = isValidDiff(Diff, LSCEV, B.BaseSCEV)) {
      B.Elements.push_back(BucketElement(Diff, MemI));
      FoundBucket = true;
      break;
    }
  }
```

then  we use `isValidConstantDiff` for others, but `isValidChainCommoningDiff` for this.

```
isValidConstantDiff(Diff, LSCEV, B.BaseSCEV) ={
return dyn_cast<SCEVConstant>(Diff)
}

isValidChainCommoningDiff(Diff, LSCEV, B.BaseSCEV) ={

  assert(LSCEV && "Invalid SCEV for Ptr value.");

  // Don't mess up previous dform prepare.
  if (isa<SCEVConstant>(LSCEV))
    return null_ptr;

  // A single integer type offset.
  if (isa<SCEVUnknown>(LSCEV) && LSCEV->getType()->isIntegerTy())
    return Diff;

  const SCEVNAryExpr *ASCEV = dyn_cast<SCEVNAryExpr>(LSCEV);
  if (!ASCEV)
    return null_ptr;

  for (const SCEV *Op : ASCEV->operands())
    if (!Op->getType()->isIntegerTy())
      return null_ptr;

  return Diff;


}


```


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:585
+  // The number of new bases should both be sqrt(EleNum).
+  if (!SawChainSeparater) {
+    unsigned ChainNum = (unsigned)sqrt(EleNum);
----------------
How about this?

```
 unsigned ChainNum=FirstOffsetReusedCount / FirstOffsetReusedCountInFirstChain;
 if (!SawChainSeparater) 
   ChainNum = (unsigned)sqrt(EleNum);

  CBucket.ChainSize = (unsigned)(EleNum / ChainNum);

  // If this is not a perfect chain(eg: all elements can be put inside
  // commoning chains.), skip now.
  if (CBucket.ChainSize * ChainNum != EleNum)
      return false;

  if (SawChainSeparater) {
  // Check that the offset seqs are the same for all chains?
      for (unsigned i = 1; i < CBucket.ChainSize; i++)
          for (unsigned j = 1; j < ChainNum; j++)
             if (CBucket.Elements[i].Offset !=
                 SE->getMinusSCEV(CBucket.Elements[i + j * CBucket.ChainSize].Offset,
                           CBucket.Elements[j * CBucket.ChainSize].Offset))
             return false;

   }

  for (unsigned i = 0; i < ChainNum; i++)
    CBucket.ChainBases.push_back(CBucket.Elements[i * CBucket.ChainSize]);
```


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:603
+
+  // All Elements can be put inside commoning Chain.
+  if (CBucket.ChainSize * ChainNum != EleNum)
----------------
Not all elements?


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:607
+
+  // Check each chain has same offsets for all elements.
+  for (unsigned i = 1; i < CBucket.ChainSize; i++)
----------------
// Check that the offset seqs are the same for all chains?


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:948
+
+  if (IsChainCommoning && !EnableChainCommoning)
+    return Buckets;
----------------
Since we are reusing `collectCandidates`, this check can be moved out to around line 1488.


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:975
+      if (IsChainCommoning)
+        addOneCandidateForChainCommoning(&J, LSCEV, Buckets, MaxCandidateNum);
+      else if (isValidCandidate(&J, PtrValue, PointerElementType))
----------------
Why we can't pass `isValidChainCommoningCandidate` as `isValidCandate` (yes, need to add one more LSCEV parameter to function prototype) , and pass`addOneCandidateForChainCommoning` as `addOneCandiate` function too?

Then we don't need the `IsChainCommoning` bool parameter and conditional check here.


================
Comment at: llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp:498
+
+  for (const auto &BB : L->blocks())
+    for (auto &J : *BB) {
----------------
shchenz wrote:
> jsji wrote:
> > We already collected both Dform and DQform buckets before, can we reuse some info to do early exit?
> Good idea. We can share the info among all forms. I split this into a new patch D112196.
D112196 looks good. But I think we can still do more for this? eg: If both Dform and DQform buckets are empty, then there is no point trying to run this commoning either?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D108750



More information about the llvm-commits mailing list