Implement invokesuper in optimizing.

- Ensure dex2oat is in PIC mode, as this will drive the decisions
  made in the compiler driver, and optimizing only suppots PIC
  anyway.

- Since invokesuper is sharpened into invoke-direct, also support
  sharpening of invokeinterface and invokevirtual.

Change-Id: I0a1bd79a13dc1c9e67e3cb11d38f0cd4459968ae
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 16b491d..76a2be9 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -374,13 +374,12 @@
   const size_t number_of_arguments = strlen(descriptor) - (is_instance_call ? 0 : 1);
 
   HInvoke* invoke = nullptr;
-  if (invoke_type == kVirtual || invoke_type == kInterface) {
+  if (invoke_type == kVirtual || invoke_type == kInterface || invoke_type == kSuper) {
     MethodReference target_method(dex_file_, method_idx);
     uintptr_t direct_code;
     uintptr_t direct_method;
     int table_index;
     InvokeType optimized_invoke_type = invoke_type;
-    // TODO: Add devirtualization support.
     compiler_driver_->ComputeInvokeInfo(dex_compilation_unit_, dex_offset, true, true,
                                         &optimized_invoke_type, &target_method, &table_index,
                                         &direct_code, &direct_method);
@@ -388,15 +387,21 @@
       return false;
     }
 
-    if (invoke_type == kVirtual) {
+    if (optimized_invoke_type == kVirtual) {
       invoke = new (arena_) HInvokeVirtual(
           arena_, number_of_arguments, return_type, dex_offset, table_index);
-    } else {
-      DCHECK_EQ(invoke_type, kInterface);
+    } else if (optimized_invoke_type == kInterface) {
       invoke = new (arena_) HInvokeInterface(
           arena_, number_of_arguments, return_type, dex_offset, method_idx, table_index);
+    } else if (optimized_invoke_type == kDirect) {
+      // For this compiler, sharpening only works if we compile PIC.
+      DCHECK(compiler_driver_->GetCompilerOptions().GetCompilePic());
+      // Treat invoke-direct like static calls for now.
+      invoke = new (arena_) HInvokeStatic(
+          arena_, number_of_arguments, return_type, dex_offset, target_method.dex_method_index);
     }
   } else {
+    DCHECK(invoke_type == kDirect || invoke_type == kStatic);
     // Treat invoke-direct like static calls for now.
     invoke = new (arena_) HInvokeStatic(
         arena_, number_of_arguments, return_type, dex_offset, method_idx);
@@ -890,10 +895,11 @@
       break;
     }
 
-    case Instruction::INVOKE_STATIC:
     case Instruction::INVOKE_DIRECT:
-    case Instruction::INVOKE_VIRTUAL:
-    case Instruction::INVOKE_INTERFACE: {
+    case Instruction::INVOKE_INTERFACE:
+    case Instruction::INVOKE_STATIC:
+    case Instruction::INVOKE_SUPER:
+    case Instruction::INVOKE_VIRTUAL: {
       uint32_t method_idx = instruction.VRegB_35c();
       uint32_t number_of_vreg_arguments = instruction.VRegA_35c();
       uint32_t args[5];
@@ -905,10 +911,11 @@
       break;
     }
 
-    case Instruction::INVOKE_STATIC_RANGE:
     case Instruction::INVOKE_DIRECT_RANGE:
-    case Instruction::INVOKE_VIRTUAL_RANGE:
-    case Instruction::INVOKE_INTERFACE_RANGE: {
+    case Instruction::INVOKE_INTERFACE_RANGE:
+    case Instruction::INVOKE_STATIC_RANGE:
+    case Instruction::INVOKE_SUPER_RANGE:
+    case Instruction::INVOKE_VIRTUAL_RANGE: {
       uint32_t method_idx = instruction.VRegB_3rc();
       uint32_t number_of_vreg_arguments = instruction.VRegA_3rc();
       uint32_t register_index = instruction.VRegC();