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)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(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