• 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 // 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