[vm/compiler] Rename Comparison to Condition, introduce proper Comparison

Previously, ComparisonInstr base class represented arbitrary conditions
used in Branch, IfThenElse and CheckCondition instructions and included
subclasses TestInt, TestCids, TestRange and unary DoubleTestOp which are
not comparisons. So this refactoring renames ComparisonInstr to
ConditionInstr.

In addition, a new Comparison instruction is added as a base class for
StrictCompare, EqualityCompare and RelationalOp.

TEST=ci (pure refactoring)

Change-Id: Ic8756ee5913ff2bc974c95cea8004370c9f5527f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/393420
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov
2024-11-05 13:50:08 +00:00
committed by Commit Queue
parent af2bea8162
commit 52cb60b34e
26 changed files with 532 additions and 517 deletions
@@ -1127,7 +1127,7 @@ bool AotCallSpecializer::TryReplaceInstanceOfWithRangeCheck(
new (Z) LoadClassIdInstr(new (Z) Value(left), kUnboxedUword);
InsertBefore(call, load_cid, nullptr, FlowGraph::kValue);
ComparisonInstr* check_range;
ConditionInstr* check_range;
if (lower_limit == upper_limit) {
ConstantInstr* cid_constant = flow_graph()->GetConstant(
Smi::Handle(Z, Smi::New(lower_limit)), kUnboxedUword);
+2 -2
View File
@@ -132,11 +132,11 @@ class BlockBuilder : public ValueObject {
return AddUnboxInstr(rep, new Value(boxed), value_mode);
}
BranchInstr* AddBranch(ComparisonInstr* comp,
BranchInstr* AddBranch(ConditionInstr* cond,
TargetEntryInstr* true_successor,
TargetEntryInstr* false_successor) {
auto branch =
new BranchInstr(comp, CompilerState::Current().GetNextDeoptId());
new BranchInstr(cond, CompilerState::Current().GetNextDeoptId());
// Some graph transformations use environments from branches.
branch->SetEnvironment(dummy_env_);
current_->AppendInstruction(branch);
+28 -26
View File
@@ -30,10 +30,10 @@ static bool PhiHasSingleUse(PhiInstr* phi, Value* use) {
}
bool BranchSimplifier::Match(JoinEntryInstr* block) {
// Match the pattern of a branch on a comparison whose left operand is a
// Match the pattern of a branch on a condition whose left operand is a
// phi from the same block, and whose right operand is a constant.
//
// Branch(Comparison(kind, Phi, Constant))
// Branch(Condition(kind, Phi, Constant))
//
// These are the branches produced by inlining in a test context. Also,
// the phi has no other uses so they can simply be eliminated. The block
@@ -41,16 +41,16 @@ bool BranchSimplifier::Match(JoinEntryInstr* block) {
// branch so the block can simply be eliminated.
BranchInstr* branch = block->last_instruction()->AsBranch();
ASSERT(branch != nullptr);
ComparisonInstr* comparison = branch->comparison();
if (comparison->InputCount() != 2) {
ConditionInstr* condition = branch->condition();
if (condition->InputCount() != 2) {
return false;
}
if (comparison->CanDeoptimize() || comparison->MayThrow()) {
if (condition->CanDeoptimize() || condition->MayThrow()) {
return false;
}
Value* left = comparison->left();
Value* left = condition->InputAt(0);
PhiInstr* phi = left->definition()->AsPhi();
Value* right = comparison->right();
Value* right = condition->InputAt(1);
ConstantInstr* constant =
(right == nullptr) ? nullptr : right->definition()->AsConstant();
return (phi != nullptr) && (constant != nullptr) &&
@@ -87,11 +87,11 @@ BranchInstr* BranchSimplifier::CloneBranch(Zone* zone,
BranchInstr* branch,
Value* new_left,
Value* new_right) {
ComparisonInstr* comparison = branch->comparison();
ComparisonInstr* new_comparison =
comparison->CopyWithNewOperands(new_left, new_right);
ConditionInstr* condition = branch->condition();
ConditionInstr* new_condition =
condition->CopyWithNewOperands(new_left, new_right);
BranchInstr* new_branch =
new (zone) BranchInstr(new_comparison, DeoptId::kNone);
new (zone) BranchInstr(new_condition, DeoptId::kNone);
return new_branch;
}
@@ -140,9 +140,10 @@ void BranchSimplifier::Simplify(FlowGraph* flow_graph) {
JoinEntryInstr* join_true = ToJoinEntry(zone, branch->true_successor());
JoinEntryInstr* join_false = ToJoinEntry(zone, branch->false_successor());
ComparisonInstr* comparison = branch->comparison();
PhiInstr* phi = comparison->left()->definition()->AsPhi();
ConstantInstr* constant = comparison->right()->definition()->AsConstant();
ConditionInstr* condition = branch->condition();
PhiInstr* phi = condition->InputAt(0)->definition()->AsPhi();
ConstantInstr* constant =
condition->InputAt(1)->definition()->AsConstant();
ASSERT(constant != nullptr);
// Copy the constant and branch and push it to all the predecessors.
for (intptr_t i = 0, count = block->PredecessorCount(); i < count; ++i) {
@@ -161,10 +162,10 @@ void BranchSimplifier::Simplify(FlowGraph* flow_graph) {
} else {
// Take the environment from the branch if it has one.
new_branch->InheritDeoptTarget(zone, branch);
// InheritDeoptTarget gave the new branch's comparison the same
// InheritDeoptTarget gave the new branch's condition the same
// deopt id that it gave the new branch. The id should be the
// deopt id of the original comparison.
new_branch->comparison()->SetDeoptId(*comparison);
// deopt id of the original condition.
new_branch->condition()->SetDeoptId(*condition);
// The phi can be used in the branch's environment. Rename such
// uses.
Definition* replacement = phi->InputAt(i)->definition();
@@ -249,11 +250,11 @@ void IfConverter::Simplify(FlowGraph* flow_graph) {
JoinEntryInstr* join = block->AsJoinEntry();
// Detect diamond control flow pattern which materializes a value depending
// on the result of the comparison:
// on the result of the condition:
//
// B_pred:
// ...
// Branch if COMP goto (B_pred1, B_pred2)
// Branch if COND goto (B_pred1, B_pred2)
// B_pred1: -- trivial block that contains at most one definition
// v1 = Constant(...)
// goto B_block
@@ -266,7 +267,7 @@ void IfConverter::Simplify(FlowGraph* flow_graph) {
// and replace it with
//
// Ba:
// v3 = IfThenElse(COMP ? v1 : v2)
// v3 = IfThenElse(COND ? v1 : v2)
//
if ((join != nullptr) && (join->phis() != nullptr) &&
(join->phis()->length() == 1) && (block->PredecessorCount() == 2)) {
@@ -291,19 +292,20 @@ void IfConverter::Simplify(FlowGraph* flow_graph) {
continue;
}
ComparisonInstr* comparison = branch->comparison();
ConditionInstr* condition = branch->condition();
// Check if the platform supports efficient branchless IfThenElseInstr
// for the given combination of comparison and values flowing from
// for the given combination of condition and values flowing from
// false and true paths.
if (IfThenElseInstr::Supports(comparison, v1, v2)) {
if (IfThenElseInstr::Supports(condition, v1, v2)) {
Value* if_true = (pred1 == branch->true_successor()) ? v1 : v2;
Value* if_false = (pred2 == branch->true_successor()) ? v1 : v2;
ComparisonInstr* new_comparison = comparison->CopyWithNewOperands(
comparison->left()->Copy(zone), comparison->right()->Copy(zone));
ConditionInstr* new_condition =
condition->CopyWithNewOperands(condition->InputAt(0)->Copy(zone),
condition->InputAt(1)->Copy(zone));
IfThenElseInstr* if_then_else =
new (zone) IfThenElseInstr(new_comparison, if_true->Copy(zone),
new (zone) IfThenElseInstr(new_condition, if_true->Copy(zone),
if_false->Copy(zone), DeoptId::kNone);
flow_graph->InsertBefore(branch, if_then_else, nullptr,
FlowGraph::kValue);
@@ -239,7 +239,7 @@ void ConstantPropagator::VisitIndirectGoto(IndirectGotoInstr* instr) {
}
void ConstantPropagator::VisitBranch(BranchInstr* instr) {
instr->comparison()->Accept(this);
instr->condition()->Accept(this);
// The successors may be reachable, but only if this instruction is. (We
// might be analyzing it because the constant value of one of its inputs
@@ -250,7 +250,7 @@ void ConstantPropagator::VisitBranch(BranchInstr* instr) {
(instr->constant_target() == instr->false_successor()));
SetReachable(instr->constant_target());
} else {
const Object& value = instr->comparison()->constant_value();
const Object& value = instr->condition()->constant_value();
if (IsNonConstant(value)) {
SetReachable(instr->true_successor());
SetReachable(instr->false_successor());
@@ -557,8 +557,8 @@ void ConstantPropagator::VisitStoreLocal(StoreLocalInstr* instr) {
}
void ConstantPropagator::VisitIfThenElse(IfThenElseInstr* instr) {
instr->comparison()->Accept(this);
const Object& value = instr->comparison()->constant_value();
instr->condition()->Accept(this);
const Object& value = instr->condition()->constant_value();
ASSERT(!value.IsNull());
if (IsUnknown(value)) {
return;
@@ -656,8 +656,6 @@ static bool CompareIntegers(Token::Kind kind,
}
}
// Comparison instruction that is equivalent to the (left & right) == 0
// comparison pattern.
void ConstantPropagator::VisitTestInt(TestIntInstr* instr) {
const Object& left = instr->left()->definition()->constant_value();
const Object& right = instr->right()->definition()->constant_value();
@@ -1614,10 +1612,11 @@ static RedefinitionInstr* InsertRedefinition(FlowGraph* graph,
void ConstantPropagator::InsertRedefinitionsAfterEqualityComparisons() {
for (auto block : graph_->reverse_postorder()) {
if (auto branch = block->last_instruction()->AsBranch()) {
auto comparison = branch->comparison();
if (comparison->IsStrictCompare() ||
(comparison->IsEqualityCompare() &&
comparison->operation_cid() != kDoubleCid)) {
auto comparison = branch->condition()->AsComparison();
if (comparison != nullptr &&
(comparison->IsStrictCompare() ||
(comparison->IsEqualityCompare() &&
comparison->operation_cid() != kDoubleCid))) {
Value* value;
ConstantInstr* constant_defn;
if (comparison->IsComparisonWithConstant(&value, &constant_defn) &&
+4 -4
View File
@@ -2818,9 +2818,9 @@ static GotoInstr* NewGoto(FlowGraph* graph,
}
static BranchInstr* NewBranch(FlowGraph* graph,
ComparisonInstr* cmp,
ConditionInstr* cond,
Instruction* inherit) {
BranchInstr* bra = new (graph->zone()) BranchInstr(cmp, DeoptId::kNone);
BranchInstr* bra = new (graph->zone()) BranchInstr(cond, DeoptId::kNone);
bra->InheritDeoptTarget(graph->zone(), inherit);
return bra;
}
@@ -2841,7 +2841,7 @@ static BranchInstr* NewBranch(FlowGraph* graph,
//
JoinEntryInstr* FlowGraph::NewDiamond(Instruction* instruction,
Instruction* inherit,
ComparisonInstr* compare,
ConditionInstr* condition,
TargetEntryInstr** b_true,
TargetEntryInstr** b_false) {
BlockEntryInstr* entry = instruction->GetBlock();
@@ -2851,7 +2851,7 @@ JoinEntryInstr* FlowGraph::NewDiamond(Instruction* instruction,
JoinEntryInstr* join = NewJoin(this, inherit);
GotoInstr* gotot = NewGoto(this, join, inherit);
GotoInstr* gotof = NewGoto(this, join, inherit);
BranchInstr* bra = NewBranch(this, compare, inherit);
BranchInstr* bra = NewBranch(this, condition, inherit);
instruction->AppendInstruction(bra);
entry->set_last_instruction(bra);
+4 -4
View File
@@ -527,9 +527,9 @@ class FlowGraph : public ZoneAllocated {
// Logical-AND (for use in short-circuit diamond).
struct LogicalAnd {
LogicalAnd(ComparisonInstr* x, ComparisonInstr* y) : oper1(x), oper2(y) {}
ComparisonInstr* oper1;
ComparisonInstr* oper2;
LogicalAnd(ConditionInstr* x, ConditionInstr* y) : oper1(x), oper2(y) {}
ConditionInstr* oper1;
ConditionInstr* oper2;
};
// Constructs a diamond control flow at the instruction, inheriting
@@ -538,7 +538,7 @@ class FlowGraph : public ZoneAllocated {
// relation, but not the succ/pred ordering on block.
JoinEntryInstr* NewDiamond(Instruction* instruction,
Instruction* inherit,
ComparisonInstr* compare,
ConditionInstr* condition,
TargetEntryInstr** block_true,
TargetEntryInstr** block_false);
@@ -229,7 +229,7 @@ void FlowGraphCompiler::InitCompiler() {
for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
Instruction* current = it.Current();
if (auto* branch = current->AsBranch()) {
current = branch->comparison();
current = branch->condition();
}
if (auto* instance_call = current->AsInstanceCall()) {
const ICData* ic_data = instance_call->ic_data();
+112 -115
View File
@@ -1090,7 +1090,7 @@ Instruction* AssertSubtypeInstr::Canonicalize(FlowGraph* flow_graph) {
bool StrictCompareInstr::AttributesEqual(const Instruction& other) const {
auto const other_op = other.AsStrictCompare();
ASSERT(other_op != nullptr);
return ComparisonInstr::AttributesEqual(other) &&
return ConditionInstr::AttributesEqual(other) &&
(needs_number_check() == other_op->needs_number_check());
}
@@ -1665,19 +1665,19 @@ void Definition::ReplaceWith(Definition* other,
ReplaceWithResult(other, other, iterator);
}
void BranchInstr::SetComparison(ComparisonInstr* new_comparison) {
for (intptr_t i = new_comparison->InputCount() - 1; i >= 0; --i) {
Value* input = new_comparison->InputAt(i);
void BranchInstr::SetCondition(ConditionInstr* new_condition) {
for (intptr_t i = new_condition->InputCount() - 1; i >= 0; --i) {
Value* input = new_condition->InputAt(i);
input->definition()->AddInputUse(input);
input->set_instruction(this);
}
// There should be no need to copy or unuse an environment.
ASSERT(comparison()->env() == nullptr);
ASSERT(new_comparison->env() == nullptr);
// Remove the current comparison's input uses.
comparison()->UnuseAllInputs();
ASSERT(!new_comparison->HasUses());
comparison_ = new_comparison;
ASSERT(condition()->env() == nullptr);
ASSERT(new_condition->env() == nullptr);
// Remove the current condition's input uses.
condition()->UnuseAllInputs();
ASSERT(!new_condition->HasUses());
condition_ = new_condition;
}
// ==== Postorder graph traversal.
@@ -3444,11 +3444,11 @@ Definition* IntConverterInstr::Canonicalize(FlowGraph* flow_graph) {
return this;
}
// Tests for a FP comparison that cannot be negated
// Tests for a FP condition that cannot be negated
// (to preserve NaN semantics).
static bool IsFpCompare(ComparisonInstr* comp) {
if (comp->IsRelationalOp()) {
return comp->operation_cid() == kDoubleCid;
static bool IsFpCompare(ConditionInstr* cond) {
if (cond->IsRelationalOp()) {
return cond->operation_cid() == kDoubleCid;
}
return false;
}
@@ -3456,11 +3456,11 @@ static bool IsFpCompare(ComparisonInstr* comp) {
Definition* BooleanNegateInstr::Canonicalize(FlowGraph* flow_graph) {
Definition* defn = value()->definition();
// Convert e.g. !(x > y) into (x <= y) for non-FP x, y.
if (defn->IsComparison() && defn->HasOnlyUse(value()) &&
if (defn->IsCondition() && defn->HasOnlyUse(value()) &&
defn->Type()->ToCid() == kBoolCid) {
ComparisonInstr* comp = defn->AsComparison();
if (!IsFpCompare(comp)) {
comp->NegateComparison();
ConditionInstr* cond = defn->AsCondition();
if (!IsFpCompare(cond)) {
cond->NegateCondition();
return defn;
}
}
@@ -3528,8 +3528,8 @@ static Definition* CanonicalizeStrictCompare(StrictCompareInstr* compare,
// We now have `e !== true` or `e === false`: these cases require
// negation.
if (auto comp = other_defn->AsComparison()) {
if (other_defn->HasOnlyUse(other) && !IsFpCompare(comp)) {
if (auto cond = other_defn->AsCondition()) {
if (other_defn->HasOnlyUse(other) && !IsFpCompare(cond)) {
*negated = true;
return other_defn;
}
@@ -3545,8 +3545,8 @@ static bool IsSingleUseUnboxOrConstant(Value* use) {
// Canonicalize [instr]. Either return [instr] or a new
// comparison instruction which is not inserted into the flow graph.
static ComparisonInstr* CanonicalizeEqualityCompare(EqualityCompareInstr* instr,
FlowGraph* flow_graph) {
static ConditionInstr* CanonicalizeEqualityCompare(EqualityCompareInstr* instr,
FlowGraph* flow_graph) {
if (instr->is_null_aware()) {
ASSERT(instr->operation_cid() == kMintCid);
// Select more efficient instructions based on operand types.
@@ -3627,85 +3627,85 @@ static bool RecognizeTestPattern(Value* left, Value* right, bool* negate) {
Instruction* BranchInstr::Canonicalize(FlowGraph* flow_graph) {
Zone* zone = flow_graph->zone();
if (comparison()->IsStrictCompare()) {
if (auto* strict_compare = condition()->AsStrictCompare()) {
bool negated = false;
Definition* replacement = CanonicalizeStrictCompare(
comparison()->AsStrictCompare(), &negated, /*is_branch=*/true);
if (replacement == comparison()) {
Definition* replacement =
CanonicalizeStrictCompare(strict_compare, &negated, /*is_branch=*/true);
if (replacement == condition()) {
return this;
}
ComparisonInstr* comp = replacement->AsComparison();
if ((comp == nullptr) || comp->CanDeoptimize()) {
ConditionInstr* cond = replacement->AsCondition();
if ((cond == nullptr) || cond->CanDeoptimize()) {
return this;
}
// Replace the comparison if the replacement is used at this branch,
// Replace the condition if the replacement is used at this branch,
// and has exactly one use.
Value* use = comp->input_use_list();
if ((use->instruction() == this) && comp->HasOnlyUse(use)) {
Value* use = cond->input_use_list();
if ((use->instruction() == this) && cond->HasOnlyUse(use)) {
if (negated) {
comp->NegateComparison();
cond->NegateCondition();
}
RemoveEnvironment();
flow_graph->CopyDeoptTarget(this, comp);
// Unlink environment from the comparison since it is copied to the
flow_graph->CopyDeoptTarget(this, cond);
// Unlink environment from the condition since it is copied to the
// branch instruction.
comp->RemoveEnvironment();
cond->RemoveEnvironment();
comp->RemoveFromGraph();
SetComparison(comp);
cond->RemoveFromGraph();
SetCondition(cond);
if (FLAG_trace_optimization && flow_graph->should_print()) {
THR_Print("Merging comparison v%" Pd "\n", comp->ssa_temp_index());
THR_Print("Merging condition v%" Pd "\n", cond->ssa_temp_index());
}
// Clear the comparison's temp index and ssa temp index since the
// value of the comparison is not used outside the branch anymore.
ASSERT(comp->input_use_list() == nullptr);
comp->ClearSSATempIndex();
comp->ClearTempIndex();
// Clear the condition's temp index and ssa temp index since the
// value of the condition is not used outside the branch anymore.
ASSERT(cond->input_use_list() == nullptr);
cond->ClearSSATempIndex();
cond->ClearTempIndex();
}
return this;
}
if (comparison()->IsEqualityCompare() &&
(comparison()->operation_cid() == kSmiCid ||
comparison()->operation_cid() == kMintCid)) {
const auto representation =
comparison()->operation_cid() == kSmiCid ? kTagged : kUnboxedInt64;
if (TestIntInstr::IsSupported(representation)) {
BinaryIntegerOpInstr* bit_and = nullptr;
bool negate = false;
if (RecognizeTestPattern(comparison()->left(), comparison()->right(),
&negate)) {
bit_and = comparison()->left()->definition()->AsBinaryIntegerOp();
} else if (RecognizeTestPattern(comparison()->right(),
comparison()->left(), &negate)) {
bit_and = comparison()->right()->definition()->AsBinaryIntegerOp();
}
if (bit_and != nullptr) {
if (FLAG_trace_optimization && flow_graph->should_print()) {
THR_Print("Merging test integer v%" Pd "\n",
bit_and->ssa_temp_index());
if (auto* equality = condition()->AsEqualityCompare()) {
if (equality->operation_cid() == kSmiCid ||
equality->operation_cid() == kMintCid) {
const auto representation =
equality->operation_cid() == kSmiCid ? kTagged : kUnboxedInt64;
if (TestIntInstr::IsSupported(representation)) {
BinaryIntegerOpInstr* bit_and = nullptr;
bool negate = false;
if (RecognizeTestPattern(equality->left(), equality->right(),
&negate)) {
bit_and = equality->left()->definition()->AsBinaryIntegerOp();
} else if (RecognizeTestPattern(equality->right(), equality->left(),
&negate)) {
bit_and = equality->right()->definition()->AsBinaryIntegerOp();
}
if (bit_and != nullptr) {
if (FLAG_trace_optimization && flow_graph->should_print()) {
THR_Print("Merging test integer v%" Pd "\n",
bit_and->ssa_temp_index());
}
TestIntInstr* test = new TestIntInstr(
equality->source(),
negate ? Token::NegateComparison(equality->kind())
: equality->kind(),
representation, bit_and->left()->Copy(zone),
bit_and->right()->Copy(zone));
ASSERT(!CanDeoptimize());
RemoveEnvironment();
flow_graph->CopyDeoptTarget(this, bit_and);
SetCondition(test);
bit_and->RemoveFromGraph();
return this;
}
TestIntInstr* test = new TestIntInstr(
comparison()->source(),
negate ? Token::NegateComparison(comparison()->kind())
: comparison()->kind(),
representation, bit_and->left()->Copy(zone),
bit_and->right()->Copy(zone));
ASSERT(!CanDeoptimize());
RemoveEnvironment();
flow_graph->CopyDeoptTarget(this, bit_and);
SetComparison(test);
bit_and->RemoveFromGraph();
return this;
}
}
auto replacement = CanonicalizeEqualityCompare(
comparison()->AsEqualityCompare(), flow_graph);
if (replacement != comparison()) {
SetComparison(replacement);
auto replacement = CanonicalizeEqualityCompare(equality, flow_graph);
if (replacement != condition()) {
SetCondition(replacement);
replacement->ClearSSATempIndex();
replacement->ClearTempIndex();
}
@@ -3720,9 +3720,9 @@ Definition* StrictCompareInstr::Canonicalize(FlowGraph* flow_graph) {
bool negated = false;
Definition* replacement = CanonicalizeStrictCompare(this, &negated,
/*is_branch=*/false);
if (negated && replacement->IsComparison()) {
if (negated && replacement->IsCondition()) {
ASSERT(replacement != this);
replacement->AsComparison()->NegateComparison();
replacement->AsCondition()->NegateCondition();
}
return replacement;
}
@@ -3779,7 +3779,7 @@ TestCidsInstr::TestCidsInstr(const InstructionSource& source,
Value* value,
const ZoneGrowableArray<intptr_t>& cid_results,
intptr_t deopt_id)
: TemplateComparison(source, kind, deopt_id), cid_results_(cid_results) {
: TemplateCondition(source, kind, deopt_id), cid_results_(cid_results) {
ASSERT((kind == Token::kIS) || (kind == Token::kISNOT));
SetInputAt(0, value);
set_operation_cid(kObjectCid);
@@ -3827,7 +3827,7 @@ TestRangeInstr::TestRangeInstr(const InstructionSource& source,
uword lower,
uword upper,
Representation value_representation)
: TemplateComparison(source, Token::kIS, DeoptId::kNone),
: TemplateCondition(source, Token::kIS, DeoptId::kNone),
lower_(lower),
upper_(upper),
value_representation_(value_representation) {
@@ -4989,15 +4989,13 @@ StrictCompareInstr::StrictCompareInstr(const InstructionSource& source,
Value* right,
bool needs_number_check,
intptr_t deopt_id)
: TemplateComparison(source, kind, deopt_id),
: ComparisonInstr(source, kind, left, right, deopt_id),
needs_number_check_(needs_number_check) {
ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
SetInputAt(0, left);
SetInputAt(1, right);
}
Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition StrictCompareInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Location left = locs()->in(0);
Location right = locs()->in(1);
ASSERT(!left.IsConstant() || !right.IsConstant());
@@ -5084,8 +5082,8 @@ LocationSummary* TestRangeInstr::MakeLocationSummary(Zone* zone,
return locs;
}
Condition TestRangeInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestRangeInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
intptr_t lower = lower_;
intptr_t upper = upper_;
if (value_representation_ == kTagged) {
@@ -6487,51 +6485,51 @@ void Environment::DeepCopyToOuter(Zone* zone,
}
}
ComparisonInstr* DoubleTestOpInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
ConditionInstr* DoubleTestOpInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
UNREACHABLE();
return nullptr;
}
ComparisonInstr* EqualityCompareInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
ConditionInstr* EqualityCompareInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
return new EqualityCompareInstr(source(), kind(), new_left, new_right,
operation_cid(), deopt_id(), is_null_aware());
}
ComparisonInstr* RelationalOpInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
ConditionInstr* RelationalOpInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
return new RelationalOpInstr(source(), kind(), new_left, new_right,
operation_cid(), deopt_id());
}
ComparisonInstr* StrictCompareInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
ConditionInstr* StrictCompareInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
return new StrictCompareInstr(source(), kind(), new_left, new_right,
needs_number_check(), DeoptId::kNone);
}
ComparisonInstr* TestIntInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
ConditionInstr* TestIntInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
return new TestIntInstr(source(), kind(), representation_, new_left,
new_right);
}
ComparisonInstr* TestCidsInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
ConditionInstr* TestCidsInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
return new TestCidsInstr(source(), kind(), new_left, cid_results(),
deopt_id());
}
ComparisonInstr* TestRangeInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
ConditionInstr* TestRangeInstr::CopyWithNewOperands(Value* new_left,
Value* new_right) {
return new TestRangeInstr(source(), new_left, lower_, upper_,
value_representation_);
}
bool TestCidsInstr::AttributesEqual(const Instruction& other) const {
auto const other_instr = other.AsTestCids();
if (!ComparisonInstr::AttributesEqual(other)) {
if (!ConditionInstr::AttributesEqual(other)) {
return false;
}
if (cid_results().length() != other_instr->cid_results().length()) {
@@ -6547,24 +6545,23 @@ bool TestCidsInstr::AttributesEqual(const Instruction& other) const {
bool TestRangeInstr::AttributesEqual(const Instruction& other) const {
auto const other_instr = other.AsTestRange();
if (!ComparisonInstr::AttributesEqual(other)) {
if (!ConditionInstr::AttributesEqual(other)) {
return false;
}
return lower_ == other_instr->lower_ && upper_ == other_instr->upper_ &&
value_representation_ == other_instr->value_representation_;
}
bool IfThenElseInstr::Supports(ComparisonInstr* comparison,
bool IfThenElseInstr::Supports(ConditionInstr* condition,
Value* v1,
Value* v2) {
bool is_smi_result = v1->BindsToSmiConstant() && v2->BindsToSmiConstant();
if (comparison->IsStrictCompare()) {
if (condition->IsStrictCompare()) {
// Strict comparison with number checks calls a stub and is not supported
// by if-conversion.
return is_smi_result &&
!comparison->AsStrictCompare()->needs_number_check();
return is_smi_result && !condition->AsStrictCompare()->needs_number_check();
}
if (comparison->operation_cid() != kSmiCid) {
if (condition->operation_cid() != kSmiCid) {
// Non-smi comparisons are not supported by if-conversion.
return false;
}
@@ -6674,7 +6671,7 @@ void PhiIterator::RemoveCurrentFromGraph() {
}
Instruction* CheckConditionInstr::Canonicalize(FlowGraph* graph) {
if (StrictCompareInstr* strict_compare = comparison()->AsStrictCompare()) {
if (StrictCompareInstr* strict_compare = condition()->AsStrictCompare()) {
if ((InputAt(0)->definition()->OriginalDefinition() ==
InputAt(1)->definition()->OriginalDefinition()) &&
strict_compare->kind() == Token::kEQ_STRICT) {
@@ -6686,9 +6683,9 @@ Instruction* CheckConditionInstr::Canonicalize(FlowGraph* graph) {
LocationSummary* CheckConditionInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
comparison()->locs()->set_out(0, Location::NoLocation());
return comparison()->locs();
condition()->InitializeLocationSummary(zone, opt);
condition()->locs()->set_out(0, Location::NoLocation());
return condition()->locs();
}
void CheckConditionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -6696,7 +6693,7 @@ void CheckConditionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler::Label* if_false =
compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnknown);
BranchLabels labels = {&if_true, if_false, &if_true};
Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
Condition true_condition = condition()->EmitConditionCode(compiler, labels);
if (true_condition != kInvalidCondition) {
__ BranchIf(InvertCondition(true_condition), if_false);
}
+200 -184
View File
@@ -48,7 +48,7 @@ class BoxIntegerInstr;
class CallTargets;
class CatchBlockEntryInstr;
class CheckBoundBaseInstr;
class ComparisonInstr;
class ConditionInstr;
class Definition;
class Environment;
class FlowGraph;
@@ -563,6 +563,7 @@ struct InstrAttrs {
M(BoxInteger, _) \
M(CheckBoundBase, _) \
M(Comparison, _) \
M(Condition, _) \
M(InstanceCallBase, _) \
M(ReturnBase, _) \
M(ShiftIntegerOp, _) \
@@ -613,8 +614,8 @@ FOR_EACH_ABSTRACT_INSTRUCTION(FORWARD_DECLARATION)
#define DECLARE_COMPARISON_METHODS \
virtual LocationSummary* MakeLocationSummary(Zone* zone, bool optimizing) \
const; \
virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, \
BranchLabels labels);
virtual Condition EmitConditionCode(FlowGraphCompiler* compiler, \
BranchLabels labels);
#define DECLARE_COMPARISON_INSTRUCTION(type) \
DECLARE_INSTRUCTION_NO_BACKEND(type) \
@@ -1399,7 +1400,7 @@ class Instruction : public ZoneAllocated {
// GetDeoptId and/or CopyDeoptIdFrom.
friend class CallSiteInliner;
friend class LICM;
friend class ComparisonInstr;
friend class ConditionInstr;
friend class Scheduler;
friend class BlockEntryInstr;
friend class CatchBlockEntryInstr; // deopt_id_
@@ -1415,7 +1416,7 @@ class Instruction : public ZoneAllocated {
// Write/read locs and environment, but not inputs.
// Used when one instruction embeds another and reuses their inputs
// (e.g. Branch/IfThenElse/CheckCondition wrap Comparison).
// (e.g. Branch/IfThenElse/CheckCondition wrap Condition).
void WriteExtraWithoutInputs(FlowGraphSerializer* s);
void ReadExtraWithoutInputs(FlowGraphDeserializer* d);
@@ -3832,20 +3833,19 @@ class IndirectGotoInstr : public TemplateInstruction<1, NoThrow> {
DISALLOW_COPY_AND_ASSIGN(IndirectGotoInstr);
};
class ComparisonInstr : public Definition {
// Base class for instructions which can be used as conditions in Branch,
// IfThenElse and CheckCondition instructions.
class ConditionInstr : public Definition {
public:
Value* left() const { return InputAt(0); }
Value* right() const { return InputAt(1); }
virtual TokenPosition token_pos() const { return token_pos_; }
Token::Kind kind() const { return kind_; }
DECLARE_ATTRIBUTE(kind())
virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
virtual ConditionInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
// Emits instructions to do the comparison and branch to the true or false
// Emits instructions for the condition and branch to the true or false
// label depending on the result. This implementation will call
// EmitComparisonCode and then generate the branch instructions afterwards.
// EmitConditionCode and then generate the branch instructions afterwards.
virtual void EmitBranchCode(FlowGraphCompiler* compiler, BranchInstr* branch);
// Used by EmitBranchCode and EmitNativeCode depending on whether the boolean
@@ -3853,13 +3853,13 @@ class ComparisonInstr : public Definition {
// condition in which case the caller is expected to emit a branch to the
// true label based on that condition (or a branch to the false label on the
// opposite condition). May also branch directly to the labels.
virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) = 0;
virtual Condition EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) = 0;
// Emits code that generates 'true' or 'false', depending on the comparison.
// This implementation will call EmitComparisonCode. If EmitComparisonCode
// does not use the labels (merely returning a condition) then EmitNativeCode
// may be able to use the condition to avoid a branch.
// Emits code that generates 'true' or 'false', depending on the condition.
// This implementation will call EmitConditionCode. If EmitConditionCode
// does not use the labels (merely setting condition flags) then
// EmitNativeCode may be able to use the condition flags to avoid a branch.
virtual void EmitNativeCode(FlowGraphCompiler* compiler);
void SetDeoptId(const Instruction& instr) { CopyDeoptIdFrom(instr); }
@@ -3868,17 +3868,88 @@ class ComparisonInstr : public Definition {
void set_operation_cid(intptr_t value) { operation_cid_ = value; }
intptr_t operation_cid() const { return operation_cid_; }
virtual void NegateComparison() { kind_ = Token::NegateComparison(kind_); }
virtual void NegateCondition() { kind_ = Token::NegateComparison(kind_); }
virtual bool CanBecomeDeoptimizationTarget() const { return true; }
virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }
virtual bool AttributesEqual(const Instruction& other) const {
auto const other_comparison = other.AsComparison();
return kind() == other_comparison->kind() &&
(operation_cid() == other_comparison->operation_cid());
auto const other_condition = other.AsCondition();
return kind() == other_condition->kind() &&
(operation_cid() == other_condition->operation_cid());
}
DECLARE_ABSTRACT_INSTRUCTION(Condition)
#define FIELD_LIST(F) \
F(const TokenPosition, token_pos_) \
F(Token::Kind, kind_) \
/* Set by optimizer. */ \
F(intptr_t, operation_cid_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(ConditionInstr,
Definition,
FIELD_LIST)
#undef FIELD_LIST
protected:
ConditionInstr(const InstructionSource& source,
Token::Kind kind,
intptr_t deopt_id = DeoptId::kNone)
: Definition(source, deopt_id),
token_pos_(source.token_pos),
kind_(kind),
operation_cid_(kIllegalCid) {}
private:
DISALLOW_COPY_AND_ASSIGN(ConditionInstr);
};
class PureCondition : public ConditionInstr {
public:
virtual bool AllowsCSE() const { return true; }
virtual bool HasUnknownSideEffects() const { return false; }
DECLARE_EMPTY_SERIALIZATION(PureCondition, ConditionInstr)
protected:
PureCondition(const InstructionSource& source,
Token::Kind kind,
intptr_t deopt_id)
: ConditionInstr(source, kind, deopt_id) {}
};
template <intptr_t N,
typename ThrowsTrait,
template <typename Impure, typename Pure> class CSETrait = NoCSE>
class TemplateCondition : public CSETrait<ConditionInstr, PureCondition>::Base {
public:
using BaseClass = typename CSETrait<ConditionInstr, PureCondition>::Base;
TemplateCondition(const InstructionSource& source,
Token::Kind kind,
intptr_t deopt_id = DeoptId::kNone)
: BaseClass(source, kind, deopt_id), inputs_() {}
virtual intptr_t InputCount() const { return N; }
virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; }
DECLARE_EMPTY_SERIALIZATION(TemplateCondition, BaseClass)
protected:
EmbeddedArray<Value*, N> inputs_;
private:
virtual void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
};
// Compares left and right.
class ComparisonInstr : public TemplateCondition<2, NoThrow, Pure> {
public:
Value* left() const { return InputAt(0); }
Value* right() const { return InputAt(1); }
// Detects comparison with a constant and returns constant and the other
// operand.
bool IsComparisonWithConstant(Value** other_operand,
@@ -3895,129 +3966,76 @@ class ComparisonInstr : public Definition {
}
DECLARE_ABSTRACT_INSTRUCTION(Comparison)
#define FIELD_LIST(F) \
F(const TokenPosition, token_pos_) \
F(Token::Kind, kind_) \
/* Set by optimizer. */ \
F(intptr_t, operation_cid_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(ComparisonInstr,
Definition,
FIELD_LIST)
#undef FIELD_LIST
DECLARE_EMPTY_SERIALIZATION(ComparisonInstr, TemplateCondition)
protected:
ComparisonInstr(const InstructionSource& source,
Token::Kind kind,
intptr_t deopt_id = DeoptId::kNone)
: Definition(source, deopt_id),
token_pos_(source.token_pos),
kind_(kind),
operation_cid_(kIllegalCid) {}
private:
DISALLOW_COPY_AND_ASSIGN(ComparisonInstr);
};
class PureComparison : public ComparisonInstr {
public:
virtual bool AllowsCSE() const { return true; }
virtual bool HasUnknownSideEffects() const { return false; }
DECLARE_EMPTY_SERIALIZATION(PureComparison, ComparisonInstr)
protected:
PureComparison(const InstructionSource& source,
Token::Kind kind,
intptr_t deopt_id)
: ComparisonInstr(source, kind, deopt_id) {}
};
template <intptr_t N,
typename ThrowsTrait,
template <typename Impure, typename Pure> class CSETrait = NoCSE>
class TemplateComparison
: public CSETrait<ComparisonInstr, PureComparison>::Base {
public:
using BaseClass = typename CSETrait<ComparisonInstr, PureComparison>::Base;
TemplateComparison(const InstructionSource& source,
Token::Kind kind,
intptr_t deopt_id = DeoptId::kNone)
: BaseClass(source, kind, deopt_id), inputs_() {}
virtual intptr_t InputCount() const { return N; }
virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; }
DECLARE_EMPTY_SERIALIZATION(TemplateComparison, BaseClass)
protected:
EmbeddedArray<Value*, N> inputs_;
private:
virtual void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
Value* left,
Value* right,
intptr_t deopt_id)
: TemplateCondition(source, kind, deopt_id) {
SetInputAt(0, left);
SetInputAt(1, right);
}
};
class BranchInstr : public Instruction {
public:
explicit BranchInstr(ComparisonInstr* comparison, intptr_t deopt_id)
: Instruction(deopt_id), comparison_(comparison) {
ASSERT(comparison->env() == nullptr);
for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) {
comparison->InputAt(i)->set_instruction(this);
explicit BranchInstr(ConditionInstr* condition, intptr_t deopt_id)
: Instruction(deopt_id), condition_(condition) {
ASSERT(condition->env() == nullptr);
for (intptr_t i = condition->InputCount() - 1; i >= 0; --i) {
condition->InputAt(i)->set_instruction(this);
}
}
DECLARE_INSTRUCTION(Branch)
virtual intptr_t ArgumentCount() const {
return comparison()->ArgumentCount();
return condition()->ArgumentCount();
}
virtual void SetMoveArguments(MoveArgumentsArray* move_arguments) {
comparison()->SetMoveArguments(move_arguments);
condition()->SetMoveArguments(move_arguments);
}
virtual MoveArgumentsArray* GetMoveArguments() const {
return comparison()->GetMoveArguments();
return condition()->GetMoveArguments();
}
intptr_t InputCount() const { return comparison()->InputCount(); }
intptr_t InputCount() const { return condition()->InputCount(); }
Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); }
Value* InputAt(intptr_t i) const { return condition()->InputAt(i); }
virtual TokenPosition token_pos() const { return comparison_->token_pos(); }
virtual intptr_t inlining_id() const { return comparison_->inlining_id(); }
virtual TokenPosition token_pos() const { return condition_->token_pos(); }
virtual intptr_t inlining_id() const { return condition_->inlining_id(); }
virtual void set_inlining_id(intptr_t value) {
return comparison_->set_inlining_id(value);
}
virtual bool has_inlining_id() const {
return comparison_->has_inlining_id();
return condition_->set_inlining_id(value);
}
virtual bool has_inlining_id() const { return condition_->has_inlining_id(); }
virtual bool ComputeCanDeoptimize() const {
return comparison()->ComputeCanDeoptimize();
return condition()->ComputeCanDeoptimize();
}
virtual bool CanBecomeDeoptimizationTarget() const {
return comparison()->CanBecomeDeoptimizationTarget();
return condition()->CanBecomeDeoptimizationTarget();
}
virtual bool HasUnknownSideEffects() const {
return comparison()->HasUnknownSideEffects();
return condition()->HasUnknownSideEffects();
}
virtual bool CanCallDart() const { return comparison()->CanCallDart(); }
virtual bool CanCallDart() const { return condition()->CanCallDart(); }
ComparisonInstr* comparison() const { return comparison_; }
void SetComparison(ComparisonInstr* comp);
ConditionInstr* condition() const { return condition_; }
void SetCondition(ConditionInstr* new_condition);
virtual intptr_t DeoptimizationTarget() const {
return comparison()->DeoptimizationTarget();
return condition()->DeoptimizationTarget();
}
virtual Representation RequiredInputRepresentation(intptr_t i) const {
return comparison()->RequiredInputRepresentation(i);
return condition()->RequiredInputRepresentation(i);
}
virtual Instruction* Canonicalize(FlowGraph* flow_graph);
@@ -4030,10 +4048,10 @@ class BranchInstr : public Instruction {
virtual void CopyDeoptIdFrom(const Instruction& instr) {
Instruction::CopyDeoptIdFrom(instr);
comparison()->CopyDeoptIdFrom(instr);
condition()->CopyDeoptIdFrom(instr);
}
virtual bool MayThrow() const { return comparison()->MayThrow(); }
virtual bool MayThrow() const { return condition()->MayThrow(); }
TargetEntryInstr* true_successor() const { return true_successor_; }
TargetEntryInstr* false_successor() const { return false_successor_; }
@@ -4046,7 +4064,7 @@ class BranchInstr : public Instruction {
PRINT_TO_SUPPORT
#define FIELD_LIST(F) F(ComparisonInstr*, comparison_)
#define FIELD_LIST(F) F(ConditionInstr*, condition_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(BranchInstr, Instruction, FIELD_LIST)
#undef FIELD_LIST
@@ -4054,7 +4072,7 @@ class BranchInstr : public Instruction {
private:
virtual void RawSetInputAt(intptr_t i, Value* value) {
comparison()->RawSetInputAt(i, value);
condition()->RawSetInputAt(i, value);
}
TargetEntryInstr* true_successor_ = nullptr;
@@ -4194,8 +4212,8 @@ class ConstraintInstr : public TemplateDefinition<1, NoThrow> {
virtual void InferRange(RangeAnalysis* analysis, Range* range);
// Constraints for branches have their target block stored in order
// to find the comparison that generated the constraint:
// target->predecessor->last_instruction->comparison.
// to find the condition that generated the constraint:
// target->predecessor->last_instruction->condition.
void set_target(TargetEntryInstr* target) { target_ = target; }
TargetEntryInstr* target() const { return target_; }
@@ -5043,7 +5061,7 @@ class DispatchTableCallInstr : public TemplateDartCall<1> {
DISALLOW_COPY_AND_ASSIGN(DispatchTableCallInstr);
};
class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
class StrictCompareInstr : public ComparisonInstr {
public:
StrictCompareInstr(const InstructionSource& source,
Token::Kind kind,
@@ -5054,7 +5072,7 @@ class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
DECLARE_COMPARISON_INSTRUCTION(StrictCompare)
virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
virtual ConditionInstr* CopyWithNewOperands(Value* left, Value* right);
virtual CompileType ComputeType() const;
@@ -5075,7 +5093,7 @@ class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
F(bool, needs_number_check_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(StrictCompareInstr,
TemplateComparison,
ComparisonInstr,
FIELD_LIST)
#undef FIELD_LIST
@@ -5093,16 +5111,15 @@ class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
DISALLOW_COPY_AND_ASSIGN(StrictCompareInstr);
};
// Comparison instruction that is equivalent to the (left & right) == 0
// comparison pattern.
class TestIntInstr : public TemplateComparison<2, NoThrow, Pure> {
// Test (left & right) == 0 pattern.
class TestIntInstr : public TemplateCondition<2, NoThrow, Pure> {
public:
TestIntInstr(const InstructionSource& source,
Token::Kind kind,
Representation representation,
Value* left,
Value* right)
: TemplateComparison(source, kind), representation_(representation) {
: TemplateCondition(source, kind), representation_(representation) {
ASSERT(kind == Token::kEQ || kind == Token::kNE);
ASSERT(IsSupported(representation));
SetInputAt(0, left);
@@ -5111,7 +5128,10 @@ class TestIntInstr : public TemplateComparison<2, NoThrow, Pure> {
DECLARE_COMPARISON_INSTRUCTION(TestInt);
virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
Value* left() const { return InputAt(0); }
Value* right() const { return InputAt(1); }
virtual ConditionInstr* CopyWithNewOperands(Value* left, Value* right);
virtual CompileType ComputeType() const;
@@ -5142,7 +5162,7 @@ class TestIntInstr : public TemplateComparison<2, NoThrow, Pure> {
#define FIELD_LIST(F) F(const Representation, representation_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(TestIntInstr,
TemplateComparison,
TemplateCondition,
FIELD_LIST)
#undef FIELD_LIST
@@ -5159,7 +5179,7 @@ class TestIntInstr : public TemplateComparison<2, NoThrow, Pure> {
// the opposite for cids not on the list. The first element in the table must
// always be the result for the Smi class-id and is allowed to differ from the
// other results even in the no-deopt case.
class TestCidsInstr : public TemplateComparison<1, NoThrow, Pure> {
class TestCidsInstr : public TemplateCondition<1, NoThrow, Pure> {
public:
TestCidsInstr(const InstructionSource& source,
Token::Kind kind,
@@ -5173,7 +5193,7 @@ class TestCidsInstr : public TemplateComparison<1, NoThrow, Pure> {
DECLARE_COMPARISON_INSTRUCTION(TestCids);
virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
virtual ConditionInstr* CopyWithNewOperands(Value* left, Value* right);
virtual CompileType ComputeType() const;
@@ -5195,7 +5215,7 @@ class TestCidsInstr : public TemplateComparison<1, NoThrow, Pure> {
#define FIELD_LIST(F) F(const ZoneGrowableArray<intptr_t>&, cid_results_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(TestCidsInstr,
TemplateComparison,
TemplateCondition,
FIELD_LIST)
#undef FIELD_LIST
@@ -5203,7 +5223,7 @@ class TestCidsInstr : public TemplateComparison<1, NoThrow, Pure> {
DISALLOW_COPY_AND_ASSIGN(TestCidsInstr);
};
class TestRangeInstr : public TemplateComparison<1, NoThrow, Pure> {
class TestRangeInstr : public TemplateCondition<1, NoThrow, Pure> {
public:
TestRangeInstr(const InstructionSource& source,
Value* value,
@@ -5216,7 +5236,7 @@ class TestRangeInstr : public TemplateComparison<1, NoThrow, Pure> {
uword lower() const { return lower_; }
uword upper() const { return upper_; }
virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
virtual ConditionInstr* CopyWithNewOperands(Value* left, Value* right);
virtual CompileType ComputeType() const;
@@ -5239,7 +5259,7 @@ class TestRangeInstr : public TemplateComparison<1, NoThrow, Pure> {
F(const Representation, value_representation_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(TestRangeInstr,
TemplateComparison,
TemplateCondition,
FIELD_LIST)
#undef FIELD_LIST
@@ -5247,7 +5267,7 @@ class TestRangeInstr : public TemplateComparison<1, NoThrow, Pure> {
DISALLOW_COPY_AND_ASSIGN(TestRangeInstr);
};
class EqualityCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
class EqualityCompareInstr : public ComparisonInstr {
public:
EqualityCompareInstr(const InstructionSource& source,
Token::Kind kind,
@@ -5256,16 +5276,15 @@ class EqualityCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
intptr_t cid,
intptr_t deopt_id,
bool null_aware)
: TemplateComparison(source, kind, deopt_id), null_aware_(null_aware) {
: ComparisonInstr(source, kind, left, right, deopt_id),
null_aware_(null_aware) {
ASSERT(Token::IsEqualityOperator(kind));
SetInputAt(0, left);
SetInputAt(1, right);
set_operation_cid(cid);
}
DECLARE_COMPARISON_INSTRUCTION(EqualityCompare)
virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
virtual ConditionInstr* CopyWithNewOperands(Value* left, Value* right);
virtual CompileType ComputeType() const;
@@ -5284,7 +5303,7 @@ class EqualityCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
}
virtual bool AttributesEqual(const Instruction& other) const {
return ComparisonInstr::AttributesEqual(other) &&
return ConditionInstr::AttributesEqual(other) &&
(null_aware_ == other.AsEqualityCompare()->null_aware_);
}
@@ -5295,7 +5314,7 @@ class EqualityCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
#define FIELD_LIST(F) F(bool, null_aware_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(EqualityCompareInstr,
TemplateComparison,
ComparisonInstr,
FIELD_LIST)
#undef FIELD_LIST
@@ -5303,7 +5322,7 @@ class EqualityCompareInstr : public TemplateComparison<2, NoThrow, Pure> {
DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr);
};
class RelationalOpInstr : public TemplateComparison<2, NoThrow, Pure> {
class RelationalOpInstr : public ComparisonInstr {
public:
RelationalOpInstr(const InstructionSource& source,
Token::Kind kind,
@@ -5311,17 +5330,15 @@ class RelationalOpInstr : public TemplateComparison<2, NoThrow, Pure> {
Value* right,
intptr_t cid,
intptr_t deopt_id)
: TemplateComparison(source, kind, deopt_id) {
: ComparisonInstr(source, kind, left, right, deopt_id) {
ASSERT(Token::IsRelationalOperator(kind));
ASSERT((cid == kSmiCid) || (cid == kMintCid) || (cid == kDoubleCid));
SetInputAt(0, left);
SetInputAt(1, right);
set_operation_cid(cid);
}
DECLARE_COMPARISON_INSTRUCTION(RelationalOp)
virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
virtual ConditionInstr* CopyWithNewOperands(Value* left, Value* right);
virtual CompileType ComputeType() const;
@@ -5336,90 +5353,90 @@ class RelationalOpInstr : public TemplateComparison<2, NoThrow, Pure> {
PRINT_OPERANDS_TO_SUPPORT
DECLARE_EMPTY_SERIALIZATION(RelationalOpInstr, TemplateComparison)
DECLARE_EMPTY_SERIALIZATION(RelationalOpInstr, ComparisonInstr)
private:
DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr);
};
// TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for
// TODO(vegorov): ConditionInstr should be switched to use IfTheElseInstr for
// materialization of true and false constants.
class IfThenElseInstr : public Definition {
public:
IfThenElseInstr(ComparisonInstr* comparison,
IfThenElseInstr(ConditionInstr* condition,
Value* if_true,
Value* if_false,
intptr_t deopt_id)
: Definition(deopt_id),
comparison_(comparison),
condition_(condition),
if_true_(Smi::Cast(if_true->BoundConstant()).Value()),
if_false_(Smi::Cast(if_false->BoundConstant()).Value()) {
// Adjust uses at the comparison.
ASSERT(comparison->env() == nullptr);
for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) {
comparison->InputAt(i)->set_instruction(this);
// Adjust uses at the condition.
ASSERT(condition->env() == nullptr);
for (intptr_t i = condition->InputCount() - 1; i >= 0; --i) {
condition->InputAt(i)->set_instruction(this);
}
}
// Returns true if this combination of comparison and values flowing on
// Returns true if this combination of condition and values flowing on
// the true and false paths is supported on the current platform.
static bool Supports(ComparisonInstr* comparison, Value* v1, Value* v2);
static bool Supports(ConditionInstr* condition, Value* v1, Value* v2);
DECLARE_INSTRUCTION(IfThenElse)
intptr_t InputCount() const { return comparison()->InputCount(); }
intptr_t InputCount() const { return condition()->InputCount(); }
Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); }
Value* InputAt(intptr_t i) const { return condition()->InputAt(i); }
virtual bool ComputeCanDeoptimize() const {
return comparison()->ComputeCanDeoptimize();
return condition()->ComputeCanDeoptimize();
}
virtual bool CanBecomeDeoptimizationTarget() const {
return comparison()->CanBecomeDeoptimizationTarget();
return condition()->CanBecomeDeoptimizationTarget();
}
virtual intptr_t DeoptimizationTarget() const {
return comparison()->DeoptimizationTarget();
return condition()->DeoptimizationTarget();
}
virtual Representation RequiredInputRepresentation(intptr_t i) const {
return comparison()->RequiredInputRepresentation(i);
return condition()->RequiredInputRepresentation(i);
}
virtual CompileType ComputeType() const;
virtual void InferRange(RangeAnalysis* analysis, Range* range);
ComparisonInstr* comparison() const { return comparison_; }
ConditionInstr* condition() const { return condition_; }
intptr_t if_true() const { return if_true_; }
intptr_t if_false() const { return if_false_; }
virtual bool AllowsCSE() const { return comparison()->AllowsCSE(); }
virtual bool AllowsCSE() const { return condition()->AllowsCSE(); }
virtual bool HasUnknownSideEffects() const {
return comparison()->HasUnknownSideEffects();
return condition()->HasUnknownSideEffects();
}
virtual bool CanCallDart() const { return comparison()->CanCallDart(); }
virtual bool CanCallDart() const { return condition()->CanCallDart(); }
virtual bool AttributesEqual(const Instruction& other) const {
auto const other_if_then_else = other.AsIfThenElse();
return (comparison()->tag() == other_if_then_else->comparison()->tag()) &&
comparison()->AttributesEqual(*other_if_then_else->comparison()) &&
return (condition()->tag() == other_if_then_else->condition()->tag()) &&
condition()->AttributesEqual(*other_if_then_else->condition()) &&
(if_true_ == other_if_then_else->if_true_) &&
(if_false_ == other_if_then_else->if_false_);
}
virtual bool MayThrow() const { return comparison()->MayThrow(); }
virtual bool MayThrow() const { return condition()->MayThrow(); }
virtual void CopyDeoptIdFrom(const Instruction& instr) {
Definition::CopyDeoptIdFrom(instr);
comparison()->CopyDeoptIdFrom(instr);
condition()->CopyDeoptIdFrom(instr);
}
PRINT_OPERANDS_TO_SUPPORT
#define FIELD_LIST(F) \
F(ComparisonInstr*, comparison_) \
F(ConditionInstr*, condition_) \
F(const intptr_t, if_true_) \
F(const intptr_t, if_false_)
@@ -5431,7 +5448,7 @@ class IfThenElseInstr : public Definition {
private:
virtual void RawSetInputAt(intptr_t i, Value* value) {
comparison()->RawSetInputAt(i, value);
condition()->RawSetInputAt(i, value);
}
DISALLOW_COPY_AND_ASSIGN(IfThenElseInstr);
@@ -8889,13 +8906,13 @@ class BinaryDoubleOpInstr : public TemplateDefinition<2, NoThrow, Pure> {
DISALLOW_COPY_AND_ASSIGN(BinaryDoubleOpInstr);
};
class DoubleTestOpInstr : public TemplateComparison<1, NoThrow, Pure> {
class DoubleTestOpInstr : public TemplateCondition<1, NoThrow, Pure> {
public:
DoubleTestOpInstr(MethodRecognizer::Kind op_kind,
Value* value,
intptr_t deopt_id,
const InstructionSource& source)
: TemplateComparison(source, Token::kEQ, deopt_id), op_kind_(op_kind) {
: TemplateCondition(source, Token::kEQ, deopt_id), op_kind_(op_kind) {
SetInputAt(0, value);
}
@@ -8920,15 +8937,15 @@ class DoubleTestOpInstr : public TemplateComparison<1, NoThrow, Pure> {
virtual bool AttributesEqual(const Instruction& other) const {
return op_kind_ == other.AsDoubleTestOp()->op_kind() &&
ComparisonInstr::AttributesEqual(other);
ConditionInstr::AttributesEqual(other);
}
virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
virtual ConditionInstr* CopyWithNewOperands(Value* left, Value* right);
#define FIELD_LIST(F) F(const MethodRecognizer::Kind, op_kind_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(DoubleTestOpInstr,
TemplateComparison,
TemplateCondition,
FIELD_LIST)
#undef FIELD_LIST
@@ -10688,20 +10705,20 @@ class CheckWritableInstr : public TemplateDefinition<1, Throws, Pure> {
DISALLOW_COPY_AND_ASSIGN(CheckWritableInstr);
};
// Instruction evaluates the given comparison and deoptimizes if it evaluates
// Instruction evaluates the given condition and deoptimizes if it evaluates
// to false.
class CheckConditionInstr : public Instruction {
public:
CheckConditionInstr(ComparisonInstr* comparison, intptr_t deopt_id)
: Instruction(deopt_id), comparison_(comparison) {
ASSERT(comparison->ArgumentCount() == 0);
ASSERT(comparison->env() == nullptr);
for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) {
comparison->InputAt(i)->set_instruction(this);
CheckConditionInstr(ConditionInstr* condition, intptr_t deopt_id)
: Instruction(deopt_id), condition_(condition) {
ASSERT(condition->ArgumentCount() == 0);
ASSERT(condition->env() == nullptr);
for (intptr_t i = condition->InputCount() - 1; i >= 0; --i) {
condition->InputAt(i)->set_instruction(this);
}
}
ComparisonInstr* comparison() const { return comparison_; }
ConditionInstr* condition() const { return condition_; }
DECLARE_INSTRUCTION(CheckCondition)
@@ -10713,23 +10730,22 @@ class CheckConditionInstr : public Instruction {
virtual bool HasUnknownSideEffects() const { return false; }
virtual bool AttributesEqual(const Instruction& other) const {
return other.AsCheckCondition()->comparison()->AttributesEqual(
*comparison());
return other.AsCheckCondition()->condition()->AttributesEqual(*condition());
}
virtual intptr_t InputCount() const { return comparison()->InputCount(); }
virtual Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); }
virtual intptr_t InputCount() const { return condition()->InputCount(); }
virtual Value* InputAt(intptr_t i) const { return condition()->InputAt(i); }
virtual bool MayThrow() const { return false; }
virtual void CopyDeoptIdFrom(const Instruction& instr) {
Instruction::CopyDeoptIdFrom(instr);
comparison()->CopyDeoptIdFrom(instr);
condition()->CopyDeoptIdFrom(instr);
}
PRINT_OPERANDS_TO_SUPPORT
#define FIELD_LIST(F) F(ComparisonInstr*, comparison_)
#define FIELD_LIST(F) F(ConditionInstr*, condition_)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(CheckConditionInstr,
Instruction,
@@ -10739,7 +10755,7 @@ class CheckConditionInstr : public Instruction {
private:
virtual void RawSetInputAt(intptr_t i, Value* value) {
comparison()->RawSetInputAt(i, value);
condition()->RawSetInputAt(i, value);
}
DISALLOW_COPY_AND_ASSIGN(CheckConditionInstr);
+24 -24
View File
@@ -727,8 +727,8 @@ static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
return comparison()->locs();
condition()->InitializeLocationSummary(zone, opt);
return condition()->locs();
}
void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -742,10 +742,10 @@ void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ eor(result, result, compiler::Operand(result));
// Emit comparison code. This must not overwrite the result register.
// IfThenElseInstr::Supports() should prevent EmitComparisonCode from using
// IfThenElseInstr::Supports() should prevent EmitConditionCode from using
// the labels or returning an invalid condition.
BranchLabels labels = {nullptr, nullptr, nullptr};
Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
Condition true_condition = condition()->EmitConditionCode(compiler, labels);
ASSERT(true_condition != kInvalidCondition);
const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
@@ -1467,8 +1467,8 @@ static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
}
}
Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition EqualityCompareInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
if (is_null_aware()) {
ASSERT(operation_cid() == kMintCid);
return EmitNullAwareInt64ComparisonOp(compiler, locs(), kind(), labels);
@@ -1499,8 +1499,8 @@ LocationSummary* TestIntInstr::MakeLocationSummary(Zone* zone, bool opt) const {
return locs;
}
Condition TestIntInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestIntInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
const Register left = locs()->in(0).reg();
Location right = locs()->in(1);
if (right.IsConstant()) {
@@ -1524,8 +1524,8 @@ LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
return locs;
}
Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestCidsInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
const Register val_reg = locs()->in(0).reg();
const Register cid_reg = locs()->temp(0).reg();
@@ -1614,8 +1614,8 @@ LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
return summary;
}
Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition RelationalOpInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
if (operation_cid() == kSmiCid) {
return EmitSmiComparisonOp(compiler, locs(), kind());
} else if (operation_cid() == kMintCid) {
@@ -4625,8 +4625,8 @@ LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone,
return summary;
}
Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition DoubleTestOpInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
ASSERT(compiler->is_optimizing());
const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg());
const bool is_negated = kind() != Token::kEQ;
@@ -6126,14 +6126,14 @@ void HashIntegerOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
LocationSummary* BranchInstr::MakeLocationSummary(Zone* zone, bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
condition()->InitializeLocationSummary(zone, opt);
// Branches don't produce a result.
comparison()->locs()->set_out(0, Location::NoLocation());
return comparison()->locs();
condition()->locs()->set_out(0, Location::NoLocation());
return condition()->locs();
}
void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
comparison()->EmitBranchCode(compiler, this);
condition()->EmitBranchCode(compiler, this);
}
LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
@@ -7321,11 +7321,11 @@ Condition StrictCompareInstr::EmitComparisonCodeRegConstant(
source(), deopt_id());
}
void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
void ConditionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
// The ARM code may not use true- and false-labels here.
compiler::Label is_true, is_false, done;
BranchLabels labels = {&is_true, &is_false, &is_false};
Condition true_condition = EmitComparisonCode(compiler, labels);
Condition true_condition = EmitConditionCode(compiler, labels);
const Register result = this->locs()->out(0).reg();
if (is_false.IsLinked() || is_true.IsLinked()) {
@@ -7339,7 +7339,7 @@ void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ LoadObject(result, Bool::True());
__ Bind(&done);
} else {
// If EmitComparisonCode did not use the labels and just returned
// If EmitConditionCode did not use the labels and just returned
// a condition we can avoid the branch and use conditional loads.
ASSERT(true_condition != kInvalidCondition);
__ LoadObject(result, Bool::True(), true_condition);
@@ -7347,10 +7347,10 @@ void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
}
void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
void ConditionInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
BranchLabels labels = compiler->CreateBranchLabels(branch);
Condition true_condition = EmitComparisonCode(compiler, labels);
Condition true_condition = EmitConditionCode(compiler, labels);
if (true_condition != kInvalidCondition) {
EmitBranchOnCondition(compiler, true_condition, labels);
}
+26 -26
View File
@@ -573,8 +573,8 @@ static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
return comparison()->locs();
condition()->InitializeLocationSummary(zone, opt);
return condition()->locs();
}
void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -585,10 +585,10 @@ void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(!left.IsConstant() || !right.IsConstant());
// Emit comparison code. This must not overwrite the result register.
// IfThenElseInstr::Supports() should prevent EmitComparisonCode from using
// IfThenElseInstr::Supports() should prevent EmitConditionCode from using
// the labels or returning an invalid condition.
BranchLabels labels = {nullptr, nullptr, nullptr};
Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
Condition true_condition = condition()->EmitConditionCode(compiler, labels);
ASSERT(true_condition != kInvalidCondition);
const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
@@ -1044,7 +1044,7 @@ static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
return true_condition;
}
// Similar to ComparisonInstr::EmitComparisonCode, may either:
// Similar to ConditionInstr::EmitConditionCode, may either:
// - emit comparison code and return a valid condition in which case the
// caller is expected to emit a branch to the true label based on that
// condition (or a branch to the false label on the opposite condition).
@@ -1209,8 +1209,8 @@ static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
}
}
Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition EqualityCompareInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
if (is_null_aware()) {
ASSERT(operation_cid() == kMintCid);
return EmitNullAwareInt64ComparisonOp(compiler, locs(), kind(), labels);
@@ -1238,8 +1238,8 @@ LocationSummary* TestIntInstr::MakeLocationSummary(Zone* zone, bool opt) const {
return locs;
}
Condition TestIntInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestIntInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
const Register left = locs()->in(0).reg();
Location right = locs()->in(1);
const auto operand_size = representation_ == kTagged ? compiler::kObjectBytes
@@ -1307,7 +1307,7 @@ void TestIntInstr::EmitBranchCode(FlowGraphCompiler* compiler,
}
// Otherwise use shared implementation.
ComparisonInstr::EmitBranchCode(compiler, branch);
ConditionInstr::EmitBranchCode(compiler, branch);
}
LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
@@ -1322,8 +1322,8 @@ LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
return locs;
}
Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestCidsInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
const Register val_reg = locs()->in(0).reg();
const Register cid_reg = locs()->temp(0).reg();
@@ -1393,8 +1393,8 @@ LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
return nullptr;
}
Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition RelationalOpInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
if (operation_cid() == kSmiCid) {
return EmitSmiComparisonOp(compiler, locs(), kind(), labels);
} else if (operation_cid() == kMintCid) {
@@ -3900,8 +3900,8 @@ LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone,
return summary;
}
Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition DoubleTestOpInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
ASSERT(compiler->is_optimizing());
const VRegister value = locs()->in(0).fpu_reg();
const bool is_negated = kind() != Token::kEQ;
@@ -5139,14 +5139,14 @@ void HashIntegerOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
LocationSummary* BranchInstr::MakeLocationSummary(Zone* zone, bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
condition()->InitializeLocationSummary(zone, opt);
// Branches don't produce a result.
comparison()->locs()->set_out(0, Location::NoLocation());
return comparison()->locs();
condition()->locs()->set_out(0, Location::NoLocation());
return condition()->locs();
}
void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
comparison()->EmitBranchCode(compiler, this);
condition()->EmitBranchCode(compiler, this);
}
LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
@@ -6348,10 +6348,10 @@ Condition StrictCompareInstr::EmitComparisonCodeRegConstant(
}
}
void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
void ConditionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler::Label is_true, is_false;
BranchLabels labels = {&is_true, &is_false, &is_false};
Condition true_condition = EmitComparisonCode(compiler, labels);
Condition true_condition = EmitConditionCode(compiler, labels);
const Register result = this->locs()->out(0).reg();
if (is_true.IsLinked() || is_false.IsLinked()) {
@@ -6366,7 +6366,7 @@ void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ LoadObject(result, Bool::True());
__ Bind(&done);
} else {
// If EmitComparisonCode did not use the labels and just returned
// If EmitConditionCode 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());
@@ -6375,10 +6375,10 @@ void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
}
void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
void ConditionInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
BranchLabels labels = compiler->CreateBranchLabels(branch);
Condition true_condition = EmitComparisonCode(compiler, labels);
Condition true_condition = EmitConditionCode(compiler, labels);
if (true_condition != kInvalidCondition) {
EmitBranchOnCondition(compiler, true_condition, labels);
}
+24 -24
View File
@@ -902,8 +902,8 @@ static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
return true_condition;
}
Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition EqualityCompareInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
if (is_null_aware()) {
// Null-aware EqualityCompare instruction is only used in AOT.
UNREACHABLE();
@@ -920,10 +920,10 @@ Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
}
}
void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
void ConditionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler::Label is_true, is_false;
BranchLabels labels = {&is_true, &is_false, &is_false};
Condition true_condition = EmitComparisonCode(compiler, labels);
Condition true_condition = EmitConditionCode(compiler, labels);
if (true_condition != kInvalidCondition) {
EmitBranchOnCondition(compiler, true_condition, labels,
compiler::Assembler::kNearJump);
@@ -939,10 +939,10 @@ void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(&done);
}
void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
void ConditionInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
BranchLabels labels = compiler->CreateBranchLabels(branch);
Condition true_condition = EmitComparisonCode(compiler, labels);
Condition true_condition = EmitConditionCode(compiler, labels);
if (true_condition != kInvalidCondition) {
EmitBranchOnCondition(compiler, true_condition, labels);
}
@@ -962,8 +962,8 @@ LocationSummary* TestIntInstr::MakeLocationSummary(Zone* zone, bool opt) const {
return locs;
}
Condition TestIntInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestIntInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Register left = locs()->in(0).reg();
Location right = locs()->in(1);
if (right.IsConstant()) {
@@ -988,8 +988,8 @@ LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
return locs;
}
Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestCidsInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
Register val_reg = locs()->in(0).reg();
Register cid_reg = locs()->temp(0).reg();
@@ -1066,8 +1066,8 @@ LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
return summary;
}
Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition RelationalOpInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
if (operation_cid() == kSmiCid) {
return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
} else if (operation_cid() == kMintCid) {
@@ -3883,8 +3883,8 @@ LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone,
return summary;
}
Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition DoubleTestOpInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
ASSERT(compiler->is_optimizing());
const XmmRegister value = locs()->in(0).fpu_reg();
const bool is_negated = kind() != Token::kEQ;
@@ -5211,14 +5211,14 @@ void HashIntegerOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
LocationSummary* BranchInstr::MakeLocationSummary(Zone* zone, bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
condition()->InitializeLocationSummary(zone, opt);
// Branches don't produce a result.
comparison()->locs()->set_out(0, Location::NoLocation());
return comparison()->locs();
condition()->locs()->set_out(0, Location::NoLocation());
return condition()->locs();
}
void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
comparison()->EmitBranchCode(compiler, this);
condition()->EmitBranchCode(compiler, this);
}
LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
@@ -6285,11 +6285,11 @@ static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
condition()->InitializeLocationSummary(zone, opt);
// TODO(dartbug.com/30953): support byte register constraints in the
// register allocator.
comparison()->locs()->set_out(0, Location::RegisterLocation(EDX));
return comparison()->locs();
condition()->locs()->set_out(0, Location::RegisterLocation(EDX));
return condition()->locs();
}
void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -6300,10 +6300,10 @@ void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ xorl(EDX, EDX);
// Emit comparison code. This must not overwrite the result register.
// IfThenElseInstr::Supports() should prevent EmitComparisonCode from using
// IfThenElseInstr::Supports() should prevent EmitConditionCode from using
// the labels or returning an invalid condition.
BranchLabels labels = {nullptr, nullptr, nullptr};
Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
Condition true_condition = condition()->EmitConditionCode(compiler, labels);
ASSERT(true_condition != kInvalidCondition);
const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
+6 -6
View File
@@ -132,7 +132,7 @@ class IlTestPrinter : public AllStatic {
}
writer->PrintProperty("o", instr->DebugName());
if (auto branch = instr->AsBranch()) {
PrintInstruction(writer, branch->comparison(), "cc");
PrintInstruction(writer, branch->condition(), "cc");
} else {
if (instr->InputCount() != 0) {
writer->OpenArray("i");
@@ -870,7 +870,7 @@ void StrictCompareInstr::PrintOperandsTo(BaseTextBuffer* f) const {
}
void TestCidsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
left()->PrintTo(f);
value()->PrintTo(f);
f->Printf(" %s [", Token::Str(kind()));
intptr_t length = cid_results().length();
for (intptr_t i = 0; i < length; i += 2) {
@@ -888,7 +888,7 @@ void TestCidsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
}
void TestRangeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
left()->PrintTo(f);
value()->PrintTo(f);
f->Printf(" %s [%" Pd "-%" Pd "]", kind() == Token::kIS ? "in" : "not in",
lower_, upper_);
}
@@ -966,7 +966,7 @@ void StoreFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
}
void IfThenElseInstr::PrintOperandsTo(BaseTextBuffer* f) const {
comparison()->PrintOperandsTo(f);
condition()->PrintOperandsTo(f);
f->Printf(" ? %" Pd " : %" Pd, if_true_, if_false_);
}
@@ -1209,7 +1209,7 @@ void CheckClassInstr::PrintOperandsTo(BaseTextBuffer* f) const {
}
void CheckConditionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
comparison()->PrintOperandsTo(f);
condition()->PrintOperandsTo(f);
}
void InvokeMathCFunctionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
@@ -1627,7 +1627,7 @@ void IndirectGotoInstr::PrintTo(BaseTextBuffer* f) const {
void BranchInstr::PrintTo(BaseTextBuffer* f) const {
f->Printf("%s ", DebugName());
f->AddString("if ");
comparison()->PrintTo(f);
condition()->PrintTo(f);
f->Printf(" goto (%" Pd ", %" Pd ")", true_successor()->block_id(),
false_successor()->block_id());
+25 -25
View File
@@ -622,8 +622,8 @@ static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
return comparison()->locs();
condition()->InitializeLocationSummary(zone, opt);
return condition()->locs();
}
void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -634,10 +634,10 @@ void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(!left.IsConstant() || !right.IsConstant());
// Emit comparison code. This must not overwrite the result register.
// IfThenElseInstr::Supports() should prevent EmitComparisonCode from using
// IfThenElseInstr::Supports() should prevent EmitConditionCode from using
// the labels or returning an invalid condition.
BranchLabels labels = {nullptr, nullptr, nullptr};
Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
Condition true_condition = condition()->EmitConditionCode(compiler, labels);
ASSERT(true_condition != kInvalidCondition);
const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
@@ -1142,7 +1142,7 @@ static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
}
}
#else
// Similar to ComparisonInstr::EmitComparisonCode, may either:
// Similar to ConditionInstr::EmitConditionCode, may either:
// - emit comparison code and return a valid condition in which case the
// caller is expected to emit a branch to the true label based on that
// condition (or a branch to the false label on the opposite condition).
@@ -1318,8 +1318,8 @@ static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
}
}
Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition EqualityCompareInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
if (is_null_aware()) {
ASSERT(operation_cid() == kMintCid);
return EmitNullAwareInt64ComparisonOp(compiler, locs(), kind(), labels);
@@ -1353,8 +1353,8 @@ LocationSummary* TestIntInstr::MakeLocationSummary(Zone* zone, bool opt) const {
return locs;
}
Condition TestIntInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestIntInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
const Register left = locs()->in(0).reg();
Location right = locs()->in(1);
if (right.IsConstant()) {
@@ -1378,8 +1378,8 @@ LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
return locs;
}
Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestCidsInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
const Register val_reg = locs()->in(0).reg();
const Register cid_reg = locs()->temp(0).reg();
@@ -1461,8 +1461,8 @@ LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
return nullptr;
}
Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition RelationalOpInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
if (operation_cid() == kSmiCid) {
return EmitSmiComparisonOp(compiler, locs(), kind(), labels);
} else if (operation_cid() == kMintCid) {
@@ -4293,8 +4293,8 @@ LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone,
return summary;
}
Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition DoubleTestOpInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
ASSERT(compiler->is_optimizing());
const FRegister value = locs()->in(0).fpu_reg();
@@ -5207,14 +5207,14 @@ void HashIntegerOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
LocationSummary* BranchInstr::MakeLocationSummary(Zone* zone, bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
condition()->InitializeLocationSummary(zone, opt);
// Branches don't produce a result.
comparison()->locs()->set_out(0, Location::NoLocation());
return comparison()->locs();
condition()->locs()->set_out(0, Location::NoLocation());
return condition()->locs();
}
void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
comparison()->EmitBranchCode(compiler, this);
condition()->EmitBranchCode(compiler, this);
}
LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
@@ -7182,10 +7182,10 @@ Condition StrictCompareInstr::EmitComparisonCodeRegConstant(
source(), deopt_id());
}
void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
void ConditionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler::Label is_true, is_false;
BranchLabels labels = {&is_true, &is_false, &is_false};
Condition true_condition = EmitComparisonCode(compiler, labels);
Condition true_condition = EmitConditionCode(compiler, labels);
Register result = locs()->out(0).reg();
if (is_true.IsLinked() || is_false.IsLinked()) {
@@ -7200,7 +7200,7 @@ void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ LoadObject(result, Bool::True());
__ Bind(&done);
} else {
// If EmitComparisonCode did not use the labels and just returned
// If EmitConditionCode did not use the labels and just returned
// a condition we can avoid the branch and use slt to generate the
// offsets to true or false.
ASSERT(kTrueOffsetFromNull + (1 << kBoolValueBitPosition) ==
@@ -7214,10 +7214,10 @@ void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
}
void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
void ConditionInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
BranchLabels labels = compiler->CreateBranchLabels(branch);
Condition true_condition = EmitComparisonCode(compiler, labels);
Condition true_condition = EmitConditionCode(compiler, labels);
if (true_condition != kInvalidCondition) {
EmitBranchOnCondition(compiler, true_condition, labels);
}
+16 -16
View File
@@ -219,11 +219,11 @@ bool FlowGraphDeserializer::ReadTrait<bool>::Read(FlowGraphDeserializer* d) {
}
void BranchInstr::WriteExtra(FlowGraphSerializer* s) {
// Branch reuses inputs from its embedded Comparison.
// Branch reuses inputs from its embedded Condition.
// Instruction::WriteExtra is not called to avoid
// writing/reading inputs twice.
WriteExtraWithoutInputs(s);
comparison_->WriteExtra(s);
condition_->WriteExtra(s);
s->WriteRef<TargetEntryInstr*>(true_successor_);
s->WriteRef<TargetEntryInstr*>(false_successor_);
s->WriteRef<TargetEntryInstr*>(constant_target_);
@@ -231,9 +231,9 @@ void BranchInstr::WriteExtra(FlowGraphSerializer* s) {
void BranchInstr::ReadExtra(FlowGraphDeserializer* d) {
ReadExtraWithoutInputs(d);
comparison_->ReadExtra(d);
for (intptr_t i = comparison_->InputCount() - 1; i >= 0; --i) {
comparison_->InputAt(i)->set_instruction(this);
condition_->ReadExtra(d);
for (intptr_t i = condition_->InputCount() - 1; i >= 0; --i) {
condition_->InputAt(i)->set_instruction(this);
}
true_successor_ = d->ReadRef<TargetEntryInstr*>();
false_successor_ = d->ReadRef<TargetEntryInstr*>();
@@ -359,18 +359,18 @@ const char* FlowGraphDeserializer::ReadTrait<const char*>::Read(
}
void CheckConditionInstr::WriteExtra(FlowGraphSerializer* s) {
// CheckCondition reuses inputs from its embedded Comparison.
// CheckCondition reuses inputs from its embedded Condition.
// Instruction::WriteExtra is not called to avoid
// writing/reading inputs twice.
WriteExtraWithoutInputs(s);
comparison_->WriteExtra(s);
condition_->WriteExtra(s);
}
void CheckConditionInstr::ReadExtra(FlowGraphDeserializer* d) {
ReadExtraWithoutInputs(d);
comparison_->ReadExtra(d);
for (intptr_t i = comparison_->InputCount() - 1; i >= 0; --i) {
comparison_->InputAt(i)->set_instruction(this);
condition_->ReadExtra(d);
for (intptr_t i = condition_->InputCount() - 1; i >= 0; --i) {
condition_->InputAt(i)->set_instruction(this);
}
}
@@ -1017,18 +1017,18 @@ const ICData* FlowGraphDeserializer::ReadTrait<const ICData*>::Read(
}
void IfThenElseInstr::WriteExtra(FlowGraphSerializer* s) {
// IfThenElse reuses inputs from its embedded Comparison.
// IfThenElse reuses inputs from its embedded Condition.
// Definition::WriteExtra is not called to avoid
// writing/reading inputs twice.
WriteExtraWithoutInputs(s);
comparison_->WriteExtra(s);
condition_->WriteExtra(s);
}
void IfThenElseInstr::ReadExtra(FlowGraphDeserializer* d) {
ReadExtraWithoutInputs(d);
comparison_->ReadExtra(d);
for (intptr_t i = comparison_->InputCount() - 1; i >= 0; --i) {
comparison_->InputAt(i)->set_instruction(this);
condition_->ReadExtra(d);
for (intptr_t i = condition_->InputCount() - 1; i >= 0; --i) {
condition_->InputAt(i)->set_instruction(this);
}
}
@@ -1121,7 +1121,7 @@ void Instruction::ReadExtraWithoutInputs(FlowGraphDeserializer* d) {
}
#define INSTRUCTIONS_SERIALIZABLE_AS_INSTRUCTION(V) \
V(Comparison, ComparisonInstr) \
V(Condition, ConditionInstr) \
V(Constant, ConstantInstr) \
V(Definition, Definition) \
V(ParallelMove, ParallelMoveInstr) \
+2 -2
View File
@@ -24,7 +24,7 @@ class CatchBlockEntryInstr;
struct CidRangeValue;
class Cids;
class Code;
class ComparisonInstr;
class ConditionInstr;
class CompileType;
class Definition;
class Environment;
@@ -82,7 +82,7 @@ class NativeCallingConvention;
V(const Cids&) \
V(const Class&) \
V(const Code&) \
V(ComparisonInstr*) \
V(ConditionInstr*) \
V(CompileType*) \
V(ConstantInstr*) \
V(Definition*) \
+24 -24
View File
@@ -532,11 +532,11 @@ static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
condition()->InitializeLocationSummary(zone, opt);
// TODO(dartbug.com/30952) support conversion of Register to corresponding
// least significant byte register (e.g. RAX -> AL, RSI -> SIL, r15 -> r15b).
comparison()->locs()->set_out(0, Location::RegisterLocation(RDX));
return comparison()->locs();
condition()->locs()->set_out(0, Location::RegisterLocation(RDX));
return condition()->locs();
}
void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -547,10 +547,10 @@ void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ xorq(RDX, RDX);
// Emit comparison code. This must not overwrite the result register.
// IfThenElseInstr::Supports() should prevent EmitComparisonCode from using
// IfThenElseInstr::Supports() should prevent EmitConditionCode from using
// the labels or returning an invalid condition.
BranchLabels labels = {nullptr, nullptr, nullptr};
Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
Condition true_condition = condition()->EmitConditionCode(compiler, labels);
ASSERT(true_condition != kInvalidCondition);
const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
@@ -1082,8 +1082,8 @@ static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
return true_condition;
}
Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition EqualityCompareInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
if (is_null_aware()) {
ASSERT(operation_cid() == kMintCid);
return EmitNullAwareInt64ComparisonOp(compiler, *locs(), kind(), labels);
@@ -1098,10 +1098,10 @@ Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
}
}
void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
void ConditionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler::Label is_true, is_false;
BranchLabels labels = {&is_true, &is_false, &is_false};
Condition true_condition = EmitComparisonCode(compiler, labels);
Condition true_condition = EmitConditionCode(compiler, labels);
Register result = locs()->out(0).reg();
if (true_condition != kInvalidCondition) {
@@ -1120,10 +1120,10 @@ void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(&done);
}
void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
void ConditionInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
BranchLabels labels = compiler->CreateBranchLabels(branch);
Condition true_condition = EmitComparisonCode(compiler, labels);
Condition true_condition = EmitConditionCode(compiler, labels);
if (true_condition != kInvalidCondition) {
EmitBranchOnCondition(compiler, true_condition, labels);
}
@@ -1142,8 +1142,8 @@ LocationSummary* TestIntInstr::MakeLocationSummary(Zone* zone, bool opt) const {
return locs;
}
Condition TestIntInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestIntInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Register left_reg = locs()->in(0).reg();
Location right = locs()->in(1);
if (right.IsConstant()) {
@@ -1175,8 +1175,8 @@ LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
return locs;
}
Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition TestCidsInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
Register val_reg = locs()->in(0).reg();
Register cid_reg = locs()->temp(0).reg();
@@ -1245,8 +1245,8 @@ LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
return nullptr;
}
Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition RelationalOpInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
if (operation_cid() == kSmiCid) {
return EmitSmiComparisonOp(compiler, *locs(), kind());
} else if (operation_cid() == kMintCid) {
@@ -4123,8 +4123,8 @@ LocationSummary* DoubleTestOpInstr::MakeLocationSummary(Zone* zone,
return summary;
}
Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
Condition DoubleTestOpInstr::EmitConditionCode(FlowGraphCompiler* compiler,
BranchLabels labels) {
ASSERT(compiler->is_optimizing());
const XmmRegister value = locs()->in(0).fpu_reg();
const bool is_negated = kind() != Token::kEQ;
@@ -5415,14 +5415,14 @@ void HashIntegerOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
LocationSummary* BranchInstr::MakeLocationSummary(Zone* zone, bool opt) const {
comparison()->InitializeLocationSummary(zone, opt);
condition()->InitializeLocationSummary(zone, opt);
// Branches don't produce a result.
comparison()->locs()->set_out(0, Location::NoLocation());
return comparison()->locs();
condition()->locs()->set_out(0, Location::NoLocation());
return condition()->locs();
}
void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
comparison()->EmitBranchCode(compiler, this);
condition()->EmitBranchCode(compiler, this);
}
LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
+7 -7
View File
@@ -133,7 +133,7 @@ class CalleeGraphValidator : public AllStatic {
for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
Instruction* current = it.Current();
if (current->IsBranch()) {
current = current->AsBranch()->comparison();
current = current->AsBranch()->condition();
}
// The following instructions are not safe to inline, since they make
// assumptions about the frame layout.
@@ -2202,21 +2202,21 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
// For all variants except the last, use a branch on the loaded class
// id.
BlockEntryInstr* cid_test_entry_block = current_block;
ComparisonInstr* compare;
ConditionInstr* condition;
if (variant.cid_start == variant.cid_end) {
ConstantInstr* cid_constant = owner_->caller_graph()->GetConstant(
Smi::ZoneHandle(Smi::New(variant.cid_end)), cid_representation);
compare = new EqualityCompareInstr(
condition = new EqualityCompareInstr(
call_->source(), Token::kEQ, new Value(load_cid),
new Value(cid_constant),
cid_representation == kTagged ? kSmiCid : kIntegerCid,
DeoptId::kNone, /*null_aware=*/false);
} else {
compare = new TestRangeInstr(call_->source(), new Value(load_cid),
variant.cid_start, variant.cid_end,
cid_representation);
condition = new TestRangeInstr(call_->source(), new Value(load_cid),
variant.cid_start, variant.cid_end,
cid_representation);
}
BranchInstr* branch = new BranchInstr(compare, DeoptId::kNone);
BranchInstr* branch = new BranchInstr(condition, DeoptId::kNone);
branch->InheritDeoptTarget(zone(), call_);
AppendInstruction(cursor, branch);
+3 -1
View File
@@ -90,7 +90,9 @@ ISOLATE_UNIT_TEST_CASE(Inliner_PolyInliningRedefinition) {
// above, or a default case if there was no branch instruction for B's cid.
while (true) {
EXPECT(current->IsBranch());
const ComparisonInstr* check = current->AsBranch()->comparison();
const EqualityCompareInstr* check =
current->AsBranch()->condition()->AsEqualityCompare();
EXPECT(check != nullptr);
EXPECT(check->left()->definition() == lcid);
if (check->right()->definition() == cid_B) break;
current = current->SuccessorAt(1);
+5 -5
View File
@@ -403,11 +403,11 @@ void InductionVarAnalysis::ClassifySCC(LoopInfo* loop) {
void InductionVarAnalysis::ClassifyControl(LoopInfo* loop) {
for (auto branch : branches_) {
// Proper comparison?
ComparisonInstr* compare = branch->comparison();
if (compare->InputCount() != 2) {
ConditionInstr* condition = branch->condition();
if (condition->InputCount() != 2) {
continue;
}
Token::Kind cmp = compare->kind();
Token::Kind cmp = condition->kind();
// Proper loop exit? Express the condition in "loop while true" form.
TargetEntryInstr* ift = branch->true_successor();
TargetEntryInstr* iff = branch->false_successor();
@@ -421,10 +421,10 @@ void InductionVarAnalysis::ClassifyControl(LoopInfo* loop) {
// Comparison against linear constant stride induction?
// Express the comparison such that induction appears left.
int64_t stride = 0;
auto left = compare->left()
auto left = condition->InputAt(0)
->definition()
->OriginalDefinitionIgnoreBoxingAndConstraints();
auto right = compare->right()
auto right = condition->InputAt(1)
->definition()
->OriginalDefinitionIgnoreBoxingAndConstraints();
InductionVar* x = Lookup(loop, left);
@@ -203,7 +203,7 @@ ConstraintInstr* RangeAnalysis::InsertConstraintFor(Value* use,
bool RangeAnalysis::ConstrainValueAfterBranch(Value* use, Definition* defn) {
BranchInstr* branch = use->instruction()->AsBranch();
RelationalOpInstr* rel_op = branch->comparison()->AsRelationalOp();
RelationalOpInstr* rel_op = branch->condition()->AsRelationalOp();
if ((rel_op != nullptr) && ((rel_op->operation_cid() == kSmiCid) ||
(rel_op->operation_cid() == kMintCid))) {
// Found comparison of two integers. Constrain defn at true and false
@@ -4604,7 +4604,7 @@ void CheckStackOverflowElimination::EliminateStackOverflow(FlowGraph* graph) {
}
if (current->IsBranch()) {
current = current->AsBranch()->comparison();
current = current->AsBranch()->condition();
}
if (current->HasUnknownSideEffects()) {
@@ -379,7 +379,7 @@ void FlowGraphTypePropagator::VisitAssertAssignable(
void FlowGraphTypePropagator::VisitAssertSubtype(AssertSubtypeInstr* instr) {}
void FlowGraphTypePropagator::VisitBranch(BranchInstr* instr) {
StrictCompareInstr* comparison = instr->comparison()->AsStrictCompare();
StrictCompareInstr* comparison = instr->condition()->AsStrictCompare();
if (comparison == nullptr) return;
bool negated = comparison->kind() == Token::kNE_STRICT;
LoadClassIdInstr* load_cid =
@@ -1939,12 +1939,12 @@ TestFragment StreamingFlowGraphBuilder::TranslateConditionForControl() {
stack()->definition() == instructions.current) {
StrictCompareInstr* compare = Pop()->definition()->AsStrictCompare();
if (negate) {
compare->NegateComparison();
compare->NegateCondition();
negate = false;
}
branch =
new (Z) BranchInstr(compare, flow_graph_builder_->GetNextDeoptId());
branch->comparison()->ClearTempIndex();
branch->condition()->ClearTempIndex();
ASSERT(instructions.current->previous() != nullptr);
instructions.current = instructions.current->previous();
} else {
+3 -3
View File
@@ -1609,9 +1609,9 @@ void IRRegExpMacroAssembler::CheckPosition(intptr_t cp_offset,
}
}
void IRRegExpMacroAssembler::BranchOrBacktrack(ComparisonInstr* comparison,
void IRRegExpMacroAssembler::BranchOrBacktrack(ConditionInstr* condition,
BlockLabel* true_successor) {
if (comparison == nullptr) { // No condition
if (condition == nullptr) { // No condition
if (true_successor == nullptr) {
Backtrack();
return;
@@ -1631,7 +1631,7 @@ void IRRegExpMacroAssembler::BranchOrBacktrack(ComparisonInstr* comparison,
// If the condition is not true, fall through to a new block.
BlockLabel fallthrough;
BranchInstr* branch = new (Z) BranchInstr(comparison, GetNextDeoptId());
BranchInstr* branch = new (Z) BranchInstr(condition, GetNextDeoptId());
*branch->true_successor_address() = TargetWithJoinGoto(true_successor_block);
*branch->false_successor_address() = TargetWithJoinGoto(fallthrough.block());
+1 -2
View File
@@ -298,8 +298,7 @@ class IRRegExpMacroAssembler : public RegExpMacroAssembler {
// Equivalent to a conditional branch to the label, unless the label
// is nullptr, in which case it is a conditional Backtrack.
void BranchOrBacktrack(ComparisonInstr* comparison,
BlockLabel* true_successor);
void BranchOrBacktrack(ConditionInstr* condition, BlockLabel* true_successor);
// Set up all local variables and parameters.
void InitializeLocals();