1 /* 2 * Copyright (c) 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 #ifndef LIBABCKIT_SRC_CODEGEN_CODEGEN_STATIC_H 17 #define LIBABCKIT_SRC_CODEGEN_CODEGEN_STATIC_H 18 19 #include "static_core/assembler/assembly-function.h" 20 #include "static_core/assembler/assembly-ins.h" 21 #include "static_core/compiler/optimizer/pass.h" 22 #include "static_core/compiler/optimizer/ir/basicblock.h" 23 #include "static_core/compiler/optimizer/ir/graph.h" 24 #include "static_core/compiler/optimizer/ir/graph_visitor.h" 25 #include "static_core/libpandabase/utils/logger.h" 26 27 #include "ins_create_api.h" 28 #include "libabckit/src/ir_impl.h" 29 30 namespace libabckit { 31 32 // CC-OFFNXT(WordsTool.95) sensitive word conflict 33 // NOLINTNEXTLINE(google-build-using-namespace) 34 using namespace ark; 35 36 using compiler::BasicBlock; 37 using compiler::Inst; 38 using compiler::Opcode; 39 40 constexpr compiler::Register MIN_REGISTER_NUMBER = 0; 41 constexpr compiler::Register MAX_NUM_SHORT_CALL_ARGS = 2; 42 constexpr compiler::Register MAX_NUM_NON_RANGE_ARGS = 4; 43 constexpr compiler::Register MAX_NUM_INPUTS = MAX_NUM_NON_RANGE_ARGS; 44 constexpr ark::compiler::Register NUM_COMPACTLY_ENCODED_REGS = 16; 45 [[maybe_unused]] constexpr compiler::Register MAX_8_BIT_REG = 255 - 1U; // exclude INVALID_REG 46 47 void DoLdaObj(compiler::Register reg, std::vector<pandasm::Ins> &result); 48 void DoLda(compiler::Register reg, std::vector<pandasm::Ins> &result); 49 void DoLda64(compiler::Register reg, std::vector<pandasm::Ins> &result); 50 void DoStaObj(compiler::Register reg, std::vector<pandasm::Ins> &result); 51 void DoSta(compiler::Register reg, std::vector<pandasm::Ins> &result); 52 void DoSta64(compiler::Register reg, std::vector<pandasm::Ins> &result); 53 void DoSta(compiler::DataType::Type type, compiler::Register reg, std::vector<pandasm::Ins> &result); 54 void DoLdaDyn(compiler::Register reg, std::vector<pandasm::Ins> &result); 55 void DoStaDyn(compiler::Register reg, std::vector<pandasm::Ins> &result); 56 57 // NOLINTNEXTLINE(fuchsia-multiple-inheritance) 58 class CodeGenStatic : public compiler::Optimization, public compiler::GraphVisitor { 59 public: CodeGenStatic(compiler::Graph * graph,pandasm::Function * function,const AbckitIrInterface * iface)60 explicit CodeGenStatic(compiler::Graph *graph, pandasm::Function *function, const AbckitIrInterface *iface) 61 : compiler::Optimization(graph), function_(function), irInterface_(iface) 62 { 63 } 64 ~CodeGenStatic() override = default; 65 NO_COPY_SEMANTIC(CodeGenStatic); 66 NO_MOVE_SEMANTIC(CodeGenStatic); 67 68 constexpr static compiler::Register RESERVED_REG = 0U; 69 bool RunImpl() override; GetPassName()70 const char *GetPassName() const override 71 { 72 return "CodeGenStatic"; 73 } GetEncodedInstructions()74 std::vector<pandasm::Ins> GetEncodedInstructions() const 75 { 76 return res_; 77 } 78 79 void Reserve(size_t resSize = 0) 80 { 81 if (resSize > 0) { 82 result_.reserve(resSize); 83 } 84 } 85 GetStatus()86 bool GetStatus() const 87 { 88 return success_; 89 } 90 GetResult()91 const std::vector<pandasm::Ins> &GetResult() const 92 { 93 return result_; 94 } 95 GetResult()96 std::vector<pandasm::Ins> &&GetResult() 97 { 98 return std::move(result_); 99 } 100 LabelName(uint32_t id)101 static std::string LabelName(uint32_t id) 102 { 103 return "label_" + std::to_string(id); 104 } 105 GetMaxReg()106 static compiler::Register GetMaxReg() 107 { 108 return compiler::GetInvalidReg() - 1; 109 } 110 EmitLabel(const std::string & label)111 void EmitLabel(const std::string &label) 112 { 113 pandasm::Ins l; 114 l.label = label; 115 l.setLabel = true; 116 result_.emplace_back(l); 117 } 118 119 void EmitJump(const BasicBlock *bb); 120 121 void EncodeSpillFillData(const compiler::SpillFillData &sf); 122 void EncodeSta(compiler::Register reg, compiler::DataType::Type type); 123 void AddLineNumber(const Inst *inst, size_t idx); 124 void AddColumnNumber(const Inst *inst, uint32_t idx); 125 void AddLineAndColumnNumber(const Inst *inst, size_t idx); 126 GetBlocksToVisit()127 const ArenaVector<BasicBlock *> &GetBlocksToVisit() const override 128 { 129 return GetGraph()->GetBlocksRPO(); 130 } 131 static void VisitSpillFill(GraphVisitor *v, Inst *inst); 132 static void VisitConstant(GraphVisitor *v, Inst *inst); 133 static void VisitCallStatic(GraphVisitor *visitor, Inst *inst); 134 static void VisitCallVirtual(GraphVisitor *visitor, Inst *inst); VisitInitObject(GraphVisitor *,Inst *)135 static void VisitInitObject(GraphVisitor * /*visitor*/, Inst * /*inst*/) 136 { 137 UNREACHABLE(); 138 } 139 static void VisitCatchPhi(GraphVisitor *visitor, Inst *inst); 140 141 static void VisitIntrinsic(GraphVisitor *visitor, Inst *inst); 142 143 static void VisitIf(GraphVisitor *v, Inst *instBase); 144 static void VisitIfImm(GraphVisitor *v, Inst *instBase); 145 static void VisitCast(GraphVisitor *v, Inst *instBase); 146 static void IfImmZero(GraphVisitor *v, Inst *instBase); 147 static void IfImmNonZero(GraphVisitor *v, Inst *instBase); 148 static void IfImm64(GraphVisitor *v, Inst *instBase); 149 static void CallHandler(GraphVisitor *visitor, Inst *inst, std::string methodId); 150 static void CallHandler(GraphVisitor *visitor, Inst *inst); VisitStoreObject(GraphVisitor *,Inst *)151 static void VisitStoreObject(GraphVisitor * /*v*/, Inst * /*instBase*/) 152 { 153 UNREACHABLE(); 154 } VisitStoreStatic(GraphVisitor *,Inst *)155 static void VisitStoreStatic(GraphVisitor * /*v*/, Inst * /*instBase*/) 156 { 157 UNREACHABLE(); 158 } VisitLoadObject(GraphVisitor *,Inst *)159 static void VisitLoadObject(GraphVisitor * /*v*/, Inst * /*instBase*/) 160 { 161 UNREACHABLE(); 162 } VisitLoadStatic(GraphVisitor *,Inst *)163 static void VisitLoadStatic(GraphVisitor * /*v*/, Inst * /*instBase*/) 164 { 165 UNREACHABLE(); 166 } VisitLoadString(GraphVisitor *,Inst *)167 static void VisitLoadString(GraphVisitor * /*v*/, Inst * /*instBase*/) 168 { 169 UNREACHABLE(); 170 } 171 static void VisitReturn(GraphVisitor *v, Inst *instBase); 172 173 #include "generated/codegen_visitors_static.inc" 174 #include "generated/insn_selection_static.h" 175 VisitDefault(Inst * inst)176 void VisitDefault(Inst *inst) override 177 { 178 std::cerr << "Opcode " << compiler::GetOpcodeString(inst->GetOpcode()) << " not yet implemented in CodeGen"; 179 success_ = false; 180 } 181 182 #include "compiler/optimizer/ir/visitor.inc" 183 184 private: 185 void AppendCatchBlock(uint32_t typeId, const compiler::BasicBlock *tryBegin, const compiler::BasicBlock *tryEnd, 186 const compiler::BasicBlock *catchBegin, const compiler::BasicBlock *catchEnd = nullptr); 187 void VisitTryBegin(const compiler::BasicBlock *bb); 188 189 private: 190 pandasm::Function *function_; 191 const AbckitIrInterface *irInterface_; 192 193 std::vector<pandasm::Ins> res_; 194 std::vector<pandasm::Function::CatchBlock> catchBlocks_; 195 196 bool success_ {true}; 197 std::vector<pandasm::Ins> result_; 198 }; 199 200 } // namespace libabckit 201 202 #endif // LIBABCKIT_SRC_CODEGEN_CODEGEN_STATIC_H 203