diff options
author | 2024-08-13 10:03:27 +0000 | |
---|---|---|
committer | 2024-08-13 10:03:27 +0000 | |
commit | 275cf7423efdb36e441b7bceb2e678944f8fa34b (patch) | |
tree | cd74101af342d0798827aa853f1f5e34cc1c01a6 /compiler/optimizing/instruction_simplifier.cc | |
parent | 7496a81f4298257a5c6ce25271873b0c12e69f96 (diff) |
Revert "Implement transform from signed to unsigned compare"
This reverts commit 7496a81f4298257a5c6ce25271873b0c12e69f96.
Reason for revert: Broke some builds because of wrong
handling of HCompare(unsigned)+{HEqual,HNotEqual}.
Change-Id: Ic233740c3997d449777207d15243c8a4786df238
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 203 |
1 files changed, 7 insertions, 196 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index ec02c6ef66..cafa83bece 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -89,7 +89,6 @@ class InstructionSimplifierVisitor final : public HGraphDelegateVisitor { void VisitAbs(HAbs* instruction) override; void VisitAdd(HAdd* instruction) override; void VisitAnd(HAnd* instruction) override; - void VisitCompare(HCompare* instruction) override; void VisitCondition(HCondition* instruction) override; void VisitGreaterThan(HGreaterThan* condition) override; void VisitGreaterThanOrEqual(HGreaterThanOrEqual* condition) override; @@ -879,7 +878,7 @@ void InstructionSimplifierVisitor::VisitStaticFieldSet(HStaticFieldSet* instruct } } -static HCondition* CreateOppositeConditionSwapOps(ArenaAllocator* allocator, HInstruction* cond) { +static HCondition* GetOppositeConditionSwapOps(ArenaAllocator* allocator, HInstruction* cond) { HInstruction *lhs = cond->InputAt(0); HInstruction *rhs = cond->InputAt(1); switch (cond->GetKind()) { @@ -1795,56 +1794,6 @@ static bool RecognizeAndSimplifyClassCheck(HCondition* condition) { } } -static HInstruction* CreateUnsignedConditionReplacement(ArenaAllocator* allocator, - HCondition* cond, - HCompare* compare) { - DCHECK(cond->InputAt(1)->IsIntConstant()); - DCHECK_EQ(cond->InputAt(1)->AsIntConstant()->GetValue(), 0); - DCHECK(cond->InputAt(0) == compare); - - HBasicBlock* block = cond->GetBlock(); - HInstruction* lhs = compare->InputAt(0); - HInstruction* rhs = compare->InputAt(1); - - switch (cond->GetKind()) { - case HInstruction::kLessThan: - return new (allocator) HBelow(lhs, rhs, cond->GetDexPc()); - case HInstruction::kLessThanOrEqual: - return new (allocator) HBelowOrEqual(lhs, rhs, cond->GetDexPc()); - case HInstruction::kGreaterThan: - return new (allocator) HAbove(lhs, rhs, cond->GetDexPc()); - case HInstruction::kGreaterThanOrEqual: - return new (allocator) HAboveOrEqual(lhs, rhs, cond->GetDexPc()); - case HInstruction::kBelow: - // Below(Compare(x, y), 0) always False since - // unsigned(-1) < 0 -> False - // 0 < 0 -> False - // 1 < 0 -> False - return block->GetGraph()->GetConstant(DataType::Type::kBool, 0, cond->GetDexPc()); - case HInstruction::kBelowOrEqual: - // BelowOrEqual(Compare(x, y), 0) transforms into Equal(x, y) - // unsigned(-1) <= 0 -> False - // 0 <= 0 -> True - // 1 <= 0 -> False - return new (allocator) HEqual(lhs, rhs, cond->GetDexPc()); - case HInstruction::kAbove: - // Above(Compare(x, y), 0) transforms into NotEqual(x, y) - // unsigned(-1) > 0 -> True - // 0 > 0 -> False - // 1 > 0 -> True - return new (allocator) HNotEqual(lhs, rhs, cond->GetDexPc()); - case HInstruction::kAboveOrEqual: - // AboveOrEqual(Compare(x, y), 0) always True since - // unsigned(-1) >= 0 -> True - // 0 >= 0 -> True - // 1 >= 0 -> True - return block->GetGraph()->GetConstant(DataType::Type::kBool, 1, cond->GetDexPc()); - default: - LOG(FATAL) << "Unknown ConditionType " << cond->GetKind(); - UNREACHABLE(); - } -} - void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) { if (condition->IsEqual() || condition->IsNotEqual()) { if (RecognizeAndSimplifyClassCheck(condition)) { @@ -1854,10 +1803,10 @@ void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) { // Reverse condition if left is constant. Our code generators prefer constant // on the right hand side. - HBasicBlock* block = condition->GetBlock(); if (condition->GetLeft()->IsConstant() && !condition->GetRight()->IsConstant()) { + HBasicBlock* block = condition->GetBlock(); HCondition* replacement = - CreateOppositeConditionSwapOps(block->GetGraph()->GetAllocator(), condition); + GetOppositeConditionSwapOps(block->GetGraph()->GetAllocator(), condition); // If it is a fp we must set the opposite bias. if (replacement != nullptr) { if (condition->IsLtBias()) { @@ -1865,7 +1814,6 @@ void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) { } else if (condition->IsGtBias()) { replacement->SetBias(ComparisonBias::kLtBias); } - block->ReplaceAndRemoveInstructionWith(condition, replacement); RecordSimplification(); @@ -1908,24 +1856,11 @@ void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) { left->RemoveEnvironmentUsers(); // We have decided to fold the HCompare into the HCondition. Transfer the information. - if (DataType::IsUnsignedType(left->AsCompare()->GetComparisonType())) { - DCHECK_EQ(condition->GetBias(), ComparisonBias::kNoBias); - HInstruction* replacement = CreateUnsignedConditionReplacement( - block->GetGraph()->GetAllocator(), condition, left->AsCompare()); - - if (replacement->IsConstant()) { - condition->ReplaceWith(replacement); - block->RemoveInstruction(condition); - } else { - block->ReplaceAndRemoveInstructionWith(condition, replacement); - } - } else { - condition->SetBias(left->AsCompare()->GetBias()); + condition->SetBias(left->AsCompare()->GetBias()); - // Replace the operands of the HCondition. - condition->ReplaceInput(left->InputAt(0), 0); - condition->ReplaceInput(left->InputAt(1), 1); - } + // Replace the operands of the HCondition. + condition->ReplaceInput(left->InputAt(0), 0); + condition->ReplaceInput(left->InputAt(1), 1); // Remove the HCompare. left->GetBlock()->RemoveInstruction(left); @@ -1933,130 +1868,6 @@ void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) { RecordSimplification(); } -static HInstruction* CheckSignedToUnsignedCompareConversion(HInstruction* operand, - HCompare* compare) { - // Check if operand looks like `ADD op, MIN_INTEGRAL` - if (operand->IsConstant()) { - // CONSTANT #x -> CONSTANT #(x - MIN_INTEGRAL) - HConstant* constant = operand->AsConstant(); - if (constant->IsIntConstant()) { - HIntConstant* int_constant = constant->AsIntConstant(); - int32_t old_value = int_constant->GetValue(); - int32_t new_value = old_value - std::numeric_limits<int32_t>::min(); - return operand->GetBlock()->GetGraph()->GetIntConstant(new_value, constant->GetDexPc()); - } else if (constant->IsLongConstant()) { - HLongConstant* long_constant = constant->AsLongConstant(); - int64_t old_value = long_constant->GetValue(); - int64_t new_value = old_value - std::numeric_limits<int64_t>::min(); - return operand->GetBlock()->GetGraph()->GetLongConstant(new_value, constant->GetDexPc()); - } else { - return nullptr; - } - } - - if (!operand->IsAdd() && !operand->IsXor()) { - return nullptr; - } - - if (!operand->GetEnvUses().empty()) { - // There is a reference to the compare result in an environment. Do we really need it? - if (operand->GetBlock()->GetGraph()->IsDebuggable()) { - return nullptr; - } - - // We have to ensure that there are no deopt points in the sequence. - if (operand->HasAnyEnvironmentUseBefore(compare)) { - return nullptr; - } - } - - HBinaryOperation* additive_operand = operand->AsBinaryOperation(); - - HInstruction* left = additive_operand->GetLeft(); - HInstruction* right = additive_operand->GetRight(); - - HConstant* constant = nullptr; - HInstruction* value = nullptr; - - if (left->IsConstant() && !right->IsConstant()) { - constant = left->AsConstant(); - value = right; - } else if (!left->IsConstant() && right->IsConstant()) { - value = left; - constant = right->AsConstant(); - } else { - return nullptr; - } - - if (constant->IsIntConstant()) { - HIntConstant* int_constant = constant->AsIntConstant(); - if (int_constant->GetValue() != std::numeric_limits<int32_t>::min()) { - return nullptr; - } - } else if (constant->IsLongConstant()) { - HLongConstant* long_constant = constant->AsLongConstant(); - if (long_constant->GetValue() != std::numeric_limits<int64_t>::min()) { - return nullptr; - } - } else { - return nullptr; - } - - return value; -} - -static DataType::Type GetOpositeSignType(DataType::Type type) { - return DataType::IsUnsignedType(type) ? DataType::ToSigned(type) : DataType::ToUnsigned(type); -} - -void InstructionSimplifierVisitor::VisitCompare(HCompare* compare) { - // Transform signed compare into unsigned if possible - // Replace code looking like - // ADD normalizedLeft, left, MIN_INTEGRAL - // ADD normalizedRight, right, MIN_INTEGRAL - // COMPARE normalizedLeft, normalizedRight, sign - // with - // COMPARE left, right, !sign - - if (!DataType::IsIntegralType(compare->GetComparisonType())) { - return; - } - - HInstruction* compare_left = compare->GetLeft(); - HInstruction* compare_right = compare->GetRight(); - - if (compare_left->IsConstant() && compare_right->IsConstant()) { - // Do not simplify, let it be folded. - return; - } - - HInstruction* left = CheckSignedToUnsignedCompareConversion(compare_left, compare); - if (left == nullptr) { - return; - } - - HInstruction* right = CheckSignedToUnsignedCompareConversion(compare_right, compare); - if (right == nullptr) { - return; - } - - compare->SetComparisonType(GetOpositeSignType(compare->GetComparisonType())); - compare->ReplaceInput(left, 0); - compare->ReplaceInput(right, 1); - - RecordSimplification(); - - if (compare_left->GetUses().empty()) { - compare_left->RemoveEnvironmentUsers(); - compare_left->GetBlock()->RemoveInstruction(compare_left); - } - - if (compare_right->GetUses().empty()) { - compare_right->RemoveEnvironmentUsers(); - compare_right->GetBlock()->RemoveInstruction(compare_right); - } -} - // Return whether x / divisor == x * (1.0f / divisor), for every float x. static constexpr bool CanDivideByReciprocalMultiplyFloat(int32_t divisor) { // True, if the most significant bits of divisor are 0. |