summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_simplifier.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r--compiler/optimizing/instruction_simplifier.cc52
1 files changed, 21 insertions, 31 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index cf1cbd578c..f739d7b4f6 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -251,7 +251,8 @@ bool InstructionSimplifierVisitor::TryCombineVecMultiplyAccumulate(HVecMul* mul)
InstructionSet isa = codegen_->GetInstructionSet();
switch (isa) {
case kArm64:
- if (!(type == DataType::Type::kInt8 ||
+ if (!(type == DataType::Type::kUint8 ||
+ type == DataType::Type::kInt8 ||
type == DataType::Type::kUint16 ||
type == DataType::Type::kInt16 ||
type == DataType::Type::kInt32)) {
@@ -260,7 +261,8 @@ bool InstructionSimplifierVisitor::TryCombineVecMultiplyAccumulate(HVecMul* mul)
break;
case kMips:
case kMips64:
- if (!(type == DataType::Type::kInt8 ||
+ if (!(type == DataType::Type::kUint8 ||
+ type == DataType::Type::kInt8 ||
type == DataType::Type::kUint16 ||
type == DataType::Type::kInt16 ||
type == DataType::Type::kInt32 ||
@@ -876,10 +878,11 @@ static bool AreLowerPrecisionArgs(DataType::Type to_type, HInstruction* a, HInst
}
DataType::Type type1 = a->GetType();
DataType::Type type2 = b->GetType();
- return (type1 == DataType::Type::kInt8 && type2 == DataType::Type::kInt8) ||
- (type1 == DataType::Type::kInt16 && type2 == DataType::Type::kInt16) ||
- (type1 == DataType::Type::kUint16 && type2 == DataType::Type::kUint16) ||
- (type1 == DataType::Type::kInt32 && type2 == DataType::Type::kInt32 &&
+ return (type1 == DataType::Type::kUint8 && type2 == DataType::Type::kUint8) ||
+ (type1 == DataType::Type::kInt8 && type2 == DataType::Type::kInt8) ||
+ (type1 == DataType::Type::kInt16 && type2 == DataType::Type::kInt16) ||
+ (type1 == DataType::Type::kUint16 && type2 == DataType::Type::kUint16) ||
+ (type1 == DataType::Type::kInt32 && type2 == DataType::Type::kInt32 &&
to_type == DataType::Type::kInt64);
}
@@ -1036,30 +1039,13 @@ void InstructionSimplifierVisitor::VisitArraySet(HArraySet* instruction) {
}
}
-static bool IsTypeConversionImplicit(DataType::Type input_type, DataType::Type result_type) {
- // Invariant: We should never generate a conversion to a Boolean value.
- DCHECK_NE(DataType::Type::kBool, result_type);
-
- // Besides conversion to the same type, widening integral conversions are implicit,
- // excluding conversions to long and the byte->char conversion where we need to
- // clear the high 16 bits of the 32-bit sign-extended representation of byte.
- return result_type == input_type ||
- (result_type == DataType::Type::kInt32 && (input_type == DataType::Type::kBool ||
- input_type == DataType::Type::kInt8 ||
- input_type == DataType::Type::kInt16 ||
- input_type == DataType::Type::kUint16)) ||
- (result_type == DataType::Type::kUint16 && input_type == DataType::Type::kBool) ||
- (result_type == DataType::Type::kInt16 && (input_type == DataType::Type::kBool ||
- input_type == DataType::Type::kInt8)) ||
- (result_type == DataType::Type::kInt8 && input_type == DataType::Type::kBool);
-}
-
static bool IsTypeConversionLossless(DataType::Type input_type, DataType::Type result_type) {
// The conversion to a larger type is loss-less with the exception of two cases,
- // - conversion to Uint16, the only unsigned type, where we may lose some bits, and
+ // - conversion to the unsigned type Uint16, where we may lose some bits, and
// - conversion from float to long, the only FP to integral conversion with smaller FP type.
// For integral to FP conversions this holds because the FP mantissa is large enough.
- DCHECK_NE(input_type, result_type);
+ // Note: The size check excludes Uint8 as the result type.
+ DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type));
return DataType::Size(result_type) > DataType::Size(input_type) &&
result_type != DataType::Type::kUint16 &&
!(result_type == DataType::Type::kInt64 && input_type == DataType::Type::kFloat32);
@@ -1069,7 +1055,7 @@ void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruct
HInstruction* input = instruction->GetInput();
DataType::Type input_type = input->GetType();
DataType::Type result_type = instruction->GetResultType();
- if (IsTypeConversionImplicit(input_type, result_type)) {
+ if (DataType::IsTypeConversionImplicit(input_type, result_type)) {
// Remove the implicit conversion; this includes conversion to the same type.
instruction->ReplaceWith(input);
instruction->GetBlock()->RemoveInstruction(instruction);
@@ -1098,7 +1084,7 @@ void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruct
if (is_first_conversion_lossless || integral_conversions_with_non_widening_second) {
// If the merged conversion is implicit, do the simplification unconditionally.
- if (IsTypeConversionImplicit(original_type, result_type)) {
+ if (DataType::IsTypeConversionImplicit(original_type, result_type)) {
instruction->ReplaceWith(original_input);
instruction->GetBlock()->RemoveInstruction(instruction);
if (!input_conversion->HasUses()) {
@@ -1127,7 +1113,7 @@ void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruct
if (trailing_ones >= kBitsPerByte * DataType::Size(result_type)) {
// The `HAnd` is useless, for example in `(byte) (x & 0xff)`, get rid of it.
HInstruction* original_input = input_and->GetLeastConstantLeft();
- if (IsTypeConversionImplicit(original_input->GetType(), result_type)) {
+ if (DataType::IsTypeConversionImplicit(original_input->GetType(), result_type)) {
instruction->ReplaceWith(original_input);
instruction->GetBlock()->RemoveInstruction(instruction);
RecordSimplification();
@@ -2167,8 +2153,12 @@ void InstructionSimplifierVisitor::SimplifyStringCharAt(HInvoke* invoke) {
HBoundsCheck* bounds_check = new (arena) HBoundsCheck(
index, length, dex_pc, invoke->GetDexMethodIndex());
invoke->GetBlock()->InsertInstructionBefore(bounds_check, invoke);
- HArrayGet* array_get = new (arena) HArrayGet(
- str, bounds_check, DataType::Type::kUint16, dex_pc, /* is_string_char_at */ true);
+ HArrayGet* array_get = new (arena) HArrayGet(str,
+ bounds_check,
+ DataType::Type::kUint16,
+ SideEffects::None(), // Strings are immutable.
+ dex_pc,
+ /* is_string_char_at */ true);
invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, array_get);
bounds_check->CopyEnvironmentFrom(invoke->GetEnvironment());
GetGraph()->SetHasBoundsChecks(true);