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)14bool 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