Commit fec831de authored by Victor Gomes's avatar Victor Gomes Committed by V8 LUCI CQ

[maglev] Support ToBooleanLogicalNot

Update LogicalNot to use same Constant::ToBoolean logic.

Bug: v8:7700
Change-Id: Id8f6c1b8fa9bb70489122f35bcee4c88bffc9499
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3769691Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Auto-Submit: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81882}
parent c53c20fe
......@@ -1285,20 +1285,39 @@ void MaglevGraphBuilder::VisitBitwiseNot() {
VisitUnaryOperation<Operation::kBitwiseNot>();
}
MAGLEV_UNIMPLEMENTED_BYTECODE(ToBooleanLogicalNot)
void MaglevGraphBuilder::VisitToBooleanLogicalNot() {
ValueNode* value = GetAccumulatorTagged();
switch (value->opcode()) {
#define CASE(Name) \
case Opcode::k##Name: { \
SetAccumulator( \
GetBooleanConstant(value->Cast<Name>()->ToBoolean(local_isolate()))); \
break; \
}
CONSTANT_VALUE_NODE_LIST(CASE)
#undef CASE
default:
SetAccumulator(AddNewNode<ToBooleanLogicalNot>({value}));
break;
}
}
void MaglevGraphBuilder::VisitLogicalNot() {
// Invariant: accumulator must already be a boolean value.
ValueNode* value = GetAccumulatorTagged();
if (RootConstant* constant = value->TryCast<RootConstant>()) {
if (constant->index() == RootIndex::kTrueValue) {
SetAccumulator(GetRootConstant(RootIndex::kFalseValue));
} else {
DCHECK_EQ(constant->index(), RootIndex::kFalseValue);
SetAccumulator(GetRootConstant(RootIndex::kTrueValue));
}
switch (value->opcode()) {
#define CASE(Name) \
case Opcode::k##Name: { \
SetAccumulator( \
GetBooleanConstant(value->Cast<Name>()->ToBoolean(local_isolate()))); \
break; \
}
CONSTANT_VALUE_NODE_LIST(CASE)
#undef CASE
default:
SetAccumulator(AddNewNode<LogicalNot>({value}));
break;
}
SetAccumulator(AddNewNode<LogicalNot>({value}));
}
MAGLEV_UNIMPLEMENTED_BYTECODE(TypeOf)
......
......@@ -311,6 +311,11 @@ class MaglevGraphBuilder {
return it->second;
}
RootConstant* GetBooleanConstant(bool value) {
return GetRootConstant(value ? RootIndex::kTrueValue
: RootIndex::kFalseValue);
}
Int32Constant* GetInt32Constant(int constant) {
auto it = graph_->int32().find(constant);
if (it == graph_->int32().end()) {
......
......@@ -107,6 +107,7 @@ class MaglevGraphVerifier {
case Opcode::kCreateClosure:
case Opcode::kFastCreateClosure:
case Opcode::kLogicalNot:
case Opcode::kToBooleanLogicalNot:
case Opcode::kTestUndetectable:
case Opcode::kTestTypeOf:
case Opcode::kReturn:
......
......@@ -685,6 +685,17 @@ void RootConstant::AllocateVreg(MaglevVregAllocationState* vreg_state) {
}
void RootConstant::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {}
bool RootConstant::ToBoolean(LocalIsolate* local_isolate) const {
switch (index_) {
case RootIndex::kFalseValue:
case RootIndex::kNullValue:
case RootIndex::kUndefinedValue:
case RootIndex::kempty_string:
return false;
default:
return true;
}
}
void RootConstant::DoLoadToRegister(MaglevCodeGenState* code_gen_state,
Register reg) {
__ LoadRoot(reg, index());
......@@ -1888,6 +1899,26 @@ void LogicalNot::GenerateCode(MaglevCodeGenState* code_gen_state,
}
}
void ToBooleanLogicalNot::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(value());
DefineAsRegister(vreg_state, this);
}
void ToBooleanLogicalNot::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
Register object = ToRegister(value());
Register return_value = ToRegister(result());
Label done;
Zone* zone = code_gen_state->compilation_info()->zone();
ZoneLabelRef object_is_true(zone), object_is_false(zone);
ToBoolean(code_gen_state, object, object_is_true, object_is_false, true);
__ bind(*object_is_true);
__ LoadRoot(return_value, RootIndex::kFalseValue);
__ jmp(&done);
__ bind(*object_is_false);
__ LoadRoot(return_value, RootIndex::kTrueValue);
__ bind(&done);
}
void TaggedEqual::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(lhs());
UseRegister(rhs());
......
......@@ -147,6 +147,7 @@ class CompactInterpreterFrameState;
V(Float64Box) \
V(CheckedFloat64Unbox) \
V(LogicalNot) \
V(ToBooleanLogicalNot) \
V(TaggedEqual) \
V(TestInstanceOf) \
V(TestUndetectable) \
......@@ -1461,6 +1462,8 @@ class Int32Constant : public FixedInputValueNodeT<0, Int32Constant> {
int32_t value() const { return value_; }
bool ToBoolean(LocalIsolate* local_isolate) const { return value_ != 0; }
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
......@@ -1485,6 +1488,10 @@ class Float64Constant : public FixedInputValueNodeT<0, Float64Constant> {
double value() const { return value_; }
bool ToBoolean(LocalIsolate* local_isolate) const {
return value_ != 0.0 && !std::isnan(value_);
}
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
......@@ -1561,6 +1568,20 @@ class LogicalNot : public FixedInputValueNodeT<1, LogicalNot> {
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
};
class ToBooleanLogicalNot
: public FixedInputValueNodeT<1, ToBooleanLogicalNot> {
using Base = FixedInputValueNodeT<1, ToBooleanLogicalNot>;
public:
explicit ToBooleanLogicalNot(uint64_t bitfield) : Base(bitfield) {}
Input& value() { return Node::input(0); }
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
};
class TaggedEqual : public FixedInputValueNodeT<2, TaggedEqual> {
using Base = FixedInputValueNodeT<2, TaggedEqual>;
......@@ -1669,6 +1690,10 @@ class SmiConstant : public FixedInputValueNodeT<0, SmiConstant> {
Smi value() const { return value_; }
bool ToBoolean(LocalIsolate* local_isolate) const {
return value_ != Smi::FromInt(0);
}
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
......@@ -1689,6 +1714,10 @@ class Constant : public FixedInputValueNodeT<0, Constant> {
explicit Constant(uint64_t bitfield, const compiler::HeapObjectRef& object)
: Base(bitfield), object_(object) {}
bool ToBoolean(LocalIsolate* local_isolate) const {
return object_.object()->BooleanValue(local_isolate);
}
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
......@@ -1709,6 +1738,8 @@ class RootConstant : public FixedInputValueNodeT<0, RootConstant> {
explicit RootConstant(uint64_t bitfield, RootIndex index)
: Base(bitfield), index_(index) {}
bool ToBoolean(LocalIsolate* local_isolate) const;
RootIndex index() const { return index_; }
void AllocateVreg(MaglevVregAllocationState*);
......
......@@ -124,6 +124,10 @@ bool Object::IsNullOrUndefined(Isolate* isolate) const {
return IsNullOrUndefined(ReadOnlyRoots(isolate));
}
bool Object::IsNullOrUndefined(LocalIsolate* local_isolate) const {
return IsNullOrUndefined(ReadOnlyRoots(local_isolate));
}
bool Object::IsNullOrUndefined(ReadOnlyRoots roots) const {
return IsNull(roots) || IsUndefined(roots);
}
......
......@@ -651,7 +651,8 @@ MaybeHandle<Object> Object::ConvertToIndex(Isolate* isolate,
return js_len;
}
bool Object::BooleanValue(Isolate* isolate) {
template <typename IsolateT>
bool Object::BooleanValue(IsolateT* isolate) {
if (IsSmi()) return Smi::ToInt(*this) != 0;
DCHECK(IsHeapObject());
if (IsBoolean()) return IsTrue(isolate);
......@@ -662,6 +663,8 @@ bool Object::BooleanValue(Isolate* isolate) {
if (IsBigInt()) return BigInt::cast(*this).ToBoolean();
return true;
}
template bool Object::BooleanValue(Isolate*);
template bool Object::BooleanValue(LocalIsolate*);
Object Object::ToBoolean(Isolate* isolate) {
if (IsBoolean()) return *this;
......
......@@ -382,7 +382,8 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
inline bool HasValidElements();
// ECMA-262 9.2.
V8_EXPORT_PRIVATE bool BooleanValue(Isolate* isolate);
template <typename IsolateT>
V8_EXPORT_PRIVATE bool BooleanValue(IsolateT* isolate);
Object ToBoolean(Isolate* isolate);
// ES6 section 7.2.11 Abstract Relational Comparison
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment