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.cc199
1 files changed, 22 insertions, 177 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 84297ec557..8e0b4145e3 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -108,22 +108,15 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
bool CanEnsureNotNullAt(HInstruction* instr, HInstruction* at) const;
- void SimplifyRotate(HInvoke* invoke, bool is_left, DataType::Type type);
void SimplifySystemArrayCopy(HInvoke* invoke);
void SimplifyStringEquals(HInvoke* invoke);
- void SimplifyCompare(HInvoke* invoke, bool is_signum, DataType::Type type);
- void SimplifyIsNaN(HInvoke* invoke);
void SimplifyFP2Int(HInvoke* invoke);
void SimplifyStringCharAt(HInvoke* invoke);
- void SimplifyStringIsEmptyOrLength(HInvoke* invoke);
+ void SimplifyStringLength(HInvoke* invoke);
void SimplifyStringIndexOf(HInvoke* invoke);
void SimplifyNPEOnArgN(HInvoke* invoke, size_t);
void SimplifyReturnThis(HInvoke* invoke);
void SimplifyAllocationIntrinsic(HInvoke* invoke);
- void SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind);
- void SimplifyMin(HInvoke* invoke, DataType::Type type);
- void SimplifyMax(HInvoke* invoke, DataType::Type type);
- void SimplifyAbs(HInvoke* invoke, DataType::Type type);
CodeGenerator* codegen_;
OptimizingCompilerStats* stats_;
@@ -2127,34 +2120,6 @@ void InstructionSimplifierVisitor::SimplifyStringEquals(HInvoke* instruction) {
}
}
-void InstructionSimplifierVisitor::SimplifyRotate(HInvoke* invoke,
- bool is_left,
- DataType::Type type) {
- DCHECK(invoke->IsInvokeStaticOrDirect());
- DCHECK_EQ(invoke->GetInvokeType(), InvokeType::kStatic);
- HInstruction* value = invoke->InputAt(0);
- HInstruction* distance = invoke->InputAt(1);
- // Replace the invoke with an HRor.
- if (is_left) {
- // Unconditionally set the type of the negated distance to `int`,
- // as shift and rotate operations expect a 32-bit (or narrower)
- // value for their distance input.
- distance = new (GetGraph()->GetAllocator()) HNeg(DataType::Type::kInt32, distance);
- invoke->GetBlock()->InsertInstructionBefore(distance, invoke);
- }
- HRor* ror = new (GetGraph()->GetAllocator()) HRor(type, value, distance);
- invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, ror);
- // Remove ClinitCheck and LoadClass, if possible.
- HInstruction* clinit = invoke->GetInputs().back();
- if (clinit->IsClinitCheck() && !clinit->HasUses()) {
- clinit->GetBlock()->RemoveInstruction(clinit);
- HInstruction* ldclass = clinit->InputAt(0);
- if (ldclass->IsLoadClass() && !ldclass->HasUses()) {
- ldclass->GetBlock()->RemoveInstruction(ldclass);
- }
- }
-}
-
static bool IsArrayLengthOf(HInstruction* potential_length, HInstruction* potential_array) {
if (potential_length->IsArrayLength()) {
return potential_length->InputAt(0) == potential_array;
@@ -2272,35 +2237,6 @@ void InstructionSimplifierVisitor::SimplifySystemArrayCopy(HInvoke* instruction)
}
}
-void InstructionSimplifierVisitor::SimplifyCompare(HInvoke* invoke,
- bool is_signum,
- DataType::Type type) {
- DCHECK(invoke->IsInvokeStaticOrDirect());
- uint32_t dex_pc = invoke->GetDexPc();
- HInstruction* left = invoke->InputAt(0);
- HInstruction* right;
- if (!is_signum) {
- right = invoke->InputAt(1);
- } else if (type == DataType::Type::kInt64) {
- right = GetGraph()->GetLongConstant(0);
- } else {
- right = GetGraph()->GetIntConstant(0);
- }
- HCompare* compare = new (GetGraph()->GetAllocator())
- HCompare(type, left, right, ComparisonBias::kNoBias, dex_pc);
- invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, compare);
-}
-
-void InstructionSimplifierVisitor::SimplifyIsNaN(HInvoke* invoke) {
- DCHECK(invoke->IsInvokeStaticOrDirect());
- uint32_t dex_pc = invoke->GetDexPc();
- // IsNaN(x) is the same as x != x.
- HInstruction* x = invoke->InputAt(0);
- HCondition* condition = new (GetGraph()->GetAllocator()) HNotEqual(x, x, dex_pc);
- condition->SetBias(ComparisonBias::kLtBias);
- invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, condition);
-}
-
void InstructionSimplifierVisitor::SimplifyFP2Int(HInvoke* invoke) {
DCHECK(invoke->IsInvokeStaticOrDirect());
uint32_t dex_pc = invoke->GetDexPc();
@@ -2355,25 +2291,14 @@ void InstructionSimplifierVisitor::SimplifyStringCharAt(HInvoke* invoke) {
GetGraph()->SetHasBoundsChecks(true);
}
-void InstructionSimplifierVisitor::SimplifyStringIsEmptyOrLength(HInvoke* invoke) {
+void InstructionSimplifierVisitor::SimplifyStringLength(HInvoke* invoke) {
HInstruction* str = invoke->InputAt(0);
uint32_t dex_pc = invoke->GetDexPc();
// We treat String as an array to allow DCE and BCE to seamlessly work on strings,
// so create the HArrayLength.
HArrayLength* length =
new (GetGraph()->GetAllocator()) HArrayLength(str, dex_pc, /* is_string_length= */ true);
- HInstruction* replacement;
- if (invoke->GetIntrinsic() == Intrinsics::kStringIsEmpty) {
- // For String.isEmpty(), create the `HEqual` representing the `length == 0`.
- invoke->GetBlock()->InsertInstructionBefore(length, invoke);
- HIntConstant* zero = GetGraph()->GetIntConstant(0);
- HEqual* equal = new (GetGraph()->GetAllocator()) HEqual(length, zero, dex_pc);
- replacement = equal;
- } else {
- DCHECK_EQ(invoke->GetIntrinsic(), Intrinsics::kStringLength);
- replacement = length;
- }
- invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, replacement);
+ invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, length);
}
void InstructionSimplifierVisitor::SimplifyStringIndexOf(HInvoke* invoke) {
@@ -2663,35 +2588,6 @@ void InstructionSimplifierVisitor::SimplifyAllocationIntrinsic(HInvoke* invoke)
}
}
-void InstructionSimplifierVisitor::SimplifyMemBarrier(HInvoke* invoke,
- MemBarrierKind barrier_kind) {
- uint32_t dex_pc = invoke->GetDexPc();
- HMemoryBarrier* mem_barrier =
- new (GetGraph()->GetAllocator()) HMemoryBarrier(barrier_kind, dex_pc);
- invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, mem_barrier);
-}
-
-void InstructionSimplifierVisitor::SimplifyMin(HInvoke* invoke, DataType::Type type) {
- DCHECK(invoke->IsInvokeStaticOrDirect());
- HMin* min = new (GetGraph()->GetAllocator())
- HMin(type, invoke->InputAt(0), invoke->InputAt(1), invoke->GetDexPc());
- invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, min);
-}
-
-void InstructionSimplifierVisitor::SimplifyMax(HInvoke* invoke, DataType::Type type) {
- DCHECK(invoke->IsInvokeStaticOrDirect());
- HMax* max = new (GetGraph()->GetAllocator())
- HMax(type, invoke->InputAt(0), invoke->InputAt(1), invoke->GetDexPc());
- invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, max);
-}
-
-void InstructionSimplifierVisitor::SimplifyAbs(HInvoke* invoke, DataType::Type type) {
- DCHECK(invoke->IsInvokeStaticOrDirect());
- HAbs* abs = new (GetGraph()->GetAllocator())
- HAbs(type, invoke->InputAt(0), invoke->GetDexPc());
- invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, abs);
-}
-
void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
switch (instruction->GetIntrinsic()) {
case Intrinsics::kStringEquals:
@@ -2700,44 +2596,19 @@ void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
case Intrinsics::kSystemArrayCopy:
SimplifySystemArrayCopy(instruction);
break;
- case Intrinsics::kIntegerRotateRight:
- SimplifyRotate(instruction, /* is_left= */ false, DataType::Type::kInt32);
- break;
- case Intrinsics::kLongRotateRight:
- SimplifyRotate(instruction, /* is_left= */ false, DataType::Type::kInt64);
- break;
- case Intrinsics::kIntegerRotateLeft:
- SimplifyRotate(instruction, /* is_left= */ true, DataType::Type::kInt32);
- break;
- case Intrinsics::kLongRotateLeft:
- SimplifyRotate(instruction, /* is_left= */ true, DataType::Type::kInt64);
- break;
- case Intrinsics::kIntegerCompare:
- SimplifyCompare(instruction, /* is_signum= */ false, DataType::Type::kInt32);
- break;
- case Intrinsics::kLongCompare:
- SimplifyCompare(instruction, /* is_signum= */ false, DataType::Type::kInt64);
- break;
- case Intrinsics::kIntegerSignum:
- SimplifyCompare(instruction, /* is_signum= */ true, DataType::Type::kInt32);
- break;
- case Intrinsics::kLongSignum:
- SimplifyCompare(instruction, /* is_signum= */ true, DataType::Type::kInt64);
- break;
- case Intrinsics::kFloatIsNaN:
- case Intrinsics::kDoubleIsNaN:
- SimplifyIsNaN(instruction);
- break;
case Intrinsics::kFloatFloatToIntBits:
case Intrinsics::kDoubleDoubleToLongBits:
SimplifyFP2Int(instruction);
break;
case Intrinsics::kStringCharAt:
+ // Instruction builder creates intermediate representation directly
+ // but the inliner can sharpen CharSequence.charAt() to String.charAt().
SimplifyStringCharAt(instruction);
break;
- case Intrinsics::kStringIsEmpty:
case Intrinsics::kStringLength:
- SimplifyStringIsEmptyOrLength(instruction);
+ // Instruction builder creates intermediate representation directly
+ // but the inliner can sharpen CharSequence.length() to String.length().
+ SimplifyStringLength(instruction);
break;
case Intrinsics::kStringIndexOf:
case Intrinsics::kStringIndexOfAfter:
@@ -2764,66 +2635,40 @@ void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
case Intrinsics::kStringBuilderToString:
SimplifyAllocationIntrinsic(instruction);
break;
+ case Intrinsics::kIntegerRotateRight:
+ case Intrinsics::kLongRotateRight:
+ case Intrinsics::kIntegerRotateLeft:
+ case Intrinsics::kLongRotateLeft:
+ case Intrinsics::kIntegerCompare:
+ case Intrinsics::kLongCompare:
+ case Intrinsics::kIntegerSignum:
+ case Intrinsics::kLongSignum:
+ case Intrinsics::kFloatIsNaN:
+ case Intrinsics::kDoubleIsNaN:
+ case Intrinsics::kStringIsEmpty:
case Intrinsics::kUnsafeLoadFence:
- SimplifyMemBarrier(instruction, MemBarrierKind::kLoadAny);
- break;
case Intrinsics::kUnsafeStoreFence:
- SimplifyMemBarrier(instruction, MemBarrierKind::kAnyStore);
- break;
case Intrinsics::kUnsafeFullFence:
- SimplifyMemBarrier(instruction, MemBarrierKind::kAnyAny);
- break;
case Intrinsics::kVarHandleFullFence:
- SimplifyMemBarrier(instruction, MemBarrierKind::kAnyAny);
- break;
case Intrinsics::kVarHandleAcquireFence:
- SimplifyMemBarrier(instruction, MemBarrierKind::kLoadAny);
- break;
case Intrinsics::kVarHandleReleaseFence:
- SimplifyMemBarrier(instruction, MemBarrierKind::kAnyStore);
- break;
case Intrinsics::kVarHandleLoadLoadFence:
- SimplifyMemBarrier(instruction, MemBarrierKind::kLoadAny);
- break;
case Intrinsics::kVarHandleStoreStoreFence:
- SimplifyMemBarrier(instruction, MemBarrierKind::kStoreStore);
- break;
case Intrinsics::kMathMinIntInt:
- SimplifyMin(instruction, DataType::Type::kInt32);
- break;
case Intrinsics::kMathMinLongLong:
- SimplifyMin(instruction, DataType::Type::kInt64);
- break;
case Intrinsics::kMathMinFloatFloat:
- SimplifyMin(instruction, DataType::Type::kFloat32);
- break;
case Intrinsics::kMathMinDoubleDouble:
- SimplifyMin(instruction, DataType::Type::kFloat64);
- break;
case Intrinsics::kMathMaxIntInt:
- SimplifyMax(instruction, DataType::Type::kInt32);
- break;
case Intrinsics::kMathMaxLongLong:
- SimplifyMax(instruction, DataType::Type::kInt64);
- break;
case Intrinsics::kMathMaxFloatFloat:
- SimplifyMax(instruction, DataType::Type::kFloat32);
- break;
case Intrinsics::kMathMaxDoubleDouble:
- SimplifyMax(instruction, DataType::Type::kFloat64);
- break;
case Intrinsics::kMathAbsInt:
- SimplifyAbs(instruction, DataType::Type::kInt32);
- break;
case Intrinsics::kMathAbsLong:
- SimplifyAbs(instruction, DataType::Type::kInt64);
- break;
case Intrinsics::kMathAbsFloat:
- SimplifyAbs(instruction, DataType::Type::kFloat32);
- break;
case Intrinsics::kMathAbsDouble:
- SimplifyAbs(instruction, DataType::Type::kFloat64);
- break;
+ // These are replaced by intermediate representation in the instruction builder.
+ LOG(FATAL) << "Unexpected " << static_cast<Intrinsics>(instruction->GetIntrinsic());
+ UNREACHABLE();
default:
break;
}