Basic block combine pass

Combine basic blocks terminated by instruction that we have since
proven not to throw.  This change is intended to relieve some of the
computational load for llvm by reducing the number of basic blocks
it has to contend with.

Also:
  Add stats to show how successful check elimination is.
  Restore mechanism to disable some expensive optimization passes when
  compiling large methods.

Change-Id: I7fae22160988cbefb90ea9fb1cc26d7364e8d229
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 8c403c5..4aa0ac8 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -80,6 +80,7 @@
   //(1 << kDebugShowMemoryUsage) |
   //(1 << kDebugShowNops) |
   //(1 << kDebugCountOpcodes) |
+  //(1 << kDebugDumpCheckStats) |
 #if defined(ART_USE_QUICK_COMPILER)
   //(1 << kDebugDumpBitcodeFile) |
   //(1 << kDebugVerifyBitcode) |
@@ -315,6 +316,7 @@
     BasicBlock *bb = (BasicBlock *) oatGrowableListGetElement(blockList,
                                                               blockIdx);
     if (bb == NULL) break;
+    if (bb->blockType == kDead) continue;
     if (bb->blockType == kEntryBlock) {
       fprintf(file, "  entry_%d [shape=Mdiamond];\n", bb->id);
     } else if (bb->blockType == kExitBlock) {
@@ -1049,18 +1051,16 @@
     }
   }
 
-#if defined(ART_USE_QUICK_COMPILER)
-  if (cUnit->genBitcode) {
-    // Bitcode generation requires full dataflow analysis, no qdMode
-    cUnit->qdMode = false;
-  }
-#endif
-
   if (cUnit->qdMode) {
+#if !defined(ART_USE_QUICK_COMPILER)
+    // Bitcode generation requires full dataflow analysis
     cUnit->disableDataflow = true;
+#endif
     // Disable optimization which require dataflow/ssa
     cUnit->disableOpt |=
+#if !defined(ART_USE_QUICK_COMPILER)
         (1 << kNullCheckElimination) |
+#endif
         (1 << kBBOpt) |
         (1 << kPromoteRegs);
     if (cUnit->printMe) {
@@ -1104,9 +1104,16 @@
   /* Perform null check elimination */
   oatMethodNullCheckElimination(cUnit.get());
 
+  /* Combine basic blocks where possible */
+  oatMethodBasicBlockCombine(cUnit.get());
+
   /* Do some basic block optimizations */
   oatMethodBasicBlockOptimization(cUnit.get());
 
+  if (cUnit->enableDebug & (1 << kDebugDumpCheckStats)) {
+    oatDumpCheckStats(cUnit.get());
+  }
+
   oatInitializeRegAlloc(cUnit.get());  // Needs to happen after SSA naming
 
   /* Allocate Registers using simple local allocation scheme */