mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
Add MIR for LdLexVar and StLexVar
Issues: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7M1VF Signed-off-by: sunzhe23 <sunzhe23@huawei.com>
This commit is contained in:
parent
90ddc0b915
commit
bd9b7009a5
@ -983,6 +983,18 @@ GateRef CircuitBuilder::LogicOr(GateRef x, GateRef y)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::LoadFromTaggedArray(GateRef array, size_t index)
|
||||
{
|
||||
auto dataOffset = TaggedArray::DATA_OFFSET + index * JSTaggedValue::TaggedTypeSize();
|
||||
return LoadConstOffset(VariableType::JS_ANY(), array, dataOffset);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::StoreToTaggedArray(GateRef array, size_t index, GateRef value)
|
||||
{
|
||||
auto dataOffset = TaggedArray::DATA_OFFSET + index * JSTaggedValue::TaggedTypeSize();
|
||||
return StoreConstOffset(VariableType::JS_ANY(), array, dataOffset, value);
|
||||
}
|
||||
|
||||
int CircuitBuilder::NextVariableId()
|
||||
{
|
||||
return env_->NextVariableId();
|
||||
|
@ -615,6 +615,19 @@ GateRef CircuitBuilder::Float64CheckRightIsZero(GateRef right)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::LexVarIsHoleCheck(GateRef value)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto frameState = acc_.FindNearestFrameState(currentDepend);
|
||||
GateRef ret = GetCircuit()->NewGate(circuit_->LexVarIsHoleCheck(),
|
||||
MachineType::I1, {currentControl, currentDepend, value, frameState}, GateType::NJSValue());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::ValueCheckNegOverflow(GateRef value)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
|
@ -277,6 +277,7 @@ public:
|
||||
GateRef NegativeIndexCheck(GateRef index);
|
||||
GateRef LargeIndexCheck(GateRef index, GateRef length);
|
||||
GateRef OverflowCheck(GateRef value);
|
||||
GateRef LexVarIsHoleCheck(GateRef value);
|
||||
GateRef Int32UnsignedUpperBoundCheck(GateRef value, GateRef upperBound);
|
||||
GateRef Int32DivWithCheck(GateRef left, GateRef right);
|
||||
MachineType GetMachineTypeOfValueType(ValueType type);
|
||||
@ -646,6 +647,8 @@ public:
|
||||
GateRef GetGlobalEnvValue(VariableType type, GateRef env, size_t index);
|
||||
GateRef IsBase(GateRef ctor);
|
||||
inline GateRef GetMethodId(GateRef func);
|
||||
inline GateRef LoadFromTaggedArray(GateRef array, size_t index);
|
||||
inline GateRef StoreToTaggedArray(GateRef array, size_t index, GateRef value);
|
||||
|
||||
private:
|
||||
#define ARITHMETIC_UNARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID) \
|
||||
|
@ -242,26 +242,34 @@ DependInfoNode* EarlyElimination::UpdateWrite(GateRef gate, DependInfoNode* depe
|
||||
|
||||
bool EarlyElimination::MayAccessOneMemory(GateRef lhs, GateRef rhs)
|
||||
{
|
||||
if (acc_.GetOpCode(rhs) == OpCode::STORE_ELEMENT) {
|
||||
return acc_.GetOpCode(lhs) == OpCode::LOAD_ELEMENT;
|
||||
}
|
||||
auto rop = acc_.GetOpCode(rhs);
|
||||
auto lop = acc_.GetOpCode(lhs);
|
||||
ASSERT(acc_.GetOpCode(rhs) == OpCode::STORE_PROPERTY ||
|
||||
acc_.GetOpCode(rhs) == OpCode::STORE_PROPERTY_NO_BARRIER ||
|
||||
acc_.GetOpCode(rhs) == OpCode::STORE_CONST_OFFSET);
|
||||
if (lop == OpCode::LOAD_PROPERTY) {
|
||||
auto loff = acc_.GetValueIn(lhs, 1);
|
||||
auto roff = acc_.GetValueIn(rhs, 1);
|
||||
ASSERT(acc_.GetOpCode(loff) == OpCode::CONSTANT);
|
||||
ASSERT(acc_.GetOpCode(roff) == OpCode::CONSTANT);
|
||||
return loff == roff;
|
||||
} else if (lop == OpCode::LOAD_CONST_OFFSET) {
|
||||
auto loff = acc_.GetOffset(lhs);
|
||||
auto roff = acc_.GetOffset(rhs);
|
||||
return loff == roff;
|
||||
} else {
|
||||
return false;
|
||||
switch (rop) {
|
||||
case OpCode::STORE_ELEMENT:
|
||||
return lop == OpCode::LOAD_ELEMENT;
|
||||
case OpCode::STORE_PROPERTY:
|
||||
case OpCode::STORE_PROPERTY_NO_BARRIER: {
|
||||
if (lop == OpCode::LOAD_PROPERTY) {
|
||||
auto loff = acc_.GetValueIn(lhs, 1);
|
||||
auto roff = acc_.GetValueIn(rhs, 1);
|
||||
ASSERT(acc_.GetOpCode(loff) == OpCode::CONSTANT);
|
||||
ASSERT(acc_.GetOpCode(roff) == OpCode::CONSTANT);
|
||||
return loff == roff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::STORE_CONST_OFFSET: {
|
||||
if (lop == OpCode::LOAD_CONST_OFFSET) {
|
||||
auto loff = acc_.GetOffset(lhs);
|
||||
auto roff = acc_.GetOffset(rhs);
|
||||
return loff == roff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EarlyElimination::CompareOrder(GateRef lhs, GateRef rhs)
|
||||
|
@ -100,6 +100,7 @@ enum class TypedJumpOp : uint8_t {
|
||||
V(LargeIndex, LARGEINDEX) \
|
||||
V(InlineFail, INLINEFAIL) \
|
||||
V(NotJSFastCallTarget, NOTJSFASTCALLTGT) \
|
||||
V(LexVarIsHole, LEXVARISHOLE) \
|
||||
V(ModZero, MODZERO)
|
||||
|
||||
enum class DeoptType : uint8_t {
|
||||
@ -198,7 +199,8 @@ std::string MachineTypeToStr(MachineType machineType);
|
||||
V(LargeIndexCheck, LARGE_INDEX_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(OverflowCheck, OVERFLOW_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(Int32UnsignedUpperBoundCheck, INT32_UNSIGNED_UPPER_BOUND_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(Int32DivWithCheck, INT32_DIV_WITH_CHECK, GateFlags::CHECKABLE, 1, 1, 2)
|
||||
V(Int32DivWithCheck, INT32_DIV_WITH_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(LexVarIsHoleCheck, LEX_VAR_IS_HOLE_CHECK, GateFlags::CHECKABLE, 1, 1, 1)
|
||||
|
||||
#define UNARY_GATE_META_DATA_CACHE_LIST(V) \
|
||||
V(Zext, ZEXT, GateFlags::NONE_FLAG, 0, 0, 1) \
|
||||
|
@ -52,6 +52,15 @@ GateRef LaterElimination::VisitGate(GateRef gate)
|
||||
case OpCode::ARRAY_GUARDIAN_CHECK:
|
||||
case OpCode::HCLASS_STABLE_ARRAY_CHECK:
|
||||
case OpCode::HEAP_OBJECT_CHECK:
|
||||
case OpCode::INT32_UNSIGNED_UPPER_BOUND_CHECK:
|
||||
case OpCode::OVERFLOW_CHECK:
|
||||
case OpCode::LARGE_INDEX_CHECK:
|
||||
case OpCode::NEGATIVE_INDEX_CHECK:
|
||||
case OpCode::VALUE_CHECK_NEG_OVERFLOW:
|
||||
case OpCode::FLOAT64_CHECK_RIGHT_IS_ZERO:
|
||||
case OpCode::INT32_CHECK_RIGHT_IS_ZERO:
|
||||
case OpCode::INT32_DIV_WITH_CHECK:
|
||||
case OpCode::LEX_VAR_IS_HOLE_CHECK:
|
||||
return TryEliminateGate(gate);
|
||||
case OpCode::DEPEND_SELECTOR:
|
||||
return TryEliminateDependSelector(gate);
|
||||
|
@ -86,6 +86,9 @@ void LCRLowering::Run()
|
||||
case OpCode::INT32_DIV_WITH_CHECK:
|
||||
LowerInt32DivWithCheck(gate);
|
||||
break;
|
||||
case OpCode::LEX_VAR_IS_HOLE_CHECK:
|
||||
LowerLexVarIsHoleCheck(gate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -568,6 +571,16 @@ void LCRLowering::LowerFloat64CheckRightIsZero(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void LCRLowering::LowerLexVarIsHoleCheck(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef frameState = acc_.GetFrameState(gate);
|
||||
GateRef value = acc_.GetValueIn(gate, 0);
|
||||
GateRef valueIsNotHole = builder_.TaggedIsNotHole(value);
|
||||
builder_.DeoptCheck(valueIsNotHole, frameState, DeoptType::LEXVARISHOLE);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void LCRLowering::LowerValueCheckNegOverflow(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
@ -69,6 +69,7 @@ private:
|
||||
void LowerOverflowCheck(GateRef gate);
|
||||
void LowerInt32UnsignedUpperBoundCheck(GateRef gate);
|
||||
void LowerInt32DivWithCheck(GateRef gate);
|
||||
void LowerLexVarIsHoleCheck(GateRef gate);
|
||||
|
||||
GateRef ConvertBoolToTaggedBoolean(GateRef gate);
|
||||
GateRef ConvertInt32ToFloat64(GateRef gate);
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "ecmascript/compiler/ntype_hcr_lowering.h"
|
||||
#include "ecmascript/compiler/circuit_builder-inl.h"
|
||||
#include "ecmascript/dfx/vmstat/opt_code_profiler.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
@ -60,11 +61,79 @@ void NTypeHCRLowering::Lower(GateRef gate)
|
||||
case EcmaOpcode::STOWNBYNAME_IMM16_ID16_V8:
|
||||
LowerTypedStOwnByName(gate);
|
||||
break;
|
||||
case EcmaOpcode::THROW_UNDEFINEDIFHOLEWITHNAME_PREF_ID16:
|
||||
LowerThrowUndefinedIfHoleWithName(gate);
|
||||
break;
|
||||
case EcmaOpcode::LDLEXVAR_IMM4_IMM4:
|
||||
case EcmaOpcode::LDLEXVAR_IMM8_IMM8:
|
||||
case EcmaOpcode::WIDE_LDLEXVAR_PREF_IMM16_IMM16:
|
||||
LowerLdLexVar(gate);
|
||||
break;
|
||||
case EcmaOpcode::STLEXVAR_IMM4_IMM4:
|
||||
case EcmaOpcode::STLEXVAR_IMM8_IMM8:
|
||||
case EcmaOpcode::WIDE_STLEXVAR_PREF_IMM16_IMM16:
|
||||
LowerStLexVar(gate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NTypeHCRLowering::LowerThrowUndefinedIfHoleWithName(GateRef gate)
|
||||
{
|
||||
|
||||
GateRef value = acc_.GetValueIn(gate, 1); // 1: the second parameter
|
||||
builder_.LexVarIsHoleCheck(value);
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void NTypeHCRLowering::LowerLdLexVar(GateRef gate)
|
||||
{
|
||||
AddProfiling(gate);
|
||||
GateRef level = acc_.GetValueIn(gate, 0); // 0: first parameter
|
||||
GateRef index = acc_.GetValueIn(gate, 1); // 1: the second parameter
|
||||
GateRef currentEnv = acc_.GetValueIn(gate, 2); // 2: the third parameter
|
||||
|
||||
uint32_t levelValue = static_cast<uint32_t>(acc_.GetConstantValue(level));
|
||||
uint32_t indexValue = static_cast<uint32_t>(acc_.GetConstantValue(index));
|
||||
indexValue += LexicalEnv::RESERVED_ENV_LENGTH;
|
||||
GateRef result = Circuit::NullGate();
|
||||
if (levelValue == 0) {
|
||||
result = builder_.LoadFromTaggedArray(currentEnv, indexValue);
|
||||
} else if (levelValue == 1) { // 1: level 1
|
||||
auto parentEnv = builder_.LoadFromTaggedArray(currentEnv, LexicalEnv::PARENT_ENV_INDEX);
|
||||
result = builder_.LoadFromTaggedArray(parentEnv, indexValue);
|
||||
} else {
|
||||
// level > 1, go slowpath
|
||||
return;
|
||||
}
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void NTypeHCRLowering::LowerStLexVar(GateRef gate)
|
||||
{
|
||||
AddProfiling(gate);
|
||||
GateRef level = acc_.GetValueIn(gate, 0); // 0: first parameter
|
||||
GateRef index = acc_.GetValueIn(gate, 1); // 1: the second parameter
|
||||
GateRef currentEnv = acc_.GetValueIn(gate, 2); // 2: the third parameter
|
||||
GateRef value = acc_.GetValueIn(gate, 3); // 3: the fourth parameter
|
||||
|
||||
uint32_t levelValue = static_cast<uint32_t>(acc_.GetConstantValue(level));
|
||||
uint32_t indexValue = static_cast<uint32_t>(acc_.GetConstantValue(index));
|
||||
indexValue += LexicalEnv::RESERVED_ENV_LENGTH;
|
||||
GateRef result = Circuit::NullGate();
|
||||
if (levelValue == 0) {
|
||||
result = builder_.StoreToTaggedArray(currentEnv, indexValue, value);
|
||||
} else if (levelValue == 1) { // 1: level 1
|
||||
auto parentEnv = builder_.LoadFromTaggedArray(currentEnv, LexicalEnv::PARENT_ENV_INDEX);
|
||||
result = builder_.StoreToTaggedArray(parentEnv, indexValue, value);
|
||||
} else {
|
||||
// level > 1, go slowpath
|
||||
return;
|
||||
}
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void NTypeHCRLowering::LowerTypedCreateEmptyArray(GateRef gate)
|
||||
{
|
||||
// in the future, the type of the elements in the array will be obtained through pgo,
|
||||
|
@ -45,6 +45,9 @@ private:
|
||||
void LowerTypedCreateEmptyArray(GateRef gate);
|
||||
void LowerTypedStownByIndex(GateRef gate);
|
||||
void LowerTypedStOwnByName(GateRef gate);
|
||||
void LowerLdLexVar(GateRef gate);
|
||||
void LowerStLexVar(GateRef gate);
|
||||
void LowerThrowUndefinedIfHoleWithName(GateRef gate);
|
||||
|
||||
bool IsLogEnabled() const
|
||||
{
|
||||
|
@ -46,6 +46,8 @@ private:
|
||||
void LowerCreateArray(GateRef gate, GateRef glue);
|
||||
void LowerCreateEmptyArray(GateRef gate);
|
||||
void LowerCreateArrayWithOwn(GateRef gate, GateRef glue);
|
||||
void LowerStLexVar(GateRef gate);
|
||||
void LowerLdLexVar(GateRef gate);
|
||||
|
||||
GateRef NewTaggedArray(size_t length);
|
||||
GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
|
||||
|
@ -126,6 +126,9 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate)
|
||||
case OpCode::FRAME_ARGS:
|
||||
case OpCode::SAVE_REGISTER:
|
||||
case OpCode::RESTORE_REGISTER:
|
||||
case OpCode::LOAD_CONST_OFFSET:
|
||||
case OpCode::STORE_CONST_OFFSET:
|
||||
case OpCode::LEX_VAR_IS_HOLE_CHECK:
|
||||
return VisitOthers(gate);
|
||||
default:
|
||||
return Circuit::NullGate();
|
||||
|
@ -442,7 +442,7 @@ void TypeMCRLowering::LowerPrimitiveToNumber(GateRef dst, GateRef src, GateType
|
||||
GateRef TypeMCRLowering::LoadFromConstPool(GateRef jsFunc, size_t index)
|
||||
{
|
||||
GateRef constPool = builder_.GetConstPool(jsFunc);
|
||||
return LoadFromTaggedArray(constPool, index);
|
||||
return builder_.LoadFromTaggedArray(constPool, index);
|
||||
}
|
||||
|
||||
GateRef TypeMCRLowering::GetObjectFromConstPool(GateRef jsFunc, GateRef index)
|
||||
@ -1072,12 +1072,6 @@ void TypeMCRLowering::LowerGetSuperConstructor(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), superCtor);
|
||||
}
|
||||
|
||||
GateRef TypeMCRLowering::LoadFromTaggedArray(GateRef array, size_t index)
|
||||
{
|
||||
auto dataOffset = TaggedArray::DATA_OFFSET + index * JSTaggedValue::TaggedTypeSize();
|
||||
return builder_.LoadConstOffset(VariableType::JS_ANY(), array, dataOffset);
|
||||
}
|
||||
|
||||
GateRef TypeMCRLowering::LoadFromVTable(GateRef receiver, size_t index)
|
||||
{
|
||||
GateRef hclass = builder_.LoadConstOffset(
|
||||
@ -1085,8 +1079,8 @@ GateRef TypeMCRLowering::LoadFromVTable(GateRef receiver, size_t index)
|
||||
GateRef vtable = builder_.LoadConstOffset(VariableType::JS_ANY(),
|
||||
hclass, JSHClass::VTABLE_OFFSET);
|
||||
|
||||
GateRef itemOwner = LoadFromTaggedArray(vtable, VTable::TupleItem::OWNER + index);
|
||||
GateRef itemOffset = LoadFromTaggedArray(vtable, VTable::TupleItem::OFFSET + index);
|
||||
GateRef itemOwner = builder_.LoadFromTaggedArray(vtable, VTable::TupleItem::OWNER + index);
|
||||
GateRef itemOffset = builder_.LoadFromTaggedArray(vtable, VTable::TupleItem::OFFSET + index);
|
||||
return builder_.Load(VariableType::JS_ANY(), itemOwner, builder_.TaggedGetInt(itemOffset));
|
||||
}
|
||||
|
||||
@ -1113,7 +1107,7 @@ GateRef TypeMCRLowering::GetLengthFromSupers(GateRef supers)
|
||||
|
||||
GateRef TypeMCRLowering::GetValueFromSupers(GateRef supers, size_t index)
|
||||
{
|
||||
GateRef val = LoadFromTaggedArray(supers, index);
|
||||
GateRef val = builder_.LoadFromTaggedArray(supers, index);
|
||||
return builder_.LoadObjectFromWeakRef(val);
|
||||
}
|
||||
|
||||
|
@ -12,3 +12,4 @@
|
||||
# limitations under the License.
|
||||
|
||||
2
|
||||
1
|
||||
|
@ -14,10 +14,16 @@
|
||||
*/
|
||||
|
||||
declare function print(str:any):string;
|
||||
{
|
||||
|
||||
function f() { return x + 1; }
|
||||
|
||||
let gValue = 0;
|
||||
function g() {
|
||||
gValue++;
|
||||
}
|
||||
|
||||
const x = 1;
|
||||
|
||||
print(f());
|
||||
}
|
||||
g();
|
||||
print(gValue);
|
||||
|
Loading…
Reference in New Issue
Block a user