diff --git a/src/main/java/com/android/tools/r8/graph/Code.java b/src/main/java/com/android/tools/r8/graph/Code.java
index 52217a3..08d65f0 100644
--- a/src/main/java/com/android/tools/r8/graph/Code.java
+++ b/src/main/java/com/android/tools/r8/graph/Code.java
@@ -60,6 +60,10 @@
     throw new Unreachable(getClass().getCanonicalName() + ".asCfCode()");
   }
 
+  public LazyCfCode asLazyCfCode() {
+    throw new Unreachable(getClass().getCanonicalName() + ".asLazyCfCode()");
+  }
+
   public DexCode asDexCode() {
     throw new Unreachable(getClass().getCanonicalName() + ".asDexCode()");
   }
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index a1125af..2f1d3fd 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -3,57 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.graph;
 
-import static org.objectweb.asm.ClassReader.EXPAND_FRAMES;
 import static org.objectweb.asm.ClassReader.SKIP_FRAMES;
 import static org.objectweb.asm.Opcodes.ACC_DEPRECATED;
 import static org.objectweb.asm.Opcodes.ASM6;
 
 import com.android.tools.r8.ProgramResource.Kind;
-import com.android.tools.r8.cf.code.CfArithmeticBinop;
-import com.android.tools.r8.cf.code.CfArrayLength;
-import com.android.tools.r8.cf.code.CfArrayLoad;
-import com.android.tools.r8.cf.code.CfArrayStore;
-import com.android.tools.r8.cf.code.CfCheckCast;
-import com.android.tools.r8.cf.code.CfCmp;
-import com.android.tools.r8.cf.code.CfConstClass;
-import com.android.tools.r8.cf.code.CfConstMethodHandle;
-import com.android.tools.r8.cf.code.CfConstMethodType;
-import com.android.tools.r8.cf.code.CfConstNull;
-import com.android.tools.r8.cf.code.CfConstNumber;
-import com.android.tools.r8.cf.code.CfConstString;
-import com.android.tools.r8.cf.code.CfFieldInstruction;
-import com.android.tools.r8.cf.code.CfFrame;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.cf.code.CfGoto;
-import com.android.tools.r8.cf.code.CfIf;
-import com.android.tools.r8.cf.code.CfIfCmp;
-import com.android.tools.r8.cf.code.CfIinc;
-import com.android.tools.r8.cf.code.CfInstanceOf;
-import com.android.tools.r8.cf.code.CfInstruction;
-import com.android.tools.r8.cf.code.CfInvoke;
-import com.android.tools.r8.cf.code.CfInvokeDynamic;
-import com.android.tools.r8.cf.code.CfLabel;
-import com.android.tools.r8.cf.code.CfLoad;
-import com.android.tools.r8.cf.code.CfLogicalBinop;
-import com.android.tools.r8.cf.code.CfMonitor;
-import com.android.tools.r8.cf.code.CfMultiANewArray;
-import com.android.tools.r8.cf.code.CfNeg;
-import com.android.tools.r8.cf.code.CfNew;
-import com.android.tools.r8.cf.code.CfNewArray;
-import com.android.tools.r8.cf.code.CfNop;
-import com.android.tools.r8.cf.code.CfNumberConversion;
-import com.android.tools.r8.cf.code.CfPosition;
-import com.android.tools.r8.cf.code.CfReturn;
-import com.android.tools.r8.cf.code.CfReturnVoid;
-import com.android.tools.r8.cf.code.CfStackInstruction;
-import com.android.tools.r8.cf.code.CfStore;
-import com.android.tools.r8.cf.code.CfSwitch;
-import com.android.tools.r8.cf.code.CfThrow;
-import com.android.tools.r8.cf.code.CfTryCatch;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.CfCode.LocalVariableInfo;
 import com.android.tools.r8.graph.DexValue.DexValueAnnotation;
 import com.android.tools.r8.graph.DexValue.DexValueArray;
 import com.android.tools.r8.graph.DexValue.DexValueBoolean;
@@ -68,26 +25,15 @@
 import com.android.tools.r8.graph.DexValue.DexValueShort;
 import com.android.tools.r8.graph.DexValue.DexValueString;
 import com.android.tools.r8.graph.DexValue.DexValueType;
-import com.android.tools.r8.graph.JarCode.ReparseContext;
-import com.android.tools.r8.ir.code.If;
-import com.android.tools.r8.ir.code.MemberType;
-import com.android.tools.r8.ir.code.Monitor;
-import com.android.tools.r8.ir.code.Position;
-import com.android.tools.r8.ir.code.ValueType;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.InternalOptions;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.IdentityHashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
@@ -96,10 +42,8 @@
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Handle;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
 import org.objectweb.asm.TypePath;
 
@@ -144,12 +88,9 @@
     input.reset();
 
     ClassReader reader = new ClassReader(input);
-    int flags = SKIP_FRAMES;
-    if (application.options.enableCfFrontend) {
-      flags = EXPAND_FRAMES;
-    }
     reader.accept(
-        new CreateDexClassVisitor(origin, classKind, reader.b, application, classConsumer), flags);
+        new CreateDexClassVisitor(origin, classKind, reader.b, application, classConsumer),
+        SKIP_FRAMES);
   }
 
   private static int cleanAccessFlags(int access) {
@@ -316,9 +257,6 @@
     @Override
     public MethodVisitor visitMethod(
         int access, String name, String desc, String signature, String[] exceptions) {
-      if (application.options.enableCfFrontend) {
-        return new CfCreateMethodVisitor(access, name, desc, signature, exceptions, this);
-      }
       return new CreateMethodVisitor(access, name, desc, signature, exceptions, this);
     }
 
@@ -628,7 +566,11 @@
     public void visitCode() {
       assert !flags.isAbstract() && !flags.isNative();
       if (parent.classKind == ClassKind.PROGRAM) {
-        code = new JarCode(method, parent.origin, parent.context, parent.application);
+        if (parent.application.options.enableCfFrontend) {
+          code = new LazyCfCode(method, parent.origin, parent.context, parent.application);
+        } else {
+          code = new JarCode(method, parent.origin, parent.context, parent.application);
+        }
       }
     }
 
@@ -682,646 +624,6 @@
     }
   }
 
