[llvm] [CostModel][AArch64] Make extractelement, with fmul user, free whenev… (PR #111479)

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 8 01:24:06 PDT 2024


================
@@ -11633,6 +11633,17 @@ InstructionCost BoUpSLP::getTreeCost(ArrayRef<Value *> VectorizedVals) {
   std::optional<DenseMap<Value *, unsigned>> ValueToExtUses;
   DenseMap<const TreeEntry *, DenseSet<Value *>> ExtractsCount;
   SmallPtrSet<Value *, 4> ScalarOpsFromCasts;
+  // Keep track of {Scalar, Index} -> User and User -> {Scalar, Index}.
+  // On AArch64, this helps in fusing a mov instruction, associated with
+  // extractelement, with fmul in the backend so that extractelement is free.
+  DenseMap<std::pair<Value *, unsigned>, SmallVector<Value *, 4>>
+      ScalarAndIdxToUser;
+  DenseMap<Value *, SmallVector<std::pair<Value *, unsigned>, 4>>
+      UserToScalarAndIdx;
+  for (ExternalUser &EU : ExternalUses) {
+    UserToScalarAndIdx[EU.User].push_back({EU.Scalar, EU.Lane});
----------------
david-arm wrote:

I'm not sure you really need two dense maps here that essentially carry exactly the same data, but in a different way. Can you not just have two arguments of SmallVectors, one for a list of `EU.User` and the other for a list of `{EU.Scalar, EU.Lane}`, i.e. something like

```
SmallVector<Value *, 4> Users;
SmallVector<std::pair<Value *, unsigned>, 4>> ScalarAndLane;
```

We then know that any give index `Idx` `Users[Idx]` corresponds to `ScalarAndLane[Idx]`. It would avoid having to duplicate the data and make the arguments simpler, unless I've missed something?

https://github.com/llvm/llvm-project/pull/111479


More information about the llvm-commits mailing list