Minor compiler tuning

Large switch statements were getting bogged down in a linear search.
Added a map for fast lookup (which may also be useful for debug
support).

Change-Id: I00e5956ea7e98ff2c870fb2d3e299e8d4c88f598
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 76649d5..1eb6c64 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -331,6 +331,7 @@
      bool usesFP;          // Method contains at least 1 non-move FP operation
      bool disableDataflow; // Skip dataflow analysis if possible
      std::map<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
+     std::map<unsigned int, LIR*> boundaryMap; // boundary lookup cache
 } CompilationUnit;
 
 BasicBlock* oatNewBB(BBType blockType, int blockId);
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index c5692bc..2a6714f 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -765,6 +765,8 @@
     cUnit->numDalvikRegisters = code_item->registers_size_;
     cUnit->blockMap = std::map<unsigned int, BasicBlock*>();
     cUnit->blockMap.clear();
+    cUnit->boundaryMap = std::map<unsigned int, LIR*>();
+    cUnit->boundaryMap.clear();
     bool useMatch = compilerMethodMatch.length() != 0;
     bool match = useMatch && (compilerFlipMatch ^
         (PrettyMethod(method_idx, dex_file).find(compilerMethodMatch) != std::string::npos));
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index 77b58ff..6f476f9 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -2049,6 +2049,8 @@
         boundaryLIR = newLIR1(cUnit, kArmPseudoDalvikByteCodeBoundary,
                              (int) oatGetDalvikDisassembly(
                              &mir->dalvikInsn, ""));
+        cUnit->boundaryMap.insert(std::make_pair(mir->offset,
+                                 (LIR*)boundaryLIR));
         /* Remember the first LIR for this block */
         if (headLIR == NULL) {
             headLIR = boundaryLIR;
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 9c4ef1e..1c2f850 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -129,21 +129,17 @@
  */
 STATIC ArmLIR* insertCaseLabel(CompilationUnit* cUnit, int vaddr, int keyVal)
 {
-    ArmLIR* lir;
-    for (lir = (ArmLIR*)cUnit->firstLIRInsn; lir; lir = NEXT_LIR(lir)) {
-        if ((lir->opcode == kArmPseudoDalvikByteCodeBoundary) &&
-            (lir->generic.dalvikOffset == vaddr)) {
-            ArmLIR* newLabel = (ArmLIR*)oatNew(sizeof(ArmLIR), true);
-            newLabel->generic.dalvikOffset = vaddr;
-            newLabel->opcode = kArmPseudoCaseLabel;
-            newLabel->operands[0] = keyVal;
-            oatInsertLIRAfter((LIR*)lir, (LIR*)newLabel);
-            return newLabel;
-        }
+    std::map<unsigned int, LIR*>::iterator it;
+    it = cUnit->boundaryMap.find(vaddr);
+    if (it == cUnit->boundaryMap.end()) {
+        LOG(FATAL) << "Error: didn't find vaddr 0x" << std::hex << vaddr;
     }
-    oatCodegenDump(cUnit);
-    LOG(FATAL) << "Error: didn't find vaddr 0x" << std::hex << vaddr;
-    return NULL; // Quiet gcc
+    ArmLIR* newLabel = (ArmLIR*)oatNew(sizeof(ArmLIR), true);
+    newLabel->generic.dalvikOffset = vaddr;
+    newLabel->opcode = kArmPseudoCaseLabel;
+    newLabel->operands[0] = keyVal;
+    oatInsertLIRAfter(it->second, (LIR*)newLabel);
+    return newLabel;
 }
 
 STATIC void markPackedCaseLabels(CompilationUnit* cUnit, SwitchTable *tabRec)