-  private static class CfCreateMethodVisitor extends CreateMethodVisitor {
-
-    private final JarApplicationReader application;
-    private final DexItemFactory factory;
-    private int maxStack;
-    private int maxLocals;
-    private List<CfInstruction> instructions;
-    private List<CfTryCatch> tryCatchRanges;
-    private List<LocalVariableInfo> localVariables;
-    private Map<Label, CfLabel> labelMap;
-
-    public CfCreateMethodVisitor(
-        int access,
-        String name,
-        String desc,
-        String signature,
-        String[] exceptions,
-        CreateDexClassVisitor parent) {
-      super(access, name, desc, signature, exceptions, parent);
-      this.application = parent.application;
-      this.factory = application.getFactory();
-    }
-
-    @Override
-    public void visitCode() {
-      assert !flags.isAbstract() && !flags.isNative();
-      maxStack = 0;
-      maxLocals = 0;
-      instructions = new ArrayList<>();
-      tryCatchRanges = new ArrayList<>();
-      localVariables = new ArrayList<>();
-      labelMap = new IdentityHashMap<>();
-    }
-
-    @Override
-    public void visitEnd() {
-      if (!flags.isAbstract() && !flags.isNative() && parent.classKind == ClassKind.PROGRAM) {
-        code =
-            new CfCode(method, maxStack, maxLocals, instructions, tryCatchRanges, localVariables);
-      }
-      super.visitEnd();
-    }
-
-    @Override
-    public void visitFrame(
-        int frameType, int nLocals, Object[] localTypes, int nStack, Object[] stackTypes) {
-      assert frameType == Opcodes.F_NEW;
-      Int2ReferenceSortedMap<FrameType> parsedLocals = parseLocals(nLocals, localTypes);
-      List<FrameType> parsedStack = parseStack(nStack, stackTypes);
-      instructions.add(new CfFrame(parsedLocals, parsedStack));
-    }
-
-    private Int2ReferenceSortedMap<FrameType> parseLocals(int typeCount, Object[] asmTypes) {
-      Int2ReferenceSortedMap<FrameType> types = new Int2ReferenceAVLTreeMap<>();
-      int i = 0;
-      for (int j = 0; j < typeCount; j++) {
-        Object localType = asmTypes[j];
-        FrameType value = getFrameType(localType);
-        types.put(i++, value);
-        if (value.isWide()) {
-          i++;
-        }
-      }
-      return types;
-    }
-
-    private List<FrameType> parseStack(int nStack, Object[] stackTypes) {
-      List<FrameType> dexStack = new ArrayList<>(nStack);
-      for (int i = 0; i < nStack; i++) {
-        dexStack.add(getFrameType(stackTypes[i]));
-      }
-      return dexStack;
-    }
-
-    private FrameType getFrameType(Object localType) {
-      if (localType instanceof Label) {
-        return FrameType.uninitializedNew(getLabel((Label) localType));
-      } else if (localType == Opcodes.UNINITIALIZED_THIS) {
-        return FrameType.uninitializedThis();
-      } else if (localType == null || localType == Opcodes.TOP) {
-        return FrameType.top();
-      } else {
-        return FrameType.initialized(parseAsmType(localType));
-      }
-    }
-
-    private CfLabel getLabel(Label label) {
-      return labelMap.computeIfAbsent(label, l -> new CfLabel());
-    }
-
-    private DexType parseAsmType(Object local) {
-      assert local != null && local != Opcodes.TOP;
-      if (local == Opcodes.INTEGER) {
-        return factory.intType;
-      } else if (local == Opcodes.FLOAT) {
-        return factory.floatType;
-      } else if (local == Opcodes.LONG) {
-        return factory.longType;
-      } else if (local == Opcodes.DOUBLE) {
-        return factory.doubleType;
-      } else if (local == Opcodes.NULL) {
-        return DexItemFactory.nullValueType;
-      } else if (local instanceof String) {
-        return createTypeFromInternalType((String) local);
-      } else {
-        throw new Unreachable("Unexpected ASM type: " + local);
-      }
-    }
-
-    private DexType createTypeFromInternalType(String local) {
-      assert local.indexOf('.') == -1;
-      return factory.createType("L" + local + ";");
-    }
-
-    @Override
-    public void visitInsn(int opcode) {
-      switch (opcode) {
-        case Opcodes.NOP:
-          instructions.add(new CfNop());
-          break;
-        case Opcodes.ACONST_NULL:
-          instructions.add(new CfConstNull());
-          break;
-        case Opcodes.ICONST_M1:
-        case Opcodes.ICONST_0:
-        case Opcodes.ICONST_1:
-        case Opcodes.ICONST_2:
-        case Opcodes.ICONST_3:
-        case Opcodes.ICONST_4:
-        case Opcodes.ICONST_5:
-          instructions.add(new CfConstNumber(opcode - Opcodes.ICONST_0, ValueType.INT));
-          break;
-        case Opcodes.LCONST_0:
-        case Opcodes.LCONST_1:
-          instructions.add(new CfConstNumber(opcode - Opcodes.LCONST_0, ValueType.LONG));
-          break;
-        case Opcodes.FCONST_0:
-        case Opcodes.FCONST_1:
-        case Opcodes.FCONST_2:
-          instructions.add(
-              new CfConstNumber(
-                  Float.floatToRawIntBits(opcode - Opcodes.FCONST_0), ValueType.FLOAT));
-          break;
-        case Opcodes.DCONST_0:
-        case Opcodes.DCONST_1:
-          instructions.add(
-              new CfConstNumber(
-                  Double.doubleToRawLongBits(opcode - Opcodes.DCONST_0), ValueType.DOUBLE));
-          break;
-        case Opcodes.IALOAD:
-        case Opcodes.LALOAD:
-        case Opcodes.FALOAD:
-        case Opcodes.DALOAD:
-        case Opcodes.AALOAD:
-        case Opcodes.BALOAD:
-        case Opcodes.CALOAD:
-        case Opcodes.SALOAD:
-          instructions.add(new CfArrayLoad(getMemberTypeForOpcode(opcode)));
-          break;
-        case Opcodes.IASTORE:
-        case Opcodes.LASTORE:
-        case Opcodes.FASTORE:
-        case Opcodes.DASTORE:
-        case Opcodes.AASTORE:
-        case Opcodes.BASTORE:
-        case Opcodes.CASTORE:
-        case Opcodes.SASTORE:
-          instructions.add(new CfArrayStore(getMemberTypeForOpcode(opcode)));
-          break;
-        case Opcodes.POP:
-        case Opcodes.POP2:
-        case Opcodes.DUP:
-        case Opcodes.DUP_X1:
-        case Opcodes.DUP_X2:
-        case Opcodes.DUP2:
-        case Opcodes.DUP2_X1:
-        case Opcodes.DUP2_X2:
-        case Opcodes.SWAP:
-          instructions.add(CfStackInstruction.fromAsm(opcode));
-          break;
-        case Opcodes.IADD:
-        case Opcodes.LADD:
-        case Opcodes.FADD:
-        case Opcodes.DADD:
-        case Opcodes.ISUB:
-        case Opcodes.LSUB:
-        case Opcodes.FSUB:
-        case Opcodes.DSUB:
-        case Opcodes.IMUL:
-        case Opcodes.LMUL:
-        case Opcodes.FMUL:
-        case Opcodes.DMUL:
-        case Opcodes.IDIV:
-        case Opcodes.LDIV:
-        case Opcodes.FDIV:
-        case Opcodes.DDIV:
-        case Opcodes.IREM:
-        case Opcodes.LREM:
-        case Opcodes.FREM:
-        case Opcodes.DREM:
-          instructions.add(CfArithmeticBinop.fromAsm(opcode));
-          break;
-        case Opcodes.INEG:
-        case Opcodes.LNEG:
-        case Opcodes.FNEG:
-        case Opcodes.DNEG:
-          instructions.add(CfNeg.fromAsm(opcode));
-          break;
-        case Opcodes.ISHL:
-        case Opcodes.LSHL:
-        case Opcodes.ISHR:
-        case Opcodes.LSHR:
-        case Opcodes.IUSHR:
-        case Opcodes.LUSHR:
-        case Opcodes.IAND:
-        case Opcodes.LAND:
-        case Opcodes.IOR:
-        case Opcodes.LOR:
-        case Opcodes.IXOR:
-        case Opcodes.LXOR:
-          instructions.add(CfLogicalBinop.fromAsm(opcode));
-          break;
-        case Opcodes.I2L:
-        case Opcodes.I2F:
-        case Opcodes.I2D:
-        case Opcodes.L2I:
-        case Opcodes.L2F:
-        case Opcodes.L2D:
-        case Opcodes.F2I:
-        case Opcodes.F2L:
-        case Opcodes.F2D:
-        case Opcodes.D2I:
-        case Opcodes.D2L:
-        case Opcodes.D2F:
-        case Opcodes.I2B:
-        case Opcodes.I2C:
-        case Opcodes.I2S:
-          instructions.add(CfNumberConversion.fromAsm(opcode));
-          break;
-        case Opcodes.LCMP:
-        case Opcodes.FCMPL:
-        case Opcodes.FCMPG:
-        case Opcodes.DCMPL:
-        case Opcodes.DCMPG:
-          instructions.add(CfCmp.fromAsm(opcode));
-          break;
-        case Opcodes.IRETURN:
-          instructions.add(new CfReturn(ValueType.INT));
-          break;
-        case Opcodes.LRETURN:
-          instructions.add(new CfReturn(ValueType.LONG));
-          break;
-        case Opcodes.FRETURN:
-          instructions.add(new CfReturn(ValueType.FLOAT));
-          break;
-        case Opcodes.DRETURN:
-          instructions.add(new CfReturn(ValueType.DOUBLE));
-          break;
-        case Opcodes.ARETURN:
-          instructions.add(new CfReturn(ValueType.OBJECT));
-          break;
-        case Opcodes.RETURN:
-          instructions.add(new CfReturnVoid());
-          break;
-        case Opcodes.ARRAYLENGTH:
-          instructions.add(new CfArrayLength());
-          break;
-        case Opcodes.ATHROW:
-          instructions.add(new CfThrow());
-          break;
-        case Opcodes.MONITORENTER:
-          instructions.add(new CfMonitor(Monitor.Type.ENTER));
-          break;
-        case Opcodes.MONITOREXIT:
-          instructions.add(new CfMonitor(Monitor.Type.EXIT));
-          break;
-        default:
-          throw new Unreachable("Unknown instruction");
-      }
-    }
-
-    private DexType opType(int opcode, DexItemFactory factory) {
-      switch (opcode) {
-        case Opcodes.IADD:
-        case Opcodes.ISUB:
-        case Opcodes.IMUL:
-        case Opcodes.IDIV:
-        case Opcodes.IREM:
-        case Opcodes.INEG:
-        case Opcodes.ISHL:
-        case Opcodes.ISHR:
-        case Opcodes.IUSHR:
-          return factory.intType;
-        case Opcodes.LADD:
-        case Opcodes.LSUB:
-        case Opcodes.LMUL:
-        case Opcodes.LDIV:
-        case Opcodes.LREM:
-        case Opcodes.LNEG:
-        case Opcodes.LSHL:
-        case Opcodes.LSHR:
-        case Opcodes.LUSHR:
-          return factory.longType;
-        case Opcodes.FADD:
-        case Opcodes.FSUB:
-        case Opcodes.FMUL:
-        case Opcodes.FDIV:
-        case Opcodes.FREM:
-        case Opcodes.FNEG:
-          return factory.floatType;
-        case Opcodes.DADD:
-        case Opcodes.DSUB:
-        case Opcodes.DMUL:
-        case Opcodes.DDIV:
-        case Opcodes.DREM:
-        case Opcodes.DNEG:
-          return factory.doubleType;
-        default:
-          throw new Unreachable("Unexpected opcode " + opcode);
-      }
-    }
-
-    private static MemberType getMemberTypeForOpcode(int opcode) {
-      switch (opcode) {
-        case Opcodes.IALOAD:
-        case Opcodes.IASTORE:
-          return MemberType.INT;
-        case Opcodes.FALOAD:
-        case Opcodes.FASTORE:
-          return MemberType.FLOAT;
-        case Opcodes.LALOAD:
-        case Opcodes.LASTORE:
-          return MemberType.LONG;
-        case Opcodes.DALOAD:
-        case Opcodes.DASTORE:
-          return MemberType.DOUBLE;
-        case Opcodes.AALOAD:
-        case Opcodes.AASTORE:
-          return MemberType.OBJECT;
-        case Opcodes.BALOAD:
-        case Opcodes.BASTORE:
-          return MemberType.BOOLEAN; // TODO: Distinguish byte and boolean.
-        case Opcodes.CALOAD:
-        case Opcodes.CASTORE:
-          return MemberType.CHAR;
-        case Opcodes.SALOAD:
-        case Opcodes.SASTORE:
-          return MemberType.SHORT;
-        default:
-          throw new Unreachable("Unexpected array opcode " + opcode);
-      }
-    }
-
-    @Override
-    public void visitIntInsn(int opcode, int operand) {
-      switch (opcode) {
-        case Opcodes.SIPUSH:
-        case Opcodes.BIPUSH:
-          instructions.add(new CfConstNumber(operand, ValueType.INT));
-          break;
-        case Opcodes.NEWARRAY:
-          instructions.add(
-              new CfNewArray(factory.createArrayType(1, arrayTypeDesc(operand, factory))));
-          break;
-        default:
-          throw new Unreachable("Unexpected int opcode " + opcode);
-      }
-    }
-
-    private static DexType arrayTypeDesc(int arrayTypeCode, DexItemFactory factory) {
-      switch (arrayTypeCode) {
-        case Opcodes.T_BOOLEAN:
-          return factory.booleanType;
-        case Opcodes.T_CHAR:
-          return factory.charType;
-        case Opcodes.T_FLOAT:
-          return factory.floatType;
-        case Opcodes.T_DOUBLE:
-          return factory.doubleType;
-        case Opcodes.T_BYTE:
-          return factory.byteType;
-        case Opcodes.T_SHORT:
-          return factory.shortType;
-        case Opcodes.T_INT:
-          return factory.intType;
-        case Opcodes.T_LONG:
-          return factory.longType;
-        default:
-          throw new Unreachable("Unexpected array-type code " + arrayTypeCode);
-      }
-    }
-
-    @Override
-    public void visitVarInsn(int opcode, int var) {
-      ValueType type;
-      switch (opcode) {
-        case Opcodes.ILOAD:
-        case Opcodes.ISTORE:
-          type = ValueType.INT;
-          break;
-        case Opcodes.FLOAD:
-        case Opcodes.FSTORE:
-          type = ValueType.FLOAT;
-          break;
-        case Opcodes.LLOAD:
-        case Opcodes.LSTORE:
-          type = ValueType.LONG;
-          break;
-        case Opcodes.DLOAD:
-        case Opcodes.DSTORE:
-          type = ValueType.DOUBLE;
-          break;
-        case Opcodes.ALOAD:
-        case Opcodes.ASTORE:
-          type = ValueType.OBJECT;
-          break;
-        case Opcodes.RET:
-          throw new Unreachable("RET should be handled by the ASM jsr inliner");
-        default:
-          throw new Unreachable("Unexpected VarInsn opcode: " + opcode);
-      }
-      if (Opcodes.ILOAD <= opcode && opcode <= Opcodes.ALOAD) {
-        instructions.add(new CfLoad(type, var));
-      } else {
-        instructions.add(new CfStore(type, var));
-      }
-    }
-
-    @Override
-    public void visitTypeInsn(int opcode, String typeName) {
-      DexType type = createTypeFromInternalType(typeName);
-      switch (opcode) {
-        case Opcodes.NEW:
-          instructions.add(new CfNew(type));
-          break;
-        case Opcodes.ANEWARRAY:
-          instructions.add(new CfNewArray(factory.createArrayType(1, type)));
-          break;
-        case Opcodes.CHECKCAST:
-          instructions.add(new CfCheckCast(type));
-          break;
-        case Opcodes.INSTANCEOF:
-          instructions.add(new CfInstanceOf(type));
-          break;
-        default:
-          throw new Unreachable("Unexpected TypeInsn opcode: " + opcode);
-      }
-    }
-
-    @Override
-    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-      DexField field =
-          factory.createField(createTypeFromInternalType(owner), factory.createType(desc), name);
-      // TODO(mathiasr): Don't require CfFieldInstruction::declaringField. It is needed for proper
-      // renaming in the backend, but it is not available here in the frontend.
-      instructions.add(new CfFieldInstruction(opcode, field, field));
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-      visitMethodInsn(opcode, owner, name, desc, false);
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
-      DexMethod method = application.getMethod(owner, name, desc);
-      instructions.add(new CfInvoke(opcode, method, itf));
-    }
-
-    @Override
-    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
-      DexCallSite callSite =
-          DexCallSite.fromAsmInvokeDynamic(application, parent.type, name, desc, bsm, bsmArgs);
-      instructions.add(new CfInvokeDynamic(callSite));
-    }
-
-    @Override
-    public void visitJumpInsn(int opcode, Label label) {
-      CfLabel target = getLabel(label);
-      if (Opcodes.IFEQ <= opcode && opcode <= Opcodes.IF_ACMPNE) {
-        if (opcode <= Opcodes.IFLE) {
-          // IFEQ, IFNE, IFLT, IFGE, IFGT, or IFLE.
-          instructions.add(new CfIf(ifType(opcode), ValueType.INT, target));
-        } else {
-          // IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, or
-          // IF_ACMPNE.
-          ValueType valueType;
-          if (opcode <= Opcodes.IF_ICMPLE) {
-            valueType = ValueType.INT;
-          } else {
-            valueType = ValueType.OBJECT;
-          }
-          instructions.add(new CfIfCmp(ifType(opcode), valueType, target));
-        }
-      } else {
-        // GOTO, JSR, IFNULL or IFNONNULL.
-        switch (opcode) {
-          case Opcodes.GOTO:
-            instructions.add(new CfGoto(target));
-            break;
-          case Opcodes.IFNULL:
-          case Opcodes.IFNONNULL:
-            If.Type type = opcode == Opcodes.IFNULL ? If.Type.EQ : If.Type.NE;
-            instructions.add(new CfIf(type, ValueType.OBJECT, target));
-            break;
-          case Opcodes.JSR:
-            throw new Unreachable("JSR should be handled by the ASM jsr inliner");
-          default:
-            throw new Unreachable("Unexpected JumpInsn opcode: " + opcode);
-        }
-      }
-    }
-
-    private static If.Type ifType(int opcode) {
-      switch (opcode) {
-        case Opcodes.IFEQ:
-        case Opcodes.IF_ICMPEQ:
-        case Opcodes.IF_ACMPEQ:
-          return If.Type.EQ;
-        case Opcodes.IFNE:
-        case Opcodes.IF_ICMPNE:
-        case Opcodes.IF_ACMPNE:
-          return If.Type.NE;
-        case Opcodes.IFLT:
-        case Opcodes.IF_ICMPLT:
-          return If.Type.LT;
-        case Opcodes.IFGE:
-        case Opcodes.IF_ICMPGE:
-          return If.Type.GE;
-        case Opcodes.IFGT:
-        case Opcodes.IF_ICMPGT:
-          return If.Type.GT;
-        case Opcodes.IFLE:
-        case Opcodes.IF_ICMPLE:
-          return If.Type.LE;
-        default:
-          throw new Unreachable("Unexpected If instruction opcode: " + opcode);
-      }
-    }
-
-    @Override
-    public void visitLabel(Label label) {
-      instructions.add(getLabel(label));
-    }
-
-    @Override
-    public void visitLdcInsn(Object cst) {
-      if (cst instanceof Type) {
-        Type type = (Type) cst;
-        if (type.getSort() == Type.METHOD) {
-          DexProto proto = application.getProto(type.getDescriptor());
-          instructions.add(new CfConstMethodType(proto));
-        } else {
-          instructions.add(new CfConstClass(factory.createType(type.getDescriptor())));
-        }
-      } else if (cst instanceof String) {
-        instructions.add(new CfConstString(factory.createString((String) cst)));
-      } else if (cst instanceof Long) {
-        instructions.add(new CfConstNumber((Long) cst, ValueType.LONG));
-      } else if (cst instanceof Double) {
-        long l = Double.doubleToRawLongBits((Double) cst);
-        instructions.add(new CfConstNumber(l, ValueType.DOUBLE));
-      } else if (cst instanceof Integer) {
-        instructions.add(new CfConstNumber((Integer) cst, ValueType.INT));
-      } else if (cst instanceof Float) {
-        long i = Float.floatToRawIntBits((Float) cst);
-        instructions.add(new CfConstNumber(i, ValueType.FLOAT));
-      } else if (cst instanceof Handle) {
-        instructions.add(
-            new CfConstMethodHandle(
-                DexMethodHandle.fromAsmHandle((Handle) cst, application, parent.type)));
-      } else {
-        throw new CompilationError("Unsupported constant: " + cst.toString());
-      }
-    }
-
-    @Override
-    public void visitIincInsn(int var, int increment) {
-      instructions.add(new CfIinc(var, increment));
-    }
-
-    @Override
-    public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
-      assert max == min + labels.length - 1;
-      ArrayList<CfLabel> targets = new ArrayList<>(labels.length);
-      for (Label label : labels) {
-        targets.add(getLabel(label));
-      }
-      instructions.add(new CfSwitch(CfSwitch.Kind.TABLE, getLabel(dflt), new int[] {min}, targets));
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-      ArrayList<CfLabel> targets = new ArrayList<>(labels.length);
-      for (Label label : labels) {
-        targets.add(getLabel(label));
-      }
-      instructions.add(new CfSwitch(CfSwitch.Kind.LOOKUP, getLabel(dflt), keys, targets));
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-      instructions.add(new CfMultiANewArray(factory.createType(desc), dims));
-    }
-
-    @Override
-    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-      List<DexType> guards =
-          Collections.singletonList(
-              type == null ? DexItemFactory.catchAllType : createTypeFromInternalType(type));
-      List<CfLabel> targets = Collections.singletonList(getLabel(handler));
-      tryCatchRanges.add(new CfTryCatch(getLabel(start), getLabel(end), guards, targets));
-    }
-
-    @Override
-    public void visitLocalVariable(
-        String name, String desc, String signature, Label start, Label end, int index) {
-      DebugLocalInfo debugLocalInfo =
-          new DebugLocalInfo(
-              factory.createString(name),
-              factory.createType(desc),
-              signature == null ? null : factory.createString(signature));
-      localVariables.add(
-          new LocalVariableInfo(index, debugLocalInfo, getLabel(start), getLabel(end)));
-    }
-
-    @Override
-    public void visitLineNumber(int line, Label start) {
-      instructions.add(new CfPosition(getLabel(start), new Position(line, null, method, null)));
-    }
-
-    @Override
-    public void visitMaxs(int maxStack, int maxLocals) {
-      assert maxStack >= 0;
-      assert maxLocals >= 0;
-      this.maxStack = maxStack;
-      this.maxLocals = maxLocals;
-    }
-  }
-
   private static class CreateAnnotationVisitor extends AnnotationVisitor {
 
     private final JarApplicationReader application;
@@ -1466,4 +768,14 @@
       return getDexValueArray(value);
     }
   }
