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 #ifndef BYTECODE_OPTIMIZER_CODEGEN_H 17 #define BYTECODE_OPTIMIZER_CODEGEN_H 18 19 #include "assembler/annotation.h" 20 #include "assembler/assembly-function.h" 21 #include "ins_create_api.h" 22 #include "ir_interface.h" 23 #include "compiler/optimizer/pass.h" 24 #include "compiler/optimizer/ir/basicblock.h" 25 #include "compiler/optimizer/ir/graph.h" 26 #include "compiler/optimizer/ir/graph_visitor.h" 27 #include "utils/logger.h" 28 29 namespace panda::bytecodeopt { 30 31 using compiler::BasicBlock; 32 using compiler::Inst; 33 using compiler::Opcode; 34 35 void DoLda(compiler::Register reg, std::vector<pandasm::InsPtr> &result); 36 void DoSta(compiler::Register reg, std::vector<pandasm::InsPtr> &result); 37 38 class BytecodeGen : public compiler::Optimization, public compiler::GraphVisitor { 39 public: BytecodeGen(compiler::Graph * graph,pandasm::Function * function,const BytecodeOptIrInterface * iface,pandasm::Program * prog)40 explicit BytecodeGen(compiler::Graph *graph, pandasm::Function *function, 41 const BytecodeOptIrInterface *iface, pandasm::Program *prog) 42 : compiler::Optimization(graph), function_(function), ir_interface_(iface), program_(prog) 43 { 44 } 45 ~BytecodeGen() override = default; 46 bool RunImpl() override; GetPassName()47 const char *GetPassName() const override 48 { 49 return "BytecodeGen"; 50 } GetEncodedInstructions()51 const std::vector<pandasm::InsPtr> &GetEncodedInstructions() const 52 { 53 return res_; 54 } 55 56 void Reserve(size_t res_size = 0) 57 { 58 if (res_size > 0) { 59 result_.reserve(res_size); 60 } 61 } 62 GetStatus()63 bool GetStatus() const 64 { 65 return success_; 66 } 67 GetResult()68 const std::vector<pandasm::InsPtr> &GetResult() const 69 { 70 return result_; 71 } 72 GetResult()73 std::vector<pandasm::InsPtr> &&GetResult() 74 { 75 return std::move(result_); 76 } 77 LabelName(uint32_t id)78 static std::string LabelName(uint32_t id) 79 { 80 return "label_" + std::to_string(id); 81 } 82 EmitLabel(const std::string label)83 void EmitLabel(const std::string label) 84 { 85 result_.emplace_back(new pandasm::LabelIns(label)); 86 } 87 88 void EmitJump(const BasicBlock *bb); 89 90 void EncodeSpillFillData(const compiler::SpillFillData &sf); 91 void EncodeSta(compiler::Register reg, compiler::DataType::Type type); 92 void AddLineNumber(const Inst *inst, const size_t idx); 93 void AddColumnNumber(const Inst *inst, const uint32_t idx); 94 GetBlocksToVisit()95 const ArenaVector<BasicBlock *> &GetBlocksToVisit() const override 96 { 97 return GetGraph()->GetBlocksRPO(); 98 } 99 static void VisitSpillFill(GraphVisitor *visitor, Inst *inst); 100 static void VisitConstant(GraphVisitor *visitor, Inst *inst); 101 static void VisitCatchPhi(GraphVisitor *visitor, Inst *inst); 102 103 static void VisitIf(GraphVisitor *v, Inst *inst_base); 104 static void VisitIfImm(GraphVisitor *v, Inst *inst_base); 105 static void IfImmZero(GraphVisitor *v, Inst *inst_base); 106 static void VisitIntrinsic(GraphVisitor *visitor, Inst *inst_base); 107 static void VisitLoadString(GraphVisitor *v, Inst *inst_base); 108 static void VisitReturn(GraphVisitor *v, Inst *inst_base); 109 110 static void VisitCastValueToAnyType(GraphVisitor *v, Inst *inst_base); 111 112 static void VisitEcma(GraphVisitor *v, Inst *inst_base); 113 static void IfEcma(GraphVisitor *v, compiler::IfInst *inst); 114 115 #include "generated/codegen_visitors.inc" 116 117 #include "generated/insn_selection.h" 118 VisitDefault(Inst * inst)119 void VisitDefault(Inst *inst) override 120 { 121 LOG(ERROR, BYTECODE_OPTIMIZER) << "Opcode " << compiler::GetOpcodeString(inst->GetOpcode()) 122 << " not yet implemented in codegen"; 123 success_ = false; 124 } 125 126 #include "compiler/optimizer/ir/visitor.inc" 127 128 private: 129 void AppendCatchBlock(uint32_t type_id, const compiler::BasicBlock *try_begin, const compiler::BasicBlock *try_end, 130 const compiler::BasicBlock *catch_begin, const compiler::BasicBlock *catch_end = nullptr); 131 void VisitTryBegin(const compiler::BasicBlock *bb); 132 133 private: 134 pandasm::Function *function_; 135 const BytecodeOptIrInterface *ir_interface_; 136 pandasm::Program *program_; 137 138 std::vector<pandasm::InsPtr> res_; 139 std::vector<pandasm::Function::CatchBlock> catch_blocks_; 140 141 bool success_ {true}; 142 std::vector<pandasm::InsPtr> result_; 143 }; 144 145 } // namespace panda::bytecodeopt 146 147 #endif // BYTECODE_OPTIMIZER_CODEGEN_H 148