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)23MethodProperties::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