+
+  public static class ReparseContext {
+
+    // This will hold the content of the whole class. Once all the methods of the class are swapped
+    // from this to the actual JarCode, no other references would be left and the content can be
+    // GC'd.
+    public byte[] classCache;
+    public DexProgramClass owner;
+    public final List<Code> codeList = new ArrayList<>();
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/graph/JarCode.java b/src/main/java/com/android/tools/r8/graph/JarCode.java
index 55ae757..dc75307 100644
--- a/src/main/java/com/android/tools/r8/graph/JarCode.java
+++ b/src/main/java/com/android/tools/r8/graph/JarCode.java
@@ -5,6 +5,7 @@
 
 import com.android.tools.r8.ApiLevelException;
 import com.android.tools.r8.errors.InvalidDebugInfoException;
+import com.android.tools.r8.graph.JarClassFileReader.ReparseContext;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.Position;
 import com.android.tools.r8.ir.code.ValueNumberGenerator;
@@ -17,9 +18,7 @@
 import com.android.tools.r8.utils.InternalOptions;
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.util.ArrayList;
 import java.util.Iterator;
-import java.util.List;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -39,16 +38,6 @@
     node.accept(visitor);
   }
 
-  public static class ReparseContext {
-
-    // This will hold the content of the whole class. Once all the methods of the class are swapped
-    // from this to the actual JarCode, no other references would be left and the content can be
-    // GC'd.
-    public byte[] classCache;
-    public DexProgramClass owner;
-    private final List<JarCode> codeList = new ArrayList<>();
-  }
-
   private final DexMethod method;
   private final Origin origin;
   private MethodNode node;
