/**
   * Initialize boot image compiler.
   *
   * @param args command line arguments to the bootimage compiler
   */
  protected void initCompiler(String[] args) {
    try {
      BaselineCompiler.initOptions();
      VM.sysWrite("BootImageCompiler: init (opt compiler)\n");

      // Writing a boot image is a little bit special.  We're not really
      // concerned about compile time, but we do care a lot about the quality
      // and stability of the generated code.  Set the options accordingly.
      OptimizingCompiler.setBootOptions(masterOptions);

      // Allow further customization by the user.
      for (int i = 0, n = args.length; i < n; i++) {
        String arg = args[i];
        if (!masterOptions.processAsOption("-X:bc:", arg)) {
          if (arg.startsWith("exclude=")) {
            excludePattern = arg.substring(8);
          } else {
            VM.sysWrite("BootImageCompiler: Unrecognized argument " + arg + "; ignoring\n");
          }
        }
      }
      EdgeCounts.loadCountsFromFileIfAvailable(masterOptions.PROFILE_EDGE_COUNT_INPUT_FILE);
      OptimizingCompiler.init(masterOptions);
    } catch (OptimizingCompilerException e) {
      String msg = "BootImageCompiler: Compiler failed during initialization: " + e + "\n";
      if (e.isFatal) {
        // An unexpected error when building the opt boot image should be fatal
        e.printStackTrace();
        System.exit(VM.EXIT_STATUS_OPT_COMPILER_FAILED);
      } else {
        VM.sysWrite(msg);
      }
    }
  }
 /**
  * Compile a method with bytecodes.
  *
  * @param method the method to compile
  * @return the compiled method
  */
 protected CompiledMethod compileMethod(NormalMethod method, TypeReference[] params) {
   if (method.hasNoOptCompileAnnotation()) {
     return baselineCompile(method);
   } else {
     CompiledMethod cm = null;
     OptimizingCompilerException escape = new OptimizingCompilerException(false);
     try {
       Callbacks.notifyMethodCompile(method, CompiledMethod.OPT);
       boolean include = match(method);
       if (!include) {
         throw escape;
       }
       int freeOptimizationPlan = getFreeOptimizationPlan();
       OptimizationPlanElement[] optimizationPlan = optimizationPlans.get(freeOptimizationPlan);
       CompilationPlan cp =
           new CompilationPlan(
               method, params, optimizationPlan, null, options.get(freeOptimizationPlan));
       cm = OptimizingCompiler.compile(cp);
       if (VM.BuildForAdaptiveSystem) {
         /* We can't accurately measure compilation time on Host JVM, so just approximate with DNA */
         int compilerId = CompilerDNA.getCompilerConstant(cp.options.getOptLevel());
         cm.setCompilationTime((float) CompilerDNA.estimateCompileTime(compilerId, method));
       }
       releaseOptimizationPlan(freeOptimizationPlan);
       return cm;
     } catch (OptimizingCompilerException e) {
       if (e.isFatal) {
         // An unexpected error when building the opt boot image should be fatal
         VM.sysWriteln("Error compiling method: " + method);
         e.printStackTrace();
         System.exit(VM.EXIT_STATUS_OPT_COMPILER_FAILED);
       } else {
         boolean printMsg = true;
         if (e instanceof MagicNotImplementedException) {
           printMsg = !((MagicNotImplementedException) e).isExpected;
         }
         if (e == escape) {
           printMsg = false;
         }
         if (printMsg) {
           if (e.toString().indexOf("method excluded") >= 0) {
             String msg = "BootImageCompiler: " + method + " excluded from opt-compilation\n";
             VM.sysWrite(msg);
           } else {
             String msg =
                 "BootImageCompiler: can't optimize \"" + method + "\" (error was: " + e + ")\n";
             VM.sysWrite(msg);
           }
         }
       }
       return baselineCompile(method);
     }
   }
 }
 /** Return a string rep of the operand (ie the effective address) */
 public String toString() {
   String addr = (base == null) ? "<0" : "<[" + base + "]";
   if (index != null) {
     addr += "+[" + index;
     switch (scale) {
       case 0:
         addr += "]";
         break;
       case 1:
         addr += "*2]";
         break;
       case 2:
         addr += "*4]";
         break;
       case 3:
         addr += "*8]";
         break;
       default:
         OptimizingCompilerException.UNREACHABLE();
     }
   }
   if (!disp.isZero()) {
     addr += "+" + disp.toInt();
   }
   switch (size) {
     case 1:
       addr += ">B";
       break;
     case 2:
       addr += ">W";
       break;
     case 4:
       addr += ">DW";
       break;
     case 8:
       addr += ">QW";
       break;
     case 16:
       addr += ">PARAGRAPH";
       break;
     default:
       OptimizingCompilerException.UNREACHABLE();
   }
   if (loc != null && guard != null) {
     addr += " (" + loc + ", " + guard + ")";
   } else if (loc != null) {
     addr += " (" + loc + ")";
   } else if (guard != null) {
     addr += " (" + guard + ")";
   }
   return addr;
 }
  /** Is a specified condition operand 'safe' to transfer into an FCMP instruction? */
  private boolean fpConditionOK(ConditionOperand c) {
    // FCOMI sets ZF, PF, and CF as follows:
    // Compare Results      ZF     PF      CF
    // left > right          0      0       0
    // left < right          0      0       1
    // left == right         1      0       0
    // UNORDERED             1      1       1
    switch (c.value) {
      case ConditionOperand.CMPL_EQUAL:
        return false; // (ZF == 1) but ordered
      case ConditionOperand.CMPL_NOT_EQUAL:
        return false; // (ZF == 0) but unordered
      case ConditionOperand.CMPG_LESS:
        return false; // (CF == 1) but ordered
      case ConditionOperand.CMPG_GREATER_EQUAL:
        return false; // (CF == 0) but unordered
      case ConditionOperand.CMPG_LESS_EQUAL:
        return false; // (CF == 1 || ZF == 1) but ordered
      case ConditionOperand.CMPG_GREATER:
        return false; // (CF == 0 && ZF == 0) but unordered

      case ConditionOperand.CMPL_GREATER:
        return true; // (CF == 0 && ZF == 0) and ordered
      case ConditionOperand.CMPL_LESS_EQUAL:
        return true; // (CF == 1 || ZF == 1) and unordered
      case ConditionOperand.CMPL_GREATER_EQUAL:
        return true; // (CF == 0) and ordered
      case ConditionOperand.CMPL_LESS:
        return true; // (CF == 1) and unordered
      default:
        OptimizingCompilerException.UNREACHABLE();
        return false; // keep jikes happy
    }
  }
