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