Restructure to reduce MIR references

This CL eliminates most of the MIR references in the lower-level
code generator.  This allows a higher level of code sharing with
the MIR->LIR and GreenlandIR->LIR lowering passes.

The invoke, launchpads and new array support will need some more
extensive refactoring (future CL).

Change-Id: I75f249268c8ac18da1dd9180ff855d5176d6c4fe
diff --git a/src/compiler/codegen/CodegenFactory.cc b/src/compiler/codegen/CodegenFactory.cc
index 3a7cb82..71b557c 100644
--- a/src/compiler/codegen/CodegenFactory.cc
+++ b/src/compiler/codegen/CodegenFactory.cc
@@ -44,7 +44,7 @@
 LIR* loadWordDisp(CompilationUnit* cUnit, int rBase, int displacement,
                   int rDest)
 {
-  return loadBaseDisp(cUnit, NULL, rBase, displacement, rDest, kWord,
+  return loadBaseDisp(cUnit, rBase, displacement, rDest, kWord,
                       INVALID_SREG);
 }
 
@@ -97,7 +97,7 @@
   } else {
     DCHECK((rlSrc.location == kLocDalvikFrame) ||
            (rlSrc.location == kLocCompilerTemp));
-    loadBaseDispWide(cUnit, NULL, rSP, oatSRegOffset(cUnit, rlSrc.sRegLow),
+    loadBaseDispWide(cUnit, rSP, oatSRegOffset(cUnit, rlSrc.sRegLow),
                      regLo, regHi, INVALID_SREG);
   }
 }
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 0d2cf00..2bd9333 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -325,11 +325,11 @@
 // FIXME: need to do some work to split out targets with
 // condition codes and those without
 #if defined(TARGET_ARM) || defined(TARGET_X86)
-LIR* genCheck(CompilationUnit* cUnit, ConditionCode cCode, MIR* mir,
+LIR* genCheck(CompilationUnit* cUnit, ConditionCode cCode,
               ThrowKind kind)
 {
   LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind,
-                    mir ? mir->offset : 0);
+                    cUnit->currentDalvikOffset);
   LIR* branch = opCondBranch(cUnit, cCode, tgt);
   // Remember branch target - will process later
   oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
@@ -338,9 +338,10 @@
 #endif
 
 LIR* genImmedCheck(CompilationUnit* cUnit, ConditionCode cCode,
-                   int reg, int immVal, MIR* mir, ThrowKind kind)
+                   int reg, int immVal, ThrowKind kind)
 {
-  LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind, mir->offset);
+  LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind,
+                    cUnit->currentDalvikOffset);
   LIR* branch;
   if (cCode == kCondAl) {
     branch = opUnconditionalBranch(cUnit, tgt);
@@ -353,21 +354,21 @@
 }
 
 /* Perform null-check on a register.  */
-LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg, MIR* mir)
+LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg, int optFlags)
 {
   if (!(cUnit->disableOpt & (1 << kNullCheckElimination)) &&
-    mir->optimizationFlags & MIR_IGNORE_NULL_CHECK) {
+    optFlags & MIR_IGNORE_NULL_CHECK) {
     return NULL;
   }
-  return genImmedCheck(cUnit, kCondEq, mReg, 0, mir, kThrowNullPointer);
+  return genImmedCheck(cUnit, kCondEq, mReg, 0, kThrowNullPointer);
 }
 
 /* Perform check on two registers */
 LIR* genRegRegCheck(CompilationUnit* cUnit, ConditionCode cCode,
-                    int reg1, int reg2, MIR* mir, ThrowKind kind)
+                    int reg1, int reg2, ThrowKind kind)
 {
   LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind,
-                    mir ? mir->offset : 0, reg1, reg2);
+                    cUnit->currentDalvikOffset, reg1, reg2);
 #if defined(TARGET_MIPS)
   LIR* branch = opCmpBranch(cUnit, cCode, reg1, reg2, tgt);
 #else
@@ -379,13 +380,13 @@
   return branch;
 }
 
-void genCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
-                         RegLocation rlSrc1, RegLocation rlSrc2, LIR* labelList)
+void genCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
+                         Instruction::Code opcode, RegLocation rlSrc1,
+                         RegLocation rlSrc2, LIR* labelList)
 {
   ConditionCode cond;
   rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
   rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
-  Instruction::Code opcode = mir->dalvikInsn.opcode;
   switch (opcode) {
     case Instruction::IF_EQ:
       cond = kCondEq;
@@ -419,12 +420,12 @@
   opUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
 }
 
-void genCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
-                             RegLocation rlSrc, LIR* labelList)
+void genCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
+                             Instruction::Code opcode, RegLocation rlSrc,
+                             LIR* labelList)
 {
   ConditionCode cond;
   rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-  Instruction::Code opcode = mir->dalvikInsn.opcode;
   switch (opcode) {
     case Instruction::IF_EQZ:
       cond = kCondEq;
@@ -457,7 +458,7 @@
   opUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
 }
 
-void genIntToLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
                   RegLocation rlSrc)
 {
   RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
@@ -470,13 +471,13 @@
   storeValueWide(cUnit, rlDest, rlResult);
 }
 
-void genIntNarrowing(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
-                     RegLocation rlSrc)
+void genIntNarrowing(CompilationUnit* cUnit, Instruction::Code opcode,
+                     RegLocation rlDest, RegLocation rlSrc)
 {
    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
    OpKind op = kOpInvalid;
-   switch (mir->dalvikInsn.opcode) {
+   switch (opcode) {
      case Instruction::INT_TO_BYTE:
        op = kOp2Byte;
        break;
@@ -498,11 +499,10 @@
  * Array::AllocFromCode(type_idx, method, count);
  * Note: AllocFromCode will handle checks for errNegativeArraySize.
  */
-void genNewArray(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genNewArray(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest,
                  RegLocation rlSrc)
 {
   oatFlushAllRegs(cUnit);  /* Everything to home location */
-  uint32_t type_idx = mir->dalvikInsn.vC;
   int funcOffset;
   if (cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
                                                   cUnit->dex_cache,
@@ -630,14 +630,13 @@
   }
 }
 
-void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
+void genSput(CompilationUnit* cUnit, uint32_t fieldIdx, RegLocation rlSrc,
        bool isLongOrDouble, bool isObject)
 {
   int fieldOffset;
   int ssbIndex;
   bool isVolatile;
   bool isReferrersClass;
-  uint32_t fieldIdx = mir->dalvikInsn.vB;
 
   OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
                            *cUnit->dex_file, *cUnit->dex_cache,
@@ -698,10 +697,8 @@
     }
     // rBase now holds static storage base
     if (isLongOrDouble) {
-      rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
       rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
     } else {
-      rlSrc = oatGetSrc(cUnit, mir, 0);
       rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
     }
 //FIXME: need to generalize the barrier call
@@ -730,14 +727,13 @@
   }
 }
 
-void genSget(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genSget(CompilationUnit* cUnit, uint32_t fieldIdx, RegLocation rlDest,
        bool isLongOrDouble, bool isObject)
 {
   int fieldOffset;
   int ssbIndex;
   bool isVolatile;
   bool isReferrersClass;
-  uint32_t fieldIdx = mir->dalvikInsn.vB;
 
   OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
                            *cUnit->dex_file, *cUnit->dex_cache,
@@ -792,14 +788,12 @@
       oatFreeTemp(cUnit, rMethod);
     }
     // rBase now holds static storage base
-    rlDest = isLongOrDouble ? oatGetDestWide(cUnit, mir, 0, 1)
-        : oatGetDest(cUnit, mir, 0);
     RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
     if (isVolatile) {
       oatGenMemBarrier(cUnit, kSY);
     }
     if (isLongOrDouble) {
-      loadBaseDispWide(cUnit, NULL, rBase, fieldOffset, rlResult.lowReg,
+      loadBaseDispWide(cUnit, rBase, fieldOffset, rlResult.lowReg,
                        rlResult.highReg, INVALID_SREG);
     } else {
       loadWordDisp(cUnit, rBase, fieldOffset, rlResult.lowReg);
@@ -840,11 +834,11 @@
 #endif
 }
 
-void genThrowVerificationError(CompilationUnit* cUnit, MIR* mir)
+void genThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
 {
   callRuntimeHelperImmImm(cUnit,
                           ENTRYPOINT_OFFSET(pThrowVerificationErrorFromCode),
-                          mir->dalvikInsn.vA, mir->dalvikInsn.vB);
+                          info1, info2);
 }
 
 void handleSuspendLaunchpads(CompilationUnit *cUnit)
@@ -982,13 +976,12 @@
            fieldOffset, isVolatile, isPut);
 }
 
-void genIGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
+void genIGet(CompilationUnit* cUnit, uint32_t fieldIdx, int optFlags, OpSize size,
              RegLocation rlDest, RegLocation rlObj,
              bool isLongOrDouble, bool isObject)
 {
   int fieldOffset;
   bool isVolatile;
-  uint32_t fieldIdx = mir->dalvikInsn.vC;
 
   bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile, false);
 
@@ -999,11 +992,11 @@
     rlObj = loadValue(cUnit, rlObj, kCoreReg);
     if (isLongOrDouble) {
       DCHECK(rlDest.wide);
-      genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
+      genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, optFlags);
 #if defined(TARGET_X86)
       rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
-      genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
-      loadBaseDispWide(cUnit, mir, rlObj.lowReg, fieldOffset, rlResult.lowReg,
+      genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, optFlags);
+      loadBaseDispWide(cUnit, rlObj.lowReg, fieldOffset, rlResult.lowReg,
                        rlResult.highReg, rlObj.sRegLow);
       if (isVolatile) {
         oatGenMemBarrier(cUnit, kSY);
@@ -1021,8 +1014,8 @@
       storeValueWide(cUnit, rlDest, rlResult);
     } else {
       rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
-      genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
-      loadBaseDisp(cUnit, mir, rlObj.lowReg, fieldOffset, rlResult.lowReg,
+      genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, optFlags);
+      loadBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlResult.lowReg,
                    kWord, rlObj.sRegLow);
       if (isVolatile) {
         oatGenMemBarrier(cUnit, kSY);
@@ -1044,12 +1037,11 @@
   }
 }
 
-void genIPut(CompilationUnit* cUnit, MIR* mir, OpSize size, RegLocation rlSrc,
-       RegLocation rlObj, bool isLongOrDouble, bool isObject)
+void genIPut(CompilationUnit* cUnit, uint32_t fieldIdx, int optFlags, OpSize size,
+             RegLocation rlSrc, RegLocation rlObj, bool isLongOrDouble, bool isObject)
 {
   int fieldOffset;
   bool isVolatile;
-  uint32_t fieldIdx = mir->dalvikInsn.vC;
 
   bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile,
                  true);
@@ -1060,7 +1052,7 @@
     if (isLongOrDouble) {
       int regPtr;
       rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
-      genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
+      genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, optFlags);
       regPtr = oatAllocTemp(cUnit);
       opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
       if (isVolatile) {
@@ -1073,7 +1065,7 @@
       oatFreeTemp(cUnit, regPtr);
     } else {
       rlSrc = loadValue(cUnit, rlSrc, regClass);
-      genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
+      genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, optFlags);
       if (isVolatile) {
         oatGenMemBarrier(cUnit, kST);
       }
@@ -1094,10 +1086,9 @@
   }
 }
 
-void genConstClass(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genConstClass(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest,
                    RegLocation rlSrc)
 {
-  uint32_t type_idx = mir->dalvikInsn.vB;
   RegLocation rlMethod = loadCurrMethod(cUnit);
   int resReg = oatAllocTemp(cUnit);
   RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
@@ -1157,11 +1148,10 @@
   }
 }
 
