Commit 51ed12f9 authored by bmeurer's avatar bmeurer Committed by Commit bot

[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.

CQ_INCLUDE_TRYBOTS=master.tryserver.v8:v8_win64_dbg
R=jarin@chromium.org
BUG=v8:5267

Review-Url: https://codereview.chromium.org/2666283002
Cr-Original-Commit-Position: refs/heads/master@{#42843}
Committed: https://chromium.googlesource.com/v8/v8/+/158ac9287193f315342ad31c38fe451620d176eb
Review-Url: https://codereview.chromium.org/2666283002
Cr-Commit-Position: refs/heads/master@{#42934}
parent 4675c975
...@@ -2968,6 +2968,10 @@ Node* CodeStubAssembler::IsWeakCell(Node* object) { ...@@ -2968,6 +2968,10 @@ Node* CodeStubAssembler::IsWeakCell(Node* object) {
return HasInstanceType(object, WEAK_CELL_TYPE); return HasInstanceType(object, WEAK_CELL_TYPE);
} }
Node* CodeStubAssembler::IsBoolean(Node* object) {
return IsBooleanMap(LoadMap(object));
}
Node* CodeStubAssembler::IsName(Node* object) { Node* CodeStubAssembler::IsName(Node* object) {
return Int32LessThanOrEqual(LoadInstanceType(object), return Int32LessThanOrEqual(LoadInstanceType(object),
Int32Constant(LAST_NAME_TYPE)); Int32Constant(LAST_NAME_TYPE));
......
...@@ -685,6 +685,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -685,6 +685,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* IsJSReceiver(Node* object); Node* IsJSReceiver(Node* object);
Node* IsMap(Node* object); Node* IsMap(Node* object);
Node* IsCallableMap(Node* map); Node* IsCallableMap(Node* map);
Node* IsBoolean(Node* object);
Node* IsName(Node* object); Node* IsName(Node* object);
Node* IsSymbol(Node* object); Node* IsSymbol(Node* object);
Node* IsPrivateSymbol(Node* object); Node* IsPrivateSymbol(Node* object);
......
...@@ -2071,11 +2071,25 @@ void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) { ...@@ -2071,11 +2071,25 @@ void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
} }
void BytecodeGraphBuilder::BuildJumpIfFalse() { 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() { 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() { void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
......
...@@ -2407,46 +2407,58 @@ void Interpreter::DoJumpConstant(InterpreterAssembler* assembler) { ...@@ -2407,46 +2407,58 @@ void Interpreter::DoJumpConstant(InterpreterAssembler* assembler) {
// JumpIfTrue <imm> // JumpIfTrue <imm>
// //
// Jump by number of bytes represented by an immediate operand if the // 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) { void Interpreter::DoJumpIfTrue(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* relative_jump = __ BytecodeOperandUImmWord(0); Node* relative_jump = __ BytecodeOperandUImmWord(0);
Node* true_value = __ BooleanConstant(true); Node* true_value = __ BooleanConstant(true);
CSA_ASSERT(assembler, assembler->TaggedIsNotSmi(accumulator));
CSA_ASSERT(assembler, assembler->IsBoolean(accumulator));
__ JumpIfWordEqual(accumulator, true_value, relative_jump); __ JumpIfWordEqual(accumulator, true_value, relative_jump);
} }
// JumpIfTrueConstant <idx> // JumpIfTrueConstant <idx>
// //
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool // 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) { void Interpreter::DoJumpIfTrueConstant(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index); Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
Node* true_value = __ BooleanConstant(true); Node* true_value = __ BooleanConstant(true);
CSA_ASSERT(assembler, assembler->TaggedIsNotSmi(accumulator));
CSA_ASSERT(assembler, assembler->IsBoolean(accumulator));
__ JumpIfWordEqual(accumulator, true_value, relative_jump); __ JumpIfWordEqual(accumulator, true_value, relative_jump);
} }
// JumpIfFalse <imm> // JumpIfFalse <imm>
// //
// Jump by number of bytes represented by an immediate operand if the // 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) { void Interpreter::DoJumpIfFalse(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* relative_jump = __ BytecodeOperandUImmWord(0); Node* relative_jump = __ BytecodeOperandUImmWord(0);
Node* false_value = __ BooleanConstant(false); Node* false_value = __ BooleanConstant(false);
CSA_ASSERT(assembler, assembler->TaggedIsNotSmi(accumulator));
CSA_ASSERT(assembler, assembler->IsBoolean(accumulator));
__ JumpIfWordEqual(accumulator, false_value, relative_jump); __ JumpIfWordEqual(accumulator, false_value, relative_jump);
} }
// JumpIfFalseConstant <idx> // JumpIfFalseConstant <idx>
// //
// Jump by number of bytes in the Smi in the |idx| entry in the constant pool // 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) { void Interpreter::DoJumpIfFalseConstant(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index); Node* relative_jump = __ LoadAndUntagConstantPoolEntry(index);
Node* false_value = __ BooleanConstant(false); Node* false_value = __ BooleanConstant(false);
CSA_ASSERT(assembler, assembler->TaggedIsNotSmi(accumulator));
CSA_ASSERT(assembler, assembler->IsBoolean(accumulator));
__ JumpIfWordEqual(accumulator, false_value, relative_jump); __ JumpIfWordEqual(accumulator, false_value, relative_jump);
} }
......
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