1b1994897Sopenharmony_ci/**
2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci * You may obtain a copy of the License at
6b1994897Sopenharmony_ci *
7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci *
9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci * limitations under the License.
14b1994897Sopenharmony_ci */
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci#ifndef BYTECODE_OPTIMIZER_CODEGEN_H
17b1994897Sopenharmony_ci#define BYTECODE_OPTIMIZER_CODEGEN_H
18b1994897Sopenharmony_ci
19b1994897Sopenharmony_ci#include "assembler/annotation.h"
20b1994897Sopenharmony_ci#include "assembler/assembly-function.h"
21b1994897Sopenharmony_ci#include "assembler/assembly-ins.h"
22b1994897Sopenharmony_ci#include "ins_create_api.h"
23b1994897Sopenharmony_ci#include "ir_interface.h"
24b1994897Sopenharmony_ci#include "compiler/optimizer/pass.h"
25b1994897Sopenharmony_ci#include "compiler/optimizer/ir/basicblock.h"
26b1994897Sopenharmony_ci#include "compiler/optimizer/ir/graph.h"
27b1994897Sopenharmony_ci#include "compiler/optimizer/ir/graph_visitor.h"
28b1994897Sopenharmony_ci#include "utils/logger.h"
29b1994897Sopenharmony_ci
30b1994897Sopenharmony_cinamespace panda::bytecodeopt {
31b1994897Sopenharmony_ci
32b1994897Sopenharmony_ciusing compiler::BasicBlock;
33b1994897Sopenharmony_ciusing compiler::Inst;
34b1994897Sopenharmony_ciusing compiler::Opcode;
35b1994897Sopenharmony_ci
36b1994897Sopenharmony_civoid DoLda(compiler::Register reg, std::vector<pandasm::Ins> &result);
37b1994897Sopenharmony_civoid DoSta(compiler::Register reg, std::vector<pandasm::Ins> &result);
38b1994897Sopenharmony_ci
39b1994897Sopenharmony_ciclass BytecodeGen : public compiler::Optimization, public compiler::GraphVisitor {
40b1994897Sopenharmony_cipublic:
41b1994897Sopenharmony_ci    explicit BytecodeGen(compiler::Graph *graph, pandasm::Function *function,
42b1994897Sopenharmony_ci        const BytecodeOptIrInterface *iface, pandasm::Program *prog)
43b1994897Sopenharmony_ci        : compiler::Optimization(graph), function_(function), ir_interface_(iface), program_(prog)
44b1994897Sopenharmony_ci    {
45b1994897Sopenharmony_ci    }
46b1994897Sopenharmony_ci    ~BytecodeGen() override = default;
47b1994897Sopenharmony_ci    bool RunImpl() override;
48b1994897Sopenharmony_ci    const char *GetPassName() const override
49b1994897Sopenharmony_ci    {
50b1994897Sopenharmony_ci        return "BytecodeGen";
51b1994897Sopenharmony_ci    }
52b1994897Sopenharmony_ci    std::vector<pandasm::Ins> GetEncodedInstructions() const
53b1994897Sopenharmony_ci    {
54b1994897Sopenharmony_ci        return res_;
55b1994897Sopenharmony_ci    }
56b1994897Sopenharmony_ci
57b1994897Sopenharmony_ci    void Reserve(size_t res_size = 0)
58b1994897Sopenharmony_ci    {
59b1994897Sopenharmony_ci        if (res_size > 0) {
60b1994897Sopenharmony_ci            result_.reserve(res_size);
61b1994897Sopenharmony_ci        }
62b1994897Sopenharmony_ci    }
63b1994897Sopenharmony_ci
64b1994897Sopenharmony_ci    bool GetStatus() const
65b1994897Sopenharmony_ci    {
66b1994897Sopenharmony_ci        return success_;
67b1994897Sopenharmony_ci    }
68b1994897Sopenharmony_ci
69b1994897Sopenharmony_ci    const std::vector<pandasm::Ins> &GetResult() const
70b1994897Sopenharmony_ci    {
71b1994897Sopenharmony_ci        return result_;
72b1994897Sopenharmony_ci    }
73b1994897Sopenharmony_ci
74b1994897Sopenharmony_ci    std::vector<pandasm::Ins> &&GetResult()
75b1994897Sopenharmony_ci    {
76b1994897Sopenharmony_ci        return std::move(result_);
77b1994897Sopenharmony_ci    }
78b1994897Sopenharmony_ci
79b1994897Sopenharmony_ci    static std::string LabelName(uint32_t id)
80b1994897Sopenharmony_ci    {
81b1994897Sopenharmony_ci        return "label_" + std::to_string(id);
82b1994897Sopenharmony_ci    }
83b1994897Sopenharmony_ci
84b1994897Sopenharmony_ci    void EmitLabel(const std::string label)
85b1994897Sopenharmony_ci    {
86b1994897Sopenharmony_ci        pandasm::Ins l;
87b1994897Sopenharmony_ci        l.label = label;
88b1994897Sopenharmony_ci        l.set_label = true;
89b1994897Sopenharmony_ci        result_.emplace_back(l);
90b1994897Sopenharmony_ci    }
91b1994897Sopenharmony_ci
92b1994897Sopenharmony_ci    void EmitJump(const BasicBlock *bb);
93b1994897Sopenharmony_ci
94b1994897Sopenharmony_ci    void EncodeSpillFillData(const compiler::SpillFillData &sf);
95b1994897Sopenharmony_ci    void EncodeSta(compiler::Register reg, compiler::DataType::Type type);
96b1994897Sopenharmony_ci    void AddLineNumber(const Inst *inst, const size_t idx);
97b1994897Sopenharmony_ci    void AddColumnNumber(const Inst *inst, const uint32_t idx);
98b1994897Sopenharmony_ci
99b1994897Sopenharmony_ci    const ArenaVector<BasicBlock *> &GetBlocksToVisit() const override
100b1994897Sopenharmony_ci    {
101b1994897Sopenharmony_ci        return GetGraph()->GetBlocksRPO();
102b1994897Sopenharmony_ci    }
103b1994897Sopenharmony_ci    static void VisitSpillFill(GraphVisitor *visitor, Inst *inst);
104b1994897Sopenharmony_ci    static void VisitConstant(GraphVisitor *visitor, Inst *inst);
105b1994897Sopenharmony_ci    static void VisitCatchPhi(GraphVisitor *visitor, Inst *inst);
106b1994897Sopenharmony_ci
107b1994897Sopenharmony_ci    static void VisitIf(GraphVisitor *v, Inst *inst_base);
108b1994897Sopenharmony_ci    static void VisitIfImm(GraphVisitor *v, Inst *inst_base);
109b1994897Sopenharmony_ci    static void IfImmZero(GraphVisitor *v, Inst *inst_base);
110b1994897Sopenharmony_ci    static void VisitIntrinsic(GraphVisitor *visitor, Inst *inst_base);
111b1994897Sopenharmony_ci    static void VisitLoadString(GraphVisitor *v, Inst *inst_base);
112b1994897Sopenharmony_ci    static void VisitReturn(GraphVisitor *v, Inst *inst_base);
113b1994897Sopenharmony_ci
114b1994897Sopenharmony_ci    static void VisitCastValueToAnyType(GraphVisitor *v, Inst *inst_base);
115b1994897Sopenharmony_ci
116b1994897Sopenharmony_ci    static void VisitEcma(GraphVisitor *v, Inst *inst_base);
117b1994897Sopenharmony_ci    static void IfEcma(GraphVisitor *v, compiler::IfInst *inst);
118b1994897Sopenharmony_ci
119b1994897Sopenharmony_ci#include "generated/codegen_visitors.inc"
120b1994897Sopenharmony_ci
121b1994897Sopenharmony_ci#include "generated/insn_selection.h"
122b1994897Sopenharmony_ci
123b1994897Sopenharmony_ci    void VisitDefault(Inst *inst) override
124b1994897Sopenharmony_ci    {
125b1994897Sopenharmony_ci        LOG(ERROR, BYTECODE_OPTIMIZER) << "Opcode " << compiler::GetOpcodeString(inst->GetOpcode())
126b1994897Sopenharmony_ci                                       << " not yet implemented in codegen";
127b1994897Sopenharmony_ci        success_ = false;
128b1994897Sopenharmony_ci    }
129b1994897Sopenharmony_ci
130b1994897Sopenharmony_ci#include "compiler/optimizer/ir/visitor.inc"
131b1994897Sopenharmony_ci
132b1994897Sopenharmony_ciprivate:
133b1994897Sopenharmony_ci    void AppendCatchBlock(uint32_t type_id, const compiler::BasicBlock *try_begin, const compiler::BasicBlock *try_end,
134b1994897Sopenharmony_ci                          const compiler::BasicBlock *catch_begin, const compiler::BasicBlock *catch_end = nullptr);
135b1994897Sopenharmony_ci    void VisitTryBegin(const compiler::BasicBlock *bb);
136b1994897Sopenharmony_ci
137b1994897Sopenharmony_ciprivate:
138b1994897Sopenharmony_ci    pandasm::Function *function_;
139b1994897Sopenharmony_ci    const BytecodeOptIrInterface *ir_interface_;
140b1994897Sopenharmony_ci    pandasm::Program *program_;
141b1994897Sopenharmony_ci
142b1994897Sopenharmony_ci    std::vector<pandasm::Ins> res_;
143b1994897Sopenharmony_ci    std::vector<pandasm::Function::CatchBlock> catch_blocks_;
144b1994897Sopenharmony_ci
145b1994897Sopenharmony_ci    bool success_ {true};
146b1994897Sopenharmony_ci    std::vector<pandasm::Ins> result_;
147b1994897Sopenharmony_ci};
148b1994897Sopenharmony_ci
149b1994897Sopenharmony_ci}  // namespace panda::bytecodeopt
150b1994897Sopenharmony_ci
151b1994897Sopenharmony_ci#endif  // BYTECODE_OPTIMIZER_CODEGEN_H
152