Extend a trace with a backward branch into a loop.

When seeing a trace that ends with a backward branch, exhaust all code
blocks reachable from that trace and try to identify if there exists a
non-nested loop. If the derived loop is found to be too complex or only
acyclic code is seen, revert to the original compilation mechanism to
translate a simple trace.

This CL uses the whole-method parser/dataflow analysis framework to
identify such loops. No optimization/codegen are performed yet.

Bug: 4086718

Change-Id: I19ed3ee53ea1cbda33940c533de8e9220e647156
diff --git a/vm/compiler/CompilerIR.h b/vm/compiler/CompilerIR.h
index c807877..7b9987b 100644
--- a/vm/compiler/CompilerIR.h
+++ b/vm/compiler/CompilerIR.h
@@ -64,6 +64,12 @@
     kCatchEntry,
 } BBType;
 
+typedef enum JitMode {
+    kJitTrace = 0, // Acyclic - all instructions come from the trace descriptor
+    kJitLoop,      // Cycle - trace descriptor is used as a hint
+    kJitMethod,    // Whole method
+} JitMode;
+
 typedef struct ChainCellCounts {
     union {
         u1 count[kChainingCellLast]; /* include one more space for the gap # */
@@ -148,6 +154,7 @@
 typedef struct BasicBlock {
     int id;
     bool visited;
+    bool hidden;
     unsigned int startOffset;
     const Method *containingMethod;     // For blocks from the callee
     BBType blockType;
@@ -249,7 +256,7 @@
     const u2 *switchOverflowPad;
 
     /* New fields only for method-based compilation */
-    bool methodJitMode;
+    JitMode jitMode;
     int numReachableBlocks;
     int numDalvikRegisters;             // method->registersSize + inlined
     BasicBlock *entryBlock;