[turbofan] Constant propagation for JumpIfFalse/JumpIfTrue.
The JumpIfFalse and JumpIfTrue bytecodes test the accumulator, and branch based on whether the accumulator is true or false (no other value allowed, and in fact TurboFan would blow up if you would pass anything else, since Branch operator can only deal with Boolean). So for either branch we know exactly the value of the accumulator, and we can update the environment to this constant value instead. This helps to avoid the useless bit materialization that currently happens when || or && is being used in a value context. R=jarin@chromium.org BUG=v8:5267 Review-Url: https://codereview.chromium.org/2666283002 Cr-Commit-Position: refs/heads/master@{#42843}
This commit is contained in:
parent
c67dc7e243
commit
158ac92871
@ -2969,6 +2969,10 @@ Node* CodeStubAssembler::IsWeakCell(Node* object) {
|
||||
return HasInstanceType(object, WEAK_CELL_TYPE);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsBoolean(Node* object) {
|
||||
return IsBooleanMap(LoadMap(object));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsName(Node* object) {
|
||||
return Int32LessThanOrEqual(LoadInstanceType(object),
|
||||
Int32Constant(LAST_NAME_TYPE));
|
||||
|
@ -685,6 +685,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
Node* IsJSReceiver(Node* object);
|
||||
Node* IsMap(Node* object);
|
||||
Node* IsCallableMap(Node* map);
|
||||
Node* IsBoolean(Node* object);
|
||||
Node* IsName(Node* object);
|
||||
Node* IsSymbol(Node* object);
|
||||
Node* IsPrivateSymbol(Node* object);
|
||||
|
@ -2072,11 +2072,25 @@ void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::BuildJumpIfFalse() {
|
||||
BuildJumpIfNot(environment()->LookupAccumulator());
|
||||
NewBranch(environment()->LookupAccumulator());
|
||||
Environment* if_true_environment = environment()->Copy();
|
||||
environment()->BindAccumulator(jsgraph()->FalseConstant());
|
||||
NewIfFalse();
|
||||
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
|
||||
if_true_environment->BindAccumulator(jsgraph()->TrueConstant());
|
||||
set_environment(if_true_environment);
|
||||
NewIfTrue();
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::BuildJumpIfTrue() {
|
||||
BuildJumpIf(environment()->LookupAccumulator());
|
||||
NewBranch(environment()->LookupAccumulator());
|
||||
Environment* if_false_environment = environment()->Copy();
|
||||
environment()->BindAccumulator(jsgraph()->TrueConstant());
|
||||
NewIfTrue();
|
||||
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
|
||||
if_false_environment->BindAccumulator(jsgraph()->FalseConstant());
|
||||
set_environment(if_false_environment);
|
||||
NewIfFalse();
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
|
||||
|
@ -894,6 +894,7 @@ class RepresentationSelector {
|
||||
// Helper for handling selects.
|
||||
void VisitSelect(Node* node, Truncation truncation,
|
||||
SimplifiedLowering* lowering) {
|
||||
DCHECK(TypeOf(node->InputAt(0))->Is(Type::Boolean()));
|
||||
ProcessInput(node, 0, UseInfo::Bool());
|
||||
|
||||
MachineRepresentation output =
|
||||
@ -1424,10 +1425,12 @@ class RepresentationSelector {
|
||||
return;
|
||||
}
|
||||
|
||||
case IrOpcode::kBranch:
|
||||
case IrOpcode::kBranch: {
|
||||
DCHECK(TypeOf(node->InputAt(0))->Is(Type::Boolean()));
|
||||
ProcessInput(node, 0, UseInfo::Bool());
|
||||
EnqueueInput(node, NodeProperties::FirstControlIndex(node));
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kSwitch:
|
||||
ProcessInput(node, 0, UseInfo::TruncatingWord32());
|
||||
EnqueueInput(node, NodeProperties::FirstControlIndex(node));
|
||||
|
@ -207,6 +207,8 @@ void Verifier::Visitor::Check(Node* node) {
|
||||
}
|
||||
CHECK_EQ(1, count_true);
|
||||
CHECK_EQ(1, count_false);
|
||||
// Condition must be a Boolean.
|
||||
CheckValueInputIs(node, 0, Type::Boolean());
|
||||
// Type is empty.
|
||||
CheckNotTyped(node);
|
||||
break;
|
||||
|
@ -2407,46 +2407,58 @@ void Interpreter::DoJumpConstant(InterpreterAssembler* assembler) {
|
||||
// JumpIfTrue <imm>
|
||||
//
|
||||
// Jump by number of bytes represented by an immediate operand if the
|
||||
// accumulator contains true.
|
||||
// accumulator contains true. This only works for boolean inputs, and
|
||||
// will misbehave if passed arbitrary input values.
|
||||
void Interpreter::DoJumpIfTrue(InterpreterAssembler* assembler) {
|
||||
Node* accumulator = __ GetAccumulator();
|
||||
Node* relative_jump = __ BytecodeOperandUImmWord(0);
|
||||
Node* true_value = __ BooleanConstant(true);
|
||||
CSA_ASSERT(assembler, assembler->TaggedIsNotSmi(accumulator));
|
||||
CSA_ASSERT(assembler, assembler->IsBoolean(accumulator));
|
||||
__ JumpIfWordEqual(accumulator, true_value, relative_jump);
|
||||
}
|
||||
|
||||
// JumpIfTrueConstant <idx>
|
||||
//
|
||||
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
|
||||
// if the accumulator contains true.
|
||||
// if the accumulator contains true. This only works for boolean inputs, and
|
||||
// will misbehave if passed arbitrary input values.
|
||||
void Interpreter::DoJumpIfTrueConstant(InterpreterAssembler* assembler) {
|
||||
Node* accumulator = __ GetAccumulator();
|
||||
Node* index = __ BytecodeOperandIdx(0);
|
||||
Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
|
||||
Node* true_value = __ BooleanConstant(true);
|
||||
CSA_ASSERT(assembler, assembler->TaggedIsNotSmi(accumulator));
|
||||
CSA_ASSERT(assembler, assembler->IsBoolean(accumulator));
|
||||
__ JumpIfWordEqual(accumulator, true_value, relative_jump);
|
||||
}
|
||||
|
||||
// JumpIfFalse <imm>
|
||||
//
|
||||
// Jump by number of bytes represented by an immediate operand if the
|
||||
// accumulator contains false.
|
||||
// accumulator contains false. This only works for boolean inputs, and
|
||||
// will misbehave if passed arbitrary input values.
|
||||
void Interpreter::DoJumpIfFalse(InterpreterAssembler* assembler) {
|
||||
Node* accumulator = __ GetAccumulator();
|
||||
Node* relative_jump = __ BytecodeOperandUImmWord(0);
|
||||
Node* false_value = __ BooleanConstant(false);
|
||||
CSA_ASSERT(assembler, assembler->TaggedIsNotSmi(accumulator));
|
||||
CSA_ASSERT(assembler, assembler->IsBoolean(accumulator));
|
||||
__ JumpIfWordEqual(accumulator, false_value, relative_jump);
|
||||
}
|
||||
|
||||
// JumpIfFalseConstant <idx>
|
||||
//
|
||||
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool
|
||||
// if the accumulator contains false.
|
||||
// if the accumulator contains false. This only works for boolean inputs, and
|
||||
// will misbehave if passed arbitrary input values.
|
||||
void Interpreter::DoJumpIfFalseConstant(InterpreterAssembler* assembler) {
|
||||
Node* accumulator = __ GetAccumulator();
|
||||
Node* index = __ BytecodeOperandIdx(0);
|
||||
Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
|
||||
Node* false_value = __ BooleanConstant(false);
|
||||
CSA_ASSERT(assembler, assembler->TaggedIsNotSmi(accumulator));
|
||||
CSA_ASSERT(assembler, assembler->IsBoolean(accumulator));
|
||||
__ JumpIfWordEqual(accumulator, false_value, relative_jump);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user