Commit afff62b4 authored by Kanghua Yu's avatar Kanghua Yu Committed by Commit Bot

[csa] Apply constant folding to remaining helper functions.

This also refactors CodeAssembler::Branch(condition,true_label,false_label)
to support constant folding, and adds Branch(condition,true_label,false_body)
variants for special cases.

Change-Id: Ifc04442657295124a95c60f76efde5c46de6f1b5
Reviewed-on: https://chromium-review.googlesource.com/1186136
Commit-Queue: Kanghua Yu <kanghua.yu@intel.com>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55372}
parent 27040aac
......@@ -4108,11 +4108,11 @@ TNode<FixedArrayBase> CodeStubAssembler::ExtractFixedArray(
BIND(&cow);
{
if (extract_flags & ExtractFixedArrayFlag::kDontCopyCOW) {
GotoIf(WordNotEqual(IntPtrOrSmiConstant(0, parameter_mode), first),
&new_space_check);
var_result.Bind(fixed_array);
Goto(&done);
Branch(WordNotEqual(IntPtrOrSmiConstant(0, parameter_mode), first),
&new_space_check, [&] {
var_result.Bind(fixed_array);
Goto(&done);
});
} else {
var_fixed_array_map.Bind(LoadRoot(Heap::kFixedArrayMapRootIndex));
Goto(&new_space_check);
......@@ -11352,69 +11352,66 @@ void CodeStubAssembler::BranchIfSameValue(Node* lhs, Node* rhs, Label* if_true,
{
// Since {lhs} is a Smi, the comparison can only yield true
// iff the {rhs} is a HeapNumber with the same float64 value.
GotoIf(TaggedIsSmi(rhs), if_false);
GotoIfNot(IsHeapNumber(rhs), if_false);
var_lhs_value.Bind(SmiToFloat64(lhs));
var_rhs_value.Bind(LoadHeapNumberValue(rhs));
Goto(&do_fcmp);
Branch(TaggedIsSmi(rhs), if_false, [&] {
GotoIfNot(IsHeapNumber(rhs), if_false);
var_lhs_value.Bind(SmiToFloat64(lhs));
var_rhs_value.Bind(LoadHeapNumberValue(rhs));
Goto(&do_fcmp);
});
}
BIND(&if_lhsisheapobject);
{
// Check if the {rhs} is a Smi.
Label if_rhsissmi(this), if_rhsisheapobject(this);
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisheapobject);
BIND(&if_rhsissmi);
{
// Since {rhs} is a Smi, the comparison can only yield true
// iff the {lhs} is a HeapNumber with the same float64 value.
GotoIfNot(IsHeapNumber(lhs), if_false);
var_lhs_value.Bind(LoadHeapNumberValue(lhs));
var_rhs_value.Bind(SmiToFloat64(rhs));
Goto(&do_fcmp);
}
BIND(&if_rhsisheapobject);
{
// Now this can only yield true if either both {lhs} and {rhs} are
// HeapNumbers with the same value, or both are Strings with the same
// character sequence, or both are BigInts with the same value.
Label if_lhsisheapnumber(this), if_lhsisstring(this),
if_lhsisbigint(this);
Node* const lhs_map = LoadMap(lhs);
GotoIf(IsHeapNumberMap(lhs_map), &if_lhsisheapnumber);
Node* const lhs_instance_type = LoadMapInstanceType(lhs_map);
GotoIf(IsStringInstanceType(lhs_instance_type), &if_lhsisstring);
Branch(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint,
if_false);
BIND(&if_lhsisheapnumber);
{
GotoIfNot(IsHeapNumber(rhs), if_false);
var_lhs_value.Bind(LoadHeapNumberValue(lhs));
var_rhs_value.Bind(LoadHeapNumberValue(rhs));
Goto(&do_fcmp);
}
BIND(&if_lhsisstring);
{
// Now we can only yield true if {rhs} is also a String
// with the same sequence of characters.
GotoIfNot(IsString(rhs), if_false);
Node* const result =
CallBuiltin(Builtins::kStringEqual, NoContextConstant(), lhs, rhs);
Branch(IsTrue(result), if_true, if_false);
}
BIND(&if_lhsisbigint);
{
GotoIfNot(IsBigInt(rhs), if_false);
Node* const result = CallRuntime(Runtime::kBigIntEqualToBigInt,
NoContextConstant(), lhs, rhs);
Branch(IsTrue(result), if_true, if_false);
}
}
Branch(TaggedIsSmi(rhs),
[&] {
// Since {rhs} is a Smi, the comparison can only yield true
// iff the {lhs} is a HeapNumber with the same float64 value.
GotoIfNot(IsHeapNumber(lhs), if_false);
var_lhs_value.Bind(LoadHeapNumberValue(lhs));
var_rhs_value.Bind(SmiToFloat64(rhs));
Goto(&do_fcmp);
},
[&] {
// Now this can only yield true if either both {lhs} and {rhs} are
// HeapNumbers with the same value, or both are Strings with the
// same character sequence, or both are BigInts with the same
// value.
Label if_lhsisheapnumber(this), if_lhsisstring(this),
if_lhsisbigint(this);
Node* const lhs_map = LoadMap(lhs);
GotoIf(IsHeapNumberMap(lhs_map), &if_lhsisheapnumber);
Node* const lhs_instance_type = LoadMapInstanceType(lhs_map);
GotoIf(IsStringInstanceType(lhs_instance_type), &if_lhsisstring);
Branch(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint,
if_false);
BIND(&if_lhsisheapnumber);
{
GotoIfNot(IsHeapNumber(rhs), if_false);
var_lhs_value.Bind(LoadHeapNumberValue(lhs));
var_rhs_value.Bind(LoadHeapNumberValue(rhs));
Goto(&do_fcmp);
}
BIND(&if_lhsisstring);
{
// Now we can only yield true if {rhs} is also a String
// with the same sequence of characters.
GotoIfNot(IsString(rhs), if_false);
Node* const result = CallBuiltin(Builtins::kStringEqual,
NoContextConstant(), lhs, rhs);
Branch(IsTrue(result), if_true, if_false);
}
BIND(&if_lhsisbigint);
{
GotoIfNot(IsBigInt(rhs), if_false);
Node* const result = CallRuntime(Runtime::kBigIntEqualToBigInt,
NoContextConstant(), lhs, rhs);
Branch(IsTrue(result), if_true, if_false);
}
});
}
BIND(&do_fcmp);
......
......@@ -1378,6 +1378,13 @@ void CodeAssembler::GotoIfNot(SloppyTNode<IntegralT> condition,
void CodeAssembler::Branch(SloppyTNode<IntegralT> condition, Label* true_label,
Label* false_label) {
int32_t constant;
if (ToInt32Constant(condition, constant)) {
if ((true_label->is_used() || true_label->is_bound()) &&
(false_label->is_used() || false_label->is_bound())) {
return Goto(constant ? true_label : false_label);
}
}
true_label->MergeVariables();
false_label->MergeVariables();
return raw_assembler()->Branch(condition, true_label->label_,
......@@ -1394,14 +1401,39 @@ void CodeAssembler::Branch(TNode<BoolT> condition,
Label vtrue(this), vfalse(this);
Branch(condition, &vtrue, &vfalse);
Bind(&vtrue);
{
true_body();
true_body();
Bind(&vfalse);
false_body();
}
void CodeAssembler::Branch(TNode<BoolT> condition, Label* true_label,
std::function<void()> false_body) {
int32_t constant;
if (ToInt32Constant(condition, constant)) {
return constant ? Goto(true_label) : false_body();
}
Label vfalse(this);
Branch(condition, true_label, &vfalse);
Bind(&vfalse);
{
false_body();
false_body();
}
void CodeAssembler::Branch(TNode<BoolT> condition,
std::function<void()> true_body,
Label* false_label) {
int32_t constant;
if (ToInt32Constant(condition, constant)) {
return constant ? true_body() : Goto(false_label);
}
Label vtrue(this);
Branch(condition, &vtrue, false_label);
Bind(&vtrue);
true_body();
}
void CodeAssembler::Switch(Node* index, Label* default_label,
......
......@@ -775,6 +775,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
void Branch(TNode<BoolT> condition, std::function<void()> true_body,
std::function<void()> false_body);
void Branch(TNode<BoolT> condition, Label* true_label,
std::function<void()> false_body);
void Branch(TNode<BoolT> condition, std::function<void()> true_body,
Label* false_label);
void Switch(Node* index, Label* default_label, const int32_t* case_values,
Label** case_labels, size_t case_count);
......
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