xref: /freebsd/contrib/llvm-project/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- PackReuse.cpp - A pack de-duplication pass -------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.h"
10 #include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h"
11 
12 namespace llvm::sandboxir {
13 
runOnRegion(Region & Rgn,const Analyses & A)14 bool PackReuse::runOnRegion(Region &Rgn, const Analyses &A) {
15   if (Rgn.empty())
16     return Change;
17   // The key to the map is the ordered operands of the pack.
18   // The value is a vector of all Pack Instrs with the same operands.
19   DenseMap<std::pair<BasicBlock *, SmallVector<Value *>>,
20            SmallVector<SmallVector<Instruction *>>>
21       PacksMap;
22   // Go over the region and look for pack patterns.
23   for (auto *I : Rgn) {
24     auto PackOpt = VecUtils::matchPack(I);
25     if (PackOpt) {
26       // TODO: For now limit pack reuse within a BB.
27       BasicBlock *BB = (*PackOpt->Instrs.front()).getParent();
28       PacksMap[{BB, PackOpt->Operands}].push_back(PackOpt->Instrs);
29     }
30   }
31   for (auto &Pair : PacksMap) {
32     auto &Packs = Pair.second;
33     if (Packs.size() <= 1)
34       continue;
35     // Sort packs by program order.
36     sort(Packs, [](const auto &PackInstrs1, const auto &PackInstrs2) {
37       return PackInstrs1.front()->comesBefore(PackInstrs2.front());
38     });
39     Instruction *TopMostPack = Packs[0].front();
40     // Replace duplicate packs with the first one.
41     for (const auto &PackInstrs :
42          make_range(std::next(Packs.begin()), Packs.end())) {
43       PackInstrs.front()->replaceAllUsesWith(TopMostPack);
44       // Delete the pack instrs bottom-up since they are now dead.
45       for (auto *PackI : PackInstrs)
46         PackI->eraseFromParent();
47     }
48     Change = true;
49   }
50   return Change;
51 }
52 
53 } // namespace llvm::sandboxir
54