Dex compiler: re-enable method pattern matching

The dex compiler's mechanism to detect simple methods and emit
streamlined code was disabled during the last big restructuring
(there was a question of how to make it useful for Portable as
well as Quick).  This CL does not address the Portable question,
but turns the optimization back on for Quick.

See b/9428200

Change-Id: I9f25b41219d7a243ec64efb18278e5a874766f4d
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index 90e68ab..264604c 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -107,6 +107,7 @@
       method_sreg_(0),
       attributes_(METHOD_IS_LEAF),  // Start with leaf assumption, change on encountering invoke.
       checkstats_(NULL),
+      special_case_(kNoHandler),
       arena_(arena) {
   try_block_addr_ = new (arena_) ArenaBitVector(arena_, 0, true /* expandable */);
 }
@@ -590,9 +591,6 @@
   bool* dead_pattern =
       static_cast<bool*>(arena_->NewMem(sizeof(bool) * num_patterns, true,
                                         ArenaAllocator::kAllocMisc));
-  SpecialCaseHandler special_case = kNoHandler;
-  // FIXME - wire this up
-  (void)special_case;
   int pattern_pos = 0;
 
   /* Parse all instructions and put them into containing basic blocks */
@@ -614,12 +612,12 @@
     /* Possible simple method? */
     if (live_pattern) {
       live_pattern = false;
-      special_case = kNoHandler;
+      special_case_ = kNoHandler;
       for (int i = 0; i < num_patterns; i++) {
         if (!dead_pattern[i]) {
           if (special_patterns[i].opcodes[pattern_pos] == opcode) {
             live_pattern = true;
-            special_case = special_patterns[i].handler_code;
+            special_case_ = special_patterns[i].handler_code;
           } else {
              dead_pattern[i] = true;
           }
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 9c63d9c..342d2a2 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -509,6 +509,14 @@
     return reg_location_[method_sreg_];
   }
 
+  bool IsSpecialCase() {
+    return special_case_ != kNoHandler;
+  }
+
+  SpecialCaseHandler GetSpecialCase() {
+    return special_case_;
+  }
+
   void BasicBlockCombine();
   void CodeLayout();
   void DumpCheckStats();
@@ -655,6 +663,7 @@
   int method_sreg_;
   unsigned int attributes_;
   Checkstats* checkstats_;
+  SpecialCaseHandler special_case_;
   ArenaAllocator* arena_;
 };
 
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index 630e294..9e9b39e 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -950,16 +950,13 @@
   /* Allocate Registers using simple local allocation scheme */
   SimpleRegAlloc();
 
-  //FIXME: re-enable by retrieving from mir_graph
-  SpecialCaseHandler special_case = kNoHandler;
-
-  if (special_case != kNoHandler) {
+  if (mir_graph_->IsSpecialCase()) {
       /*
        * Custom codegen for special cases.  If for any reason the
        * special codegen doesn't succeed, first_lir_insn_ will
        * set to NULL;
        */
-      SpecialMIR2LIR(special_case);
+      SpecialMIR2LIR(mir_graph_->GetSpecialCase());
     }
 
   /* Convert MIR to LIR, etc. */