mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
Fix the bug that the Phi node is not generated
If the loop head is the first bb block, the variables used in the head cannot correctly generate Phi node Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6Y4JU Signed-off-by: weng-xi <wengxi1@huawei.com> Change-Id: I57927992e19ef9c53c598197609a17ba69b6f3ff
This commit is contained in:
parent
787e618f01
commit
3e37a79f72
@ -174,18 +174,35 @@ void BytecodeCircuitBuilder::CollectTryCatchBlockInfo(ExceptionInfo &byteCodeExc
|
||||
});
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::BuildEntryBlock()
|
||||
{
|
||||
BytecodeRegion &entryBlock = graph_[0];
|
||||
BytecodeRegion &nextBlock = graph_[1];
|
||||
entryBlock.succs.emplace_back(&nextBlock);
|
||||
nextBlock.preds.emplace_back(&entryBlock);
|
||||
entryBlock.bytecodeIterator_.Reset(this, INVALID_INDEX, INVALID_INDEX);
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::BuildRegions(const ExceptionInfo &byteCodeException)
|
||||
{
|
||||
auto &items = regionsInfo_.GetBlockItems();
|
||||
auto blockSize = items.size();
|
||||
graph_.resize(blockSize);
|
||||
|
||||
// 1 : entry block. if the loop head is in the first bb block, the variables used in the head cannot correctly
|
||||
// generate Phi nodes through the dominator-tree algorithm, resulting in an infinite loop. Therefore, an empty
|
||||
// BB block is generated as an entry block
|
||||
graph_.resize(blockSize + 1);
|
||||
|
||||
// build entry block
|
||||
BuildEntryBlock();
|
||||
|
||||
// build basic block
|
||||
size_t blockId = 0;
|
||||
size_t blockId = 1;
|
||||
for (const auto &item : items) {
|
||||
auto &curBlock = GetBasicBlockById(blockId);
|
||||
curBlock.id = blockId;
|
||||
curBlock.start = item.GetStartBcIndex();
|
||||
if (blockId != 0) {
|
||||
if (blockId != 1) {
|
||||
auto &prevBlock = graph_[blockId - 1];
|
||||
prevBlock.end = curBlock.start - 1;
|
||||
prevBlock.bytecodeIterator_.Reset(this, prevBlock.start, prevBlock.end);
|
||||
@ -1106,6 +1123,12 @@ void BytecodeCircuitBuilder::BuildSubCircuit()
|
||||
auto dependCur = bb.dependCurrent;
|
||||
ASSERT(stateCur != Circuit::NullGate());
|
||||
ASSERT(dependCur != Circuit::NullGate());
|
||||
if (IsEntryBlock(bb.id)) {
|
||||
auto &bbNext = graph_[bb.id + 1];
|
||||
SetBlockPred(bb, bbNext, stateCur, dependCur);
|
||||
bbNext.expandedPreds.push_back({bb.id, bb.end, false});
|
||||
continue;
|
||||
}
|
||||
if (!bb.trys.empty()) {
|
||||
dependCur = circuit_->NewGate(circuit_->GetException(),
|
||||
MachineType::I64, {stateCur, dependCur}, GateType::AnyType());
|
||||
@ -1449,8 +1472,12 @@ void BytecodeCircuitBuilder::PrintGraph(const char* title)
|
||||
log += std::to_string(bb.preds[k]->id) + ", ";
|
||||
}
|
||||
LOG_COMPILER(INFO) << log;
|
||||
LOG_COMPILER(INFO) << "\tBytecodePC: [" << std::to_string(bb.start) << ", "
|
||||
<< std::to_string(bb.end) << ")";
|
||||
if (IsEntryBlock(bb.id)) {
|
||||
LOG_COMPILER(INFO) << "\tBytecodePC: Empty";
|
||||
} else {
|
||||
LOG_COMPILER(INFO) << "\tBytecodePC: [" << std::to_string(bb.start) << ", "
|
||||
<< std::to_string(bb.end) << ")";
|
||||
}
|
||||
|
||||
std::string log1("\tSucces: ");
|
||||
for (size_t j = 0; j < bb.succs.size(); j++) {
|
||||
@ -1501,6 +1528,10 @@ void BytecodeCircuitBuilder::PrintBytecodeInfo(BytecodeRegion& bb)
|
||||
if (bb.isDead) {
|
||||
return;
|
||||
}
|
||||
if (IsEntryBlock(bb.id)) {
|
||||
LOG_COMPILER(INFO) << "\tBytecode[] = Empty";
|
||||
return;
|
||||
}
|
||||
LOG_COMPILER(INFO) << "\tBytecode[] = ";
|
||||
EnumerateBlock(bb, [&](const BytecodeInfo &bytecodeInfo) -> bool {
|
||||
auto &iterator = bb.GetBytecodeIterator();
|
||||
|
@ -123,10 +123,10 @@ public:
|
||||
const auto &it = std::upper_bound(blockItems_.begin(),
|
||||
blockItems_.end(), bcIndex, findFunc);
|
||||
if (it == blockItems_.end()) {
|
||||
return blockItems_.size() - 1; // 1: last bb
|
||||
return blockItems_.size();
|
||||
}
|
||||
// blockItems_[0]'s value is 0, bcIndex must be: bcIndex > blockItems_.begin()
|
||||
return std::distance(blockItems_.begin(), it) - 1; // 1: -1 for bbIndx
|
||||
return std::distance(blockItems_.begin(), it);
|
||||
}
|
||||
|
||||
const std::vector<BytecodeSplitItem> &GetSplitItems() const
|
||||
@ -334,6 +334,10 @@ public:
|
||||
template <class Callback>
|
||||
void EnumerateBlock(BytecodeRegion &bb, const Callback &cb)
|
||||
{
|
||||
// Entry block is a empry block
|
||||
if (IsEntryBlock(bb.id)) {
|
||||
return;
|
||||
}
|
||||
auto &iterator = bb.GetBytecodeIterator();
|
||||
for (iterator.GotoStart(); !iterator.Done(); ++iterator) {
|
||||
auto &bytecodeInfo = iterator.GetBytecodeInfo();
|
||||
@ -430,6 +434,7 @@ public:
|
||||
private:
|
||||
void CollectTryCatchBlockInfo(ExceptionInfo &Exception);
|
||||
void BuildCatchBlocks(const ExceptionInfo &Exception);
|
||||
void BuildEntryBlock();
|
||||
void BuildRegions(const ExceptionInfo &Exception);
|
||||
void ComputeDominatorTree();
|
||||
void BuildImmediateDominator(const std::vector<size_t> &immDom);
|
||||
@ -477,9 +482,14 @@ private:
|
||||
return bbId == 0;
|
||||
}
|
||||
|
||||
inline bool IsFirstBasicBlock(const size_t bbId) const
|
||||
{
|
||||
return bbId == 1;
|
||||
}
|
||||
|
||||
inline bool IsFirstBCEnvIn(const size_t bbId, const size_t bcIndex, const uint16_t reg) const
|
||||
{
|
||||
return (IsEntryBlock(bbId) && bcIndex == 0 && reg == GetNumberVRegs());
|
||||
return (IsFirstBasicBlock(bbId) && bcIndex == 0 && reg == GetNumberVRegs());
|
||||
}
|
||||
|
||||
TSManager *tsManager_;
|
||||
|
@ -735,4 +735,4 @@ public:
|
||||
}
|
||||
};
|
||||
} // panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_COMPILER_BYTECODES_H
|
||||
#endif // ECMASCRIPT_COMPILER_BYTECODES_H
|
||||
|
@ -99,8 +99,9 @@ void FrameStateBuilder::BuildPostOrderList(size_t size)
|
||||
postOrderList_.clear();
|
||||
std::deque<size_t> pendingList;
|
||||
std::vector<bool> visited(size, false);
|
||||
auto entryId = 0;
|
||||
pendingList.emplace_back(entryId);
|
||||
// entry block (bbid=0) is a empty block, need skip
|
||||
auto firstBlockId = 1;
|
||||
pendingList.emplace_back(firstBlockId);
|
||||
|
||||
while (!pendingList.empty()) {
|
||||
size_t curBlockId = pendingList.back();
|
||||
|
@ -123,6 +123,7 @@ group("ark_aot_ts_test") {
|
||||
"ldstlexvar",
|
||||
"ldsuperbyname",
|
||||
"logic_op",
|
||||
"loop_phi",
|
||||
"loop_with_variable_exchange",
|
||||
"loops",
|
||||
"mod",
|
||||
|
18
test/aottest/loop_phi/BUILD.gn
Normal file
18
test/aottest/loop_phi/BUILD.gn
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_test_action("loop_phi") {
|
||||
deps = []
|
||||
}
|
14
test/aottest/loop_phi/expect_output.txt
Normal file
14
test/aottest/loop_phi/expect_output.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
1
|
23
test/aottest/loop_phi/loop_phi.ts
Normal file
23
test/aottest/loop_phi/loop_phi.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
declare function print(str:any):number;
|
||||
function foo(l) {
|
||||
while (l !== null) {
|
||||
l = l.b;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
print(foo({a:1, b:null}));
|
Loading…
Reference in New Issue
Block a user