• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #include "optimizer/code_generator/codegen.h"
17 #include "optimizer/code_generator/method_properties.h"
18 #include "optimizer/ir/graph.h"
19 #include "optimizer/ir/graph_visitor.h"
20 
21 namespace ark::compiler {
22 
MethodProperties(const Graph * graph)23 MethodProperties::MethodProperties(const Graph *graph)
24 {
25     for (auto bb : graph->GetBlocksRPO()) {
26         // Calls may be in the middle of method
27         for (auto inst : bb->Insts()) {
28             if (inst->IsInitObject()) {
29                 ASSERT(g_options.IsCompilerSupportInitObjectInst());
30             }
31             if (inst->GetFlag(inst_flags::CAN_DEOPTIMIZE)) {
32                 SetHasDeopt(true);
33             }
34             if (inst->IsReturn()) {
35                 lastReturn_ = inst;
36             }
37             if (!GetHasParamsOnStack() && inst->GetOpcode() == Opcode::Parameter) {
38                 CheckAndSetStackParams(inst);
39             }
40             if (inst->GetOpcode() == Opcode::SafePoint) {
41                 SetHasSafepoints(true);
42             }
43             if (inst->IsCall() || inst->IsIntrinsic()) {
44                 SetHasCalls(true);
45             }
46             if (Codegen::InstEncodedWithLibCall(inst, graph->GetArch())) {
47                 SetHasLibCalls(true);
48             }
49             if (inst->IsRuntimeCall()) {
50                 SetHasRuntimeCalls(true);
51             }
52             if (inst->RequireState()) {
53                 SetHasRequireState(true);
54             }
55             if (inst->CanThrow()) {
56                 SetCanThrow(true);
57             }
58         }
59     }
60 
61     /**
62      * "Compact" prologue/epilogue means that unused callee-saved registers
63      * are not saved in the prologue and restored in the epilogue.
64      *
65      * 1. We do support compact prologue/epilogue only for AARCH64.
66      *    The reasons are as follows:
67      *      - for X86_64 we're reserving almost all callee-saved registers for temporaries
68      *      - for AARCH32 we're treating all callee-saved registers as "used".
69      *    Thus there is no sense in supporting compact prologue for these targets.
70      *
71      * 2. We don't support compact prologue/epilogue for OSR to simplify OSR entry bridge.
72      */
73     SetCompactPrologueAllowed(graph->GetArch() == Arch::AARCH64 && !graph->IsOsrMode() &&
74                               g_options.IsCompilerCompactPrologue());
75 
76     SetRequireFrameSetup(!IsLeaf() || graph->IsOsrMode());
77 }
78 
CheckAndSetStackParams(Inst * inst)79 void MethodProperties::CheckAndSetStackParams(Inst *inst)
80 {
81     auto sf = static_cast<const ParameterInst *>(inst)->GetLocationData();
82     if (sf.DstValue() != INVALID_REG && sf.SrcType() == LocationType::STACK_PARAMETER) {
83         SetHasParamsOnStack(true);
84     }
85 }
86 }  // namespace ark::compiler
87