Compiler constant handling rework

In preparation for de-optimization, reworked the constant
handling mechanism.  Also took advantage of knowledge of
constant operands (particularly for long operations).

Significant performance improvements for Mandelbrot
(~60 seconds to ~34 seconds).  Minor improvements in other
benchmarks.

The new constant handling breaks two of the existing
optimization passes: "Skip Large Method" and "Load/Store
Elimization."

I don't intend to update the large method optimization
because it will be superceeded by the upcoming interpreter/
fingerprinting mechanism.  Leaving the code in place for
now in order to compare compile-time improvements with
fingerprinting/interpret.  All related code will be deleted
when that is complete.

The load/store elimination pass needs some rework to handle
uses of multiple-register loads and stores.  It will be
updated & restored in a future CL.

Change-Id: Ia979abaf51b8ae81bbb0428031cbcea854625fac
diff --git a/src/compiler/codegen/local_optimizations.cc b/src/compiler/codegen/local_optimizations.cc
index b6981ca..2b86421 100644
--- a/src/compiler/codegen/local_optimizations.cc
+++ b/src/compiler/codegen/local_optimizations.cc
@@ -81,13 +81,20 @@
   if (head_lir == tail_lir) return;
 
   for (this_lir = PREV_LIR(tail_lir); this_lir != head_lir; this_lir = PREV_LIR(this_lir)) {
+
+    if (is_pseudo_opcode(this_lir->opcode)) continue;
+
     int sink_distance = 0;
 
+    uint64_t target_flags = cg->GetTargetInstFlags(this_lir->opcode);
+
     /* Skip non-interesting instructions */
     if ((this_lir->flags.is_nop == true) ||
-        is_pseudo_opcode(this_lir->opcode) ||
-        (cg->GetTargetInstFlags(this_lir->opcode) & IS_BRANCH) ||
-        !(cg->GetTargetInstFlags(this_lir->opcode) & (IS_LOAD | IS_STORE))) {
+        (target_flags & IS_BRANCH) ||
+        ((target_flags & (REG_DEF0 | REG_DEF1)) == (REG_DEF0 | REG_DEF1)) ||  // Skip wide loads.
+        ((target_flags & (REG_USE0 | REG_USE1 | REG_USE2)) ==
+         (REG_USE0 | REG_USE1 | REG_USE2)) ||  // Skip wide stores.
+        !(target_flags & (IS_LOAD | IS_STORE))) {
       continue;
     }
 
@@ -130,7 +137,7 @@
        * Skip already dead instructions (whose dataflow information is
        * outdated and misleading).
        */
-      if (check_lir->flags.is_nop) continue;
+      if (check_lir->flags.is_nop || is_pseudo_opcode(check_lir->opcode)) continue;
 
       uint64_t check_mem_mask = (check_lir->use_mask | check_lir->def_mask) & ENCODE_MEM;
       uint64_t alias_condition = this_mem_mask & check_mem_mask;
@@ -139,14 +146,18 @@
       /*
        * Potential aliases seen - check the alias relations
        */
-      if (check_mem_mask != ENCODE_MEM && alias_condition != 0) {
-        bool is_check_lir_load = cg->GetTargetInstFlags(check_lir->opcode) & IS_LOAD;
+      uint64_t check_flags = cg->GetTargetInstFlags(check_lir->opcode);
+      // TUNING: Support instructions with multiple register targets.
+      if ((check_flags & (REG_DEF0 | REG_DEF1)) == (REG_DEF0 | REG_DEF1)) {
+        stop_here = true;
+      } else if (check_mem_mask != ENCODE_MEM && alias_condition != 0) {
+        bool is_check_lir_load = check_flags & IS_LOAD;
         if  (alias_condition == ENCODE_LITERAL) {
           /*
            * Should only see literal loads in the instruction
            * stream.
            */
-          DCHECK(!(cg->GetTargetInstFlags(check_lir->opcode) & IS_STORE));
+          DCHECK(!(check_flags & IS_STORE));
           /* Same value && same register type */
           if (check_lir->alias_info == this_lir->alias_info &&
               cg->SameRegType(check_lir->operands[0], native_reg_id)) {
@@ -276,10 +287,13 @@
   /* Start from the second instruction */
   for (this_lir = NEXT_LIR(head_lir); this_lir != tail_lir; this_lir = NEXT_LIR(this_lir)) {
 
+    if (is_pseudo_opcode(this_lir->opcode)) continue;
+
+    uint64_t target_flags = cg->GetTargetInstFlags(this_lir->opcode);
     /* Skip non-interesting instructions */
     if ((this_lir->flags.is_nop == true) ||
-        is_pseudo_opcode(this_lir->opcode) ||
-        !(cg->GetTargetInstFlags(this_lir->opcode) & IS_LOAD)) {
+        ((target_flags & (REG_DEF0 | REG_DEF1)) == (REG_DEF0 | REG_DEF1)) ||
+        !(target_flags & IS_LOAD)) {
       continue;
     }