• 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_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 enum class FrameConstantDescriptor {
41     FRAME_FLAGS,
42     TLS_FRAME_OFFSET,
43 };
44 
45 struct InlineAsmBuilder;
46 
47 struct FrameBuilderInterface {
48     using ConstantPoolHandler = std::function<ssize_t(FrameConstantDescriptor)>;
49 
50 public:
FrameBuilderInterfaceFrameBuilderInterface51     FrameBuilderInterface(FrameInfo frameInfo, ConstantPoolHandler handler)
52         : frameInfo_ {std::move(frameInfo)}, constantPool_ {std::move(handler)}
53     {
54     }
55     virtual ~FrameBuilderInterface() = default;
56 
57     virtual bool RemovePrologue(llvm::MachineBasicBlock &mblock) = 0;
58     virtual bool RemoveEpilogue(llvm::MachineBasicBlock &mblock) = 0;
59     virtual void InsertPrologue(llvm::MachineBasicBlock &mblock) = 0;
60     virtual void InsertEpilogue(llvm::MachineBasicBlock &mblock) = 0;
61 
GetFrameInfoFrameBuilderInterface62     FrameInfo &GetFrameInfo()
63     {
64         return frameInfo_;
65     }
66 
67     FrameBuilderInterface(const FrameBuilderInterface &) = delete;
68     void operator=(const FrameBuilderInterface &) = delete;
69     FrameBuilderInterface(FrameBuilderInterface &&) = delete;
70     FrameBuilderInterface &operator=(FrameBuilderInterface &&) = delete;
71 
72 protected:
73     FrameInfo frameInfo_;               // NOLINT(misc-non-private-member-variables-in-classes)
74     ConstantPoolHandler constantPool_;  // NOLINT(misc-non-private-member-variables-in-classes)
75 };
76 
77 struct AMD64FrameBuilder final : FrameBuilderInterface {
AMD64FrameBuilderfinal78     AMD64FrameBuilder(FrameInfo frameInfo, ConstantPoolHandler handler)
79         : FrameBuilderInterface(std::move(frameInfo), std::move(handler))
80     {
81     }
82     ~AMD64FrameBuilder() override = default;
83 
84     bool RemovePrologue(llvm::MachineBasicBlock &mblock) override;
85     bool RemoveEpilogue(llvm::MachineBasicBlock &mblock) override;
86     void InsertPrologue(llvm::MachineBasicBlock &mblock) override;
87     void InsertEpilogue(llvm::MachineBasicBlock &mblock) override;
88 
89     AMD64FrameBuilder(const AMD64FrameBuilder &) = delete;
90     void operator=(const AMD64FrameBuilder &) = delete;
91     AMD64FrameBuilder(AMD64FrameBuilder &&) = delete;
92     AMD64FrameBuilder &operator=(AMD64FrameBuilder &&) = delete;
93 };
94 
95 struct ARM64FrameBuilder final : FrameBuilderInterface {
ARM64FrameBuilderfinal96     ARM64FrameBuilder(FrameInfo frameInfo, ConstantPoolHandler handler)
97         : FrameBuilderInterface(std::move(frameInfo), std::move(handler))
98     {
99     }
100     ~ARM64FrameBuilder() override = default;
101 
102     bool RemovePrologue(llvm::MachineBasicBlock &mblock) override;
103     bool RemoveEpilogue(llvm::MachineBasicBlock &mblock) override;
104     void InsertPrologue(llvm::MachineBasicBlock &mblock) override;
105     void InsertEpilogue(llvm::MachineBasicBlock &mblock) override;
106 
107     ARM64FrameBuilder(const ARM64FrameBuilder &) = delete;
108     void operator=(const ARM64FrameBuilder &) = delete;
109     ARM64FrameBuilder(ARM64FrameBuilder &&) = delete;
110     ARM64FrameBuilder &operator=(ARM64FrameBuilder &&) = delete;
111 
112 private:
113     void EmitCSRSaveRestoreCode(InlineAsmBuilder *builder, uint32_t regsMask, std::string_view asmSingleReg,
114                                 std::string_view asmPairRegs, ssize_t calleeOffset);
115 };
116 
117 #endif  //  LIBLLVMBACKEND_TRANSFORMS_PASSES_ARK_FRAME_LOWERING_FRAME_BUILDER_H
118