示例#5
0
 /**
  * @param type one of INT_VALUE, FLOAT_VALUE, or DOUBLE_VALUE
  * @return the move operator for a type of value.
  */
 private static Operator getMoveOperator(Register type) {
   if (type.isNatural()) {
     return IA32_MOV;
   } else if (type.isDouble()) {
     return SSE2_FULL ? IA32_MOVSD : IA32_FMOV;
   } else if (type.isFloat()) {
     return SSE2_FULL ? IA32_MOVSS : IA32_FMOV;
   } else {
     OptimizingCompilerException.TODO("getMoveOperator: unsupported: " + type);
     return null;
   }
 }
示例#6
0
 /**
  * @param type one of INT_VALUE, FLOAT_VALUE, or DOUBLE_VALUE
  * @return the size of a type of value, in bytes. NOTE: For the purpose of register allocation, an
  *     x87 FLOAT_VALUE is 64 bits!
  */
 private static byte getSizeOfType(Register type) {
   if (type.isNatural()) {
     if (VM.BuildFor64Addr && type.isInteger()) {
       return (byte) BYTES_IN_INT;
     } else {
       return (byte) WORDSIZE;
     }
   } else if (type.isFloat()) {
     if (SSE2_FULL) return (byte) BYTES_IN_FLOAT;
     return (byte) BYTES_IN_DOUBLE;
   } else if (type.isDouble()) {
     return (byte) BYTES_IN_DOUBLE;
   } else {
     OptimizingCompilerException.TODO("getSizeOfValue: unsupported: " + type);
     return (byte) -1;
   }
 }
示例#7
0
 /**
  * Get a constructor object for this compiler phase
  *
  * @return exception/null as this phase can't be created
  */
 public Constructor<CompilerPhase> getClassConstructor() {
   OptimizingCompilerException.UNREACHABLE();
   return null;
 }