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 #include "memlayout.h"
17 #include "cgfunc.h"
18 
19 namespace maplebe {
20 using namespace maple;
21 
22 /*
23  * Go over all outgoing calls in the function body and get the maximum space
24  * needed for storing the actuals based on the actual parameters and the ABI.
25  * These are usually those arguments that cannot be passed
26  * through registers because a call passes more than 8 arguments, or
27  * they cannot be fit in a pair of registers.
28 
29  * This assumes that all nesting of statements has been removed,
30  * so that all the statements are at only one block level.
31  */
FindLargestActualArea(int32 &aggCopySize)32 uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize)
33 {
34     StmtNode *stmt = mirFunction->GetBody()->GetFirst();
35     if (stmt == nullptr) {
36         return 0;
37     }
38     uint32 maxActualSize = 0;
39     uint32 maxParamStackSize = 0;  // Size of parameter stack requirement
40     uint32 maxCopyStackSize = 0;   // Size of aggregate param stack copy requirement
41     for (; stmt != nullptr; stmt = stmt->GetNext()) {
42         Opcode opCode = stmt->GetOpCode();
43         if ((opCode < OP_call || opCode > OP_intrinsiccallassigned) && opCode != OP_icallproto) {
44             continue;
45         }
46         if (opCode == OP_intrinsiccallwithtype ||
47             opCode == OP_intrinsiccallassigned || opCode == OP_intrinsiccall) {
48             /*
49              * Some intrinsics, such as MPL_ATOMIC_EXCHANGE_PTR, are handled by CG,
50              * and map to machine code sequences.  We ignore them because they are not
51              * function calls.
52              */
53             continue;
54         }
55         /*
56          * if the following check fails, most likely it has invoke-custom etc
57          * that is not supported yet
58          */
59         DCHECK((opCode == OP_call || opCode == OP_icall || opCode == OP_icallproto), "Not lowered to call or icall?");
60         int32 copySize;
61         uint32 size =
62             ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall || opCode == OP_icallproto);
63         if (size > maxParamStackSize) {
64             maxParamStackSize = size;
65         }
66         if (static_cast<uint32>(copySize) > maxCopyStackSize) {
67             maxCopyStackSize = static_cast<uint32>(copySize);
68         }
69         if ((maxParamStackSize + maxCopyStackSize) > maxActualSize) {
70             maxActualSize = maxParamStackSize + maxCopyStackSize;
71         }
72     }
73     aggCopySize = static_cast<int32>(maxCopyStackSize);
74     /* GetPointerSize() * 2's pow 2 is 4, set the low 4 bit of maxActualSize to 0 */
75     if (CGOptions::IsArm64ilp32()) {
76         maxActualSize = RoundUp(maxActualSize, k8ByteSize << 1);
77     } else {
78         maxActualSize = RoundUp(maxActualSize, GetPointerSize() << 1);
79     }
80     return maxActualSize;
81 }
82 
PhaseRun(maplebe::CGFunc &f)83 bool CgLayoutFrame::PhaseRun(maplebe::CGFunc &f)
84 {
85     f.LayoutStackFrame();
86     return false;
87 }
88 } /* namespace maplebe */
89