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