[vm, compiler] Predicate boolean loads.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/29908
Change-Id: I5a5c57a8a79dbe4f2ee5303a4b9436bd36e8d7be
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/189921
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Ryan Macnak 2021-03-15 20:53:04 +00:00 committed by commit-bot@chromium.org
parent cf3dcc4256
commit c9e10c931c
2 changed files with 43 additions and 21 deletions

View file

@ -6912,19 +6912,27 @@ void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler::Label is_true, is_false;
BranchLabels labels = {&is_true, &is_false, &is_false};
Condition true_condition = EmitComparisonCode(compiler, labels);
const Register result = this->locs()->out(0).reg();
// TODO(dartbug.com/29908): Use csel here for better branch prediction?
if (true_condition != kInvalidCondition) {
EmitBranchOnCondition(compiler, true_condition, labels);
const Register result = this->locs()->out(0).reg();
if (is_true.IsLinked() || is_false.IsLinked()) {
if (true_condition != kInvalidCondition) {
EmitBranchOnCondition(compiler, true_condition, labels);
}
compiler::Label done;
__ Bind(&is_false);
__ LoadObject(result, Bool::False());
__ b(&done);
__ Bind(&is_true);
__ LoadObject(result, Bool::True());
__ Bind(&done);
} else {
// If EmitComparisonCode did not use the labels and just returned
// a condition we can avoid the branch and use conditional loads.
ASSERT(true_condition != kInvalidCondition);
__ LoadObject(TMP, Bool::True());
__ LoadObject(TMP2, Bool::False());
__ csel(result, TMP, TMP2, true_condition);
}
compiler::Label done;
__ Bind(&is_false);
__ LoadObject(result, Bool::False());
__ b(&done);
__ Bind(&is_true);
__ LoadObject(result, Bool::True());
__ Bind(&done);
}
void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,

View file

@ -931,17 +931,31 @@ void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler::Label is_true, is_false;
BranchLabels labels = {&is_true, &is_false, &is_false};
Condition true_condition = EmitComparisonCode(compiler, labels);
if (true_condition != kInvalidCondition) {
EmitBranchOnCondition(compiler, true_condition, labels);
}
Register result = locs()->out(0).reg();
compiler::Label done;
__ Bind(&is_false);
__ LoadObject(result, Bool::False());
__ jmp(&done);
__ Bind(&is_true);
__ LoadObject(result, Bool::True());
__ Bind(&done);
if (is_true.IsLinked() || is_false.IsLinked()) {
if (true_condition != kInvalidCondition) {
EmitBranchOnCondition(compiler, true_condition, labels);
}
compiler::Label done;
__ Bind(&is_false);
__ LoadObject(result, Bool::False());
__ jmp(&done, compiler::Assembler::kNearJump);
__ Bind(&is_true);
__ LoadObject(result, Bool::True());
__ Bind(&done);
} else {
// If EmitComparisonCode did not use the labels and just returned
// a condition we can avoid the branch and use conditional loads.
ASSERT(true_condition != kInvalidCondition);
__ setcc(InvertCondition(true_condition), ByteRegisterOf(result));
__ movzxb(result, result);
__ movq(result,
compiler::Address(THR, result, TIMES_8,
compiler::target::Thread::bool_true_offset()));
ASSERT(compiler::target::Thread::bool_true_offset() + 8 ==
compiler::target::Thread::bool_false_offset());
}
}
void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,