public void compile(Clazz clazz) throws IOException {
    reset();

    File llFile = config.getLlFile(clazz);
    File bcFile = config.getBcFile(clazz);
    File sFile = config.getSFile(clazz);
    File oFile = config.getOFile(clazz);
    llFile.getParentFile().mkdirs();
    bcFile.getParentFile().mkdirs();
    sFile.getParentFile().mkdirs();
    oFile.getParentFile().mkdirs();

    OutputStream out = null;
    try {
      config.getLogger().debug("Compiling %s", clazz);
      out = new FileOutputStream(llFile);
      compile(clazz, out);
    } catch (Throwable t) {
      FileUtils.deleteQuietly(llFile);
      if (t instanceof IOException) {
        throw (IOException) t;
      }
      if (t instanceof RuntimeException) {
        throw (RuntimeException) t;
      }
      throw new RuntimeException(t);
    } finally {
      IOUtils.closeQuietly(out);
    }

    config.getLogger().debug("Optimizing %s", clazz);
    CompilerUtil.opt(config, llFile, bcFile, "-mem2reg", "-always-inline");

    config.getLogger().debug("Generating %s assembly for %s", config.getArch(), clazz);
    CompilerUtil.llc(config, bcFile, sFile);

    patchAsmWithFunctionSizes(clazz, sFile);

    config.getLogger().debug("Assembling %s", clazz);
    CompilerUtil.assemble(config, sFile, oFile);
  }
  public boolean mustCompile(Clazz clazz) {
    File oFile = config.getOFile(clazz);
    if (!oFile.exists() || oFile.lastModified() < clazz.lastModified()) {
      return true;
    }

    Set<Dependency> dependencies = clazz.getDependencies();
    for (Dependency dep : dependencies) {
      Clazz depClazz = config.getClazzes().load(dep.getClassName());
      if (depClazz == null) {
        if (dep.getPath() != null) {
          // depClazz was available the last time clazz was compiled but is now gone
          return true;
        }
      } else {
        if (dep.getPath() == null) {
          // depClazz was not available the last time clazz was compiled but is now available
          return true;
        }
        if (!dep.getPath().equals(depClazz.getPath().getFile().getAbsolutePath())) {
          // depClazz was located in another place the last time clazz was built
          return true;
        }
        if (depClazz.isInBootClasspath() != dep.isInBootClasspath()) {
          // depClazz has moved to/from the bootclasspath since the last time clazz was built
          return true;
        }
        if (depClazz.lastModified() > oFile.lastModified()) {
          // depClazz has been changed since the last time clazz was built
          return true;
        }
      }
    }

    // No class or interface has zero dependencies (we always add java.lang.Object as a dependency)
    // If dependencies is empty it probably means that an error occurred while reading the
    // serialized dependencies. By returning true here in that case the class will be recompiled
    // and the dependencies regenerated.
    return dependencies.isEmpty();
  }