Perf(aot): nbody optimization

1. Inc overcheck change to sadd_overflow
2. Optimize ValueWithBarrier

Issue:#I6S62N

Change-Id: I8ec283cba223f13df7d5fd7b676f93a642eea17e
Signed-off-by: yingguofeng@huawei.com <yingguofeng@huawei.com>
This commit is contained in:
yingguofeng@huawei.com 2023-04-04 11:33:48 +08:00
parent 4e3d3b35da
commit e28bd8ecf6
8 changed files with 111 additions and 64 deletions

View File

@ -761,8 +761,7 @@ GateRef CircuitBuilder::Call(const CallSignature* cs, GateRef glue, GateRef targ
return result;
}
// memory
void CircuitBuilder::Store(VariableType type, GateRef glue, GateRef base, GateRef offset, GateRef value)
void CircuitBuilder::StoreWithNoBarrier(VariableType type, GateRef base, GateRef offset, GateRef value)
{
auto label = GetCurrentLabel();
auto depend = label->GetDepend();
@ -770,8 +769,25 @@ void CircuitBuilder::Store(VariableType type, GateRef glue, GateRef base, GateRe
GateRef result = GetCircuit()->NewGate(circuit_->Store(),
MachineType::NOVALUE, { depend, value, ptr }, type.GetGateType());
label->SetDepend(result);
}
// memory
void CircuitBuilder::Store(VariableType type, GateRef glue, GateRef base, GateRef offset, GateRef value)
{
StoreWithNoBarrier(type, base, offset, value);
if (type == VariableType::JS_POINTER() || type == VariableType::JS_ANY()) {
CallStub(glue, base, CommonStubCSigns::SetValueWithBarrier, { glue, base, offset, value });
Label entry(env_);
SubCfgEntry(&entry);
Label exit(env_);
Label isHeapObject(env_);
Branch(TaggedIsHeapObject(value), &isHeapObject, &exit);
Bind(&isHeapObject);
{
CallStub(glue, base, CommonStubCSigns::SetValueWithBarrier, { glue, base, offset, value });
Jump(&exit);
}
Bind(&exit);
SubCfgExit();
}
}
@ -830,6 +846,12 @@ GateRef CircuitBuilder::StoreProperty(GateRef receiver, GateRef propertyLookupRe
return ret;
}
GateRef CircuitBuilder::StorePropertyNoBarrier(GateRef gate)
{
acc_.SetMetaData(gate, circuit_->StorePropertyNoBarrier());
return gate;
}
GateRef CircuitBuilder::LoadArrayLength(GateRef array)
{
auto currentLabel = env_->GetCurrentLabel();

View File

@ -334,6 +334,7 @@ public:
inline GateRef Load(VariableType type, GateRef base, GateRef offset);
inline GateRef Load(VariableType type, GateRef base, GateRef offset, GateRef depend);
void Store(VariableType type, GateRef glue, GateRef base, GateRef offset, GateRef value);
void StoreWithNoBarrier(VariableType type, GateRef base, GateRef offset, GateRef value);
#define ARITHMETIC_BINARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID) \
inline GateRef NAME(GateRef x, GateRef y) \
@ -461,6 +462,7 @@ public:
GateRef StoreElement(GateRef receiver, GateRef index, GateRef value);
GateRef LoadProperty(GateRef receiver, GateRef propertyLookupResult, bool isFunction);
GateRef StoreProperty(GateRef receiver, GateRef propertyLookupResult, GateRef value);
GateRef StorePropertyNoBarrier(GateRef gate);
GateRef LoadArrayLength(GateRef array);
GateRef HeapAlloc(GateRef initialHClass, GateType type, RegionSpaceFlag flag);
GateRef Construct(GateRef hirGate, std::vector<GateRef> args);

View File

@ -208,6 +208,7 @@ std::string MachineTypeToStr(MachineType machineType);
V(StableArrayCheck, STABLE_ARRAY_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
V(DeoptCheck, DEOPT_CHECK, GateFlags::NONE_FLAG, 1, 1, 3) \
V(StoreProperty, STORE_PROPERTY, GateFlags::NONE_FLAG, 1, 1, 3) \
V(StorePropertyNoBarrier, STORE_PROPERTY_NO_BARRIER, GateFlags::NONE_FLAG, 1, 1, 3) \
V(ToLength, TO_LENGTH, GateFlags::NONE_FLAG, 1, 1, 1) \
V(DefaultCase, DEFAULT_CASE, GateFlags::CONTROL, 1, 0, 0) \
V(LoadArrayLength, LOAD_ARRAY_LENGTH, GateFlags::NO_WRITE, 1, 1, 1) \

View File

@ -56,6 +56,10 @@ void NumberSpeculativeLowering::VisitGate(GateRef gate)
VisitConstant(gate);
break;
}
case OpCode::STORE_PROPERTY: {
VisitStoreProperty(gate);
break;
}
default:
break;
}
@ -255,7 +259,8 @@ void NumberSpeculativeLowering::VisitTypedInc(GateRef gate)
void NumberSpeculativeLowering::VisitIntInc(GateRef gate)
{
GateRef value = acc_.GetValueIn(gate, 0);
GateRef result = builder_.Int32Add(value, builder_.Int32(1));
GateRef right = builder_.Int32(1);
GateRef result = CalculateInts<TypedBinOp::TYPED_ADD>(value, right);
acc_.SetMachineType(gate, MachineType::I32);
acc_.SetGateType(gate, GateType::NJSValue());
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
@ -297,6 +302,20 @@ void NumberSpeculativeLowering::VisitUndefinedStrictEq(GateRef gate)
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
}
void NumberSpeculativeLowering::VisitStoreProperty(GateRef gate)
{
TypeInfo output = typeInfos_[acc_.GetId(gate)];
switch (output) {
case TypeInfo::INT1:
case TypeInfo::INT32:
case TypeInfo::FLOAT64:
builder_.StorePropertyNoBarrier(gate);
break;
default:
break;
}
}
void NumberSpeculativeLowering::VisitConstant(GateRef gate)
{
TypeInfo output = typeInfos_[acc_.GetId(gate)];

View File

@ -41,7 +41,8 @@ private:
void VisitConstant(GateRef gate);
void VisitPhi(GateRef gate);
void VisitUndefinedStrictEq(GateRef gate);
void VisitStoreProperty(GateRef gate);
template<TypedBinOp Op>
void VisitNumberCalculate(GateRef gate);
template<TypedBinOp Op>
@ -70,4 +71,4 @@ private:
ChunkVector<TypeInfo>& typeInfos_;
};
} // panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_NUMBER_SPECULATIVE_LOWERING_H
#endif // ECMASCRIPT_COMPILER_NUMBER_SPECULATIVE_LOWERING_H

