• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "x64_memlayout.h"
17 #include "x64_call_conv.h"
18 #include "cg.h"
19 
20 namespace maplebe {
21 using namespace maple;
22 
ComputeStackSpaceRequirementForCall(StmtNode & stmt,int32 & aggCopySize,bool isIcall)23 uint32 X64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, int32 &aggCopySize, bool isIcall)
24 {
25     /* instantiate a parm locator */
26     X64CallConvImpl parmLocator(cgFunc->GetBecommon(), X64CallConvImpl::GetCallConvKind(stmt));
27     uint32 sizeOfArgsToStkPass = 0;
28     size_t i = 0;
29     /* An indirect call's first operand is the invocation target */
30     if (isIcall) {
31         ++i;
32     }
33 
34     aggCopySize = 0;
35     for (uint32 anum = 0; i < stmt.NumOpnds(); ++i, ++anum) {
36         BaseNode *opnd = stmt.Opnd(i);
37         MIRType *ty = nullptr;
38         ty = GlobalTables::GetTypeTable().GetTypeTable()[static_cast<uint32>(opnd->GetPrimType())];
39         CCLocInfo ploc;
40         aggCopySize += parmLocator.LocateNextParm(*ty, ploc);
41         if (ploc.reg0 != 0) {
42             continue; /* passed in register, so no effect on actual area */
43         }
44         sizeOfArgsToStkPass = RoundUp(ploc.memOffset + ploc.memSize, GetPointerSize());
45     }
46 
47     return sizeOfArgsToStkPass;
48 }
49 
SetSizeAlignForTypeIdx(uint32 typeIdx,uint32 & size,uint32 & align) const50 void X64MemLayout::SetSizeAlignForTypeIdx(uint32 typeIdx, uint32 &size, uint32 &align) const
51 {
52     align = GlobalTables::GetTypeTable().GetTypeFromTyIdx(typeIdx)->GetAlign();
53     size = GlobalTables::GetTypeTable().GetTypeFromTyIdx(typeIdx)->GetSize();
54 }
55 
LayoutFormalParams()56 void X64MemLayout::LayoutFormalParams()
57 {
58     X64CallConvImpl parmLocator(be);
59     CCLocInfo ploc;
60     for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) {
61         MIRSymbol *sym = mirFunction->GetFormal(i);
62         uint32 stIndex = sym->GetStIndex();
63         X64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New<X64SymbolAlloc>();
64         SetSymAllocInfo(stIndex, *symLoc);
65         if (i == 0) {
66             // The function name here is not appropriate, it should be to determine
67             // whether the function returns a structure less than 16 bytes. At this
68             // time, the first parameter is a structure occupant, which has no
69             // practical significance.
70             if (be.HasFuncReturnType(*mirFunction)) {
71                 symLoc->SetMemSegment(GetSegArgsRegPassed());
72                 symLoc->SetOffset(GetSegArgsRegPassed().GetSize());
73                 continue;
74             }
75         }
76 
77         MIRType *ty = mirFunction->GetNthParamType(i);
78         uint32 ptyIdx = ty->GetTypeIndex();
79         parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction);
80         uint32 size = 0;
81         uint32 align = 0;
82         if (ploc.reg0 != kRinvalid) {
83             if (!sym->IsPreg()) {
84                 SetSizeAlignForTypeIdx(ptyIdx, size, align);
85                 symLoc->SetMemSegment(GetSegArgsRegPassed());
86                 segArgsRegPassed.SetSize(static_cast<uint32>(RoundUp(segArgsRegPassed.GetSize(), align)));
87                 symLoc->SetOffset(segArgsRegPassed.GetSize());
88                 segArgsRegPassed.SetSize(segArgsRegPassed.GetSize() + size);
89             }
90         } else {
91             SetSizeAlignForTypeIdx(ptyIdx, size, align);
92             symLoc->SetMemSegment(GetSegArgsStkPassed());
93             segArgsStkPassed.SetSize(static_cast<uint32>(RoundUp(segArgsStkPassed.GetSize(), align)));
94             symLoc->SetOffset(segArgsStkPassed.GetSize());
95             segArgsStkPassed.SetSize(segArgsStkPassed.GetSize() + size);
96             segArgsStkPassed.SetSize(static_cast<uint32>(RoundUp(segArgsStkPassed.GetSize(), GetPointerSize())));
97         }
98     }
99 }
100 
LayoutLocalVariables()101 void X64MemLayout::LayoutLocalVariables()
102 {
103     uint32 symTabSize = mirFunction->GetSymTab()->GetSymbolTableSize();
104     for (uint32 i = 0; i < symTabSize; ++i) {
105         MIRSymbol *sym = mirFunction->GetSymTab()->GetSymbolFromStIdx(i);
106         if (sym == nullptr || sym->GetStorageClass() != kScAuto || sym->IsDeleted()) {
107             continue;
108         }
109         uint32 stIndex = sym->GetStIndex();
110         TyIdx tyIdx = sym->GetTyIdx();
111         X64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New<X64SymbolAlloc>();
112         SetSymAllocInfo(stIndex, *symLoc);
113         CHECK_FATAL(!symLoc->IsRegister(), "expect not register");
114 
115         symLoc->SetMemSegment(segLocals);
116         MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
117         uint32 align = ty->GetAlign();
118         segLocals.SetSize(static_cast<uint32>(RoundUp(segLocals.GetSize(), align)));
119         symLoc->SetOffset(segLocals.GetSize());
120         segLocals.SetSize(segLocals.GetSize() + GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->GetSize());
121     }
122 }
123 
AssignSpillLocationsToPseudoRegisters()124 void X64MemLayout::AssignSpillLocationsToPseudoRegisters()
125 {
126     MIRPregTable *pregTab = cgFunc->GetFunction().GetPregTab();
127 
128     /* BUG: n_regs include index 0 which is not a valid preg index. */
129     size_t nRegs = pregTab->Size();
130     spillLocTable.resize(nRegs);
131     for (size_t i = 1; i < nRegs; ++i) {
132         PrimType pType = pregTab->PregFromPregIdx(i)->GetPrimType();
133         X64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New<X64SymbolAlloc>();
134         symLoc->SetMemSegment(segLocals);
135         segLocals.SetSize(RoundUp(segLocals.GetSize(), GetPrimTypeSize(pType)));
136         symLoc->SetOffset(segLocals.GetSize());
137         MIRType *mirTy = GlobalTables::GetTypeTable().GetTypeTable()[pType];
138         segLocals.SetSize(segLocals.GetSize() + mirTy->GetSize());
139         spillLocTable[i] = symLoc;
140     }
141 }
142 
LayoutReturnRef(int32 & structCopySize,int32 & maxParmStackSize)143 void X64MemLayout::LayoutReturnRef(int32 &structCopySize, int32 &maxParmStackSize)
144 {
145     segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize));
146     maxParmStackSize = static_cast<int32>(segArgsToStkPass.GetSize());
147     if (Globals::GetInstance()->GetOptimLevel() == CGOptions::kLevel0) {
148         AssignSpillLocationsToPseudoRegisters();
149     }
150     segLocals.SetSize(static_cast<uint32>(RoundUp(segLocals.GetSize(), GetPointerSize())));
151 }
152 
LayoutStackFrame(int32 & structCopySize,int32 & maxParmStackSize)153 void X64MemLayout::LayoutStackFrame(int32 &structCopySize, int32 &maxParmStackSize)
154 {
155     LayoutFormalParams();
156 
157     // Need to be aligned ?
158     segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), GetPointerSize()));
159     segArgsStkPassed.SetSize(RoundUp(segArgsStkPassed.GetSize(), GetPointerSize() + GetPointerSize()));
160 
161     /* allocate the local variables in the stack */
162     LayoutLocalVariables();
163     LayoutReturnRef(structCopySize, maxParmStackSize);
164 
165     // Need to adapt to the cc interface.
166     structCopySize = 0;
167     // Scenes with more than 6 parameters are not yet enabled.
168     maxParmStackSize = 0;
169 
170     cgFunc->SetUseFP(cgFunc->UseFP() || static_cast<int32>(StackFrameSize()) > kMaxPimm32);
171 }
172 
StackFrameSize() const173 uint64 X64MemLayout::StackFrameSize() const
174 {
175     uint64 total = Locals().GetSize() + segArgsRegPassed.GetSize() + segArgsToStkPass.GetSize() +
176                    segGrSaveArea.GetSize() + segVrSaveArea.GetSize() + segSpillReg.GetSize() +
177                    cgFunc->GetFunction().GetFrameReseverdSlot();  // frame reserved slot
178     return RoundUp(total, stackPtrAlignment);
179 }
180 
GetGRSaveAreaBaseLoc()181 int32 X64MemLayout::GetGRSaveAreaBaseLoc()
182 {
183     int32 total = static_cast<int32>(RoundUp(GetSizeOfGRSaveArea(), stackPtrAlignment));
184     return total;
185 }
186 
GetVRSaveAreaBaseLoc()187 int32 X64MemLayout::GetVRSaveAreaBaseLoc()
188 {
189     int32 total = static_cast<int32>(RoundUp(GetSizeOfGRSaveArea(), stackPtrAlignment) +
190                                      RoundUp(GetSizeOfVRSaveArea(), stackPtrAlignment));
191     return total;
192 }
193 } /* namespace maplebe */
194