arkcompiler_ets_runtime/ecmascript/compiler/frame_states.h
weng-xi 02f07cb331 Fix the compilation bug in the process of bytecode to circuit
When there is only one predecessor (input) of the BB, the value_selector gate is no longer generated.
However, the logic of frame_state.cpp was not modified, resulting in compilation failure

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6X14O
Signed-off-by: weng-xi <wengxi1@huawei.com>
Change-Id: Icbcec395e66b68ab372894032f9dae709a0b864b
2023-04-20 19:05:50 +08:00

148 lines
4.7 KiB
C++

/*
* Copyright (c) 2022 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.
*/
#ifndef ECMASCRIPT_COMPILER_FRAME_STATE_H
#define ECMASCRIPT_COMPILER_FRAME_STATE_H
#include "ecmascript/compiler/argument_accessor.h"
#include "ecmascript/compiler/base/bit_set.h"
#include "ecmascript/compiler/circuit.h"
#include "ecmascript/compiler/gate.h"
#include "ecmascript/compiler/gate_accessor.h"
#include "ecmascript/jspandafile/method_literal.h"
namespace panda::ecmascript::kungfu {
class BytecodeCircuitBuilder;
struct BytecodeRegion;
class FrameStateInfo {
public:
explicit FrameStateInfo(size_t numVregs) : values_(numVregs), liveout_(numVregs) {}
void SetValuesAt(size_t index, GateRef gate)
{
ASSERT(index < values_.size());
values_[index] = gate;
}
void SetBit(size_t index)
{
liveout_.SetBit(index);
}
void ClearBit(size_t index)
{
liveout_.ClearBit(index);
}
GateRef ValuesAt(size_t index) const
{
ASSERT(index < values_.size());
return values_[index];
}
void CopyFrom(FrameStateInfo *other)
{
values_.assign(other->values_.begin(), other->values_.end());
liveout_.CopyFrom(other->liveout_);
}
bool MergeLiveout(FrameStateInfo *other)
{
return liveout_.UnionWithChanged(other->liveout_);
}
private:
// [numVRegs_] [extra args] [numArgs_] [accumulator]
std::vector<GateRef> values_ {};
BitSet liveout_;
};
class FrameStateBuilder {
public:
FrameStateBuilder(BytecodeCircuitBuilder *builder,
Circuit *circuit, const MethodLiteral *literal);
~FrameStateBuilder();
void BuildFrameState(GateRef frameArgs);
private:
GateRef ValuesAt(size_t index) const
{
return liveOutResult_->ValuesAt(index);
}
GateRef ValuesAtAccumulator() const
{
return ValuesAt(accumulatorIndex_);
}
void UpdateVirtualRegister(size_t index, GateRef gate)
{
liveOutResult_->SetValuesAt(index, gate);
if (gate == Circuit::NullGate()) {
liveOutResult_->ClearBit(index);
} else {
liveOutResult_->SetBit(index);
}
}
void UpdateAccumulator(GateRef gate)
{
UpdateVirtualRegister(accumulatorIndex_, gate);
}
void BindStateSplit(GateRef gate, size_t pcOffset, FrameStateInfo *stateInfo);
void BindStateSplit(size_t size);
void UpdateVirtualRegister(size_t id, size_t index, GateRef gate);
GateRef FrameState(size_t pcOffset, FrameStateInfo *stateInfo);
FrameStateInfo *CreateEmptyStateInfo();
void BuildPostOrderList(size_t size);
bool ComputeLiveOut(size_t bbId);
void ComputeLiveState();
void ComputeLiveOutBC(uint32_t index, const BytecodeInfo &bytecodeInfo);
bool IsAsyncResolveOrSusp(const BytecodeInfo &bytecodeInfo);
bool MergeIntoPredBC(uint32_t predPc);
bool MergeIntoPredBB(BytecodeRegion *bb, BytecodeRegion *predBb);
FrameStateInfo *GetOrOCreateBCEndStateInfo(uint32_t bcIndex)
{
auto currentInfo = bcEndStateInfos_[bcIndex];
if (currentInfo == nullptr) {
currentInfo = CreateEmptyStateInfo();
bcEndStateInfos_[bcIndex] = currentInfo;
}
return currentInfo;
}
FrameStateInfo *GetBBBeginStateInfo(size_t bbId) const
{
return bbBeginStateInfos_.at(bbId);
}
void UpdateVirtualRegistersOfSuspend(GateRef gate);
void UpdateVirtualRegistersOfResume(GateRef gate);
void SaveBBBeginStateInfo(size_t bbId);
FrameStateInfo *GetCurrentFrameInfo(BytecodeRegion &bb, uint32_t bcId);
GateRef GetPreBBInput(BytecodeRegion *bb, BytecodeRegion *predBb, GateRef gate);
GateRef GetPhiComponent(BytecodeRegion *bb, BytecodeRegion *predBb, GateRef phi);
BytecodeCircuitBuilder *builder_{nullptr};
FrameStateInfo *liveOutResult_{nullptr};
size_t numVregs_ {0};
size_t accumulatorIndex_ {0};
Circuit *circuit_ {nullptr};
GateAccessor gateAcc_;
ArgumentAccessor argAcc_;
std::vector<FrameStateInfo *> bcEndStateInfos_;
std::vector<FrameStateInfo *> bbBeginStateInfos_;
std::vector<size_t> postOrderList_;
};
} // panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_FRAME_STATE_H