示例#1
0
  // Generate code for a single tree root.
  private void generateTree(OPT_BURS_TreeNode k, OPT_BURS_STATE burs) {
    OPT_BURS_TreeNode child1 = k.child1;
    OPT_BURS_TreeNode child2 = k.child2;
    if (child1 != null) {
      if (child2 != null) {
        // k has two children; use register labeling to
        // determine order that minimizes register pressure
        if (k.isSuperNodeRoot()) {
          byte act = burs.action[k.rule(k.getNonTerminal())];
          if ((act & burs.RIGHT_CHILD_FIRST) != 0) {
            // rule selected forces order of evaluation
            generateTree(child2, burs);
            generateTree(child1, burs);
          } else {
            generateTree(child1, burs);
            generateTree(child2, burs);
          }
        } else {
          generateTree(child1, burs);
          generateTree(child2, burs);
        }
      } else {
        generateTree(child1, burs);
      }
    } else if (child2 != null) {
      generateTree(child2, burs);
    }

    if (k.isSuperNodeRoot()) {
      int nonterminal = k.getNonTerminal();
      int rule = k.rule(nonterminal);
      burs.code(k, nonterminal, rule);
      if (DEBUG) VM.sysWrite(k + " " + OPT_BURS_Debug.string[rule] + "\n");
    }
  }
示例#2
0
  /**
   * Build a BURS Tree for each OPT_Instruction. Complete BURS trees by adding leaf nodes as needed,
   * and creating tree edges by calling insertChild1() or insertChild2() This step is also where we
   * introduce intermediate tree nodes for any LIR instruction that has > 2 "real" operands e.g., a
   * CALL.
   *
   * @param s The instruction for which a tree must be built
   */
  private OPT_BURS_TreeNode buildTree(OPT_Instruction s) {

    OPT_BURS_TreeNode root = new OPT_BURS_TreeNode(new OPT_DepGraphNode(s));
    OPT_BURS_TreeNode cur = root;
    for (OPT_OperandEnumeration uses = s.getUses(); uses.hasMoreElements(); ) {
      OPT_Operand op = uses.next();
      if (op == null) continue;

      op.clear();
      // Set child = OPT_BURS_TreeNode for operand op
      OPT_BURS_TreeNode child;
      if (op instanceof OPT_RegisterOperand) {
        if (op.asRegister().register.isValidation()) continue;
        child = Register;
      } else if (op instanceof OPT_IntConstantOperand) {
        child = new OPT_BURS_IntConstantTreeNode(((OPT_IntConstantOperand) op).value);
      } else if (op instanceof OPT_LongConstantOperand) {
        child = LongConstant;
      } else if (op instanceof OPT_AddressConstantOperand) {
        child = AddressConstant;
      } else if (op instanceof OPT_BranchOperand && s.isCall()) {
        child = BranchTarget;
        // -#if RVM_WITH_OSR
      } else if (op instanceof OPT_InlinedOsrTypeInfoOperand && s.isYieldPoint()) {
        child = NullTreeNode;
        // -#endif
      } else {
        continue;
      }

      // Attach child as child of cur_parent in correct position
      if (cur.child1 == null) {
        cur.child1 = child;
      } else if (cur.child2 == null) {
        cur.child2 = child;
      } else {
        // Create auxiliary node so as to represent
        // a instruction with arity > 2 in a binary tree.
        OPT_BURS_TreeNode child1 = cur.child2;
        OPT_BURS_TreeNode aux = new OPT_BURS_TreeNode(OTHER_OPERAND_opcode);
        cur.child2 = aux;
        cur = aux;
        cur.child1 = child1;
        cur.child2 = child;
      }
    }

    // patch for calls & return
    switch (s.getOpcode()) {
      case CALL_opcode:
      case SYSCALL_opcode:
        // -#if RVM_WITH_OSR
      case YIELDPOINT_OSR_opcode:
        // -#endif
        if (cur.child2 == null) cur.child2 = NullTreeNode;
        // fall through
      case RETURN_opcode:
        if (cur.child1 == null) cur.child1 = NullTreeNode;
    }
    return root;
  }
示例#3
0
 /* node accessors */
 protected final OPT_Instruction P(OPT_BURS_TreeNode p) {
   return p.getInstruction();
 }