1 /* 2 * Copyright (c) 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 #include "aarch64_fixup_sdiv.h" 17 18 #include "llvm_ark_interface.h" 19 20 #include "transforms/transform_utils.h" 21 22 #define DEBUG_TYPE "aarch64-fixup-sdiv" 23 24 namespace ark::llvmbackend::passes { 25 Create(LLVMArkInterface * arkInterface,const LLVMCompilerOptions * options)26AArch64FixupSDiv AArch64FixupSDiv::Create(LLVMArkInterface *arkInterface, 27 [[maybe_unused]] const LLVMCompilerOptions *options) 28 { 29 return AArch64FixupSDiv(arkInterface); 30 } 31 ReplaceSelect(llvm::Instruction * selectInst)32bool AArch64FixupSDiv::ReplaceSelect(llvm::Instruction *selectInst) 33 { 34 auto cmp = llvm::cast<llvm::Instruction>(selectInst->getOperand(0U)); 35 auto sub = selectInst->getOperand(1U); 36 auto sdiv = selectInst->getOperand(2U); 37 38 // sub instruction may be replaced with value 39 auto sdivInst = llvm::cast<llvm::Instruction>(sdiv); 40 41 selectInst->replaceAllUsesWith(sdivInst); 42 sdivInst->takeName(selectInst); 43 ASSERT(!sdivInst->getDebugLoc()); 44 sdivInst->setDebugLoc(selectInst->getDebugLoc()); 45 selectInst->eraseFromParent(); 46 if (cmp->uses().empty()) { 47 cmp->eraseFromParent(); 48 } 49 if (sub->uses().empty() && llvm::isa<llvm::Instruction>(sub)) { 50 auto subInst = llvm::cast<llvm::Instruction>(sub); 51 subInst->eraseFromParent(); 52 } 53 return true; 54 } 55 AArch64FixupSDiv(LLVMArkInterface * arkInterface)56AArch64FixupSDiv::AArch64FixupSDiv(LLVMArkInterface *arkInterface) : arkInterface_(arkInterface) {} 57 run(llvm::Function & function,llvm::FunctionAnalysisManager & analysisManager)58llvm::PreservedAnalyses AArch64FixupSDiv::run(llvm::Function &function, 59 [[maybe_unused]] llvm::FunctionAnalysisManager &analysisManager) 60 { 61 if (!arkInterface_->IsArm64()) { 62 return llvm::PreservedAnalyses::all(); 63 } 64 bool changed = false; 65 for (auto &basicBlock : function) { 66 llvm::SmallVector<llvm::Instruction *> selectInsts; 67 for (auto &instruction : basicBlock) { 68 if (instruction.hasMetadata(LLVMArkInterface::AARCH64_SDIV_INST)) { 69 ASSERT(instruction.getOpcode() == llvm::Instruction::Select); 70 selectInsts.push_back(&instruction); 71 } 72 } 73 for (auto selectInst : selectInsts) { 74 changed |= ReplaceSelect(selectInst); 75 } 76 } 77 78 return changed ? llvm::PreservedAnalyses::none() : llvm::PreservedAnalyses::all(); 79 } 80 81 } // namespace ark::llvmbackend::passes 82