• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_LLVM_ARK_INTERFACE_H
17 #define LIBLLVMBACKEND_LLVM_ARK_INTERFACE_H
18 
19 #include <map>
20 #include <unordered_map>
21 
22 #include <llvm/ADT/DenseMap.h>
23 #include <llvm/ADT/Triple.h>
24 #include <llvm/ADT/StringMap.h>
25 #include <llvm/IR/IRBuilder.h>
26 #include <llvm/IR/ValueMap.h>
27 #include <llvm/IR/Intrinsics.h>
28 #include <llvm/Support/AtomicOrdering.h>
29 
30 #include "llvm/IR/Instructions.h"
31 
32 namespace llvm {
33 class Function;
34 class FunctionType;
35 class Instruction;
36 class Module;
37 }  // namespace llvm
38 
39 namespace panda {
40 class Method;
41 }  // namespace panda
42 
43 namespace panda::compiler {
44 class RuntimeInterface;
45 class Graph;
46 }  // namespace panda::compiler
47 
48 namespace panda::panda_file {
49 class File;
50 }  // namespace panda::panda_file
51 
52 namespace panda::llvmbackend {
53 
54 class LLVMArkInterface {
55 public:
56     using MethodPtr = void *;
57     using MethodId = uint32_t;
58     using IntrinsicId = int;
59     using EntrypointId = int;
60     using RuntimeCallee = std::pair<llvm::FunctionType *, llvm::StringRef>;
61     using RegMasks = std::tuple<uint32_t, uint32_t>;
62     enum class RuntimeCallType { INTRINSIC, ENTRYPOINT };
63 
64     explicit LLVMArkInterface(panda::compiler::RuntimeInterface *runtime, llvm::Triple triple);
65 
66     RuntimeCallee GetEntrypointCallee(EntrypointId id) const;
67 
68     const char *GetThreadRegister() const;
69 
70     const char *GetFramePointerRegister() const;
71 
72     uintptr_t GetEntrypointTlsOffset(EntrypointId id) const;
73 
74     size_t GetTlsPreWrbEntrypointOffset() const;
75 
76     llvm::Function *GetFunctionByMethodPtr(MethodPtr method) const;
77 
78     void PutFunction(MethodPtr methodPtr, llvm::Function *function);
79 
80     const char *GetIntrinsicRuntimeFunctionName(IntrinsicId id) const;
81 
82     const char *GetEntrypointRuntimeFunctionName(EntrypointId id) const;
83 
84     llvm::StringRef GetRuntimeFunctionName(LLVMArkInterface::RuntimeCallType callType, IntrinsicId id);
85     llvm::FunctionType *GetRuntimeFunctionType(llvm::StringRef name) const;
86     llvm::FunctionType *GetOrCreateRuntimeFunctionType(llvm::LLVMContext &ctx, llvm::Module *module,
87                                                        LLVMArkInterface::RuntimeCallType callType, IntrinsicId id);
88 
89     void RememberFunctionOrigin(const llvm::Function *function, MethodPtr methodPtr);
90 
91     std::string GetUniqMethodName(MethodPtr methodPtr) const;
92 
93     std::string GetUniqMethodName(const Method *method) const;
94 
95     static std::string GetUniqueBasicBlockName(const std::string &bbName, const std::string &uniqueSuffix);
96 
97     uint32_t GetManagedThreadPostWrbOneObjectOffset() const;
98 
99     bool IsIrtocMode() const;
100 
IsArm64()101     bool IsArm64() const
102     {
103         return triple_.getArch() == llvm::Triple::ArchType::aarch64;
104     }
105 
106     void AppendIrtocReturnHandler(llvm::StringRef returnHandler);
107 
108     bool IsIrtocReturnHandler(const llvm::Function &function) const;
109 
110 public:
111     static constexpr auto NO_INTRINSIC_ID = static_cast<IntrinsicId>(-1);
112     static constexpr auto GC_ADDR_SPACE = 271;
113 
114     static constexpr auto VOLATILE_ORDER = llvm::AtomicOrdering::SequentiallyConsistent;
115     static constexpr auto NOT_ATOMIC_ORDER = llvm::AtomicOrdering::NotAtomic;
116 
117     static constexpr std::string_view FUNCTION_MD_CLASS_ID = "class_id";
118     static constexpr std::string_view FUNCTION_MD_INLINE_MODULE = "inline_module";
119     static constexpr std::string_view PATCH_STACK_ADJUSTMENT_COMMENT = " ${:comment} patch-stack-adjustment";
120 
GetRuntime()121     panda::compiler::RuntimeInterface *GetRuntime()
122     {
123         return runtime_;
124     }
125 
126 private:
127     static constexpr auto NO_INTRINSIC_ID_CONTINUE = static_cast<IntrinsicId>(-2);
128 
129     panda::compiler::RuntimeInterface *runtime_;
130     llvm::Triple triple_;
131     llvm::StringMap<llvm::FunctionType *> runtimeFunctionTypes_;
132 
133     llvm::ValueMap<const llvm::Function *, const panda_file::File *> functionOrigins_;
134     llvm::DenseMap<MethodPtr, llvm::Function *> functions_;
135     llvm::DenseMap<llvm::Function *, uint8_t> sourceLanguages_;
136     std::vector<llvm::StringRef> irtocReturnHandlers_;
137 };
138 }  // namespace panda::llvmbackend
139 #endif  // LIBLLVMBACKEND_LLVM_ARK_INTERFACE_H
140