Remove type conversion nodes converting to the same type.

When optimizing, we ensure these conversions do not reach the
code generators. When not optimizing, we cannot get such situations.

Change-Id: I717247c957667675dc261183019c88efa3a38452
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index dc86114..5b2be2e 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -1363,6 +1363,7 @@
       new (GetGraph()->GetArena()) LocationSummary(conversion, LocationSummary::kNoCall);
   Primitive::Type result_type = conversion->GetResultType();
   Primitive::Type input_type = conversion->GetInputType();
+  DCHECK_NE(result_type, input_type);
   switch (result_type) {
     case Primitive::kPrimByte:
       switch (input_type) {
@@ -1444,7 +1445,6 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
-        case Primitive::kPrimChar:
           // Processing a Dex `int-to-char' instruction.
           locations->SetInAt(0, Location::RequiresRegister());
           locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
@@ -1531,6 +1531,7 @@
   Location in = locations->InAt(0);
   Primitive::Type result_type = conversion->GetResultType();
   Primitive::Type input_type = conversion->GetInputType();
+  DCHECK_NE(result_type, input_type);
   switch (result_type) {
     case Primitive::kPrimByte:
       switch (input_type) {
@@ -1624,7 +1625,6 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
-        case Primitive::kPrimChar:
           // Processing a Dex `int-to-char' instruction.
           __ ubfx(out.AsRegister<Register>(), in.AsRegister<Register>(), 0, 16);
           break;
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 943f71f..a61ef2d 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -2129,6 +2129,7 @@
       new (GetGraph()->GetArena()) LocationSummary(conversion, LocationSummary::kNoCall);
   Primitive::Type input_type = conversion->GetInputType();
   Primitive::Type result_type = conversion->GetResultType();
+  DCHECK_NE(input_type, result_type);
   if ((input_type == Primitive::kPrimNot) || (input_type == Primitive::kPrimVoid) ||
       (result_type == Primitive::kPrimNot) || (result_type == Primitive::kPrimVoid)) {
     LOG(FATAL) << "Unexpected type conversion from " << input_type << " to " << result_type;
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index b21abad..fd794f9 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -1330,6 +1330,7 @@
       new (GetGraph()->GetArena()) LocationSummary(conversion, LocationSummary::kNoCall);
   Primitive::Type result_type = conversion->GetResultType();
   Primitive::Type input_type = conversion->GetInputType();
+  DCHECK_NE(result_type, input_type);
   switch (result_type) {
     case Primitive::kPrimByte:
       switch (input_type) {
@@ -1411,7 +1412,6 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
-        case Primitive::kPrimChar:
           // Processing a Dex `int-to-char' instruction.
           locations->SetInAt(0, Location::Any());
           locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
@@ -1495,6 +1495,7 @@
   Location in = locations->InAt(0);
   Primitive::Type result_type = conversion->GetResultType();
   Primitive::Type input_type = conversion->GetInputType();
+  DCHECK_NE(result_type, input_type);
   switch (result_type) {
     case Primitive::kPrimByte:
       switch (input_type) {
@@ -1600,7 +1601,6 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
-        case Primitive::kPrimChar:
           // Processing a Dex `Process a Dex `int-to-char'' instruction.
           if (in.IsRegister()) {
             __ movzxw(out.AsRegister<Register>(), in.AsRegister<Register>());
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 5d3e809..4d70efc 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1320,6 +1320,7 @@
       new (GetGraph()->GetArena()) LocationSummary(conversion, LocationSummary::kNoCall);
   Primitive::Type result_type = conversion->GetResultType();
   Primitive::Type input_type = conversion->GetInputType();
+  DCHECK_NE(result_type, input_type);
   switch (result_type) {
     case Primitive::kPrimByte:
       switch (input_type) {
@@ -1403,7 +1404,6 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
-        case Primitive::kPrimChar:
           // Processing a Dex `int-to-char' instruction.
           locations->SetInAt(0, Location::Any());
           locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
@@ -1483,6 +1483,7 @@
   Location in = locations->InAt(0);
   Primitive::Type result_type = conversion->GetResultType();
   Primitive::Type input_type = conversion->GetInputType();
+  DCHECK_NE(result_type, input_type);
   switch (result_type) {
     case Primitive::kPrimByte:
       switch (input_type) {
@@ -1590,7 +1591,6 @@
         case Primitive::kPrimByte:
         case Primitive::kPrimShort:
         case Primitive::kPrimInt:
-        case Primitive::kPrimChar:
           // Processing a Dex `int-to-char' instruction.
           if (in.IsRegister()) {
             __ movzxw(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>());
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 3d65e9a..49ca443 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -26,6 +26,7 @@
   void VisitSuspendCheck(HSuspendCheck* check) OVERRIDE;
   void VisitEqual(HEqual* equal) OVERRIDE;
   void VisitArraySet(HArraySet* equal) OVERRIDE;
+  void VisitTypeConversion(HTypeConversion* instruction) OVERRIDE;
 };
 
 void InstructionSimplifier::Run() {
@@ -78,4 +79,12 @@
   }
 }
 
+void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruction) {
+  if (instruction->GetResultType() == instruction->GetInputType()) {
+    // Remove the instruction if it's converting to the same type.
+    instruction->ReplaceWith(instruction->GetInput());
+    instruction->GetBlock()->RemoveInstruction(instruction);
+  }
+}
+
 }  // namespace art