1/*
2 * Copyright (c) 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 "ecmascript/compiler/array_bounds_check_elimination.h"
17#include "ecmascript/compiler/combined_pass_visitor.h"
18#include "ecmascript/compiler/number_gate_info.h"
19#include "ecmascript/compiler/number_speculative_lowering.h"
20#include "ecmascript/compiler/number_speculative_runner.h"
21#include "ecmascript/compiler/range_analysis.h"
22
23namespace panda::ecmascript::kungfu {
24void NumberSpeculativeRunner::Run()
25{
26    CombinedPassVisitor rangeGuardVisitor(circuit_, enableLog_, methodName_, chunk_);
27    RangeGuard rangeGuard(circuit_, &rangeGuardVisitor, chunk_);
28    rangeGuardVisitor.AddPass(&rangeGuard);
29    rangeGuardVisitor.VisitGraph();
30
31    if (IsLogEnabled()) {
32        LOG_COMPILER(INFO) << "";
33        LOG_COMPILER(INFO) << "\033[34m"
34                           << "===================="
35                           << " After range guard "
36                           << "[" << GetMethodName() << "]"
37                           << "===================="
38                           << "\033[0m";
39        circuit_->PrintAllGatesWithBytecode();
40        LOG_COMPILER(INFO) << "\033[34m" << "========================= End ==========================" << "\033[0m";
41    }
42
43    auto maxId = circuit_->GetMaxGateId();
44    typeInfos_.resize(maxId + 1, TypeInfo::NONE);
45
46    if (enableArrayBoundsCheckElimination_) {
47        ArrayBoundsCheckElimination arrayBoundsCheck(circuit_, enableLog_, methodName_, chunk_);
48        arrayBoundsCheck.Run();
49        if (IsLogEnabled()) {
50            LOG_COMPILER(INFO) << "";
51            LOG_COMPILER(INFO) << "\033[34m"
52                            << "===================="
53                            << " After array bounds check elimination "
54                            << "[" << GetMethodName() << "]"
55                            << "===================="
56                            << "\033[0m";
57            circuit_->PrintAllGatesWithBytecode();
58            LOG_COMPILER(INFO) << "\033[34m" << "========================= End ==========================" << "\033[0m";
59        }
60    }
61
62    maxId = circuit_->GetMaxGateId();
63    typeInfos_.resize(maxId + 1, TypeInfo::NONE);
64
65    // visit gate in RPO, propagate use infos and
66    // reset the machine type of number operator gate and related phi,
67    // if some tagged phi is used as native value, change it to native phi.
68    NumberSpeculativeRetype retype(circuit_, chunk_, typeInfos_);
69    CombinedPassVisitor retypeVisitor(circuit_, enableLog_, methodName_, chunk_);
70    NumberSpeculativeRetypeManager retypePhase(circuit_, &retypeVisitor, chunk_,
71                                               &retype, NumberSpeculativeRetype::State::Retype);
72    retypeVisitor.AddPass(&retypePhase);
73    retypeVisitor.VisitGraph();
74    CombinedPassVisitor convertVisitor(circuit_, enableLog_, methodName_, chunk_);
75    NumberSpeculativeRetypeManager convertPhase(circuit_, &convertVisitor,
76                                                chunk_, &retype, NumberSpeculativeRetype::State::Convert);
77    convertVisitor.AddPass(&convertPhase);
78    convertVisitor.VisitGraph();
79
80    if (IsLogEnabled()) {
81        LOG_COMPILER(INFO) << "";
82        LOG_COMPILER(INFO) << "\033[34m"
83                           << "===================="
84                           << " After number speculative retype "
85                           << "[" << GetMethodName() << "]"
86                           << "===================="
87                           << "\033[0m";
88        circuit_->PrintAllGatesWithBytecode();
89        LOG_COMPILER(INFO) << "\033[34m" << "========================= End ==========================" << "\033[0m";
90    }
91
92    maxId = circuit_->GetMaxGateId();
93    rangeInfos_.resize(maxId + 1, RangeInfo::NONE());
94    typeInfos_.resize(maxId + 1, TypeInfo::NONE);
95    CombinedPassVisitor rangeAnalysisVisitor(circuit_, enableLog_, methodName_, chunk_);
96    RangeAnalysis rangeAnalysis(circuit_, &rangeAnalysisVisitor, chunk_, typeInfos_, rangeInfos_);
97    rangeAnalysisVisitor.AddPass(&rangeAnalysis);
98    rangeAnalysisVisitor.VisitGraph();
99
100    if (IsLogEnabled()) {
101        LOG_COMPILER(INFO) << "";
102        LOG_COMPILER(INFO) << "\033[34m"
103                           << "===================="
104                           << " After range analysis "
105                           << "[" << GetMethodName() << "]"
106                           << "===================="
107                           << "\033[0m";
108        rangeAnalysis.PrintRangeInfo();
109        LOG_COMPILER(INFO) << "\033[34m" << "========================= End ==========================" << "\033[0m";
110    }
111
112    NumberSpeculativeLowering lowering(circuit_, chunk_, typeInfos_, rangeInfos_);
113    lowering.Run();
114    if (IsLogEnabled()) {
115        LOG_COMPILER(INFO) << "";
116        LOG_COMPILER(INFO) << "\033[34m"
117                           << "===================="
118                           << " After number speculative runner "
119                           << "[" << GetMethodName() << "]"
120                           << "===================="
121                           << "\033[0m";
122        circuit_->PrintAllGatesWithBytecode();
123        LOG_COMPILER(INFO) << "\033[34m" << "========================= End ==========================" << "\033[0m";
124    }
125}
126}  // panda::ecmascript::kungfu
127