-void genConstString(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genConstString(CompilationUnit* cUnit, uint32_t string_idx, RegLocation rlDest,
           RegLocation rlSrc)
 {
   /* NOTE: Most strings should be available at compile time */
-  uint32_t string_idx = mir->dalvikInsn.vB;
   int32_t offset_of_string = Array::DataOffset(sizeof(String*)).Int32Value() +
                  (sizeof(String*) * string_idx);
   if (!cUnit->compiler->CanAssumeStringIsPresentInDexCache(
@@ -1216,10 +1206,9 @@
  * Let helper function take care of everything.  Will
  * call Class::NewInstanceFromCode(type_idx, method);
  */
-void genNewInstance(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest)
+void genNewInstance(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest)
 {
   oatFlushAllRegs(cUnit);  /* Everything to home location */
-  uint32_t type_idx = mir->dalvikInsn.vB;
   // alloc will always check for resolution, do we also need to verify
   // access because the verifier was unable to?
   int funcOffset;
@@ -1234,20 +1223,19 @@
   storeValue(cUnit, rlDest, rlResult);
 }
 
-void genThrow(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genThrow(CompilationUnit* cUnit, RegLocation rlSrc)
 {
   oatFlushAllRegs(cUnit);
   callRuntimeHelperRegLocation(cUnit, ENTRYPOINT_OFFSET(pDeliverException),
                                rlSrc);
 }
 
-void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genInstanceof(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest,
                    RegLocation rlSrc)
 {
   oatFlushAllRegs(cUnit);
   // May generate a call - use explicit registers
   oatLockCallTemps(cUnit);
-  uint32_t type_idx = mir->dalvikInsn.vC;
   loadCurrMethodDirect(cUnit, rARG1);  // rARG1 <= current Method*
   int classReg = rARG2;  // rARG2 will hold the Class*
   if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
@@ -1328,12 +1316,11 @@
 #endif
 }
 
-void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genCheckCast(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlSrc)
 {
   oatFlushAllRegs(cUnit);
   // May generate a call - use explicit registers
   oatLockCallTemps(cUnit);
-  uint32_t type_idx = mir->dalvikInsn.vB;
   loadCurrMethodDirect(cUnit, rARG1);  // rARG1 <= current Method*
   int classReg = rARG2;  // rARG2 will hold the Class*
   if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
@@ -1403,7 +1390,7 @@
  * Generate array store
  *
  */
-void genArrayObjPut(CompilationUnit* cUnit, MIR* mir, RegLocation rlArray,
+void genArrayObjPut(CompilationUnit* cUnit, int optFlags, RegLocation rlArray,
           RegLocation rlIndex, RegLocation rlSrc, int scale)
 {
   int lenOffset = Array::LengthOffset().Int32Value();
@@ -1421,7 +1408,7 @@
   loadValueDirectFixed(cUnit, rlSrc, rValue);  // Grab value
   loadValueDirectFixed(cUnit, rlIndex, rIndex);  // Grab index
 
-  genNullCheck(cUnit, rlArray.sRegLow, rArray, mir);  // NPE?
+  genNullCheck(cUnit, rlArray.sRegLow, rArray, optFlags);  // NPE?
 
   // Store of null?
   LIR* null_value_check = opCmpImmBranch(cUnit, kCondEq, rValue, 0, NULL);
@@ -1443,15 +1430,14 @@
 #if defined(TARGET_X86)
   // make an extra temp available for card mark below
   oatFreeTemp(cUnit, rARG1);
-  if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+  if (!(optFlags & MIR_IGNORE_RANGE_CHECK)) {
     /* if (rlIndex >= [rlArray + lenOffset]) goto kThrowArrayBounds */
-    genRegMemCheck(cUnit, kCondUge, rIndex, rArray,
-                   lenOffset, mir, kThrowArrayBounds);
+    genRegMemCheck(cUnit, kCondUge, rIndex, rArray, lenOffset, kThrowArrayBounds);
   }
-  storeBaseIndexedDisp(cUnit, NULL, rArray, rIndex, scale,
+  storeBaseIndexedDisp(cUnit, rArray, rIndex, scale,
                        dataOffset, rValue, INVALID_REG, kWord, INVALID_SREG);
 #else
-  bool needsRangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
+  bool needsRangeCheck = (!(optFlags & MIR_IGNORE_RANGE_CHECK));
   int regLen = INVALID_REG;
   if (needsRangeCheck) {
     regLen = rARG1;
@@ -1461,8 +1447,7 @@
   int rPtr = oatAllocTemp(cUnit);
   opRegRegImm(cUnit, kOpAdd, rPtr, rArray, dataOffset);
   if (needsRangeCheck) {
-    genRegRegCheck(cUnit, kCondCs, rIndex, regLen, mir,
-                   kThrowArrayBounds);
+    genRegRegCheck(cUnit, kCondCs, rIndex, regLen, kThrowArrayBounds);
   }
   storeBaseIndexed(cUnit, rPtr, rIndex, rValue, scale, kWord);
   oatFreeTemp(cUnit, rPtr);
@@ -1474,7 +1459,7 @@
 /*
  * Generate array load
  */
-void genArrayGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
+void genArrayGet(CompilationUnit* cUnit, int optFlags, OpSize size,
                  RegLocation rlArray, RegLocation rlIndex,
                  RegLocation rlDest, int scale)
 {
@@ -1492,13 +1477,13 @@
   }
 
   /* null object? */
-  genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, mir);
+  genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, optFlags);
 
 #if defined(TARGET_X86)
-  if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+  if (!(optFlags & MIR_IGNORE_RANGE_CHECK)) {
     /* if (rlIndex >= [rlArray + lenOffset]) goto kThrowArrayBounds */
     genRegMemCheck(cUnit, kCondUge, rlIndex.lowReg, rlArray.lowReg,
-                   lenOffset, mir, kThrowArrayBounds);
+                   lenOffset, kThrowArrayBounds);
   }
   if ((size == kLong) || (size == kDouble)) {
     int regAddr = oatAllocTemp(cUnit);
@@ -1506,13 +1491,13 @@
     oatFreeTemp(cUnit, rlArray.lowReg);
     oatFreeTemp(cUnit, rlIndex.lowReg);
     rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
-    loadBaseIndexedDisp(cUnit, NULL, regAddr, INVALID_REG, 0, 0, rlResult.lowReg,
+    loadBaseIndexedDisp(cUnit, regAddr, INVALID_REG, 0, 0, rlResult.lowReg,
                         rlResult.highReg, size, INVALID_SREG);
     storeValueWide(cUnit, rlDest, rlResult);
   } else {
     rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
 
-    loadBaseIndexedDisp(cUnit, NULL, rlArray.lowReg, rlIndex.lowReg, scale,
+    loadBaseIndexedDisp(cUnit, rlArray.lowReg, rlIndex.lowReg, scale,
                         dataOffset, rlResult.lowReg, INVALID_REG, size,
                         INVALID_SREG);
 
@@ -1520,7 +1505,7 @@
   }
 #else
   int regPtr = oatAllocTemp(cUnit);
-  bool needsRangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
+  bool needsRangeCheck = (!(optFlags & MIR_IGNORE_RANGE_CHECK));
   int regLen = INVALID_REG;
   if (needsRangeCheck) {
     regLen = oatAllocTemp(cUnit);
@@ -1545,8 +1530,7 @@
     if (needsRangeCheck) {
       // TODO: change kCondCS to a more meaningful name, is the sense of
       // carry-set/clear flipped?
-      genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
-                     kThrowArrayBounds);
+      genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, kThrowArrayBounds);
       oatFreeTemp(cUnit, regLen);
     }
     loadPair(cUnit, regPtr, rlResult.lowReg, rlResult.highReg);
@@ -1559,8 +1543,7 @@
     if (needsRangeCheck) {
       // TODO: change kCondCS to a more meaningful name, is the sense of
       // carry-set/clear flipped?
-      genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
-                     kThrowArrayBounds);
+      genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, kThrowArrayBounds);
       oatFreeTemp(cUnit, regLen);
     }
     loadBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlResult.lowReg,
@@ -1576,7 +1559,7 @@
  * Generate array store
  *
  */
-void genArrayPut(CompilationUnit* cUnit, MIR* mir, OpSize size,
+void genArrayPut(CompilationUnit* cUnit, int optFlags, OpSize size,
                  RegLocation rlArray, RegLocation rlIndex,
                  RegLocation rlSrc, int scale)
 {
@@ -1604,24 +1587,24 @@
 #endif
 
   /* null object? */
-  genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, mir);
+  genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, optFlags);
 
 #if defined(TARGET_X86)
-  if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+  if (!(optFlags & MIR_IGNORE_RANGE_CHECK)) {
     /* if (rlIndex >= [rlArray + lenOffset]) goto kThrowArrayBounds */
     genRegMemCheck(cUnit, kCondUge, rlIndex.lowReg, rlArray.lowReg,
-                   lenOffset, mir, kThrowArrayBounds);
+                   lenOffset, kThrowArrayBounds);
   }
   if ((size == kLong) || (size == kDouble)) {
     rlSrc = loadValueWide(cUnit, rlSrc, regClass);
   } else {
     rlSrc = loadValue(cUnit, rlSrc, regClass);
   }
-  storeBaseIndexedDisp(cUnit, NULL, rlArray.lowReg, rlIndex.lowReg, scale,
+  storeBaseIndexedDisp(cUnit, rlArray.lowReg, rlIndex.lowReg, scale,
                        dataOffset, rlSrc.lowReg, rlSrc.highReg, size,
                        INVALID_SREG);
 #else
-  bool needsRangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
+  bool needsRangeCheck = (!(optFlags & MIR_IGNORE_RANGE_CHECK));
   int regLen = INVALID_REG;
   if (needsRangeCheck) {
     regLen = oatAllocTemp(cUnit);
@@ -1645,8 +1628,7 @@
     rlSrc = loadValueWide(cUnit, rlSrc, regClass);
 
     if (needsRangeCheck) {
-      genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
-                     kThrowArrayBounds);
+      genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, kThrowArrayBounds);
       oatFreeTemp(cUnit, regLen);
     }
 
@@ -1656,8 +1638,7 @@
   } else {
     rlSrc = loadValue(cUnit, rlSrc, regClass);
     if (needsRangeCheck) {
-      genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
-                     kThrowArrayBounds);
+      genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, kThrowArrayBounds);
       oatFreeTemp(cUnit, regLen);
     }
     storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg,
@@ -1666,7 +1647,7 @@
 #endif
 }
 
-void genLong3Addr(CompilationUnit* cUnit, MIR* mir, OpKind firstOp,
+void genLong3Addr(CompilationUnit* cUnit, OpKind firstOp,
                   OpKind secondOp, RegLocation rlDest,
                   RegLocation rlSrc1, RegLocation rlSrc2)
 {
@@ -1715,12 +1696,12 @@
 }
 
 
-bool genShiftOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genShiftOpLong(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest,
                     RegLocation rlSrc1, RegLocation rlShift)
 {
   int funcOffset;
 
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::SHL_LONG:
     case Instruction::SHL_LONG_2ADDR:
       funcOffset = ENTRYPOINT_OFFSET(pShlLong);
@@ -1745,7 +1726,7 @@
 }
 
 
-bool genArithOpInt(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genArithOpInt(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest,
            RegLocation rlSrc1, RegLocation rlSrc2)
 {
   OpKind op = kOpBkpt;
@@ -1756,7 +1737,7 @@
   bool shiftOp = false;
   int funcOffset;
   int retReg = rRET0;
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::NEG_INT:
       op = kOpNeg;
       unary = true;
@@ -1823,7 +1804,7 @@
       break;
     default:
       LOG(FATAL) << "Invalid word arith op: " <<
-        (int)mir->dalvikInsn.opcode;
+        (int)opcode;
   }
   if (!callOut) {
     if (unary) {
@@ -1862,7 +1843,7 @@
 #endif
     loadValueDirectFixed(cUnit, rlSrc1, rARG0);
     if (checkZero) {
-      genImmedCheck(cUnit, kCondEq, rARG1, 0, mir, kThrowDivZero);
+      genImmedCheck(cUnit, kCondEq, rARG1, 0, kThrowDivZero);
     }
 #if !defined(TARGET_X86)
     opReg(cUnit, kOpBlx, rTgt);
@@ -2034,17 +2015,16 @@
   return true;
 }
 
-bool genArithOpIntLit(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
-                      RegLocation rlSrc, int lit)
+bool genArithOpIntLit(CompilationUnit* cUnit, Instruction::Code opcode,
+                      RegLocation rlDest, RegLocation rlSrc, int lit)
 {
-  Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
   RegLocation rlResult;
   OpKind op = (OpKind)0;    /* Make gcc happy */
   int shiftOp = false;
   bool isDiv = false;
   int funcOffset;
 
-  switch (dalvikOpcode) {
+  switch (opcode) {
     case Instruction::RSUB_INT_LIT8:
     case Instruction::RSUB_INT: {
       int tReg;
@@ -2104,18 +2084,18 @@
     case Instruction::REM_INT_LIT8:
     case Instruction::REM_INT_LIT16:
       if (lit == 0) {
-        genImmedCheck(cUnit, kCondAl, 0, 0, mir, kThrowDivZero);
+        genImmedCheck(cUnit, kCondAl, 0, 0, kThrowDivZero);
         return false;
       }
-      if (handleEasyDivide(cUnit, dalvikOpcode, rlSrc, rlDest, lit)) {
+      if (handleEasyDivide(cUnit, opcode, rlSrc, rlDest, lit)) {
         return false;
       }
       oatFlushAllRegs(cUnit);   /* Everything to home location */
       loadValueDirectFixed(cUnit, rlSrc, rARG0);
       oatClobber(cUnit, rARG0);
       funcOffset = ENTRYPOINT_OFFSET(pIdivmod);
-      if ((dalvikOpcode == Instruction::DIV_INT_LIT8) ||
-          (dalvikOpcode == Instruction::DIV_INT_LIT16)) {
+      if ((opcode == Instruction::DIV_INT_LIT8) ||
+          (opcode == Instruction::DIV_INT_LIT16)) {
         isDiv = true;
       } else {
         isDiv = false;
@@ -2143,7 +2123,7 @@
   return false;
 }
 
-bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genArithOpLong(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest,
           RegLocation rlSrc1, RegLocation rlSrc2)
 {
   RegLocation rlResult;
@@ -2154,7 +2134,7 @@
   int funcOffset;
   int retReg = rRET0;
 
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::NOT_LONG:
       rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
       rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
@@ -2175,7 +2155,7 @@
     case Instruction::ADD_LONG:
     case Instruction::ADD_LONG_2ADDR:
 #if defined(TARGET_MIPS) || defined(TARGET_X86)
-      return genAddLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genAddLong(cUnit, rlDest, rlSrc1, rlSrc2);
 #else
       firstOp = kOpAdd;
       secondOp = kOpAdc;
@@ -2184,7 +2164,7 @@
     case Instruction::SUB_LONG:
     case Instruction::SUB_LONG_2ADDR:
 #if defined(TARGET_MIPS) || defined(TARGET_X86)
-      return genSubLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genSubLong(cUnit, rlDest, rlSrc1, rlSrc2);
 #else
       firstOp = kOpSub;
       secondOp = kOpSbc;
@@ -2218,7 +2198,7 @@
     case Instruction::AND_LONG_2ADDR:
     case Instruction::AND_LONG:
 #if defined(TARGET_X86)
-      return genAndLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genAndLong(cUnit, rlDest, rlSrc1, rlSrc2);
 #else
       firstOp = kOpAnd;
       secondOp = kOpAnd;
@@ -2227,7 +2207,7 @@
     case Instruction::OR_LONG:
     case Instruction::OR_LONG_2ADDR:
 #if defined(TARGET_X86)
-      return genOrLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genOrLong(cUnit, rlDest, rlSrc1, rlSrc2);
 #else
       firstOp = kOpOr;
       secondOp = kOpOr;
@@ -2236,20 +2216,20 @@
     case Instruction::XOR_LONG:
     case Instruction::XOR_LONG_2ADDR:
 #if defined(TARGET_X86)
-      return genXorLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genXorLong(cUnit, rlDest, rlSrc1, rlSrc2);
 #else
       firstOp = kOpXor;
       secondOp = kOpXor;
       break;
 #endif
     case Instruction::NEG_LONG: {
-      return genNegLong(cUnit, mir, rlDest, rlSrc2);
+      return genNegLong(cUnit, rlDest, rlSrc2);
     }
     default:
       LOG(FATAL) << "Invalid long arith op";
   }
   if (!callOut) {
-    genLong3Addr(cUnit, mir, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
+    genLong3Addr(cUnit, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
   } else {
     oatFlushAllRegs(cUnit);   /* Send everything to home location */
     if (checkZero) {
@@ -2261,11 +2241,11 @@
 #if defined(TARGET_ARM)
       newLIR4(cUnit, kThumb2OrrRRRs, tReg, rARG2, rARG3, 0);
       oatFreeTemp(cUnit, tReg);
-      genCheck(cUnit, kCondEq, mir, kThrowDivZero);
+      genCheck(cUnit, kCondEq, kThrowDivZero);
 #else
       opRegRegReg(cUnit, kOpOr, tReg, rARG2, rARG3);
 #endif
-      genImmedCheck(cUnit, kCondEq, tReg, 0, mir, kThrowDivZero);
+      genImmedCheck(cUnit, kCondEq, tReg, 0, kThrowDivZero);
       oatFreeTemp(cUnit, tReg);
       loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1);
 #if !defined(TARGET_X86)
@@ -2288,47 +2268,41 @@
   return false;
 }
 
-bool genConversionCall(CompilationUnit* cUnit, MIR* mir, int funcOffset,
-             int srcSize, int tgtSize)
+bool genConversionCall(CompilationUnit* cUnit, int funcOffset,
+                       RegLocation rlDest, RegLocation rlSrc)
 {
   /*
    * Don't optimize the register usage since it calls out to support
    * functions
    */
-  RegLocation rlSrc;
-  RegLocation rlDest;
   oatFlushAllRegs(cUnit);   /* Send everything to home location */
-  if (srcSize == 1) {
-    rlSrc = oatGetSrc(cUnit, mir, 0);
-    loadValueDirectFixed(cUnit, rlSrc, rARG0);
-  } else {
-    rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+  if (rlSrc.wide) {
     loadValueDirectWideFixed(cUnit, rlSrc, rARG0, rARG1);
+  } else {
+    loadValueDirectFixed(cUnit, rlSrc, rARG0);
   }
   callRuntimeHelperRegLocation(cUnit, funcOffset, rlSrc);
-  if (tgtSize == 1) {
+  if (rlDest.wide) {
     RegLocation rlResult;
-    rlDest = oatGetDest(cUnit, mir, 0);
-    rlResult = oatGetReturn(cUnit, rlDest.fp);
-    storeValue(cUnit, rlDest, rlResult);
-  } else {
-    RegLocation rlResult;
-    rlDest = oatGetDestWide(cUnit, mir, 0, 1);
     rlResult = oatGetReturnWide(cUnit, rlDest.fp);
     storeValueWide(cUnit, rlDest, rlResult);
+  } else {
+    RegLocation rlResult;
+    rlResult = oatGetReturn(cUnit, rlDest.fp);
+    storeValue(cUnit, rlDest, rlResult);
   }
   return false;
 }
 
 void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc);
-bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode,
                              RegLocation rlDest, RegLocation rlSrc1,
                              RegLocation rlSrc2)
 {
   RegLocation rlResult;
   int funcOffset;
 
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::ADD_FLOAT_2ADDR:
     case Instruction::ADD_FLOAT:
       funcOffset = ENTRYPOINT_OFFSET(pFadd);
@@ -2364,14 +2338,14 @@
 }
 
 void genNegDouble(CompilationUnit* cUnit, RegLocation rlDst, RegLocation rlSrc);
-bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode,
                               RegLocation rlDest, RegLocation rlSrc1,
                               RegLocation rlSrc2)
 {
   RegLocation rlResult;
   int funcOffset;
 
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::ADD_DOUBLE_2ADDR:
     case Instruction::ADD_DOUBLE:
       funcOffset = ENTRYPOINT_OFFSET(pDadd);
@@ -2406,41 +2380,41 @@
   return false;
 }
 
-bool genConversionPortable(CompilationUnit* cUnit, MIR* mir)
+bool genConversionPortable(CompilationUnit* cUnit, Instruction::Code opcode,
+                           RegLocation rlDest, RegLocation rlSrc)
 {
-  Instruction::Code opcode = mir->dalvikInsn.opcode;
 
   switch (opcode) {
     case Instruction::INT_TO_FLOAT:
-      return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pI2f),
-                   1, 1);
+      return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pI2f),
+                   rlDest, rlSrc);
     case Instruction::FLOAT_TO_INT:
-      return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pF2iz),
-                   1, 1);
+      return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pF2iz),
+                   rlDest, rlSrc);
     case Instruction::DOUBLE_TO_FLOAT:
-      return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pD2f),
-                   2, 1);
+      return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pD2f),
+                   rlDest, rlSrc);
     case Instruction::FLOAT_TO_DOUBLE:
-      return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pF2d),
-                   1, 2);
+      return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pF2d),
+                   rlDest, rlSrc);
     case Instruction::INT_TO_DOUBLE:
-      return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pI2d),
-                   1, 2);
+      return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pI2d),
+                   rlDest, rlSrc);
     case Instruction::DOUBLE_TO_INT:
-      return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pD2iz),
-                   2, 1);
+      return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pD2iz),
+                   rlDest, rlSrc);
     case Instruction::FLOAT_TO_LONG:
-      return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pF2l),
-                   1, 2);
+      return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pF2l),
+                   rlDest, rlSrc);
     case Instruction::LONG_TO_FLOAT:
-      return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pL2f),
-                   2, 1);
+      return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pL2f),
+                   rlDest, rlSrc);
     case Instruction::DOUBLE_TO_LONG:
-      return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pD2l),
-                   2, 2);
+      return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pD2l),
+                   rlDest, rlSrc);
     case Instruction::LONG_TO_DOUBLE:
-      return genConversionCall(cUnit, mir, ENTRYPOINT_OFFSET(pL2d),
-                   2, 2);
+      return genConversionCall(cUnit, ENTRYPOINT_OFFSET(pL2d),
+                   rlDest, rlSrc);
     default:
       return true;
   }
@@ -2480,9 +2454,9 @@
 }
 
 /* Check if we need to check for pending suspend request */
-void genSuspendTest(CompilationUnit* cUnit, MIR* mir)
+void genSuspendTest(CompilationUnit* cUnit, int optFlags)
 {
-  if (NO_SUSPEND || (mir->optimizationFlags & MIR_IGNORE_SUSPEND_CHECK)) {
+  if (NO_SUSPEND || (optFlags & MIR_IGNORE_SUSPEND_CHECK)) {
     return;
   }
   oatFlushAllRegs(cUnit);
@@ -2513,21 +2487,21 @@
 #endif
     LIR* retLab = newLIR0(cUnit, kPseudoTargetLabel);
     LIR* target = rawLIR(cUnit, cUnit->currentDalvikOffset,
-               kPseudoSuspendTarget, (intptr_t)retLab, mir->offset);
+               kPseudoSuspendTarget, (intptr_t)retLab, cUnit->currentDalvikOffset);
     branch->target = (LIR*)target;
     oatInsertGrowableList(cUnit, &cUnit->suspendLaunchpads, (intptr_t)target);
   }
 }
 
 /* Check if we need to check for pending suspend request */
-void genSuspendTestAndBranch(CompilationUnit* cUnit, MIR* mir, LIR* target)
+void genSuspendTestAndBranch(CompilationUnit* cUnit, int optFlags, LIR* target)
 {
-  if (NO_SUSPEND || (mir->optimizationFlags & MIR_IGNORE_SUSPEND_CHECK)) {
+  if (NO_SUSPEND || (optFlags & MIR_IGNORE_SUSPEND_CHECK)) {
     opUnconditionalBranch(cUnit, target);
     return;
   }
   if (cUnit->genDebugger) {
-    genSuspendTest(cUnit, mir);
+    genSuspendTest(cUnit, optFlags);
     opUnconditionalBranch(cUnit, target);
   } else {
 #if defined(TARGET_ARM)
@@ -2542,7 +2516,7 @@
     opCmpImmBranch(cUnit, kCondNe, rSUSPEND, 0, target);
 #endif
     LIR* launchPad = rawLIR(cUnit, cUnit->currentDalvikOffset,
-                kPseudoSuspendTarget, (intptr_t)target, mir->offset);
+                kPseudoSuspendTarget, (intptr_t)target, cUnit->currentDalvikOffset);
     oatFlushAllRegs(cUnit);
     opUnconditionalBranch(cUnit, launchPad);
     oatInsertGrowableList(cUnit, &cUnit->suspendLaunchpads,
diff --git a/src/compiler/codegen/GenInvoke.cc b/src/compiler/codegen/GenInvoke.cc
index 2217059..b22cd1a 100644
--- a/src/compiler/codegen/GenInvoke.cc
+++ b/src/compiler/codegen/GenInvoke.cc
@@ -256,7 +256,7 @@
       loadValueDirectFixed(cUnit, rlArg, rARG1);
       break;
     case 1: // Is "this" null? [use rARG1]
-      genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir);
+      genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir->optimizationFlags);
       // get this->klass_ [use rARG1, set rINVOKE_TGT]
       loadWordDisp(cUnit, rARG1, Object::ClassOffset().Int32Value(),
                    rINVOKE_TGT);
@@ -471,7 +471,8 @@
                           type, skipThis);
 
   if (pcrLabel) {
-    *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir);
+    *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), rARG1,
+                             mir->optimizationFlags);
   }
   return callState;
 }