View File

@ -939,71 +939,66 @@ void StubBuilder::SetValueWithBarrier(GateRef glue, GateRef obj, GateRef offset,
Label entry(env);
env->SubCfgEntry(&entry);
Label exit(env);
Label isHeapObject(env);
Label isVailedIndex(env);
Label notValidIndex(env);
Branch(TaggedIsHeapObject(value), &isHeapObject, &exit);
Bind(&isHeapObject);
// ObjectAddressToRange function may cause obj is not an object. GC may not mark this obj.
GateRef objectRegion = ObjectAddressToRange(obj);
GateRef valueRegion = ObjectAddressToRange(value);
GateRef slotAddr = PtrAdd(TaggedCastToIntPtr(obj), offset);
GateRef objectNotInYoung = BoolNot(InYoungGeneration(objectRegion));
GateRef valueRegionInYoung = InYoungGeneration(valueRegion);
Branch(BoolAnd(objectNotInYoung, valueRegionInYoung), &isVailedIndex, &notValidIndex);
Bind(&isVailedIndex);
{
// ObjectAddressToRange function may cause obj is not an object. GC may not mark this obj.
GateRef objectRegion = ObjectAddressToRange(obj);
GateRef valueRegion = ObjectAddressToRange(value);
GateRef slotAddr = PtrAdd(TaggedCastToIntPtr(obj), offset);
GateRef objectNotInYoung = BoolNot(InYoungGeneration(objectRegion));
GateRef valueRegionInYoung = InYoungGeneration(valueRegion);
Branch(BoolAnd(objectNotInYoung, valueRegionInYoung), &isVailedIndex, &notValidIndex);
Bind(&isVailedIndex);
GateRef loadOffset = IntPtr(Region::PackedData::GetOldToNewSetOffset(env_->Is32Bit()));
auto oldToNewSet = Load(VariableType::NATIVE_POINTER(), objectRegion, loadOffset);
Label isNullPtr(env);
Label notNullPtr(env);
Branch(IntPtrEuqal(oldToNewSet, IntPtr(0)), &isNullPtr, &notNullPtr);
Bind(&notNullPtr);
{
GateRef loadOffset = IntPtr(Region::PackedData::GetOldToNewSetOffset(env_->Is32Bit()));
auto oldToNewSet = Load(VariableType::NATIVE_POINTER(), objectRegion, loadOffset);
Label isNullPtr(env);
Label notNullPtr(env);
Branch(IntPtrEuqal(oldToNewSet, IntPtr(0)), &isNullPtr, &notNullPtr);
Bind(&notNullPtr);
{
// (slotAddr - this) >> TAGGED_TYPE_SIZE_LOG
GateRef bitOffsetPtr = IntPtrLSR(PtrSub(slotAddr, objectRegion), IntPtr(TAGGED_TYPE_SIZE_LOG));
GateRef bitOffset = TruncPtrToInt32(bitOffsetPtr);
GateRef bitPerWordLog2 = Int32(GCBitset::BIT_PER_WORD_LOG2);
GateRef bytePerWord = Int32(GCBitset::BYTE_PER_WORD);
// bitOffset >> BIT_PER_WORD_LOG2
GateRef index = Int32LSR(bitOffset, bitPerWordLog2);
GateRef byteIndex = Int32Mul(index, bytePerWord);
// bitset_[index] |= mask;
GateRef bitsetData = PtrAdd(oldToNewSet, IntPtr(RememberedSet::GCBITSET_DATA_OFFSET));
GateRef oldsetValue = Load(VariableType::INT32(), bitsetData, byteIndex);
GateRef newmapValue = Int32Or(oldsetValue, GetBitMask(bitOffset));
// (slotAddr - this) >> TAGGED_TYPE_SIZE_LOG
GateRef bitOffsetPtr = IntPtrLSR(PtrSub(slotAddr, objectRegion), IntPtr(TAGGED_TYPE_SIZE_LOG));
GateRef bitOffset = TruncPtrToInt32(bitOffsetPtr);
GateRef bitPerWordLog2 = Int32(GCBitset::BIT_PER_WORD_LOG2);
GateRef bytePerWord = Int32(GCBitset::BYTE_PER_WORD);
// bitOffset >> BIT_PER_WORD_LOG2
GateRef index = Int32LSR(bitOffset, bitPerWordLog2);
GateRef byteIndex = Int32Mul(index, bytePerWord);
// bitset_[index] |= mask;
GateRef bitsetData = PtrAdd(oldToNewSet, IntPtr(RememberedSet::GCBITSET_DATA_OFFSET));
GateRef oldsetValue = Load(VariableType::INT32(), bitsetData, byteIndex);
GateRef newmapValue = Int32Or(oldsetValue, GetBitMask(bitOffset));
Store(VariableType::INT32(), glue, bitsetData, byteIndex, newmapValue);
Jump(&notValidIndex);
}
Bind(&isNullPtr);
{
CallNGCRuntime(glue, RTSTUB_ID(InsertOldToNewRSet), { glue, obj, offset });
Jump(&notValidIndex);
}
Store(VariableType::INT32(), glue, bitsetData, byteIndex, newmapValue);
Jump(&notValidIndex);
}
Bind(&notValidIndex);
Bind(&isNullPtr);
{
Label marking(env);
bool isArch32 = GetEnvironment()->Is32Bit();
GateRef stateBitFieldAddr = Int64Add(glue,
Int64(JSThread::GlueData::GetStateBitFieldOffset(isArch32)));
GateRef stateBitField = Load(VariableType::INT64(), stateBitFieldAddr, Int64(0));
// mask: 1 << JSThread::CONCURRENT_MARKING_BITFIELD_NUM - 1
GateRef markingBitMask = Int64Sub(
Int64LSL(Int64(1), Int64(JSThread::CONCURRENT_MARKING_BITFIELD_NUM)), Int64(1));
GateRef state = Int64And(stateBitField, markingBitMask);
Branch(Int64Equal(state, Int64(static_cast<int64_t>(MarkStatus::READY_TO_MARK))), &exit, &marking);
Bind(&marking);
CallNGCRuntime(
glue,
RTSTUB_ID(MarkingBarrier), { glue, obj, offset, value });
Jump(&exit);
CallNGCRuntime(glue, RTSTUB_ID(InsertOldToNewRSet), { glue, obj, offset });
Jump(&notValidIndex);
}
}
Bind(&notValidIndex);
{
Label marking(env);
bool isArch32 = GetEnvironment()->Is32Bit();
GateRef stateBitFieldAddr = Int64Add(glue,
Int64(JSThread::GlueData::GetStateBitFieldOffset(isArch32)));
GateRef stateBitField = Load(VariableType::INT64(), stateBitFieldAddr, Int64(0));
// mask: 1 << JSThread::CONCURRENT_MARKING_BITFIELD_NUM - 1
GateRef markingBitMask = Int64Sub(
Int64LSL(Int64(1), Int64(JSThread::CONCURRENT_MARKING_BITFIELD_NUM)), Int64(1));
GateRef state = Int64And(stateBitField, markingBitMask);
Branch(Int64Equal(state, Int64(static_cast<int64_t>(MarkStatus::READY_TO_MARK))), &exit, &marking);
Bind(&marking);
CallNGCRuntime(
glue,
RTSTUB_ID(MarkingBarrier), { glue, obj, offset, value });
Jump(&exit);
}
Bind(&exit);
env->SubCfgExit();
}

