1 /* 2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef LIBLLVMBACKEND_TRANSFORMS_PASSES_GEP_PROPAGATION_H 17 #define LIBLLVMBACKEND_TRANSFORMS_PASSES_GEP_PROPAGATION_H 18 19 #include <llvm/IR/IRBuilder.h> 20 #include <llvm/IR/PassManager.h> 21 22 namespace ark::llvmbackend { 23 struct LLVMCompilerOptions; 24 } // namespace ark::llvmbackend 25 26 namespace llvm { 27 class Instruction; 28 } // namespace llvm 29 30 namespace ark::llvmbackend::passes { 31 32 class GepPropagation : public llvm::PassInfoMixin<GepPropagation> { 33 public: ShouldInsert(const ark::llvmbackend::LLVMCompilerOptions * options)34 static bool ShouldInsert([[maybe_unused]] const ark::llvmbackend::LLVMCompilerOptions *options) 35 { 36 return true; 37 } 38 39 // NOLINTNEXTLINE(readability-identifier-naming) 40 llvm::PreservedAnalyses run(llvm::Function &function, llvm::FunctionAnalysisManager &analysisManager); 41 42 private: 43 using SelectorSplitMap = llvm::DenseMap<llvm::Instruction *, std::pair<llvm::Instruction *, llvm::Instruction *>>; 44 45 void AddToVector(llvm::Instruction *inst, llvm::SmallVector<llvm::Instruction *> *toExpand, 46 llvm::SmallVector<llvm::Instruction *> *selectors); 47 48 void Propagate(llvm::Function *function); 49 50 void SplitGepSelectors(llvm::Function *function, llvm::SmallVector<llvm::Instruction *> *selectors, 51 llvm::DenseMap<llvm::Instruction *, llvm::Instruction *> *sgeps); 52 53 std::pair<llvm::Value *, llvm::Value *> GenerateInput(llvm::Value *input, llvm::Instruction *inst, 54 llvm::Instruction *inPoint, const SelectorSplitMap &mapping); 55 56 void GenerateSelectorInputs(llvm::Instruction *inst, const SelectorSplitMap &mapping); 57 58 llvm::Value *GetConstantOffset(llvm::Constant *offset, llvm::Type *type); 59 60 std::pair<llvm::Value *, bool> GetBasePointer(llvm::Value *value); 61 62 llvm::Value *GetConstantInput(llvm::Instruction *inst); 63 64 void OptimizeGepoffs(SelectorSplitMap &mapping); 65 66 void OptimizeSelectors(SelectorSplitMap &mapping); 67 68 void ReplaceWithSplitGep(llvm::Instruction *inst, llvm::Instruction *gep); 69 70 void ReplaceRecursively(llvm::Instruction *inst, llvm::SmallVector<llvm::Instruction *, 1> *seq); 71 72 llvm::Instruction *CloneSequence(llvm::IRBuilder<> *builder, llvm::SmallVector<llvm::Instruction *, 1> *seq); 73 74 public: 75 static constexpr llvm::StringRef ARG_NAME = "gep-propagation"; 76 }; 77 78 } // namespace ark::llvmbackend::passes 79 80 #endif // LIBLLVMBACKEND_TRANSFORMS_PASSES_GEP_PROPAGATION_H 81