@@ -589,7 +590,8 @@
   callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
                            directCode, directMethod, type);
   if (pcrLabel) {
-    *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir);
+    *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), rARG1,
+                             mir->optimizationFlags);
   }
   return callState;
 }
@@ -640,7 +642,7 @@
   int regMax;
   int regOff = oatAllocTemp(cUnit);
   int regPtr = oatAllocTemp(cUnit);
-  genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);
+  genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->optimizationFlags);
   bool rangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
   if (rangeCheck) {
     regMax = oatAllocTemp(cUnit);
@@ -710,7 +712,7 @@
   rlObj = loadValue(cUnit, rlObj, kCoreReg);
   RegLocation rlDest = inlineTarget(cUnit, bb, mir);
   RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);
+  genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->optimizationFlags);
   loadWordDisp(cUnit, rlObj.lowReg, String::CountOffset().Int32Value(),
                rlResult.lowReg);
   if (isEmpty) {
@@ -816,7 +818,7 @@
     loadValueDirectFixed(cUnit, rlStart, regStart);
   }
   int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pIndexOf));
-  genNullCheck(cUnit, rlObj.sRegLow, regPtr, mir);
+  genNullCheck(cUnit, rlObj.sRegLow, regPtr, mir->optimizationFlags);
   LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
   oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
               (intptr_t)launchPad);
@@ -848,7 +850,7 @@
   loadValueDirectFixed(cUnit, rlThis, regThis);
   loadValueDirectFixed(cUnit, rlCmp, regCmp);
   int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pStringCompareTo));
-  genNullCheck(cUnit, rlThis.sRegLow, regThis, mir);
+  genNullCheck(cUnit, rlThis.sRegLow, regThis, mir->optimizationFlags);
   //TUNING: check if rlCmp.sRegLow is already null checked
   LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
   oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index 01ac436..9c51f0a 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -172,6 +172,10 @@
   RegLocation rlDest = badLoc;
   RegLocation rlResult = badLoc;
   Instruction::Code opcode = mir->dalvikInsn.opcode;
+  int optFlags = mir->optimizationFlags;
+  uint32_t vA = mir->dalvikInsn.vA;
+  uint32_t vB = mir->dalvikInsn.vB;
+  uint32_t vC = mir->dalvikInsn.vC;
 
   /* Prep Src and Dest locations */
   int nextSreg = 0;
@@ -232,35 +236,35 @@
     }
     case Instruction::RETURN_VOID:
       if (!cUnit->attrs & METHOD_IS_LEAF) {
-        genSuspendTest(cUnit, mir);
+        genSuspendTest(cUnit, optFlags);
       }
       break;
 
     case Instruction::RETURN:
     case Instruction::RETURN_OBJECT:
       if (!cUnit->attrs & METHOD_IS_LEAF) {
-        genSuspendTest(cUnit, mir);
+        genSuspendTest(cUnit, optFlags);
       }
       storeValue(cUnit, oatGetReturn(cUnit, cUnit->shorty[0] == 'F'), rlSrc[0]);
       break;
 
     case Instruction::RETURN_WIDE:
       if (!cUnit->attrs & METHOD_IS_LEAF) {
-        genSuspendTest(cUnit, mir);
+        genSuspendTest(cUnit, optFlags);
       }
       storeValueWide(cUnit, oatGetReturnWide(cUnit,
                        cUnit->shorty[0] == 'D'), rlSrc[0]);
       break;
 
     case Instruction::MOVE_RESULT_WIDE:
-      if (mir->optimizationFlags & MIR_INLINED)
+      if (optFlags & MIR_INLINED)
         break;  // Nop - combined w/ previous invoke
       storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
       break;
 
     case Instruction::MOVE_RESULT:
     case Instruction::MOVE_RESULT_OBJECT:
-      if (mir->optimizationFlags & MIR_INLINED)
+      if (optFlags & MIR_INLINED)
         break;  // Nop - combined w/ previous invoke
       storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
       break;
@@ -284,22 +288,21 @@
     case Instruction::CONST_4:
     case Instruction::CONST_16:
       rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
-      loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB);
+      loadConstantNoClobber(cUnit, rlResult.lowReg, vB);
       storeValue(cUnit, rlDest, rlResult);
       break;
 
     case Instruction::CONST_HIGH16:
       rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
-      loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB << 16);
+      loadConstantNoClobber(cUnit, rlResult.lowReg, vB << 16);
       storeValue(cUnit, rlDest, rlResult);
       break;
 
     case Instruction::CONST_WIDE_16:
     case Instruction::CONST_WIDE_32:
       rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
-      loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
-                            mir->dalvikInsn.vB,
-                            (mir->dalvikInsn.vB & 0x80000000) ? -1 : 0);
+      loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg, vB,
+                            (vB & 0x80000000) ? -1 : 0);
       storeValueWide(cUnit, rlDest, rlResult);
       break;
 
@@ -314,43 +317,43 @@
     case Instruction::CONST_WIDE_HIGH16:
       rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
       loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
-                            0, mir->dalvikInsn.vB << 16);
+                            0, vB << 16);
       storeValueWide(cUnit, rlDest, rlResult);
       break;
 
     case Instruction::MONITOR_ENTER:
-      genMonitorEnter(cUnit, mir, rlSrc[0]);
+      genMonitorEnter(cUnit, optFlags, rlSrc[0]);
       break;
 
     case Instruction::MONITOR_EXIT:
-      genMonitorExit(cUnit, mir, rlSrc[0]);
+      genMonitorExit(cUnit, optFlags, rlSrc[0]);
       break;
 
     case Instruction::CHECK_CAST:
-      genCheckCast(cUnit, mir, rlSrc[0]);
+      genCheckCast(cUnit, vB, rlSrc[0]);
       break;
 
     case Instruction::INSTANCE_OF:
-      genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
+      genInstanceof(cUnit, vC, rlDest, rlSrc[0]);
       break;
 
     case Instruction::NEW_INSTANCE:
-      genNewInstance(cUnit, mir, rlDest);
+      genNewInstance(cUnit, vB, rlDest);
       break;
 
     case Instruction::THROW:
-      genThrow(cUnit, mir, rlSrc[0]);
+      genThrow(cUnit, rlSrc[0]);
       break;
 
     case Instruction::THROW_VERIFICATION_ERROR:
-      genThrowVerificationError(cUnit, mir);
+      genThrowVerificationError(cUnit, vA, vB);
       break;
 
     case Instruction::ARRAY_LENGTH:
       int lenOffset;
       lenOffset = Array::LengthOffset().Int32Value();
       rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
-      genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
+      genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, optFlags);
       rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
       loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
       storeValue(cUnit, rlDest, rlResult);
@@ -358,15 +361,15 @@
 
     case Instruction::CONST_STRING:
     case Instruction::CONST_STRING_JUMBO:
-      genConstString(cUnit, mir, rlDest, rlSrc[0]);
+      genConstString(cUnit, vB, rlDest, rlSrc[0]);
       break;
 
     case Instruction::CONST_CLASS:
-      genConstClass(cUnit, mir, rlDest, rlSrc[0]);
+      genConstClass(cUnit, vB, rlDest, rlSrc[0]);
       break;
 
     case Instruction::FILL_ARRAY_DATA:
-      genFillArrayData(cUnit, mir, rlSrc[0]);
+      genFillArrayData(cUnit, vB, rlSrc[0]);
       break;
 
     case Instruction::FILLED_NEW_ARRAY:
@@ -378,36 +381,36 @@
       break;
 
     case Instruction::NEW_ARRAY:
-      genNewArray(cUnit, mir, rlDest, rlSrc[0]);
+      genNewArray(cUnit, vC, rlDest, rlSrc[0]);
       break;
 
     case Instruction::GOTO:
     case Instruction::GOTO_16:
     case Instruction::GOTO_32:
       if (bb->taken->startOffset <= mir->offset) {
-        genSuspendTestAndBranch(cUnit, mir, &labelList[bb->taken->id]);
+        genSuspendTestAndBranch(cUnit, optFlags, &labelList[bb->taken->id]);
       } else {
         opUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
       }
       break;
 
     case Instruction::PACKED_SWITCH:
-      genPackedSwitch(cUnit, mir, rlSrc[0]);
+      genPackedSwitch(cUnit, vB, rlSrc[0]);
       break;
 
     case Instruction::SPARSE_SWITCH:
-      genSparseSwitch(cUnit, mir, rlSrc[0], labelList);
+      genSparseSwitch(cUnit, vB, rlSrc[0], labelList);
       break;
 
     case Instruction::CMPL_FLOAT:
     case Instruction::CMPG_FLOAT:
     case Instruction::CMPL_DOUBLE:
     case Instruction::CMPG_DOUBLE:
-      res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
+      res = genCmpFP(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
       break;
 
     case Instruction::CMP_LONG:
-      genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
+      genCmpLong(cUnit, rlDest, rlSrc[0], rlSrc[1]);
       break;
 
     case Instruction::IF_EQ:
@@ -419,9 +422,9 @@
       bool backwardBranch;
       backwardBranch = (bb->taken->startOffset <= mir->offset);
       if (backwardBranch) {
-        genSuspendTest(cUnit, mir);
+        genSuspendTest(cUnit, optFlags);
       }
-      genCompareAndBranch(cUnit, bb, mir, rlSrc[0], rlSrc[1], labelList);
+      genCompareAndBranch(cUnit, bb, opcode, rlSrc[0], rlSrc[1], labelList);
       break;
       }
 
@@ -434,123 +437,123 @@
       bool backwardBranch;
       backwardBranch = (bb->taken->startOffset <= mir->offset);
       if (backwardBranch) {
-        genSuspendTest(cUnit, mir);
+        genSuspendTest(cUnit, optFlags);
       }
-      genCompareZeroAndBranch(cUnit, bb, mir, rlSrc[0], labelList);
+      genCompareZeroAndBranch(cUnit, bb, opcode, rlSrc[0], labelList);
       break;
       }
 
     case Instruction::AGET_WIDE:
-      genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
+      genArrayGet(cUnit, optFlags, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
       break;
     case Instruction::AGET:
     case Instruction::AGET_OBJECT:
-      genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
+      genArrayGet(cUnit, optFlags, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
       break;
     case Instruction::AGET_BOOLEAN:
-      genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
+      genArrayGet(cUnit, optFlags, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
       break;
     case Instruction::AGET_BYTE:
-      genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
+      genArrayGet(cUnit, optFlags, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
       break;
     case Instruction::AGET_CHAR:
-      genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
+      genArrayGet(cUnit, optFlags, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
       break;
     case Instruction::AGET_SHORT:
-      genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
+      genArrayGet(cUnit, optFlags, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
       break;
     case Instruction::APUT_WIDE:
-      genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
+      genArrayPut(cUnit, optFlags, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
       break;
     case Instruction::APUT:
-      genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
+      genArrayPut(cUnit, optFlags, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
       break;
     case Instruction::APUT_OBJECT:
-      genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
+      genArrayObjPut(cUnit, optFlags, rlSrc[1], rlSrc[2], rlSrc[0], 2);
       break;
     case Instruction::APUT_SHORT:
     case Instruction::APUT_CHAR:
-      genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
+      genArrayPut(cUnit, optFlags, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
       break;
     case Instruction::APUT_BYTE:
     case Instruction::APUT_BOOLEAN:
-      genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
+      genArrayPut(cUnit, optFlags, kUnsignedByte, rlSrc[1], rlSrc[2],
             rlSrc[0], 0);
       break;
 
     case Instruction::IGET_OBJECT:
     //case Instruction::IGET_OBJECT_VOLATILE:
-      genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
+      genIGet(cUnit, vC, optFlags, kWord, rlDest, rlSrc[0], false, true);
       break;
 
     case Instruction::IGET_WIDE:
     //case Instruction::IGET_WIDE_VOLATILE:
-      genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
+      genIGet(cUnit, vC, optFlags, kLong, rlDest, rlSrc[0], true, false);
       break;
 
     case Instruction::IGET:
     //case Instruction::IGET_VOLATILE:
-      genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
+      genIGet(cUnit, vC, optFlags, kWord, rlDest, rlSrc[0], false, false);
       break;
 
     case Instruction::IGET_CHAR:
-      genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
+      genIGet(cUnit, vC, optFlags, kUnsignedHalf, rlDest, rlSrc[0], false, false);
       break;
 
     case Instruction::IGET_SHORT:
-      genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
+      genIGet(cUnit, vC, optFlags, kSignedHalf, rlDest, rlSrc[0], false, false);
       break;
 
     case Instruction::IGET_BOOLEAN:
     case Instruction::IGET_BYTE:
-      genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
+      genIGet(cUnit, vC, optFlags, kUnsignedByte, rlDest, rlSrc[0], false, false);
       break;
 
     case Instruction::IPUT_WIDE:
     //case Instruction::IPUT_WIDE_VOLATILE:
-      genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
+      genIPut(cUnit, vC, optFlags, kLong, rlSrc[0], rlSrc[1], true, false);
       break;
 
     case Instruction::IPUT_OBJECT:
     //case Instruction::IPUT_OBJECT_VOLATILE:
-      genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
+      genIPut(cUnit, vC, optFlags, kWord, rlSrc[0], rlSrc[1], false, true);
       break;
 
     case Instruction::IPUT:
     //case Instruction::IPUT_VOLATILE:
-      genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
+      genIPut(cUnit, vC, optFlags, kWord, rlSrc[0], rlSrc[1], false, false);
       break;
 
     case Instruction::IPUT_BOOLEAN:
     case Instruction::IPUT_BYTE:
-      genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
+      genIPut(cUnit, vC, optFlags, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
       break;
 
     case Instruction::IPUT_CHAR:
-      genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
+      genIPut(cUnit, vC, optFlags, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
       break;
 
     case Instruction::IPUT_SHORT:
-      genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
+      genIPut(cUnit, vC, optFlags, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
       break;
 
     case Instruction::SGET_OBJECT:
-      genSget(cUnit, mir, rlDest, false, true);
+      genSget(cUnit, vB, rlDest, false, true);
       break;
     case Instruction::SGET:
     case Instruction::SGET_BOOLEAN:
     case Instruction::SGET_BYTE:
     case Instruction::SGET_CHAR:
     case Instruction::SGET_SHORT:
-      genSget(cUnit, mir, rlDest, false, false);
+      genSget(cUnit, vB, rlDest, false, false);
       break;
 
     case Instruction::SGET_WIDE:
-      genSget(cUnit, mir, rlDest, true, false);
+      genSget(cUnit, vB, rlDest, true, false);
       break;
 
     case Instruction::SPUT_OBJECT:
-      genSput(cUnit, mir, rlSrc[0], false, true);
+      genSput(cUnit, vB, rlSrc[0], false, true);
       break;
 
     case Instruction::SPUT:
@@ -558,11 +561,11 @@
     case Instruction::SPUT_BYTE:
     case Instruction::SPUT_CHAR:
     case Instruction::SPUT_SHORT:
-      genSput(cUnit, mir, rlSrc[0], false, false);
+      genSput(cUnit, vB, rlSrc[0], false, false);
       break;
 
     case Instruction::SPUT_WIDE:
-      genSput(cUnit, mir, rlSrc[0], true, false);
+      genSput(cUnit, vB, rlSrc[0], true, false);
       break;
 
     case Instruction::INVOKE_STATIC_RANGE:
@@ -602,24 +605,24 @@
 
     case Instruction::NEG_INT:
     case Instruction::NOT_INT:
-      res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
+      res = genArithOpInt(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
       break;
 
     case Instruction::NEG_LONG:
     case Instruction::NOT_LONG:
-      res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
+      res = genArithOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
       break;
 
     case Instruction::NEG_FLOAT:
-      res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
+      res = genArithOpFloat(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
       break;
 
     case Instruction::NEG_DOUBLE:
-      res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
+      res = genArithOpDouble(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
       break;
 
     case Instruction::INT_TO_LONG:
-      genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
+      genIntToLong(cUnit, rlDest, rlSrc[0]);
       break;
 
     case Instruction::LONG_TO_INT:
@@ -631,7 +634,7 @@
     case Instruction::INT_TO_BYTE:
     case Instruction::INT_TO_SHORT:
     case Instruction::INT_TO_CHAR:
-      genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
+      genIntNarrowing(cUnit, opcode, rlDest, rlSrc[0]);
       break;
 
     case Instruction::INT_TO_FLOAT:
@@ -644,7 +647,7 @@
     case Instruction::DOUBLE_TO_INT:
     case Instruction::DOUBLE_TO_LONG:
     case Instruction::DOUBLE_TO_FLOAT:
-      genConversion(cUnit, mir);
+      genConversion(cUnit, opcode, rlDest, rlSrc[0]);
       break;
 
     case Instruction::ADD_INT:
@@ -669,7 +672,7 @@
     case Instruction::SHL_INT_2ADDR:
     case Instruction::SHR_INT_2ADDR:
     case Instruction::USHR_INT_2ADDR:
-      genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
+      genArithOpInt(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
       break;
 
     case Instruction::ADD_LONG:
@@ -688,7 +691,7 @@
     case Instruction::AND_LONG_2ADDR:
     case Instruction::OR_LONG_2ADDR:
     case Instruction::XOR_LONG_2ADDR:
-      genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
+      genArithOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
       break;
 
     case Instruction::SHL_LONG:
@@ -697,7 +700,7 @@
     case Instruction::SHL_LONG_2ADDR:
     case Instruction::SHR_LONG_2ADDR:
     case Instruction::USHR_LONG_2ADDR:
-      genShiftOpLong(cUnit,mir, rlDest, rlSrc[0], rlSrc[1]);
+      genShiftOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
       break;
 
     case Instruction::ADD_FLOAT:
@@ -710,7 +713,7 @@
     case Instruction::MUL_FLOAT_2ADDR:
     case Instruction::DIV_FLOAT_2ADDR:
     case Instruction::REM_FLOAT_2ADDR:
-      genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
+      genArithOpFloat(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
       break;
 
     case Instruction::ADD_DOUBLE:
@@ -723,7 +726,7 @@
     case Instruction::MUL_DOUBLE_2ADDR:
     case Instruction::DIV_DOUBLE_2ADDR:
     case Instruction::REM_DOUBLE_2ADDR:
-      genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
+      genArithOpDouble(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
       break;
 
     case Instruction::RSUB_INT:
@@ -745,7 +748,7 @@
     case Instruction::SHL_INT_LIT8:
     case Instruction::SHR_INT_LIT8:
     case Instruction::USHR_INT_LIT8:
-      genArithOpIntLit(cUnit, mir, rlDest, rlSrc[0], mir->dalvikInsn.vC);
+      genArithOpIntLit(cUnit, opcode, rlDest, rlSrc[0], vC);
       break;
 
     default:
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index c20151e..bc30335 100644
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ b/src/compiler/codegen/arm/ArchFactory.cc
@@ -28,7 +28,7 @@
 
 void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset);
 
-bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc)
 {
   rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
@@ -95,7 +95,7 @@
   }
   if (!skipOverflowCheck) {
     opRegRegImm(cUnit, kOpSub, rLR, rSP, cUnit->frameSize - (spillCount * 4));
-    genRegRegCheck(cUnit, kCondCc, rLR, r12, NULL, kThrowStackOverflow);
+    genRegRegCheck(cUnit, kCondCc, rLR, r12, kThrowStackOverflow);
     opRegCopy(cUnit, rSP, rLR);     // Establish stack
   } else {
     opRegImm(cUnit, kOpSub, rSP, cUnit->frameSize - (spillCount * 4));
diff --git a/src/compiler/codegen/arm/Codegen.h b/src/compiler/codegen/arm/Codegen.h
index 10f5e38..22f6157 100644
--- a/src/compiler/codegen/arm/Codegen.h
+++ b/src/compiler/codegen/arm/Codegen.h
@@ -31,19 +31,20 @@
 LIR *opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2);
 LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
                     int checkValue, LIR* target);
-bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc);
 
 /* Forward declaraton the portable versions due to circular dependency */
-bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode,
                              RegLocation rlDest, RegLocation rlSrc1,
                              RegLocation rlSrc2);
 
-bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode,
                               RegLocation rlDest, RegLocation rlSrc1,
                               RegLocation rlSrc2);
 
-bool genConversionPortable(CompilationUnit* cUnit, MIR* mir);
+bool genConversionPortable(CompilationUnit* cUnit, Instruction::Code opcode,
+                           RegLocation rlDest, RegLocation rlSrc);
 
 ArmConditionCode oatArmConditionEncoding(ConditionCode code);
 
diff --git a/src/compiler/codegen/arm/FP/Thumb2VFP.cc b/src/compiler/codegen/arm/FP/Thumb2VFP.cc
index fbce1f5..fb14aec 100644
--- a/src/compiler/codegen/arm/FP/Thumb2VFP.cc
+++ b/src/compiler/codegen/arm/FP/Thumb2VFP.cc
@@ -16,7 +16,7 @@
 
 namespace art {
 
-bool genArithOpFloat(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genArithOpFloat(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest,
                      RegLocation rlSrc1, RegLocation rlSrc2)
 {
   int op = kThumbBkpt;
@@ -26,7 +26,7 @@
    * Don't attempt to optimize register usage since these opcodes call out to
    * the handlers.
    */
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::ADD_FLOAT_2ADDR:
     case Instruction::ADD_FLOAT:
       op = kThumb2Vadds;
@@ -46,7 +46,7 @@
     case Instruction::REM_FLOAT_2ADDR:
     case Instruction::REM_FLOAT:
     case Instruction::NEG_FLOAT: {
-      return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genArithOpFloatPortable(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
     }
     default:
       return true;
@@ -59,13 +59,13 @@
   return false;
 }
 
-bool genArithOpDouble(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
-                      RegLocation rlSrc1, RegLocation rlSrc2)
+bool genArithOpDouble(CompilationUnit* cUnit, Instruction::Code opcode,
+                      RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
 {
   int op = kThumbBkpt;
   RegLocation rlResult;
 
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::ADD_DOUBLE_2ADDR:
     case Instruction::ADD_DOUBLE:
       op = kThumb2Vaddd;
@@ -85,7 +85,7 @@
     case Instruction::REM_DOUBLE_2ADDR:
     case Instruction::REM_DOUBLE:
     case Instruction::NEG_DOUBLE: {
-      return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genArithOpDoublePortable(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
     }
     default:
       return true;
@@ -105,73 +105,53 @@
   return false;
 }
 
-bool genConversion(CompilationUnit* cUnit, MIR* mir)
+bool genConversion(CompilationUnit* cUnit, Instruction::Code opcode,
+                   RegLocation rlDest, RegLocation rlSrc)
 {
-  Instruction::Code opcode = mir->dalvikInsn.opcode;
   int op = kThumbBkpt;
-  bool longSrc = false;
-  bool longDest = false;
   int srcReg;
-  RegLocation rlSrc;
-  RegLocation rlDest;
   RegLocation rlResult;
 
   switch (opcode) {
     case Instruction::INT_TO_FLOAT:
-      longSrc = false;
-      longDest = false;
       op = kThumb2VcvtIF;
       break;
     case Instruction::FLOAT_TO_INT:
-      longSrc = false;
-      longDest = false;
       op = kThumb2VcvtFI;
       break;
     case Instruction::DOUBLE_TO_FLOAT:
-      longSrc = true;
-      longDest = false;
       op = kThumb2VcvtDF;
       break;
     case Instruction::FLOAT_TO_DOUBLE:
-      longSrc = false;
-      longDest = true;
       op = kThumb2VcvtFd;
       break;
     case Instruction::INT_TO_DOUBLE:
-      longSrc = false;
-      longDest = true;
       op = kThumb2VcvtID;
       break;
     case Instruction::DOUBLE_TO_INT:
-      longSrc = true;
-      longDest = false;
       op = kThumb2VcvtDI;
       break;
     case Instruction::LONG_TO_DOUBLE:
     case Instruction::FLOAT_TO_LONG:
     case Instruction::LONG_TO_FLOAT:
     case Instruction::DOUBLE_TO_LONG:
-      return genConversionPortable(cUnit, mir);
+      return genConversionPortable(cUnit, opcode, rlDest, rlSrc);
     default:
       return true;
   }
-  if (longSrc) {
-    rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+  if (rlSrc.wide) {
     rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
     srcReg = S2D(rlSrc.lowReg, rlSrc.highReg);
   } else {
-    rlSrc = oatGetSrc(cUnit, mir, 0);
     rlSrc = loadValue(cUnit, rlSrc, kFPReg);
     srcReg = rlSrc.lowReg;
   }
-  if (longDest) {
-    rlDest = oatGetDestWide(cUnit, mir, 0, 1);
+  if (rlDest.wide) {
     rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
     newLIR2(cUnit, (ArmOpcode)op, S2D(rlResult.lowReg, rlResult.highReg),
             srcReg);
     storeValueWide(cUnit, rlDest, rlResult);
   } else {
-    rlDest = oatGetDest(cUnit, mir, 0);
     rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
     newLIR2(cUnit, (ArmOpcode)op, rlResult.lowReg, srcReg);
     storeValue(cUnit, rlDest, rlResult);
@@ -233,14 +213,14 @@
 }
 
 
-bool genCmpFP(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genCmpFP(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest,
         RegLocation rlSrc1, RegLocation rlSrc2)
 {
   bool isDouble;
   int defaultResult;
   RegLocation rlResult;
 
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::CMPL_FLOAT:
       isDouble = false;
       defaultResult = -1;
diff --git a/src/compiler/codegen/arm/Thumb2/Factory.cc b/src/compiler/codegen/arm/Thumb2/Factory.cc
index 67f7938..c9dbe62 100644
--- a/src/compiler/codegen/arm/Thumb2/Factory.cc
+++ b/src/compiler/codegen/arm/Thumb2/Factory.cc
@@ -774,7 +774,7 @@
  * on base (which must have an associated sReg and MIR).  If not
  * performing null check, incoming MIR can be null.
  */
-LIR* loadBaseDispBody(CompilationUnit* cUnit, MIR* mir, int rBase,
+LIR* loadBaseDispBody(CompilationUnit* cUnit, int rBase,
                       int displacement, int rDest, int rDestHi, OpSize size,
                       int sReg)
 {
@@ -802,9 +802,9 @@
         }
         break;
       } else {
-        res = loadBaseDispBody(cUnit, mir, rBase, displacement, rDest,
+        res = loadBaseDispBody(cUnit, rBase, displacement, rDest,
                                -1, kWord, sReg);
-        loadBaseDispBody(cUnit, NULL, rBase, displacement + 4, rDestHi,
+        loadBaseDispBody(cUnit, rBase, displacement + 4, rDestHi,
                          -1, kWord, INVALID_SREG);
         return res;
       }
@@ -890,17 +890,17 @@
   return load;
 }
 
-LIR* loadBaseDisp(CompilationUnit* cUnit, MIR* mir, int rBase,
+LIR* loadBaseDisp(CompilationUnit* cUnit, int rBase,
                   int displacement, int rDest, OpSize size, int sReg)
 {
-  return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1, size,
+  return loadBaseDispBody(cUnit, rBase, displacement, rDest, -1, size,
                           sReg);
 }
 
- LIR* loadBaseDispWide(CompilationUnit* cUnit, MIR* mir, int rBase,
+ LIR* loadBaseDispWide(CompilationUnit* cUnit, int rBase,
                        int displacement, int rDestLo, int rDestHi, int sReg)
 {
-  return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi,
+  return loadBaseDispBody(cUnit, rBase, displacement, rDestLo, rDestHi,
                           kLong, sReg);
 }
 
@@ -1011,7 +1011,7 @@
 
 void loadPair(CompilationUnit* cUnit, int base, int lowReg, int highReg)
 {
-  loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG);
+  loadBaseDispWide(cUnit, base, 0, lowReg, highReg, INVALID_SREG);
 }
 
 LIR* fpRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 5252b49..9ec470c 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -163,7 +163,8 @@
   // Point of no return - no aborts after this
   genPrintLabel(cUnit, mir);
   rlObj = loadArg(cUnit, rlObj);
-  genIGet(cUnit, mir, size, rlDest, rlObj, longOrDouble, isObject);
+  genIGet(cUnit, fieldIdx, mir->optimizationFlags, size, rlDest, rlObj,
+          longOrDouble, isObject);
   return getNextMir(cUnit, bb, mir);
 }
 
@@ -198,7 +199,8 @@
   genPrintLabel(cUnit, mir);
   rlObj = loadArg(cUnit, rlObj);
   rlSrc = loadArg(cUnit, rlSrc);
-  genIPut(cUnit, mir, size, rlSrc, rlObj, longOrDouble, isObject);
+  genIPut(cUnit, fieldIdx, mir->optimizationFlags, size, rlSrc, rlObj,
+          longOrDouble, isObject);
   return getNextMir(cUnit, bb, mir);
 }
 
@@ -366,10 +368,10 @@
  *   add   rPC, rDisp   ; This is the branch from which we compute displacement
  *   cbnz  rIdx, lp
  */
-void genSparseSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
-                     LIR* labelList)
+void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
+                     RegLocation rlSrc, LIR* labelList)
 {
-  const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
   if (cUnit->printMe) {
     dumpSparseSwitchTable(table);
   }
@@ -377,7 +379,7 @@
   SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
                                               true, kAllocData);
   tabRec->table = table;
-  tabRec->vaddr = mir->offset;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
   int size = table[1];
   tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true, kAllocLIR);
   oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
@@ -414,9 +416,10 @@
 }
 
 
-void genPackedSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
+                     RegLocation rlSrc)
 {
-  const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
   if (cUnit->printMe) {
     dumpPackedSwitchTable(table);
   }
@@ -424,7 +427,7 @@
   SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
                                               true, kAllocData);
   tabRec->table = table;
-  tabRec->vaddr = mir->offset;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
   int size = table[1];
   tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true, kAllocLIR);
   oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
@@ -470,14 +473,14 @@
  *
  * Total size is 4+(width * size + 1)/2 16-bit code units.
  */
-void genFillArrayData(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genFillArrayData(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc)
 {
-  const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
   // Add the table to the list - we'll process it later
   FillArrayData *tabRec = (FillArrayData *)
      oatNew(cUnit, sizeof(FillArrayData), true, kAllocData);
   tabRec->table = table;
-  tabRec->vaddr = mir->offset;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
   u2 width = tabRec->table[1];
   u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16);
   tabRec->size = (size * width) + 8;
@@ -540,13 +543,13 @@
  * preserved.
  *
  */
-void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genMonitorEnter(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
 {
   oatFlushAllRegs(cUnit);
   DCHECK_EQ(LW_SHAPE_THIN, 0);
   loadValueDirectFixed(cUnit, rlSrc, r0);  // Get obj
   oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, r0, mir);
+  genNullCheck(cUnit, rlSrc.sRegLow, r0, optFlags);
   loadWordDisp(cUnit, rSELF, Thread::ThinLockIdOffset().Int32Value(), r2);
   newLIR3(cUnit, kThumb2Ldrex, r1, r0,
           Object::MonitorOffset().Int32Value() >> 2); // Get object->lock
@@ -574,13 +577,13 @@
  * a zero recursion count, it's safe to punch it back to the
  * initial, unlock thin state with a store word.
  */
-void genMonitorExit(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genMonitorExit(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
 {
   DCHECK_EQ(LW_SHAPE_THIN, 0);
   oatFlushAllRegs(cUnit);
   loadValueDirectFixed(cUnit, rlSrc, r0);  // Get obj
   oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, r0, mir);
+  genNullCheck(cUnit, rlSrc.sRegLow, r0, optFlags);
   loadWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r1); // Get lock
   loadWordDisp(cUnit, rSELF, Thread::ThinLockIdOffset().Int32Value(), r2);
   // Is lock unheld on lock or held by us (==threadId) on unlock?
@@ -614,7 +617,7 @@
  *     neg   rX
  * done:
  */
-void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genCmpLong(CompilationUnit* cUnit, RegLocation rlDest,
         RegLocation rlSrc1, RegLocation rlSrc2)
 {
   LIR* target1;
diff --git a/src/compiler/codegen/mips/ArchFactory.cc b/src/compiler/codegen/mips/ArchFactory.cc
index 8317215..4fd127f 100644
--- a/src/compiler/codegen/mips/ArchFactory.cc
+++ b/src/compiler/codegen/mips/ArchFactory.cc
@@ -26,7 +26,7 @@
 
 namespace art {
 
-bool genAddLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2)
 {
   rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
@@ -50,7 +50,7 @@
   return false;
 }
 
-bool genSubLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest,
         RegLocation rlSrc1, RegLocation rlSrc2)
 {
   rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
@@ -74,7 +74,7 @@
   return false;
 }
 
-bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc)
 {
   rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
@@ -177,7 +177,7 @@
   DCHECK_EQ(cUnit->numFPSpills, 0);
   if (!skipOverflowCheck) {
     opRegRegImm(cUnit, kOpSub, newSP, rSP, cUnit->frameSize - (spillCount * 4));
-    genRegRegCheck(cUnit, kCondCc, newSP, checkReg, NULL, kThrowStackOverflow);
+    genRegRegCheck(cUnit, kCondCc, newSP, checkReg, kThrowStackOverflow);
     opRegCopy(cUnit, rSP, newSP);     // Establish stack
   } else {
     opRegImm(cUnit, kOpSub, rSP, cUnit->frameSize - (spillCount * 4));
diff --git a/src/compiler/codegen/mips/ArchUtility.cc b/src/compiler/codegen/mips/ArchUtility.cc
index f1afa78..ead9ff5 100644
--- a/src/compiler/codegen/mips/ArchUtility.cc
+++ b/src/compiler/codegen/mips/ArchUtility.cc
@@ -127,7 +127,7 @@
   return buf;
 }
 
-// FIXME: need to redo resourse maps for MIPS - fix this at that time
+// FIXME: need to redo resource maps for MIPS - fix this at that time
 void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix)
 {
   char buf[256];
diff --git a/src/compiler/codegen/mips/Codegen.h b/src/compiler/codegen/mips/Codegen.h
index 6ddc5ac..6add82a 100644
--- a/src/compiler/codegen/mips/Codegen.h
+++ b/src/compiler/codegen/mips/Codegen.h
@@ -27,11 +27,11 @@
 namespace art {
 
 #if defined(_CODEGEN_C)
-bool genAddLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2);
-bool genSubLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2);
-bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc);
 LIR *opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value);
 LIR *opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2);
@@ -41,15 +41,16 @@
                     int checkValue, LIR* target);
 
 /* Forward declaraton the portable versions due to circular dependency */
-bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode,
                                     RegLocation rlDest, RegLocation rlSrc1,
                                     RegLocation rlSrc2);
 
-bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode,
                                      RegLocation rlDest, RegLocation rlSrc1,
                                      RegLocation rlSrc2);
 
-bool genConversionPortable(CompilationUnit* cUnit, MIR* mir);
+bool genConversionPortable(CompilationUnit* cUnit, Instruction::Code opcode,
+                           RegLocation rlDest, RegLocation rlSrc);
 
 int loadHelper(CompilationUnit* cUnit, int offset);
 LIR* loadConstant(CompilationUnit* cUnit, int reg, int immVal);
diff --git a/src/compiler/codegen/mips/FP/MipsFP.cc b/src/compiler/codegen/mips/FP/MipsFP.cc
index c101039..a57d34a 100644
--- a/src/compiler/codegen/mips/FP/MipsFP.cc
+++ b/src/compiler/codegen/mips/FP/MipsFP.cc
@@ -18,7 +18,7 @@
 
 namespace art {
 
-bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
+bool genArithOpFloat(CompilationUnit *cUnit, Instruction::Code opcode, RegLocation rlDest,
                      RegLocation rlSrc1, RegLocation rlSrc2)
 {
 #ifdef __mips_hard_float
@@ -29,7 +29,7 @@
    * Don't attempt to optimize register usage since these opcodes call out to
    * the handlers.
    */
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::ADD_FLOAT_2ADDR:
     case Instruction::ADD_FLOAT:
       op = kMipsFadds;
@@ -49,7 +49,7 @@
     case Instruction::REM_FLOAT_2ADDR:
     case Instruction::REM_FLOAT:
     case Instruction::NEG_FLOAT: {
-      return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genArithOpFloatPortable(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
     }
     default:
       return true;
@@ -63,11 +63,11 @@
 
   return false;
 #else
-  return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+  return genArithOpFloatPortable(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
 #endif
 }
 
-static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir,
+static bool genArithOpDouble(CompilationUnit *cUnit, Instruction::Code opcode,
                              RegLocation rlDest, RegLocation rlSrc1,
                              RegLocation rlSrc2)
 {
@@ -75,7 +75,7 @@
   int op = kMipsNop;
   RegLocation rlResult;
 
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::ADD_DOUBLE_2ADDR:
     case Instruction::ADD_DOUBLE:
       op = kMipsFaddd;
@@ -95,7 +95,7 @@
     case Instruction::REM_DOUBLE_2ADDR:
     case Instruction::REM_DOUBLE:
     case Instruction::NEG_DOUBLE: {
-      return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genArithOpDoublePortable(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
     }
     default:
       return true;
@@ -113,40 +113,28 @@
   storeValueWide(cUnit, rlDest, rlResult);
   return false;
 #else
-  return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+  return genArithOpDoublePortable(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
 #endif
 }
 
-static bool genConversion(CompilationUnit *cUnit, MIR *mir)
+static bool genConversion(CompilationUnit *cUnit, Instruction::Code opcode,
+                          RegLocation rlDest, RegLocation rlSrc)
 {
 #ifdef __mips_hard_float
-  Instruction::Code opcode = mir->dalvikInsn.opcode;
-  bool longSrc = false;
-  bool longDest = false;
-  RegLocation rlSrc;
-  RegLocation rlDest;
   int op = kMipsNop;
   int srcReg;
   RegLocation rlResult;
   switch (opcode) {
     case Instruction::INT_TO_FLOAT:
-      longSrc = false;
-      longDest = false;
       op = kMipsFcvtsw;
       break;
     case Instruction::DOUBLE_TO_FLOAT:
-      longSrc = true;
-      longDest = false;
       op = kMipsFcvtsd;
       break;
     case Instruction::FLOAT_TO_DOUBLE:
-      longSrc = false;
-      longDest = true;
       op = kMipsFcvtds;
       break;
     case Instruction::INT_TO_DOUBLE:
-      longSrc = false;
-      longDest = true;
       op = kMipsFcvtdw;
       break;
     case Instruction::FLOAT_TO_INT:
@@ -155,44 +143,40 @@
     case Instruction::FLOAT_TO_LONG:
     case Instruction::LONG_TO_FLOAT:
     case Instruction::DOUBLE_TO_LONG:
-      return genConversionPortable(cUnit, mir);
+      return genConversionPortable(cUnit, opcode, rlDest, rlSrc);
     default:
       return true;
   }
-  if (longSrc) {
-    rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+  if (rlSrc.wide) {
     rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
     srcReg = S2D(rlSrc.lowReg, rlSrc.highReg);
   } else {
-    rlSrc = oatGetSrc(cUnit, mir, 0);
     rlSrc = loadValue(cUnit, rlSrc, kFPReg);
     srcReg = rlSrc.lowReg;
   }
-  if (longDest) {
-    rlDest = oatGetDestWide(cUnit, mir, 0, 1);
+  if (rlDest.wide) {
     rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
     newLIR2(cUnit, (MipsOpCode)op, S2D(rlResult.lowReg, rlResult.highReg),
             srcReg);
     storeValueWide(cUnit, rlDest, rlResult);
   } else {
-    rlDest = oatGetDest(cUnit, mir, 0);
     rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
     newLIR2(cUnit, (MipsOpCode)op, rlResult.lowReg, srcReg);
     storeValue(cUnit, rlDest, rlResult);
   }
   return false;
 #else
-  return genConversionPortable(cUnit, mir);
+  return genConversionPortable(cUnit, opcode, rlDest, rlSrc);
 #endif
 }
 
-static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
+static bool genCmpFP(CompilationUnit *cUnit, Instruction::Code opcode, RegLocation rlDest,
                      RegLocation rlSrc1, RegLocation rlSrc2)
 {
   bool wide = true;
   int offset;
 
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::CMPL_FLOAT:
       offset = ENTRYPOINT_OFFSET(pCmplFloat);
       wide = false;
diff --git a/src/compiler/codegen/mips/Mips32/Factory.cc b/src/compiler/codegen/mips/Mips32/Factory.cc
index 8f3c1ec..ad220f8 100644
--- a/src/compiler/codegen/mips/Mips32/Factory.cc
+++ b/src/compiler/codegen/mips/Mips32/Factory.cc
@@ -521,7 +521,7 @@
   return res; /* NULL always returned which should be ok since no callers use it */
 }
 
-LIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase,
+LIR *loadBaseDispBody(CompilationUnit *cUnit, int rBase,
                       int displacement, int rDest, int rDestHi,
                       OpSize size, int sReg)
 /*
@@ -626,17 +626,17 @@
   return load;
 }
 
-LIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase,
+LIR *loadBaseDisp(CompilationUnit *cUnit, int rBase,
                   int displacement, int rDest, OpSize size, int sReg)
 {
-  return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1,
+  return loadBaseDispBody(cUnit, rBase, displacement, rDest, -1,
                           size, sReg);
 }
 
-LIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase,
+LIR *loadBaseDispWide(CompilationUnit *cUnit, int rBase,
                       int displacement, int rDestLo, int rDestHi, int sReg)
 {
-  return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi,
+  return loadBaseDispBody(cUnit, rBase, displacement, rDestLo, rDestHi,
                           kLong, sReg);
 }
 
diff --git a/src/compiler/codegen/mips/Mips32/Gen.cc b/src/compiler/codegen/mips/Mips32/Gen.cc
index 46c90f8..090c086 100644
--- a/src/compiler/codegen/mips/Mips32/Gen.cc
+++ b/src/compiler/codegen/mips/Mips32/Gen.cc
@@ -63,10 +63,10 @@
  * done:
  *
  */
-void genSparseSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
-           LIR* labelList)
+void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
+                     RegLocation rlSrc, LIR* labelList)
 {
-  const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
   if (cUnit->printMe) {
     dumpSparseSwitchTable(table);
   }
@@ -74,7 +74,7 @@
   SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
                                               true, kAllocData);
   tabRec->table = table;
-  tabRec->vaddr = mir->offset;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
   int elements = table[1];
   tabRec->targets = (LIR* *)oatNew(cUnit, elements * sizeof(LIR*), true,
                                    kAllocLIR);
@@ -142,9 +142,10 @@
  *   jr    r_RA
  * done:
  */
-void genPackedSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
+                     RegLocation rlSrc)
 {
-  const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
   if (cUnit->printMe) {
     dumpPackedSwitchTable(table);
   }
@@ -152,7 +153,7 @@
   SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
                         true, kAllocData);
   tabRec->table = table;
-  tabRec->vaddr = mir->offset;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
   int size = table[1];
   tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true,
                     kAllocLIR);
@@ -225,14 +226,15 @@
  *
  * Total size is 4+(width * size + 1)/2 16-bit code units.
  */
-void genFillArrayData(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genFillArrayData(CompilationUnit* cUnit, uint32_t tableOffset,
+                      RegLocation rlSrc)
 {
-  const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
   // Add the table to the list - we'll process it later
   FillArrayData *tabRec = (FillArrayData *)
      oatNew(cUnit, sizeof(FillArrayData), true, kAllocData);
   tabRec->table = table;
-  tabRec->vaddr = mir->offset;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
   u2 width = tabRec->table[1];
   u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16);
   tabRec->size = (size * width) + 8;
@@ -284,12 +286,12 @@
 /*
  * TODO: implement fast path to short-circuit thin-lock case
  */
-void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genMonitorEnter(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
 {
   oatFlushAllRegs(cUnit);
   loadValueDirectFixed(cUnit, rlSrc, rARG0);  // Get obj
   oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, rARG0, mir);
+  genNullCheck(cUnit, rlSrc.sRegLow, rARG0, optFlags);
   // Go expensive route - artLockObjectFromCode(self, obj);
   int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pLockObjectFromCode));
   oatClobberCalleeSave(cUnit);
@@ -299,12 +301,12 @@
 /*
  * TODO: implement fast path to short-circuit thin-lock case
  */
-void genMonitorExit(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genMonitorExit(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
 {
   oatFlushAllRegs(cUnit);
   loadValueDirectFixed(cUnit, rlSrc, rARG0);  // Get obj
   oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, rARG0, mir);
+  genNullCheck(cUnit, rlSrc.sRegLow, rARG0, optFlags);
   // Go expensive route - UnlockObjectFromCode(obj);
   int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pUnlockObjectFromCode));
   oatClobberCalleeSave(cUnit);
@@ -327,7 +329,7 @@
  * finish:
  *
  */
-void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genCmpLong(CompilationUnit* cUnit, RegLocation rlDest,
         RegLocation rlSrc1, RegLocation rlSrc2)
 {
   rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
diff --git a/src/compiler/codegen/x86/ArchFactory.cc b/src/compiler/codegen/x86/ArchFactory.cc
index 1d3893a..9e6ef09 100644
--- a/src/compiler/codegen/x86/ArchFactory.cc
+++ b/src/compiler/codegen/x86/ArchFactory.cc
@@ -24,7 +24,7 @@
 
 namespace art {
 
-bool genAddLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2)
 {
   oatFlushAllRegs(cUnit);
@@ -39,7 +39,7 @@
   return false;
 }
 
-bool genSubLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2)
 {
   oatFlushAllRegs(cUnit);
@@ -54,7 +54,7 @@
   return false;
 }
 
-bool genAndLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2)
 {
   oatFlushAllRegs(cUnit);
@@ -69,7 +69,7 @@
   return false;
 }
 
-bool genOrLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest,
                RegLocation rlSrc1, RegLocation rlSrc2)
 {
   oatFlushAllRegs(cUnit);
@@ -84,7 +84,7 @@
   return false;
 }
 
-bool genXorLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2)
 {
   oatFlushAllRegs(cUnit);
@@ -99,7 +99,7 @@
   return false;
 }
 
-bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc)
 {
   oatFlushAllRegs(cUnit);
diff --git a/src/compiler/codegen/x86/Codegen.h b/src/compiler/codegen/x86/Codegen.h
index f04acd4..568a388 100644
--- a/src/compiler/codegen/x86/Codegen.h
+++ b/src/compiler/codegen/x86/Codegen.h
@@ -27,17 +27,17 @@
 namespace art {
 
 #if defined(_CODEGEN_C)
-bool genAddLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2);
-bool genSubLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2);
-bool genAndLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2);
-bool genOrLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2);
-bool genXorLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2);
-bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc);
 LIR *opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value);
 LIR *opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2);
@@ -47,15 +47,16 @@
                     int checkValue, LIR* target);
 
 /* Forward declaration of the portable versions due to circular dependency */
-bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode,
                                     RegLocation rlDest, RegLocation rlSrc1,
                                     RegLocation rlSrc2);
 
-bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode,
                                      RegLocation rlDest, RegLocation rlSrc1,
                                      RegLocation rlSrc2);
 
-bool genConversionPortable(CompilationUnit* cUnit, MIR* mir);
+bool genConversionPortable(CompilationUnit* cUnit, Instruction::Code opcode,
+                           RegLocation rlDest, RegLocation rlSrc);
 
 int loadHelper(CompilationUnit* cUnit, int offset);
 LIR* loadConstant(CompilationUnit* cUnit, int reg, int immVal);
diff --git a/src/compiler/codegen/x86/FP/X86FP.cc b/src/compiler/codegen/x86/FP/X86FP.cc
index e6b47d2..460f56b 100644
--- a/src/compiler/codegen/x86/FP/X86FP.cc
+++ b/src/compiler/codegen/x86/FP/X86FP.cc
@@ -16,7 +16,7 @@
 
 namespace art {
 
-static bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir,
+static bool genArithOpFloat(CompilationUnit *cUnit, Instruction::Code opcode,
                             RegLocation rlDest, RegLocation rlSrc1,
                             RegLocation rlSrc2) {
   X86OpCode op = kX86Nop;
@@ -26,7 +26,7 @@
    * Don't attempt to optimize register usage since these opcodes call out to
    * the handlers.
    */
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::ADD_FLOAT_2ADDR:
     case Instruction::ADD_FLOAT:
       op = kX86AddssRR;
@@ -52,7 +52,7 @@
       return false;
     case Instruction::REM_FLOAT_2ADDR:
     case Instruction::REM_FLOAT: {
-      return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genArithOpFloatPortable(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
     }
     default:
       return true;
@@ -71,13 +71,13 @@
   return false;
 }
 
-static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir,
+static bool genArithOpDouble(CompilationUnit *cUnit, Instruction::Code opcode,
                              RegLocation rlDest, RegLocation rlSrc1,
                              RegLocation rlSrc2) {
   X86OpCode op = kX86Nop;
   RegLocation rlResult;
 
-  switch (mir->dalvikInsn.opcode) {
+  switch (opcode) {
     case Instruction::ADD_DOUBLE_2ADDR:
     case Instruction::ADD_DOUBLE:
       op = kX86AddsdRR;
@@ -103,7 +103,7 @@
       return false;
     case Instruction::REM_DOUBLE_2ADDR:
     case Instruction::REM_DOUBLE: {
-      return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
+      return genArithOpDoublePortable(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
     }
     default:
       return true;
@@ -125,46 +125,32 @@
   return false;
 }
 
-static bool genConversion(CompilationUnit *cUnit, MIR *mir) {
-  Instruction::Code opcode = mir->dalvikInsn.opcode;
-  bool longSrc = false;
-  bool longDest = false;
+static bool genConversion(CompilationUnit *cUnit, Instruction::Code opcode,
+                          RegLocation rlDest, RegLocation rlSrc) {
   RegisterClass rcSrc = kFPReg;
-  RegLocation rlSrc;
-  RegLocation rlDest;
   X86OpCode op = kX86Nop;
   int srcReg;
   RegLocation rlResult;
   switch (opcode) {
     case Instruction::INT_TO_FLOAT:
-      longSrc = false;
-      longDest = false;
       rcSrc = kCoreReg;
       op = kX86Cvtsi2ssRR;
       break;
     case Instruction::DOUBLE_TO_FLOAT:
-      longSrc = true;
-      longDest = false;
       rcSrc = kFPReg;
       op = kX86Cvtsd2ssRR;
       break;
     case Instruction::FLOAT_TO_DOUBLE:
-      longSrc = false;
-      longDest = true;
       rcSrc = kFPReg;
       op = kX86Cvtss2sdRR;
       break;
     case Instruction::INT_TO_DOUBLE:
-      longSrc = false;
-      longDest = true;
       rcSrc = kCoreReg;
       op = kX86Cvtsi2sdRR;
       break;
     case Instruction::FLOAT_TO_INT: {
-      rlSrc = oatGetSrc(cUnit, mir, 0);
       rlSrc = loadValue(cUnit, rlSrc, kFPReg);
       srcReg = rlSrc.lowReg;
-      rlDest = oatGetDest(cUnit, mir, 0);
       oatClobberSReg(cUnit, rlDest.sRegLow);
       rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
       int tempReg = oatAllocTempFloat(cUnit);
@@ -184,10 +170,8 @@
       return false;
     }
     case Instruction::DOUBLE_TO_INT: {
-      rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
       rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
       srcReg = rlSrc.lowReg;
-      rlDest = oatGetDest(cUnit, mir, 0);
       oatClobberSReg(cUnit, rlDest.sRegLow);
       rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
       int tempReg = oatAllocTempDouble(cUnit);
@@ -213,26 +197,22 @@
       UNIMPLEMENTED(WARNING) << "inline l2[df] " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
     case Instruction::FLOAT_TO_LONG:
     case Instruction::DOUBLE_TO_LONG:
-      return genConversionPortable(cUnit, mir);
+      return genConversionPortable(cUnit, opcode, rlDest, rlSrc);
     default:
       return true;
   }
-  if (longSrc) {
-    rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+  if (rlSrc.wide) {
     rlSrc = loadValueWide(cUnit, rlSrc, rcSrc);
     srcReg = S2D(rlSrc.lowReg, rlSrc.highReg);
   } else {
-    rlSrc = oatGetSrc(cUnit, mir, 0);
     rlSrc = loadValue(cUnit, rlSrc, rcSrc);
     srcReg = rlSrc.lowReg;
   }
-  if (longDest) {
-    rlDest = oatGetDestWide(cUnit, mir, 0, 1);
+  if (rlDest.wide) {
     rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
     newLIR2(cUnit, op, S2D(rlResult.lowReg, rlResult.highReg), srcReg);
     storeValueWide(cUnit, rlDest, rlResult);
   } else {
-    rlDest = oatGetDest(cUnit, mir, 0);
     rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
     newLIR2(cUnit, op, rlResult.lowReg, srcReg);
     storeValue(cUnit, rlDest, rlResult);
@@ -240,9 +220,8 @@
   return false;
 }
 
-static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
+static bool genCmpFP(CompilationUnit *cUnit, Instruction::Code code, RegLocation rlDest,
                      RegLocation rlSrc1, RegLocation rlSrc2) {
-  Instruction::Code code = mir->dalvikInsn.opcode;
   bool single = (code == Instruction::CMPL_FLOAT) || (code == Instruction::CMPG_FLOAT);
   bool unorderedGt = (code == Instruction::CMPG_DOUBLE) || (code == Instruction::CMPG_FLOAT);
   int srcReg1;
diff --git a/src/compiler/codegen/x86/X86/Factory.cc b/src/compiler/codegen/x86/X86/Factory.cc
index 66e7028..c5186c6 100644
--- a/src/compiler/codegen/x86/X86/Factory.cc
+++ b/src/compiler/codegen/x86/X86/Factory.cc
@@ -414,7 +414,7 @@
 #endif
 }
 
-LIR* loadBaseIndexedDisp(CompilationUnit *cUnit, MIR *mir,
+LIR* loadBaseIndexedDisp(CompilationUnit *cUnit,
                          int rBase, int rIndex, int scale, int displacement,
                          int rDest, int rDestHi,
                          OpSize size, int sReg) {
@@ -505,27 +505,27 @@
 /* Load value from base + scaled index. */
 LIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase,
                      int rIndex, int rDest, int scale, OpSize size) {
-  return loadBaseIndexedDisp(cUnit, NULL, rBase, rIndex, scale, 0,
+  return loadBaseIndexedDisp(cUnit, rBase, rIndex, scale, 0,
                              rDest, INVALID_REG, size, INVALID_SREG);
 }
 
-LIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir,
+LIR *loadBaseDisp(CompilationUnit *cUnit,
                   int rBase, int displacement,
                   int rDest,
                   OpSize size, int sReg) {
-  return loadBaseIndexedDisp(cUnit, mir, rBase, INVALID_REG, 0, displacement,
+  return loadBaseIndexedDisp(cUnit, rBase, INVALID_REG, 0, displacement,
                              rDest, INVALID_REG, size, sReg);
 }
 
-LIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir,
+LIR *loadBaseDispWide(CompilationUnit *cUnit,
                       int rBase, int displacement,
                       int rDestLo, int rDestHi,
                       int sReg) {
-  return loadBaseIndexedDisp(cUnit, mir, rBase, INVALID_REG, 0, displacement,
+  return loadBaseIndexedDisp(cUnit, rBase, INVALID_REG, 0, displacement,
                              rDestLo, rDestHi, kLong, sReg);
 }
 
-LIR* storeBaseIndexedDisp(CompilationUnit *cUnit, MIR *mir,
+LIR* storeBaseIndexedDisp(CompilationUnit *cUnit,
                           int rBase, int rIndex, int scale, int displacement,
                           int rSrc, int rSrcHi,
                           OpSize size, int sReg) {
@@ -600,14 +600,14 @@
 LIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase, int rIndex, int rSrc,
                       int scale, OpSize size)
 {
-  return storeBaseIndexedDisp(cUnit, NULL, rBase, rIndex, scale, 0,
+  return storeBaseIndexedDisp(cUnit, rBase, rIndex, scale, 0,
                               rSrc, INVALID_REG, size, INVALID_SREG);
 }
 
 LIR *storeBaseDisp(CompilationUnit *cUnit, int rBase, int displacement,
                    int rSrc, OpSize size)
 {
-    return storeBaseIndexedDisp(cUnit, NULL, rBase, INVALID_REG, 0,
+    return storeBaseIndexedDisp(cUnit, rBase, INVALID_REG, 0,
                                 displacement, rSrc, INVALID_REG, size,
                                 INVALID_SREG);
 }
@@ -615,7 +615,7 @@
 LIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase, int displacement,
                        int rSrcLo, int rSrcHi)
 {
-  return storeBaseIndexedDisp(cUnit, NULL, rBase, INVALID_REG, 0, displacement,
+  return storeBaseIndexedDisp(cUnit, rBase, INVALID_REG, 0, displacement,
                               rSrcLo, rSrcHi, kLong, INVALID_SREG);
 }
 
diff --git a/src/compiler/codegen/x86/X86/Gen.cc b/src/compiler/codegen/x86/X86/Gen.cc
index 46c98ad..597eda1 100644
--- a/src/compiler/codegen/x86/X86/Gen.cc
+++ b/src/compiler/codegen/x86/X86/Gen.cc
@@ -34,10 +34,10 @@
  * Perform register memory operation.
  */
 LIR* genRegMemCheck(CompilationUnit* cUnit, ConditionCode cCode,
-                    int reg1, int base, int offset, MIR* mir, ThrowKind kind)
+                    int reg1, int base, int offset, ThrowKind kind)
 {
   LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind,
-                    mir ? mir->offset : 0, reg1, base, offset);
+                    cUnit->currentDalvikOffset, reg1, base, offset);
   opRegMem(cUnit, kOpCmp, reg1, base, offset);
   LIR* branch = opCondBranch(cUnit, cCode, tgt);
   // Remember branch target - will process later
@@ -51,10 +51,10 @@
  */
 BasicBlock *findBlock(CompilationUnit* cUnit, unsigned int codeOffset,
                       bool split, bool create, BasicBlock** immedPredBlockP);
-void genSparseSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
-                     LIR* labelList)
+void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
+                     RegLocation rlSrc, LIR* labelList)
 {
-  const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
   if (cUnit->printMe) {
     dumpSparseSwitchTable(table);
   }
@@ -64,7 +64,8 @@
   rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
   for (int i = 0; i < entries; i++) {
     int key = keys[i];
-    BasicBlock* case_block = findBlock(cUnit, mir->offset + targets[i],
+    BasicBlock* case_block = findBlock(cUnit,
+                                       cUnit->currentDalvikOffset + targets[i],
                                        false, false, NULL);
     opCmpImmBranch(cUnit, kCondEq, rlSrc.lowReg, key,
                    &labelList[case_block->id]);
@@ -87,9 +88,10 @@
  * jmp  rStartOfMethod
  * done:
  */
-void genPackedSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
+                     RegLocation rlSrc)
 {
-  const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
   if (cUnit->printMe) {
     dumpPackedSwitchTable(table);
   }
@@ -97,7 +99,7 @@
   SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
                                               true, kAllocData);
   tabRec->table = table;
-  tabRec->vaddr = mir->offset;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
   int size = table[1];
   tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true,
                                    kAllocLIR);
@@ -149,14 +151,15 @@
  *
  * Total size is 4+(width * size + 1)/2 16-bit code units.
  */
-void genFillArrayData(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genFillArrayData(CompilationUnit* cUnit, uint32_t tableOffset,
+                      RegLocation rlSrc)
 {
-  const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
   // Add the table to the list - we'll process it later
   FillArrayData *tabRec = (FillArrayData *)oatNew(cUnit, sizeof(FillArrayData),
       true, kAllocData);
   tabRec->table = table;
-  tabRec->vaddr = mir->offset;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
   u2 width = tabRec->table[1];
   u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16);
   tabRec->size = (size * width) + 8;
@@ -204,18 +207,18 @@
 #endif
 }
 
-LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg, MIR* mir);
+LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg, int optFlags);
 void callRuntimeHelperReg(CompilationUnit* cUnit, int helperOffset, int arg0);
 
 /*
  * TODO: implement fast path to short-circuit thin-lock case
  */
-void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genMonitorEnter(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
 {
   oatFlushAllRegs(cUnit);
   loadValueDirectFixed(cUnit, rlSrc, rARG0);  // Get obj
   oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, rARG0, mir);
+  genNullCheck(cUnit, rlSrc.sRegLow, rARG0, optFlags);
   // Go expensive route - artLockObjectFromCode(self, obj);
   callRuntimeHelperReg(cUnit, ENTRYPOINT_OFFSET(pLockObjectFromCode), rARG0);
 }
@@ -223,12 +226,12 @@
 /*
  * TODO: implement fast path to short-circuit thin-lock case
  */
-void genMonitorExit(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+void genMonitorExit(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
 {
   oatFlushAllRegs(cUnit);
   loadValueDirectFixed(cUnit, rlSrc, rARG0);  // Get obj
   oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, rARG0, mir);
+  genNullCheck(cUnit, rlSrc.sRegLow, rARG0, optFlags);
   // Go expensive route - UnlockObjectFromCode(obj);
   callRuntimeHelperReg(cUnit, ENTRYPOINT_OFFSET(pUnlockObjectFromCode), rARG0);
 }
@@ -249,7 +252,7 @@
  * finish:
  *
  */
-void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+void genCmpLong(CompilationUnit* cUnit, RegLocation rlDest,
                 RegLocation rlSrc1, RegLocation rlSrc2)
 {
   oatFlushAllRegs(cUnit);