diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 79 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.h | 3 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips64.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/constant_folding.cc | 18 | ||||
-rw-r--r-- | compiler/optimizing/dead_code_elimination.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/inliner.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 30 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 43 | ||||
-rw-r--r-- | compiler/optimizing/reference_type_propagation.cc | 8 |
14 files changed, 128 insertions, 94 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 46f08a8d6a..23528b50ff 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -1412,13 +1412,13 @@ void InstructionCodeGeneratorARM::GenerateTestAndBranch(HInstruction* instructio // Nothing to do. The code always falls through. return; } else if (cond->IsIntConstant()) { - // Constant condition, statically compared against 1. - if (cond->AsIntConstant()->IsOne()) { + // Constant condition, statically compared against "true" (integer value 1). + if (cond->AsIntConstant()->IsTrue()) { if (true_target != nullptr) { __ b(true_target); } } else { - DCHECK(cond->AsIntConstant()->IsZero()); + DCHECK(cond->AsIntConstant()->IsFalse()) << cond->AsIntConstant()->GetValue(); if (false_target != nullptr) { __ b(false_target); } diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 99fa9c6103..a04918a601 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -1949,7 +1949,7 @@ void InstructionCodeGeneratorARM64::VisitArm64DataProcWithShifterOp( __ And(out, left, right_operand); break; case HInstruction::kNeg: - DCHECK(instruction->InputAt(0)->AsConstant()->IsZero()); + DCHECK(instruction->InputAt(0)->AsConstant()->IsArithmeticZero()); __ Neg(out, right_operand); break; case HInstruction::kOr: @@ -1994,7 +1994,7 @@ void LocationsBuilderARM64::VisitMultiplyAccumulate(HMultiplyAccumulate* instr) HInstruction* accumulator = instr->InputAt(HMultiplyAccumulate::kInputAccumulatorIndex); if (instr->GetOpKind() == HInstruction::kSub && accumulator->IsConstant() && - accumulator->AsConstant()->IsZero()) { + accumulator->AsConstant()->IsArithmeticZero()) { // Don't allocate register for Mneg instruction. } else { locations->SetInAt(HMultiplyAccumulate::kInputAccumulatorIndex, @@ -2033,7 +2033,7 @@ void InstructionCodeGeneratorARM64::VisitMultiplyAccumulate(HMultiplyAccumulate* } else { DCHECK(instr->GetOpKind() == HInstruction::kSub); HInstruction* accum_instr = instr->InputAt(HMultiplyAccumulate::kInputAccumulatorIndex); - if (accum_instr->IsConstant() && accum_instr->AsConstant()->IsZero()) { + if (accum_instr->IsConstant() && accum_instr->AsConstant()->IsArithmeticZero()) { __ Mneg(res, mul_left, mul_right); } else { Register accumulator = InputRegisterAt(instr, HMultiplyAccumulate::kInputAccumulatorIndex); @@ -2378,9 +2378,35 @@ void InstructionCodeGeneratorARM64::VisitClinitCheck(HClinitCheck* check) { GenerateClassInitializationCheck(slow_path, InputRegisterAt(check, 0)); } -static bool IsFloatingPointZeroConstant(HInstruction* instruction) { - return (instruction->IsFloatConstant() && (instruction->AsFloatConstant()->GetValue() == 0.0f)) - || (instruction->IsDoubleConstant() && (instruction->AsDoubleConstant()->GetValue() == 0.0)); +static bool IsFloatingPointZeroConstant(HInstruction* inst) { + return (inst->IsFloatConstant() && (inst->AsFloatConstant()->IsArithmeticZero())) + || (inst->IsDoubleConstant() && (inst->AsDoubleConstant()->IsArithmeticZero())); +} + +void InstructionCodeGeneratorARM64::GenerateFcmp(HInstruction* instruction) { + FPRegister lhs_reg = InputFPRegisterAt(instruction, 0); + Location rhs_loc = instruction->GetLocations()->InAt(1); + if (rhs_loc.IsConstant()) { + // 0.0 is the only immediate that can be encoded directly in + // an FCMP instruction. + // + // Both the JLS (section 15.20.1) and the JVMS (section 6.5) + // specify that in a floating-point comparison, positive zero + // and negative zero are considered equal, so we can use the + // literal 0.0 for both cases here. + // + // Note however that some methods (Float.equal, Float.compare, + // Float.compareTo, Double.equal, Double.compare, + // Double.compareTo, Math.max, Math.min, StrictMath.max, + // StrictMath.min) consider 0.0 to be (strictly) greater than + // -0.0. So if we ever translate calls to these methods into a + // HCompare instruction, we must handle the -0.0 case with + // care here. + DCHECK(IsFloatingPointZeroConstant(rhs_loc.GetConstant())); + __ Fcmp(lhs_reg, 0.0); + } else { + __ Fcmp(lhs_reg, InputFPRegisterAt(instruction, 1)); + } } void LocationsBuilderARM64::VisitCompare(HCompare* compare) { @@ -2430,14 +2456,7 @@ void InstructionCodeGeneratorARM64::VisitCompare(HCompare* compare) { case Primitive::kPrimFloat: case Primitive::kPrimDouble: { Register result = OutputRegister(compare); - FPRegister left = InputFPRegisterAt(compare, 0); - if (compare->GetLocations()->InAt(1).IsConstant()) { - DCHECK(IsFloatingPointZeroConstant(compare->GetLocations()->InAt(1).GetConstant())); - // 0.0 is the only immediate that can be encoded directly in an FCMP instruction. - __ Fcmp(left, 0.0); - } else { - __ Fcmp(left, InputFPRegisterAt(compare, 1)); - } + GenerateFcmp(compare); __ Cset(result, ne); __ Cneg(result, result, ARM64FPCondition(kCondLT, compare->IsGtBias())); break; @@ -2477,14 +2496,7 @@ void InstructionCodeGeneratorARM64::HandleCondition(HCondition* instruction) { IfCondition if_cond = instruction->GetCondition(); if (Primitive::IsFloatingPointType(instruction->InputAt(0)->GetType())) { - FPRegister lhs = InputFPRegisterAt(instruction, 0); - if (locations->InAt(1).IsConstant()) { - DCHECK(IsFloatingPointZeroConstant(locations->InAt(1).GetConstant())); - // 0.0 is the only immediate that can be encoded directly in an FCMP instruction. - __ Fcmp(lhs, 0.0); - } else { - __ Fcmp(lhs, InputFPRegisterAt(instruction, 1)); - } + GenerateFcmp(instruction); __ Cset(res, ARM64FPCondition(if_cond, instruction->IsGtBias())); } else { // Integer cases. @@ -2815,13 +2827,13 @@ void InstructionCodeGeneratorARM64::GenerateTestAndBranch(HInstruction* instruct // Nothing to do. The code always falls through. return; } else if (cond->IsIntConstant()) { - // Constant condition, statically compared against 1. - if (cond->AsIntConstant()->IsOne()) { + // Constant condition, statically compared against "true" (integer value 1). + if (cond->AsIntConstant()->IsTrue()) { if (true_target != nullptr) { __ B(true_target); } } else { - DCHECK(cond->AsIntConstant()->IsZero()); + DCHECK(cond->AsIntConstant()->IsFalse()) << cond->AsIntConstant()->GetValue(); if (false_target != nullptr) { __ B(false_target); } @@ -2853,14 +2865,7 @@ void InstructionCodeGeneratorARM64::GenerateTestAndBranch(HInstruction* instruct Primitive::Type type = condition->InputAt(0)->GetType(); if (Primitive::IsFloatingPointType(type)) { - FPRegister lhs = InputFPRegisterAt(condition, 0); - if (condition->GetLocations()->InAt(1).IsConstant()) { - DCHECK(IsFloatingPointZeroConstant(condition->GetLocations()->InAt(1).GetConstant())); - // 0.0 is the only immediate that can be encoded directly in an FCMP instruction. - __ Fcmp(lhs, 0.0); - } else { - __ Fcmp(lhs, InputFPRegisterAt(condition, 1)); - } + GenerateFcmp(condition); if (true_target == nullptr) { IfCondition opposite_condition = condition->GetOppositeCondition(); __ B(ARM64FPCondition(opposite_condition, condition->IsGtBias()), false_target); @@ -3044,13 +3049,7 @@ void InstructionCodeGeneratorARM64::VisitSelect(HSelect* select) { csel_cond = HasSwappedInputs(variant) ? eq : ne; } } else if (IsConditionOnFloatingPointValues(cond)) { - Location rhs = cond->GetLocations()->InAt(1); - if (rhs.IsConstant()) { - DCHECK(IsFloatingPointZeroConstant(rhs.GetConstant())); - __ Fcmp(InputFPRegisterAt(cond, 0), 0.0); - } else { - __ Fcmp(InputFPRegisterAt(cond, 0), InputFPRegisterAt(cond, 1)); - } + GenerateFcmp(cond); csel_cond = GetConditionForSelect(cond->AsCondition(), variant); } else { __ Cmp(InputRegisterAt(cond, 0), InputOperandAt(cond, 1)); diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index 10f1e7f008..0af825bccd 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -257,6 +257,9 @@ class InstructionCodeGeneratorARM64 : public InstructionCodeGenerator { vixl::Register obj, uint32_t offset); + // Generate a floating-point comparison. + void GenerateFcmp(HInstruction* instruction); + void HandleShift(HBinaryOperation* instr); void GenerateImplicitNullCheck(HNullCheck* instruction); void GenerateExplicitNullCheck(HNullCheck* instruction); diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index ba6c16e33e..4b2a461131 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -3264,13 +3264,13 @@ void InstructionCodeGeneratorMIPS::GenerateTestAndBranch(HInstruction* instructi // Nothing to do. The code always falls through. return; } else if (cond->IsIntConstant()) { - // Constant condition, statically compared against 1. - if (cond->AsIntConstant()->IsOne()) { + // Constant condition, statically compared against "true" (integer value 1). + if (cond->AsIntConstant()->IsTrue()) { if (true_target != nullptr) { __ B(true_target); } } else { - DCHECK(cond->AsIntConstant()->IsZero()); + DCHECK(cond->AsIntConstant()->IsFalse()) << cond->AsIntConstant()->GetValue(); if (false_target != nullptr) { __ B(false_target); } diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 90a0941594..9c8c4660f2 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -2588,13 +2588,13 @@ void InstructionCodeGeneratorMIPS64::GenerateTestAndBranch(HInstruction* instruc // Nothing to do. The code always falls through. return; } else if (cond->IsIntConstant()) { - // Constant condition, statically compared against 1. - if (cond->AsIntConstant()->IsOne()) { + // Constant condition, statically compared against "true" (integer value 1). + if (cond->AsIntConstant()->IsTrue()) { if (true_target != nullptr) { __ Bc(true_target); } } else { - DCHECK(cond->AsIntConstant()->IsZero()); + DCHECK(cond->AsIntConstant()->IsFalse()) << cond->AsIntConstant()->GetValue(); if (false_target != nullptr) { __ Bc(false_target); } diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 830e69de36..33a977b66e 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -1391,13 +1391,13 @@ void InstructionCodeGeneratorX86::GenerateTestAndBranch(HInstruction* instructio // Nothing to do. The code always falls through. return; } else if (cond->IsIntConstant()) { - // Constant condition, statically compared against 1. - if (cond->AsIntConstant()->IsOne()) { + // Constant condition, statically compared against "true" (integer value 1). + if (cond->AsIntConstant()->IsTrue()) { if (true_target != nullptr) { __ jmp(true_target); } } else { - DCHECK(cond->AsIntConstant()->IsZero()); + DCHECK(cond->AsIntConstant()->IsFalse()) << cond->AsIntConstant()->GetValue(); if (false_target != nullptr) { __ jmp(false_target); } diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index b1674d65ca..3d1fe7fdc6 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -1402,13 +1402,13 @@ void InstructionCodeGeneratorX86_64::GenerateTestAndBranch(HInstruction* instruc // Nothing to do. The code always falls through. return; } else if (cond->IsIntConstant()) { - // Constant condition, statically compared against 1. - if (cond->AsIntConstant()->IsOne()) { + // Constant condition, statically compared against "true" (integer value 1). + if (cond->AsIntConstant()->IsTrue()) { if (true_target != nullptr) { __ jmp(true_target); } } else { - DCHECK(cond->AsIntConstant()->IsZero()); + DCHECK(cond->AsIntConstant()->IsFalse()) << cond->AsIntConstant()->GetValue(); if (false_target != nullptr) { __ jmp(false_target); } diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc index 7ddabdee78..0614945ddc 100644 --- a/compiler/optimizing/constant_folding.cc +++ b/compiler/optimizing/constant_folding.cc @@ -120,7 +120,7 @@ void HConstantFoldingVisitor::VisitTypeConversion(HTypeConversion* inst) { void HConstantFoldingVisitor::VisitDivZeroCheck(HDivZeroCheck* inst) { // We can safely remove the check if the input is a non-null constant. HInstruction* check_input = inst->InputAt(0); - if (check_input->IsConstant() && !check_input->AsConstant()->IsZero()) { + if (check_input->IsConstant() && !check_input->AsConstant()->IsArithmeticZero()) { inst->ReplaceWith(check_input); inst->GetBlock()->RemoveInstruction(inst); } @@ -130,7 +130,7 @@ void HConstantFoldingVisitor::VisitDivZeroCheck(HDivZeroCheck* inst) { void InstructionWithAbsorbingInputSimplifier::VisitShift(HBinaryOperation* instruction) { DCHECK(instruction->IsShl() || instruction->IsShr() || instruction->IsUShr()); HInstruction* left = instruction->GetLeft(); - if (left->IsConstant() && left->AsConstant()->IsZero()) { + if (left->IsConstant() && left->AsConstant()->IsArithmeticZero()) { // Replace code looking like // SHL dst, 0, shift_amount // with @@ -142,7 +142,7 @@ void InstructionWithAbsorbingInputSimplifier::VisitShift(HBinaryOperation* instr void InstructionWithAbsorbingInputSimplifier::VisitAbove(HAbove* instruction) { if (instruction->GetLeft()->IsConstant() && - instruction->GetLeft()->AsConstant()->IsZero()) { + instruction->GetLeft()->AsConstant()->IsArithmeticZero()) { // Replace code looking like // ABOVE dst, 0, src // unsigned 0 > src is always false // with @@ -154,7 +154,7 @@ void InstructionWithAbsorbingInputSimplifier::VisitAbove(HAbove* instruction) { void InstructionWithAbsorbingInputSimplifier::VisitAboveOrEqual(HAboveOrEqual* instruction) { if (instruction->GetRight()->IsConstant() && - instruction->GetRight()->AsConstant()->IsZero()) { + instruction->GetRight()->AsConstant()->IsArithmeticZero()) { // Replace code looking like // ABOVE_OR_EQUAL dst, src, 0 // unsigned src >= 0 is always true // with @@ -166,7 +166,7 @@ void InstructionWithAbsorbingInputSimplifier::VisitAboveOrEqual(HAboveOrEqual* i void InstructionWithAbsorbingInputSimplifier::VisitBelow(HBelow* instruction) { if (instruction->GetRight()->IsConstant() && - instruction->GetRight()->AsConstant()->IsZero()) { + instruction->GetRight()->AsConstant()->IsArithmeticZero()) { // Replace code looking like // BELOW dst, src, 0 // unsigned src < 0 is always false // with @@ -178,7 +178,7 @@ void InstructionWithAbsorbingInputSimplifier::VisitBelow(HBelow* instruction) { void InstructionWithAbsorbingInputSimplifier::VisitBelowOrEqual(HBelowOrEqual* instruction) { if (instruction->GetLeft()->IsConstant() && - instruction->GetLeft()->AsConstant()->IsZero()) { + instruction->GetLeft()->AsConstant()->IsArithmeticZero()) { // Replace code looking like // BELOW_OR_EQUAL dst, 0, src // unsigned 0 <= src is always true // with @@ -190,7 +190,7 @@ void InstructionWithAbsorbingInputSimplifier::VisitBelowOrEqual(HBelowOrEqual* i void InstructionWithAbsorbingInputSimplifier::VisitAnd(HAnd* instruction) { HConstant* input_cst = instruction->GetConstantRight(); - if ((input_cst != nullptr) && input_cst->IsZero()) { + if ((input_cst != nullptr) && input_cst->IsZeroBitPattern()) { // Replace code looking like // AND dst, src, 0 // with @@ -224,7 +224,7 @@ void InstructionWithAbsorbingInputSimplifier::VisitMul(HMul* instruction) { HConstant* input_cst = instruction->GetConstantRight(); Primitive::Type type = instruction->GetType(); if (Primitive::IsIntOrLongType(type) && - (input_cst != nullptr) && input_cst->IsZero()) { + (input_cst != nullptr) && input_cst->IsArithmeticZero()) { // Replace code looking like // MUL dst, src, 0 // with @@ -264,7 +264,7 @@ void InstructionWithAbsorbingInputSimplifier::VisitRem(HRem* instruction) { HBasicBlock* block = instruction->GetBlock(); if (instruction->GetLeft()->IsConstant() && - instruction->GetLeft()->AsConstant()->IsZero()) { + instruction->GetLeft()->AsConstant()->IsArithmeticZero()) { // Replace code looking like // REM dst, 0, src // with diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc index e170e37bdd..5b41736e74 100644 --- a/compiler/optimizing/dead_code_elimination.cc +++ b/compiler/optimizing/dead_code_elimination.cc @@ -41,11 +41,11 @@ static void MarkReachableBlocks(HGraph* graph, ArenaBitVector* visited) { HIf* if_instruction = last_instruction->AsIf(); HInstruction* condition = if_instruction->InputAt(0); if (condition->IsIntConstant()) { - if (condition->AsIntConstant()->IsOne()) { + if (condition->AsIntConstant()->IsTrue()) { live_successors = live_successors.SubArray(0u, 1u); DCHECK_EQ(live_successors[0], if_instruction->IfTrueSuccessor()); } else { - DCHECK(condition->AsIntConstant()->IsZero()); + DCHECK(condition->AsIntConstant()->IsFalse()) << condition->AsIntConstant()->GetValue(); live_successors = live_successors.SubArray(1u, 1u); DCHECK_EQ(live_successors[0], if_instruction->IfFalseSuccessor()); } diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index d861e39c8b..a46478e7d6 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -912,8 +912,7 @@ bool HInliner::TryPatternSubstitution(HInvoke* invoke_instruction, bool needs_constructor_barrier = false; for (size_t i = 0; i != number_of_iputs; ++i) { HInstruction* value = GetInvokeInputForArgVRegIndex(invoke_instruction, iput_args[i]); - if (!value->IsConstant() || - (!value->AsConstant()->IsZero() && !value->IsNullConstant())) { + if (!value->IsConstant() || !value->AsConstant()->IsZeroBitPattern()) { if (dex_cache.GetReference() == nullptr) { dex_cache = handles_->NewHandle(resolved_method->GetDexCache()); } diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index 9cfc16f596..05ee10981f 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -608,12 +608,12 @@ void InstructionSimplifierVisitor::VisitEqual(HEqual* equal) { HBasicBlock* block = equal->GetBlock(); // We are comparing the boolean to a constant which is of type int and can // be any constant. - if (input_const->AsIntConstant()->IsOne()) { + if (input_const->AsIntConstant()->IsTrue()) { // Replace (bool_value == true) with bool_value equal->ReplaceWith(input_value); block->RemoveInstruction(equal); RecordSimplification(); - } else if (input_const->AsIntConstant()->IsZero()) { + } else if (input_const->AsIntConstant()->IsFalse()) { equal->ReplaceWith(GetGraph()->InsertOppositeCondition(input_value, equal)); block->RemoveInstruction(equal); RecordSimplification(); @@ -639,11 +639,11 @@ void InstructionSimplifierVisitor::VisitNotEqual(HNotEqual* not_equal) { HBasicBlock* block = not_equal->GetBlock(); // We are comparing the boolean to a constant which is of type int and can // be any constant. - if (input_const->AsIntConstant()->IsOne()) { + if (input_const->AsIntConstant()->IsTrue()) { not_equal->ReplaceWith(GetGraph()->InsertOppositeCondition(input_value, not_equal)); block->RemoveInstruction(not_equal); RecordSimplification(); - } else if (input_const->AsIntConstant()->IsZero()) { + } else if (input_const->AsIntConstant()->IsFalse()) { // Replace (bool_value != false) with bool_value not_equal->ReplaceWith(input_value); block->RemoveInstruction(not_equal); @@ -668,10 +668,10 @@ void InstructionSimplifierVisitor::VisitBooleanNot(HBooleanNot* bool_not) { if (input->IsIntConstant()) { // Replace !(true/false) with false/true. - if (input->AsIntConstant()->IsOne()) { + if (input->AsIntConstant()->IsTrue()) { replace_with = GetGraph()->GetIntConstant(0); } else { - DCHECK(input->AsIntConstant()->IsZero()); + DCHECK(input->AsIntConstant()->IsFalse()) << input->AsIntConstant()->GetValue(); replace_with = GetGraph()->GetIntConstant(1); } } else if (input->IsBooleanNot()) { @@ -712,19 +712,19 @@ void InstructionSimplifierVisitor::VisitSelect(HSelect* select) { // Replace (cond ? x : x) with (x). replace_with = true_value; } else if (condition->IsIntConstant()) { - if (condition->AsIntConstant()->IsOne()) { + if (condition->AsIntConstant()->IsTrue()) { // Replace (true ? x : y) with (x). replace_with = true_value; } else { // Replace (false ? x : y) with (y). - DCHECK(condition->AsIntConstant()->IsZero()); + DCHECK(condition->AsIntConstant()->IsFalse()) << condition->AsIntConstant()->GetValue(); replace_with = false_value; } } else if (true_value->IsIntConstant() && false_value->IsIntConstant()) { - if (true_value->AsIntConstant()->IsOne() && false_value->AsIntConstant()->IsZero()) { + if (true_value->AsIntConstant()->IsTrue() && false_value->AsIntConstant()->IsFalse()) { // Replace (cond ? true : false) with (cond). replace_with = condition; - } else if (true_value->AsIntConstant()->IsZero() && false_value->AsIntConstant()->IsOne()) { + } else if (true_value->AsIntConstant()->IsFalse() && false_value->AsIntConstant()->IsTrue()) { // Replace (cond ? false : true) with (!cond). replace_with = GetGraph()->InsertOppositeCondition(condition, select); } @@ -904,7 +904,7 @@ void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruct void InstructionSimplifierVisitor::VisitAdd(HAdd* instruction) { HConstant* input_cst = instruction->GetConstantRight(); HInstruction* input_other = instruction->GetLeastConstantLeft(); - if ((input_cst != nullptr) && input_cst->IsZero()) { + if ((input_cst != nullptr) && input_cst->IsArithmeticZero()) { // Replace code looking like // ADD dst, src, 0 // with @@ -1335,7 +1335,7 @@ void InstructionSimplifierVisitor::VisitOr(HOr* instruction) { HConstant* input_cst = instruction->GetConstantRight(); HInstruction* input_other = instruction->GetLeastConstantLeft(); - if ((input_cst != nullptr) && input_cst->IsZero()) { + if ((input_cst != nullptr) && input_cst->IsZeroBitPattern()) { // Replace code looking like // OR dst, src, 0 // with @@ -1380,7 +1380,7 @@ void InstructionSimplifierVisitor::VisitSub(HSub* instruction) { return; } - if ((input_cst != nullptr) && input_cst->IsZero()) { + if ((input_cst != nullptr) && input_cst->IsArithmeticZero()) { // Replace code looking like // SUB dst, src, 0 // with @@ -1461,7 +1461,7 @@ void InstructionSimplifierVisitor::VisitXor(HXor* instruction) { HConstant* input_cst = instruction->GetConstantRight(); HInstruction* input_other = instruction->GetLeastConstantLeft(); - if ((input_cst != nullptr) && input_cst->IsZero()) { + if ((input_cst != nullptr) && input_cst->IsZeroBitPattern()) { // Replace code looking like // XOR dst, src, 0 // with @@ -1731,7 +1731,7 @@ void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) { void InstructionSimplifierVisitor::VisitDeoptimize(HDeoptimize* deoptimize) { HInstruction* cond = deoptimize->InputAt(0); if (cond->IsConstant()) { - if (cond->AsIntConstant()->IsZero()) { + if (cond->AsIntConstant()->IsFalse()) { // Never deopt: instruction can be removed. deoptimize->GetBlock()->RemoveInstruction(deoptimize); } else { diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 98766a31a6..6a8c813ea6 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -2402,10 +2402,10 @@ HInstruction* HGraph::InsertOppositeCondition(HInstruction* cond, HInstruction* return replacement; } else if (cond->IsIntConstant()) { HIntConstant* int_const = cond->AsIntConstant(); - if (int_const->IsZero()) { + if (int_const->IsFalse()) { return GetIntConstant(1); } else { - DCHECK(int_const->IsOne()); + DCHECK(int_const->IsTrue()) << int_const->GetValue(); return GetIntConstant(0); } } else { diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 3733850745..88d39d16e5 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -2427,8 +2427,13 @@ class HConstant : public HExpression<0> { bool CanBeMoved() const OVERRIDE { return true; } + // Is this constant -1 in the arithmetic sense? virtual bool IsMinusOne() const { return false; } - virtual bool IsZero() const { return false; } + // Is this constant 0 in the arithmetic sense? + virtual bool IsArithmeticZero() const { return false; } + // Is this constant a 0-bit pattern? + virtual bool IsZeroBitPattern() const { return false; } + // Is this constant 1 in the arithmetic sense? virtual bool IsOne() const { return false; } virtual uint64_t GetValueAsUint64() const = 0; @@ -2449,6 +2454,9 @@ class HNullConstant : public HConstant { size_t ComputeHashCode() const OVERRIDE { return 0; } + // The null constant representation is a 0-bit pattern. + virtual bool IsZeroBitPattern() const { return true; } + DECLARE_INSTRUCTION(NullConstant); private: @@ -2476,9 +2484,15 @@ class HIntConstant : public HConstant { size_t ComputeHashCode() const OVERRIDE { return GetValue(); } bool IsMinusOne() const OVERRIDE { return GetValue() == -1; } - bool IsZero() const OVERRIDE { return GetValue() == 0; } + bool IsArithmeticZero() const OVERRIDE { return GetValue() == 0; } + bool IsZeroBitPattern() const OVERRIDE { return GetValue() == 0; } bool IsOne() const OVERRIDE { return GetValue() == 1; } + // Integer constants are used to encode Boolean values as well, + // where 1 means true and 0 means false. + bool IsTrue() const { return GetValue() == 1; } + bool IsFalse() const { return GetValue() == 0; } + DECLARE_INSTRUCTION(IntConstant); private: @@ -2509,7 +2523,8 @@ class HLongConstant : public HConstant { size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); } bool IsMinusOne() const OVERRIDE { return GetValue() == -1; } - bool IsZero() const OVERRIDE { return GetValue() == 0; } + bool IsArithmeticZero() const OVERRIDE { return GetValue() == 0; } + bool IsZeroBitPattern() const OVERRIDE { return GetValue() == 0; } bool IsOne() const OVERRIDE { return GetValue() == 1; } DECLARE_INSTRUCTION(LongConstant); @@ -2542,7 +2557,16 @@ class HFloatConstant : public HConstant { bool IsMinusOne() const OVERRIDE { return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>((-1.0f)); } - bool IsZero() const OVERRIDE { + bool IsArithmeticZero() const OVERRIDE { + return std::fpclassify(value_) == FP_ZERO; + } + bool IsArithmeticPositiveZero() const { + return IsArithmeticZero() && !std::signbit(value_); + } + bool IsArithmeticNegativeZero() const { + return IsArithmeticZero() && std::signbit(value_); + } + bool IsZeroBitPattern() const OVERRIDE { return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>(0.0f); } bool IsOne() const OVERRIDE { @@ -2584,7 +2608,16 @@ class HDoubleConstant : public HConstant { bool IsMinusOne() const OVERRIDE { return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((-1.0)); } - bool IsZero() const OVERRIDE { + bool IsArithmeticZero() const OVERRIDE { + return std::fpclassify(value_) == FP_ZERO; + } + bool IsArithmeticPositiveZero() const { + return IsArithmeticZero() && !std::signbit(value_); + } + bool IsArithmeticNegativeZero() const { + return IsArithmeticZero() && std::signbit(value_); + } + bool IsZeroBitPattern() const OVERRIDE { return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((0.0)); } bool IsOne() const OVERRIDE { diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index 75356c848b..95f10e0720 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -291,12 +291,12 @@ static bool MatchIfInstanceOf(HIf* ifInstruction, if (rhs != nullptr) { HInstruction* lhs = input->AsEqual()->GetLeastConstantLeft(); if (lhs->IsInstanceOf() && rhs->IsIntConstant()) { - if (rhs->AsIntConstant()->IsOne()) { + if (rhs->AsIntConstant()->IsTrue()) { // Case (1a) *trueBranch = ifInstruction->IfTrueSuccessor(); } else { // Case (2a) - DCHECK(rhs->AsIntConstant()->IsZero()); + DCHECK(rhs->AsIntConstant()->IsFalse()) << rhs->AsIntConstant()->GetValue(); *trueBranch = ifInstruction->IfFalseSuccessor(); } *instanceOf = lhs->AsInstanceOf(); @@ -308,12 +308,12 @@ static bool MatchIfInstanceOf(HIf* ifInstruction, if (rhs != nullptr) { HInstruction* lhs = input->AsNotEqual()->GetLeastConstantLeft(); if (lhs->IsInstanceOf() && rhs->IsIntConstant()) { - if (rhs->AsIntConstant()->IsZero()) { + if (rhs->AsIntConstant()->IsFalse()) { // Case (1b) *trueBranch = ifInstruction->IfTrueSuccessor(); } else { // Case (2b) - DCHECK(rhs->AsIntConstant()->IsOne()); + DCHECK(rhs->AsIntConstant()->IsTrue()) << rhs->AsIntConstant()->GetValue(); *trueBranch = ifInstruction->IfFalseSuccessor(); } *instanceOf = lhs->AsInstanceOf(); |