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_ARK_FRAME_LOWERING_FRAME_BUILDER_H 17 #define LIBLLVMBACKEND_TRANSFORMS_PASSES_ARK_FRAME_LOWERING_FRAME_BUILDER_H 18 19 #include <functional> 20 21 #include <llvm/CodeGen/MachineFunction.h> 22 23 struct FrameInfo { 24 using RegMasks = std::tuple<uint32_t, uint32_t>; 25 26 // This field used only in aarch64 FrameBuilder 27 uint32_t stackSize {}; 28 // Mask of used callee saved registers in Ark terms 29 RegMasks regMasks {}; 30 bool hasCalls = false; 31 ssize_t soOffset = 0; 32 // True, if the function uses stack in blocks except prologue and epilogue. 33 // E.g. allocates a stack object 34 bool usesStack = false; 35 // True, if the function uses float register in some way. 36 // It is needed to notify runtime about usage of float registers 37 bool usesFloatRegs = false; 38 }; 39 40 // CC-OFFNXT(G.NAM.01) false positive 41 enum class FrameConstantDescriptor { 42 FRAME_FLAGS, 43 TLS_FRAME_OFFSET, 44 }; 45 46 struct InlineAsmBuilder; 47 48 struct FrameBuilderInterface { 49 using ConstantPoolHandler = std::function<ssize_t(FrameConstantDescriptor)>; 50 51 public: FrameBuilderInterfaceFrameBuilderInterface52 FrameBuilderInterface(FrameInfo frameInfo, ConstantPoolHandler handler) 53 : frameInfo_ {std::move(frameInfo)}, constantPool_ {std::move(handler)} 54 { 55 } 56 virtual ~FrameBuilderInterface() = default; 57 58 virtual bool RemovePrologue(llvm::MachineBasicBlock &mblock) = 0; 59 virtual bool RemoveEpilogue(llvm::MachineBasicBlock &mblock) = 0; 60 virtual void InsertPrologue(llvm::MachineBasicBlock &mblock) = 0; 61 virtual void InsertEpilogue(llvm::MachineBasicBlock &mblock) = 0; 62 GetFrameInfoFrameBuilderInterface63 FrameInfo &GetFrameInfo() 64 { 65 return frameInfo_; 66 } 67 68 FrameBuilderInterface(const FrameBuilderInterface &) = delete; 69 void operator=(const FrameBuilderInterface &) = delete; 70 FrameBuilderInterface(FrameBuilderInterface &&) = delete; 71 FrameBuilderInterface &operator=(FrameBuilderInterface &&) = delete; 72 73 protected: 74 FrameInfo frameInfo_; // NOLINT(misc-non-private-member-variables-in-classes) 75 ConstantPoolHandler constantPool_; // NOLINT(misc-non-private-member-variables-in-classes) 76 }; 77 78 struct AMD64FrameBuilder final : FrameBuilderInterface { AMD64FrameBuilderfinal79 AMD64FrameBuilder(FrameInfo frameInfo, ConstantPoolHandler handler) 80 : FrameBuilderInterface(std::move(frameInfo), std::move(handler)) 81 { 82 } 83 ~AMD64FrameBuilder() override = default; 84 85 bool RemovePrologue(llvm::MachineBasicBlock &mblock) override; 86 bool RemoveEpilogue(llvm::MachineBasicBlock &mblock) override; 87 void InsertPrologue(llvm::MachineBasicBlock &mblock) override; 88 void InsertEpilogue(llvm::MachineBasicBlock &mblock) override; 89 90 AMD64FrameBuilder(const AMD64FrameBuilder &) = delete; 91 void operator=(const AMD64FrameBuilder &) = delete; 92 AMD64FrameBuilder(AMD64FrameBuilder &&) = delete; 93 AMD64FrameBuilder &operator=(AMD64FrameBuilder &&) = delete; 94 }; 95 96 struct ARM64FrameBuilder final : FrameBuilderInterface { ARM64FrameBuilderfinal97 ARM64FrameBuilder(FrameInfo frameInfo, ConstantPoolHandler handler) 98 : FrameBuilderInterface(std::move(frameInfo), std::move(handler)) 99 { 100 } 101 ~ARM64FrameBuilder() override = default; 102 103 bool RemovePrologue(llvm::MachineBasicBlock &mblock) override; 104 bool RemoveEpilogue(llvm::MachineBasicBlock &mblock) override; 105 void InsertPrologue(llvm::MachineBasicBlock &mblock) override; 106 void InsertEpilogue(llvm::MachineBasicBlock &mblock) override; 107 108 ARM64FrameBuilder(const ARM64FrameBuilder &) = delete; 109 void operator=(const ARM64FrameBuilder &) = delete; 110 ARM64FrameBuilder(ARM64FrameBuilder &&) = delete; 111 ARM64FrameBuilder &operator=(ARM64FrameBuilder &&) = delete; 112 113 private: 114 void EmitCSRSaveRestoreCode(InlineAsmBuilder *builder, uint32_t regsMask, std::string_view asmSingleReg, 115 std::string_view asmPairRegs, ssize_t calleeOffset); 116 }; 117 118 #endif // LIBLLVMBACKEND_TRANSFORMS_PASSES_ARK_FRAME_LOWERING_FRAME_BUILDER_H 119