[PATCH] D46018: [GlobalISel][IRTranslator] Split aggregates during IR translation

Roman Tereshin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 8 23:28:42 PDT 2018


rtereshin added a comment.

Hi Amara,

I think I'm about half-way through, didn't touch the `{pack,unpack}Regs` functions and the whole story with interfacing with legacy call-lowering yet.

This is great work, thank you for doing this!

Roman



================
Comment at: lib/CodeGen/GlobalISel/IRTranslator.cpp:121
+      computeValueLLTs(DL, **EI, ValueTys, Offsets,
+                       StartingOffset + SL->getElementOffset(EI - EB));
+    return;
----------------
Maybe this way it's just a bit more straightforward:
```
  for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I)
    computeValueLLTs(DL, *STy->getElementType(I), ValueTys, Offsets,
                     StartingOffset + SL->getElementOffset(I));
```
It's alright as it is, of course, just in case you would like the version above better yourself.


================
Comment at: lib/CodeGen/GlobalISel/IRTranslator.cpp:128
+    uint64_t EltSize = DL.getTypeAllocSize(EltTy);
+    for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
+      computeValueLLTs(DL, *EltTy, ValueTys, Offsets,
----------------
I think we're trying to stick to capitalized local variables' names, including loop induction variables.


================
Comment at: lib/CodeGen/GlobalISel/IRTranslator.cpp:157
+  SmallVector<LLT, 4> SplitTys;
+  computeValueLLTs(*DL, *Val.getType(), SplitTys, *Offsets);
+
----------------
Looks like technically for aggregate constants `getOrCreateVRegs` has worst case complexity of `O(N^2)`, for constants like `{ i8 0, { i8 0, { i8 0, ... } } }`, but this is probably not easy to avoid and such constants hopefully don't happen often.


================
Comment at: lib/CodeGen/GlobalISel/IRTranslator.cpp:173
+    }
+  } else {
+    assert(SplitTys.size() == 1 && "unexpectedly split LLT");
----------------
This piece in general is not exactly trivial, perhaps it makes sense to add test cases having multiple deeply nested aggregate constants sharing some parts so `getOrCreateVRegs` would visit an actual non-tree DAG while traversing them.


================
Comment at: lib/CodeGen/GlobalISel/IRTranslator.cpp:176
+    VRegs->push_back(MRI->createGenericVirtualRegister(SplitTys[0]));
+    bool Success = translate(cast<Constant>(Val), (*VRegs)[0]);
     if (!Success) {
----------------
`VRegs->front()` maybe


================
Comment at: lib/CodeGen/GlobalISel/IRTranslator.cpp:474
+  for (auto DstReg : getOrCreateVRegs(U))
+    MIRBuilder.buildCopy(DstReg, SrcRegs[Idx++]);
 
----------------
Same note as for `insertvalue`, do we really need to build these copies here?


================
Comment at: lib/CodeGen/GlobalISel/IRTranslator.cpp:508
+    else
+      MIRBuilder.buildCopy(DstRegs[i], SrcRegs[i]);
+  }
----------------
Let's say we have a large aggregate that eventually maps to N vregs, and also N `insertvalue`s each of which replaces just a single item (vreg). Will we end up generating N^2 `COPY`s for the IR of initial size `O(N)` here?

Granted, this probably happens very rarely in practice, but what if we don't `getOrCreateVRegs(U)`, but rather just `get(U)` (no implicit `MIR.createGenericRegister` calls), resize, and assign either `*InsertedIt++` or `SrcRegs[i]` to it directly w/o building any explicit `COPY`s at all? We're just remapping values back and forth here during translation, with always constant indices, so the whole thing could be copy-propagated on the fly avoiding quite a bit of MIR-churn.


Repository:
  rL LLVM

https://reviews.llvm.org/D46018





More information about the llvm-commits mailing list