@@ -227,7 +216,7 @@
       JarCode code = null;
       MethodAccessFlags flags = JarClassFileReader.createMethodAccessFlags(name, access);
       if (!flags.isAbstract() && !flags.isNative()) {
-        code = context.codeList.get(methodIndex++);
+        code = context.codeList.get(methodIndex++).asJarCode();
         assert code.method == application.getMethod(context.owner.type, name, desc);
       }
       if (code != null) {
diff --git a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
new file mode 100644
index 0000000..a864aba
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
@@ -0,0 +1,804 @@
+// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.graph;
+
+import com.android.tools.r8.ApiLevelException;
+import com.android.tools.r8.cf.code.CfArithmeticBinop;
+import com.android.tools.r8.cf.code.CfArrayLength;
+import com.android.tools.r8.cf.code.CfArrayLoad;
+import com.android.tools.r8.cf.code.CfArrayStore;
+import com.android.tools.r8.cf.code.CfCheckCast;
+import com.android.tools.r8.cf.code.CfCmp;
+import com.android.tools.r8.cf.code.CfConstClass;
+import com.android.tools.r8.cf.code.CfConstMethodHandle;
+import com.android.tools.r8.cf.code.CfConstMethodType;
+import com.android.tools.r8.cf.code.CfConstNull;
+import com.android.tools.r8.cf.code.CfConstNumber;
+import com.android.tools.r8.cf.code.CfConstString;
+import com.android.tools.r8.cf.code.CfFieldInstruction;
+import com.android.tools.r8.cf.code.CfFrame;
+import com.android.tools.r8.cf.code.CfFrame.FrameType;
+import com.android.tools.r8.cf.code.CfGoto;
+import com.android.tools.r8.cf.code.CfIf;
+import com.android.tools.r8.cf.code.CfIfCmp;
+import com.android.tools.r8.cf.code.CfIinc;
+import com.android.tools.r8.cf.code.CfInstanceOf;
+import com.android.tools.r8.cf.code.CfInstruction;
+import com.android.tools.r8.cf.code.CfInvoke;
+import com.android.tools.r8.cf.code.CfInvokeDynamic;
+import com.android.tools.r8.cf.code.CfLabel;
+import com.android.tools.r8.cf.code.CfLoad;
+import com.android.tools.r8.cf.code.CfLogicalBinop;
+import com.android.tools.r8.cf.code.CfMonitor;
+import com.android.tools.r8.cf.code.CfMultiANewArray;
+import com.android.tools.r8.cf.code.CfNeg;
+import com.android.tools.r8.cf.code.CfNew;
+import com.android.tools.r8.cf.code.CfNewArray;
+import com.android.tools.r8.cf.code.CfNop;
+import com.android.tools.r8.cf.code.CfNumberConversion;
+import com.android.tools.r8.cf.code.CfPosition;
+import com.android.tools.r8.cf.code.CfReturn;
+import com.android.tools.r8.cf.code.CfReturnVoid;
+import com.android.tools.r8.cf.code.CfStackInstruction;
+import com.android.tools.r8.cf.code.CfStore;
+import com.android.tools.r8.cf.code.CfSwitch;
+import com.android.tools.r8.cf.code.CfThrow;
+import com.android.tools.r8.cf.code.CfTryCatch;
+import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.errors.Unimplemented;
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.CfCode.LocalVariableInfo;
+import com.android.tools.r8.graph.JarClassFileReader.ReparseContext;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.If;
+import com.android.tools.r8.ir.code.MemberType;
+import com.android.tools.r8.ir.code.Monitor;
+import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.ValueNumberGenerator;
+import com.android.tools.r8.ir.code.ValueType;
+import com.android.tools.r8.naming.ClassNameMapper;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.InternalOptions;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.JSRInlinerAdapter;
+
+public class LazyCfCode extends Code {
+
+  public LazyCfCode(
+      DexMethod method, Origin origin, ReparseContext context, JarApplicationReader application) {
+
+    this.method = method;
+    this.origin = origin;
+    this.context = context;
+    this.application = application;
+    context.codeList.add(this);
+  }
+
+  private final DexMethod method;
+  private final Origin origin;
+  private final JarApplicationReader application;
+  private CfCode code;
+  private ReparseContext context;
+
+  @Override
+  public boolean isCfCode() {
+    return true;
+  }
+
+  @Override
+  public LazyCfCode asLazyCfCode() {
+    return this;
+  }
+
+  @Override
+  public CfCode asCfCode() {
+    if (code == null) {
+      assert context != null;
+      // The SecondVistor is in charge of setting the context to null.
+      DexProgramClass owner = context.owner;
+      ClassReader classReader = new ClassReader(context.classCache);
+      classReader.accept(new ClassCodeVisitor(context, application), ClassReader.EXPAND_FRAMES);
+      assert verifyNoReparseContext(owner);
+    }
+    assert code != null;
+    return code;
+  }
+
+  private void setCode(CfCode code) {
+    assert this.code == null;
+    assert this.context != null;
+    this.code = code;
+    this.context = null;
+  }
+
+  @Override
+  protected int computeHashCode() {
+    throw new Unimplemented();
+  }
+
+  @Override
+  protected boolean computeEquals(Object other) {
+    throw new Unimplemented();
+  }
+
+  @Override
+  public boolean isEmptyVoidMethod() {
+    return asCfCode().isEmptyVoidMethod();
+  }
+
+  @Override
+  public IRCode buildIR(DexEncodedMethod encodedMethod, InternalOptions options)
+      throws ApiLevelException {
+    return asCfCode().buildIR(encodedMethod, options);
+  }
+
+  @Override
+  public IRCode buildInliningIR(
+      DexEncodedMethod encodedMethod,
+      InternalOptions options,
+      ValueNumberGenerator valueNumberGenerator,
+      Position callerPosition)
+      throws ApiLevelException {
+    return asCfCode().buildInliningIR(encodedMethod, options, valueNumberGenerator, callerPosition);
+  }
+
+  @Override
+  public void registerCodeReferences(UseRegistry registry) {
+    asCfCode().registerCodeReferences(registry);
+  }
+
+  @Override
+  public String toString() {
+    return asCfCode().toString();
+  }
+
+  @Override
+  public String toString(DexEncodedMethod method, ClassNameMapper naming) {
+    return null;
+  }
+
+  private static class ClassCodeVisitor extends ClassVisitor {
+
+    private final ReparseContext context;
+    private final JarApplicationReader application;
+    private int methodIndex = 0;
+
+    ClassCodeVisitor(ReparseContext context, JarApplicationReader application) {
+      super(Opcodes.ASM6);
+      this.context = context;
+      this.application = application;
+    }
+
+    @Override
+    public MethodVisitor visitMethod(
+        int access, String name, String desc, String signature, String[] exceptions) {
+      MethodAccessFlags flags = JarClassFileReader.createMethodAccessFlags(name, access);
+      if (!flags.isAbstract() && !flags.isNative()) {
+        LazyCfCode code = context.codeList.get(methodIndex++).asLazyCfCode();
+        DexMethod method = application.getMethod(context.owner.type, name, desc);
+        assert code.method == method;
+        MethodCodeVisitor methodVisitor = new MethodCodeVisitor(application, code);
+        return new JSRInlinerAdapter(methodVisitor, access, name, desc, signature, exceptions);
+      }
+      return null;
+    }
+  }
+
+  private static class MethodCodeVisitor extends MethodVisitor {
+    private final JarApplicationReader application;
+    private final DexItemFactory factory;
+    private int maxStack;
+    private int maxLocals;
+    private List<CfInstruction> instructions;
+    private List<CfTryCatch> tryCatchRanges;
+    private List<LocalVariableInfo> localVariables;
+    private Map<Label, CfLabel> labelMap;
+    private final LazyCfCode code;
+    private DexMethod method;
+
+    MethodCodeVisitor(JarApplicationReader application, LazyCfCode code) {
+      super(Opcodes.ASM6);
+      this.application = application;
+      this.factory = application.getFactory();
+      this.method = code.method;
+      this.code = code;
+    }
+
+    @Override
+    public void visitCode() {
+      maxStack = 0;
+      maxLocals = 0;
+      instructions = new ArrayList<>();
+      tryCatchRanges = new ArrayList<>();
+      localVariables = new ArrayList<>();
+      labelMap = new IdentityHashMap<>();
+    }
+
+    @Override
+    public void visitEnd() {
+      code.setCode(
+          new CfCode(method, maxStack, maxLocals, instructions, tryCatchRanges, localVariables));
+    }
+
+    @Override
+    public void visitFrame(
+        int frameType, int nLocals, Object[] localTypes, int nStack, Object[] stackTypes) {
+      assert frameType == Opcodes.F_NEW;
+      Int2ReferenceSortedMap<FrameType> parsedLocals = parseLocals(nLocals, localTypes);
+      List<FrameType> parsedStack = parseStack(nStack, stackTypes);
+      instructions.add(new CfFrame(parsedLocals, parsedStack));
+    }
+
+    private Int2ReferenceSortedMap<FrameType> parseLocals(int typeCount, Object[] asmTypes) {
+      Int2ReferenceSortedMap<FrameType> types = new Int2ReferenceAVLTreeMap<>();
+      int i = 0;
+      for (int j = 0; j < typeCount; j++) {
+        Object localType = asmTypes[j];
+        FrameType value = getFrameType(localType);
+        types.put(i++, value);
+        if (value.isWide()) {
+          i++;
+        }
+      }
+      return types;
+    }
+
+    private List<FrameType> parseStack(int nStack, Object[] stackTypes) {
+      List<FrameType> dexStack = new ArrayList<>(nStack);
+      for (int i = 0; i < nStack; i++) {
+        dexStack.add(getFrameType(stackTypes[i]));
+      }
+      return dexStack;
+    }
+
+    private FrameType getFrameType(Object localType) {
+      if (localType instanceof Label) {
+        return FrameType.uninitializedNew(getLabel((Label) localType));
+      } else if (localType == Opcodes.UNINITIALIZED_THIS) {
+        return FrameType.uninitializedThis();
+      } else if (localType == null || localType == Opcodes.TOP) {
+        return FrameType.top();
+      } else {
+        return FrameType.initialized(parseAsmType(localType));
+      }
+    }
+
+    private CfLabel getLabel(Label label) {
+      return labelMap.computeIfAbsent(label, l -> new CfLabel());
+    }
+
+    private DexType parseAsmType(Object local) {
+      assert local != null && local != Opcodes.TOP;
+      if (local == Opcodes.INTEGER) {
+        return factory.intType;
+      } else if (local == Opcodes.FLOAT) {
+        return factory.floatType;
+      } else if (local == Opcodes.LONG) {
+        return factory.longType;
+      } else if (local == Opcodes.DOUBLE) {
+        return factory.doubleType;
+      } else if (local == Opcodes.NULL) {
+        return DexItemFactory.nullValueType;
+      } else if (local instanceof String) {
+        return createTypeFromInternalType((String) local);
+      } else {
+        throw new Unreachable("Unexpected ASM type: " + local);
+      }
+    }
+
+    private DexType createTypeFromInternalType(String local) {
+      assert local.indexOf('.') == -1;
+      return factory.createType("L" + local + ";");
+    }
+
+    @Override
+    public void visitInsn(int opcode) {
+      switch (opcode) {
+        case Opcodes.NOP:
+          instructions.add(new CfNop());
+          break;
+        case Opcodes.ACONST_NULL:
+          instructions.add(new CfConstNull());
+          break;
+        case Opcodes.ICONST_M1:
+        case Opcodes.ICONST_0:
+        case Opcodes.ICONST_1:
+        case Opcodes.ICONST_2:
+        case Opcodes.ICONST_3:
+        case Opcodes.ICONST_4:
+        case Opcodes.ICONST_5:
+          instructions.add(new CfConstNumber(opcode - Opcodes.ICONST_0, ValueType.INT));
+          break;
+        case Opcodes.LCONST_0:
+        case Opcodes.LCONST_1:
+          instructions.add(new CfConstNumber(opcode - Opcodes.LCONST_0, ValueType.LONG));
+          break;
+        case Opcodes.FCONST_0:
+        case Opcodes.FCONST_1:
+        case Opcodes.FCONST_2:
+          instructions.add(
+              new CfConstNumber(
+                  Float.floatToRawIntBits(opcode - Opcodes.FCONST_0), ValueType.FLOAT));
+          break;
+        case Opcodes.DCONST_0:
+        case Opcodes.DCONST_1:
+          instructions.add(
+              new CfConstNumber(
+                  Double.doubleToRawLongBits(opcode - Opcodes.DCONST_0), ValueType.DOUBLE));
+          break;
+        case Opcodes.IALOAD:
+        case Opcodes.LALOAD:
+        case Opcodes.FALOAD:
+        case Opcodes.DALOAD:
+        case Opcodes.AALOAD:
+        case Opcodes.BALOAD:
+        case Opcodes.CALOAD:
+        case Opcodes.SALOAD:
+          instructions.add(new CfArrayLoad(getMemberTypeForOpcode(opcode)));
+          break;
+        case Opcodes.IASTORE:
+        case Opcodes.LASTORE:
+        case Opcodes.FASTORE:
+        case Opcodes.DASTORE:
+        case Opcodes.AASTORE:
+        case Opcodes.BASTORE:
+        case Opcodes.CASTORE:
+        case Opcodes.SASTORE:
+          instructions.add(new CfArrayStore(getMemberTypeForOpcode(opcode)));
+          break;
+        case Opcodes.POP:
+        case Opcodes.POP2:
+        case Opcodes.DUP:
+        case Opcodes.DUP_X1:
+        case Opcodes.DUP_X2:
+        case Opcodes.DUP2:
+        case Opcodes.DUP2_X1:
+        case Opcodes.DUP2_X2:
+        case Opcodes.SWAP:
+          instructions.add(CfStackInstruction.fromAsm(opcode));
+          break;
+        case Opcodes.IADD:
+        case Opcodes.LADD:
+        case Opcodes.FADD:
+        case Opcodes.DADD:
+        case Opcodes.ISUB:
+        case Opcodes.LSUB:
+        case Opcodes.FSUB:
+        case Opcodes.DSUB:
+        case Opcodes.IMUL:
+        case Opcodes.LMUL:
+        case Opcodes.FMUL:
+        case Opcodes.DMUL:
+        case Opcodes.IDIV:
+        case Opcodes.LDIV:
+        case Opcodes.FDIV:
+        case Opcodes.DDIV:
+        case Opcodes.IREM:
+        case Opcodes.LREM:
+        case Opcodes.FREM:
+        case Opcodes.DREM:
+          instructions.add(CfArithmeticBinop.fromAsm(opcode));
+          break;
+        case Opcodes.INEG:
+        case Opcodes.LNEG:
+        case Opcodes.FNEG:
+        case Opcodes.DNEG:
+          instructions.add(CfNeg.fromAsm(opcode));
+          break;
+        case Opcodes.ISHL:
+        case Opcodes.LSHL:
+        case Opcodes.ISHR:
+        case Opcodes.LSHR:
+        case Opcodes.IUSHR:
+        case Opcodes.LUSHR:
+        case Opcodes.IAND:
+        case Opcodes.LAND:
+        case Opcodes.IOR:
+        case Opcodes.LOR:
+        case Opcodes.IXOR:
+        case Opcodes.LXOR:
+          instructions.add(CfLogicalBinop.fromAsm(opcode));
+          break;
+        case Opcodes.I2L:
+        case Opcodes.I2F:
+        case Opcodes.I2D:
+        case Opcodes.L2I:
+        case Opcodes.L2F:
+        case Opcodes.L2D:
+        case Opcodes.F2I:
+        case Opcodes.F2L:
+        case Opcodes.F2D:
+        case Opcodes.D2I:
+        case Opcodes.D2L:
+        case Opcodes.D2F:
+        case Opcodes.I2B:
+        case Opcodes.I2C:
+        case Opcodes.I2S:
+          instructions.add(CfNumberConversion.fromAsm(opcode));
+          break;
+        case Opcodes.LCMP:
+        case Opcodes.FCMPL:
+        case Opcodes.FCMPG:
+        case Opcodes.DCMPL:
+        case Opcodes.DCMPG:
+          instructions.add(CfCmp.fromAsm(opcode));
+          break;
+        case Opcodes.IRETURN:
+          instructions.add(new CfReturn(ValueType.INT));
+          break;
+        case Opcodes.LRETURN:
+          instructions.add(new CfReturn(ValueType.LONG));
+          break;
+        case Opcodes.FRETURN:
+          instructions.add(new CfReturn(ValueType.FLOAT));
+          break;
+        case Opcodes.DRETURN:
+          instructions.add(new CfReturn(ValueType.DOUBLE));
+          break;
+        case Opcodes.ARETURN:
+          instructions.add(new CfReturn(ValueType.OBJECT));
+          break;
+        case Opcodes.RETURN:
+          instructions.add(new CfReturnVoid());
+          break;
+        case Opcodes.ARRAYLENGTH:
+          instructions.add(new CfArrayLength());
+          break;
+        case Opcodes.ATHROW:
+          instructions.add(new CfThrow());
+          break;
+        case Opcodes.MONITORENTER:
+          instructions.add(new CfMonitor(Monitor.Type.ENTER));
+          break;
+        case Opcodes.MONITOREXIT:
+          instructions.add(new CfMonitor(Monitor.Type.EXIT));
+          break;
+        default:
+          throw new Unreachable("Unknown instruction");
+      }
+    }
+
+    private static MemberType getMemberTypeForOpcode(int opcode) {
+      switch (opcode) {
+        case Opcodes.IALOAD:
+        case Opcodes.IASTORE:
+          return MemberType.INT;
+        case Opcodes.FALOAD:
+        case Opcodes.FASTORE:
+          return MemberType.FLOAT;
+        case Opcodes.LALOAD:
+        case Opcodes.LASTORE:
+          return MemberType.LONG;
+        case Opcodes.DALOAD:
+        case Opcodes.DASTORE:
+          return MemberType.DOUBLE;
+        case Opcodes.AALOAD:
+        case Opcodes.AASTORE:
+          return MemberType.OBJECT;
+        case Opcodes.BALOAD:
+        case Opcodes.BASTORE:
+          return MemberType.BOOLEAN; // TODO: Distinguish byte and boolean.
+        case Opcodes.CALOAD:
+        case Opcodes.CASTORE:
+          return MemberType.CHAR;
+        case Opcodes.SALOAD:
+        case Opcodes.SASTORE:
+          return MemberType.SHORT;
+        default:
+          throw new Unreachable("Unexpected array opcode " + opcode);
+      }
+    }
+
+    @Override
+    public void visitIntInsn(int opcode, int operand) {
+      switch (opcode) {
+        case Opcodes.SIPUSH:
+        case Opcodes.BIPUSH:
+          instructions.add(new CfConstNumber(operand, ValueType.INT));
+          break;
+        case Opcodes.NEWARRAY:
+          instructions.add(
+              new CfNewArray(factory.createArrayType(1, arrayTypeDesc(operand, factory))));
+          break;
+        default:
+          throw new Unreachable("Unexpected int opcode " + opcode);
+      }
+    }
+
+    private static DexType arrayTypeDesc(int arrayTypeCode, DexItemFactory factory) {
+      switch (arrayTypeCode) {
+        case Opcodes.T_BOOLEAN:
+          return factory.booleanType;
+        case Opcodes.T_CHAR:
+          return factory.charType;
+        case Opcodes.T_FLOAT:
+          return factory.floatType;
+        case Opcodes.T_DOUBLE:
+          return factory.doubleType;
+        case Opcodes.T_BYTE:
+          return factory.byteType;
+        case Opcodes.T_SHORT:
+          return factory.shortType;
+        case Opcodes.T_INT:
+          return factory.intType;
+        case Opcodes.T_LONG:
+          return factory.longType;
+        default:
+          throw new Unreachable("Unexpected array-type code " + arrayTypeCode);
+      }
+    }
+
+    @Override
+    public void visitVarInsn(int opcode, int var) {
+      ValueType type;
+      switch (opcode) {
+        case Opcodes.ILOAD:
+        case Opcodes.ISTORE:
+          type = ValueType.INT;
+          break;
+        case Opcodes.FLOAD:
+        case Opcodes.FSTORE:
+          type = ValueType.FLOAT;
+          break;
+        case Opcodes.LLOAD:
+        case Opcodes.LSTORE:
+          type = ValueType.LONG;
+          break;
+        case Opcodes.DLOAD:
+        case Opcodes.DSTORE:
+          type = ValueType.DOUBLE;
+          break;
+        case Opcodes.ALOAD:
+        case Opcodes.ASTORE:
+          type = ValueType.OBJECT;
+          break;
+        case Opcodes.RET:
+          throw new Unreachable("RET should be handled by the ASM jsr inliner");
+        default:
+          throw new Unreachable("Unexpected VarInsn opcode: " + opcode);
+      }
+      if (Opcodes.ILOAD <= opcode && opcode <= Opcodes.ALOAD) {
+        instructions.add(new CfLoad(type, var));
+      } else {
+        instructions.add(new CfStore(type, var));
+      }
+    }
+
+    @Override
+    public void visitTypeInsn(int opcode, String typeName) {
+      DexType type = factory.createType(Type.getObjectType(typeName).getDescriptor());
+      switch (opcode) {
+        case Opcodes.NEW:
+          instructions.add(new CfNew(type));
+          break;
+        case Opcodes.ANEWARRAY:
+          instructions.add(new CfNewArray(factory.createArrayType(1, type)));
+          break;
+        case Opcodes.CHECKCAST:
+          instructions.add(new CfCheckCast(type));
+          break;
+        case Opcodes.INSTANCEOF:
+          instructions.add(new CfInstanceOf(type));
+          break;
+        default:
+          throw new Unreachable("Unexpected TypeInsn opcode: " + opcode);
+      }
+    }
+
+    @Override
+    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+      DexField field =
+          factory.createField(createTypeFromInternalType(owner), factory.createType(desc), name);
+      // TODO(mathiasr): Don't require CfFieldInstruction::declaringField. It is needed for proper
+      // renaming in the backend, but it is not available here in the frontend.
+      instructions.add(new CfFieldInstruction(opcode, field, field));
+    }
+
+    @Override
+    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+      visitMethodInsn(opcode, owner, name, desc, false);
+    }
+
+    @Override
+    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
+      DexMethod method = application.getMethod(owner, name, desc);
+      instructions.add(new CfInvoke(opcode, method, itf));
+    }
+
+    @Override
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
+      DexCallSite callSite =
+          DexCallSite.fromAsmInvokeDynamic(application, method.holder, name, desc, bsm, bsmArgs);
+      instructions.add(new CfInvokeDynamic(callSite));
+    }
+
+    @Override
+    public void visitJumpInsn(int opcode, Label label) {
+      CfLabel target = getLabel(label);
+      if (Opcodes.IFEQ <= opcode && opcode <= Opcodes.IF_ACMPNE) {
+        if (opcode <= Opcodes.IFLE) {
+          // IFEQ, IFNE, IFLT, IFGE, IFGT, or IFLE.
+          instructions.add(new CfIf(ifType(opcode), ValueType.INT, target));
+        } else {
+          // IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, or
+          // IF_ACMPNE.
+          ValueType valueType;
+          if (opcode <= Opcodes.IF_ICMPLE) {
+            valueType = ValueType.INT;
+          } else {
+            valueType = ValueType.OBJECT;
+          }
+          instructions.add(new CfIfCmp(ifType(opcode), valueType, target));
+        }
+      } else {
+        // GOTO, JSR, IFNULL or IFNONNULL.
+        switch (opcode) {
+          case Opcodes.GOTO:
+            instructions.add(new CfGoto(target));
+            break;
+          case Opcodes.IFNULL:
+          case Opcodes.IFNONNULL:
+            If.Type type = opcode == Opcodes.IFNULL ? If.Type.EQ : If.Type.NE;
+            instructions.add(new CfIf(type, ValueType.OBJECT, target));
+            break;
+          case Opcodes.JSR:
+            throw new Unreachable("JSR should be handled by the ASM jsr inliner");
+          default:
+            throw new Unreachable("Unexpected JumpInsn opcode: " + opcode);
+        }
+      }
+    }
+
+    private static If.Type ifType(int opcode) {
+      switch (opcode) {
+        case Opcodes.IFEQ:
+        case Opcodes.IF_ICMPEQ:
+        case Opcodes.IF_ACMPEQ:
+          return If.Type.EQ;
+        case Opcodes.IFNE:
+        case Opcodes.IF_ICMPNE:
+        case Opcodes.IF_ACMPNE:
+          return If.Type.NE;
+        case Opcodes.IFLT:
+        case Opcodes.IF_ICMPLT:
+          return If.Type.LT;
+        case Opcodes.IFGE:
+        case Opcodes.IF_ICMPGE:
+          return If.Type.GE;
+        case Opcodes.IFGT:
+        case Opcodes.IF_ICMPGT:
+          return If.Type.GT;
+        case Opcodes.IFLE:
+        case Opcodes.IF_ICMPLE:
+          return If.Type.LE;
+        default:
+          throw new Unreachable("Unexpected If instruction opcode: " + opcode);
+      }
+    }
+
+    @Override
+    public void visitLabel(Label label) {
+      instructions.add(getLabel(label));
+    }
+
+    @Override
+    public void visitLdcInsn(Object cst) {
+      if (cst instanceof Type) {
+        Type type = (Type) cst;
+        if (type.getSort() == Type.METHOD) {
+          DexProto proto = application.getProto(type.getDescriptor());
+          instructions.add(new CfConstMethodType(proto));
+        } else {
+          instructions.add(new CfConstClass(factory.createType(type.getDescriptor())));
+        }
+      } else if (cst instanceof String) {
+        instructions.add(new CfConstString(factory.createString((String) cst)));
+      } else if (cst instanceof Long) {
+        instructions.add(new CfConstNumber((Long) cst, ValueType.LONG));
+      } else if (cst instanceof Double) {
+        long l = Double.doubleToRawLongBits((Double) cst);
+        instructions.add(new CfConstNumber(l, ValueType.DOUBLE));
+      } else if (cst instanceof Integer) {
+        instructions.add(new CfConstNumber((Integer) cst, ValueType.INT));
+      } else if (cst instanceof Float) {
+        long i = Float.floatToRawIntBits((Float) cst);
+        instructions.add(new CfConstNumber(i, ValueType.FLOAT));
+      } else if (cst instanceof Handle) {
+        instructions.add(
+            new CfConstMethodHandle(
+                DexMethodHandle.fromAsmHandle((Handle) cst, application, method.holder)));
+      } else {
+        throw new CompilationError("Unsupported constant: " + cst.toString());
+      }
+    }
+
+    @Override
+    public void visitIincInsn(int var, int increment) {
+      instructions.add(new CfIinc(var, increment));
+    }
+
+    @Override
+    public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
+      assert max == min + labels.length - 1;
+      ArrayList<CfLabel> targets = new ArrayList<>(labels.length);
+      for (Label label : labels) {
+        targets.add(getLabel(label));
+      }
+      instructions.add(new CfSwitch(CfSwitch.Kind.TABLE, getLabel(dflt), new int[] {min}, targets));
+    }
+
+    @Override
+    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+      ArrayList<CfLabel> targets = new ArrayList<>(labels.length);
+      for (Label label : labels) {
+        targets.add(getLabel(label));
+      }
+      instructions.add(new CfSwitch(CfSwitch.Kind.LOOKUP, getLabel(dflt), keys, targets));
+    }
+
+    @Override
+    public void visitMultiANewArrayInsn(String desc, int dims) {
+      instructions.add(new CfMultiANewArray(factory.createType(desc), dims));
+    }
+
+    @Override
+    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+      List<DexType> guards =
+          Collections.singletonList(
+              type == null ? DexItemFactory.catchAllType : createTypeFromInternalType(type));
+      List<CfLabel> targets = Collections.singletonList(getLabel(handler));
+      tryCatchRanges.add(new CfTryCatch(getLabel(start), getLabel(end), guards, targets));
+    }
+
+    @Override
+    public void visitLocalVariable(
+        String name, String desc, String signature, Label start, Label end, int index) {
+      DebugLocalInfo debugLocalInfo =
+          new DebugLocalInfo(
+              factory.createString(name),
+              factory.createType(desc),
+              signature == null ? null : factory.createString(signature));
+      localVariables.add(
+          new LocalVariableInfo(index, debugLocalInfo, getLabel(start), getLabel(end)));
+    }
+
+    @Override
+    public void visitLineNumber(int line, Label start) {
+      instructions.add(new CfPosition(getLabel(start), new Position(line, null, method, null)));
+    }
+
+    @Override
+    public void visitMaxs(int maxStack, int maxLocals) {
+      assert maxStack >= 0;
+      assert maxLocals >= 0;
+      this.maxStack = maxStack;
+      this.maxLocals = maxLocals;
+    }
+  }
+
+  private static boolean verifyNoReparseContext(DexProgramClass owner) {
+    for (DexEncodedMethod method : owner.virtualMethods()) {
+      Code code = method.getCode();
+      assert code == null || !(code instanceof LazyCfCode) || ((LazyCfCode) code).context == null;
+    }
+    for (DexEncodedMethod method : owner.directMethods()) {
+      Code code = method.getCode();
+      assert code == null || !(code instanceof LazyCfCode) || ((LazyCfCode) code).context == null;
+    }
+    return true;
+  }
+}
