• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_GC_UTILS_H
17 #define LIBLLVMBACKEND_TRANSFORMS_PASSES_GC_UTILS_H
18 
19 #include "llvm_ark_interface.h"
20 
21 #include <llvm/ADT/SmallSet.h>
22 #include <llvm/IR/Function.h>
23 #include <llvm/IR/Type.h>
24 #include <llvm/IR/Instructions.h>
25 
26 namespace ark::llvmbackend::gc_utils {
27 
28 enum class DerivedStatus { UNKNOWN, DERIVED, NOT_DERIVED };
29 bool IsDerived(llvm::Value *val);
30 DerivedStatus IsPHIDerived(llvm::PHINode *phi, llvm::SmallSet<llvm::Value *, 8U> *visited);
31 DerivedStatus IsDerivedImpl(llvm::Value *val, llvm::SmallSet<llvm::Value *, 8U> *visited = nullptr);
32 bool HasBeenGcRef(const llvm::Value *val, bool any = true);
33 void MarkAsNonMovable(llvm::Instruction *instruction);
34 bool IsNonMovable(const llvm::Value *value);
35 
IsGcRefType(llvm::Type * type)36 inline bool IsGcRefType(llvm::Type *type)
37 {
38     return type->isPointerTy() && type->getPointerAddressSpace() == ark::llvmbackend::LLVMArkInterface::GC_ADDR_SPACE;
39 }
40 
IsGcFunction(const llvm::Function & function)41 inline bool IsGcFunction(const llvm::Function &function)
42 {
43     return function.hasGC() && function.getGC() == ark::llvmbackend::LLVMArkInterface::GC_STRATEGY;
44 }
45 
IsFunctionSupplemental(const llvm::Function & function)46 inline bool IsFunctionSupplemental(const llvm::Function &function)
47 {
48     if (function.isDeclaration()) {
49         return true;
50     }
51     if (function.getName().equals(ark::llvmbackend::LLVMArkInterface::GC_SAFEPOINT_POLL_NAME)) {
52         return true;
53     }
54     return false;
55 }
56 
57 /// Returns true if a value is an integer comparison with 0.
IsNullCmp(const llvm::Value * val)58 inline bool IsNullCmp(const llvm::Value *val)
59 {
60     auto cmp = llvm::dyn_cast<llvm::ICmpInst>(val);
61     if (cmp == nullptr) {
62         return false;
63     }
64 
65     auto op0 = llvm::dyn_cast<llvm::Constant>(cmp->getOperand(0));
66     auto op1 = llvm::dyn_cast<llvm::Constant>(cmp->getOperand(1));
67     return (op0 != nullptr && op0->isNullValue()) || (op1 != nullptr && op1->isNullValue());
68 }
69 
70 /// Returns true if a value is an instruction that allowed to use with escaped value.
IsAllowedEscapedUser(const llvm::Value * val)71 inline bool IsAllowedEscapedUser(const llvm::Value *val)
72 {
73     return llvm::isa<llvm::CastInst>(val) || IsNullCmp(val);
74 }
75 
76 }  // namespace ark::llvmbackend::gc_utils
77 
78 #endif  //  LIBLLVMBACKEND_TRANSFORMS_PASSES_GC_UTILS_H
79