• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)26 AArch64FixupSDiv AArch64FixupSDiv::Create(LLVMArkInterface *arkInterface,
27                                           [[maybe_unused]] const LLVMCompilerOptions *options)
28 {
29     return AArch64FixupSDiv(arkInterface);
30 }
31 
ReplaceSelect(llvm::Instruction * selectInst)32 bool 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)56 AArch64FixupSDiv::AArch64FixupSDiv(LLVMArkInterface *arkInterface) : arkInterface_(arkInterface) {}
57 
run(llvm::Function & function,llvm::FunctionAnalysisManager & analysisManager)58 llvm::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