• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "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 panda::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                 auto sf = static_cast<const ParameterInst *>(inst)->GetLocationData();
39                 if (sf.DstValue() != INVALID_REG && sf.SrcType() == LocationType::STACK_PARAMETER) {
40                     SetHasParamsOnStack(true);
41                 }
42             }
43             if (inst->GetOpcode() == Opcode::SafePoint) {
44                 SetHasSafepoints(true);
45             }
46             if (inst->IsCall() || inst->IsIntrinsic()) {
47                 SetHasCalls(true);
48             }
49             if (Codegen::InstEncodedWithLibCall(inst, graph->GetArch())) {
50                 SetHasLibCalls(true);
51             }
52             if (inst->IsRuntimeCall()) {
53                 SetHasRuntimeCalls(true);
54             }
55             if (inst->RequireState()) {
56                 SetHasRequireState(true);
57             }
58             if (inst->CanThrow()) {
59                 SetCanThrow(true);
60             }
61         }
62     }
63 
64     /**
65      * "Compact" prologue/epilogue means that unused callee-saved registers
66      * are not saved in the prologue and restored in the epilogue.
67      *
68      * 1. We do support compact prologue/epilogue only for AARCH64.
69      *    The reasons are as follows:
70      *      - for X86_64 we're reserving almost all callee-saved registers for temporaries
71      *      - for AARCH32 we're treating all callee-saved registers as "used".
72      *    Thus there is no sense in supporting compact prologue for these targets.
73      *
74      * 2. We don't support compact prologue/epilogue for OSR to simplify OSR entry bridge.
75      */
76     SetCompactPrologueAllowed(graph->GetArch() == Arch::AARCH64 && !graph->IsOsrMode() &&
77                               g_options.IsCompilerCompactPrologue());
78 
79     SetRequireFrameSetup(!IsLeaf() || graph->IsOsrMode());
80 }
81 }  // namespace panda::compiler
82