View File

@ -453,8 +453,7 @@ void TSTypeLowering::SpeculateNumbers(GateRef gate)
bool TSTypeLowering::NeedInt32OverflowCheck(TypedUnOp op) const
{
if (op == TypedUnOp::TYPED_INC || op == TypedUnOp::TYPED_DEC ||
op == TypedUnOp::TYPED_NEG) {
if (op == TypedUnOp::TYPED_DEC || op == TypedUnOp::TYPED_NEG) {
return true;
}
return false;

View File

@ -92,6 +92,7 @@ void TypeLowering::LowerType(GateRef gate)
LowerCallGetter(gate, glue);
break;
case OpCode::STORE_PROPERTY:
case OpCode::STORE_PROPERTY_NO_BARRIER:
LowerStoreProperty(gate, glue);
break;
case OpCode::CALL_SETTER:
@ -576,7 +577,14 @@ void TypeLowering::LowerStoreProperty(GateRef gate, GateRef glue)
PropertyLookupResult plr(acc_.TryGetValue(propertyLookupResult));
ASSERT(plr.IsLocal());
GateRef offset = builder_.IntPtr(plr.GetOffset());
builder_.Store(VariableType::JS_ANY(), glue, receiver, offset, value);
auto op = OpCode(acc_.GetOpCode(gate));
if (op == OpCode::STORE_PROPERTY) {
builder_.Store(VariableType::JS_ANY(), glue, receiver, offset, value);
} else if (op == OpCode::STORE_PROPERTY_NO_BARRIER) {
builder_.StoreWithNoBarrier(VariableType::JS_ANY(), receiver, offset, value);
} else {
UNREACHABLE();
}
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
}