示例#1
0
 public void detectedCountedLoops() {
   for (LoopEx loop : loops()) {
     InductionVariables ivs = new InductionVariables(loop);
     LoopBeginNode loopBegin = loop.loopBegin();
     FixedNode next = loopBegin.next();
     while (next instanceof FixedGuardNode || next instanceof ValueAnchorNode) {
       next = ((FixedWithNextNode) next).next();
     }
     if (next instanceof IfNode) {
       IfNode ifNode = (IfNode) next;
       boolean negated = false;
       if (!loopBegin.isLoopExit(ifNode.falseSuccessor())) {
         if (!loopBegin.isLoopExit(ifNode.trueSuccessor())) {
           continue;
         }
         negated = true;
       }
       LogicNode ifTest = ifNode.condition();
       if (!(ifTest instanceof IntegerLessThanNode)) {
         if (ifTest instanceof IntegerBelowThanNode) {
           Debug.log("Ignored potential Counted loop at %s with |<|", loopBegin);
         }
         continue;
       }
       IntegerLessThanNode lessThan = (IntegerLessThanNode) ifTest;
       Condition condition = null;
       InductionVariable iv = null;
       ValueNode limit = null;
       if (loop.isOutsideLoop(lessThan.x())) {
         iv = ivs.get(lessThan.y());
         if (iv != null) {
           condition = lessThan.condition().mirror();
           limit = lessThan.x();
         }
       } else if (loop.isOutsideLoop(lessThan.y())) {
         iv = ivs.get(lessThan.x());
         if (iv != null) {
           condition = lessThan.condition();
           limit = lessThan.y();
         }
       }
       if (condition == null) {
         continue;
       }
       if (negated) {
         condition = condition.negate();
       }
       boolean oneOff = false;
       switch (condition) {
         case LE:
           oneOff = true; // fall through
         case LT:
           if (iv.direction() != Direction.Up) {
             continue;
           }
           break;
         case GE:
           oneOff = true; // fall through
         case GT:
           if (iv.direction() != Direction.Down) {
             continue;
           }
           break;
         default:
           throw GraalInternalError.shouldNotReachHere();
       }
       loop.setCounted(
           new CountedLoopInfo(
               loop,
               iv,
               limit,
               oneOff,
               negated ? ifNode.falseSuccessor() : ifNode.trueSuccessor()));
     }
   }
 }
示例#2
0
 public static void emit(
     TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Compare opcode, Value x, Value y) {
   if (isRegister(y)) {
     switch (opcode) {
       case ICMP:
         masm.cmpl(asIntReg(x), asIntReg(y));
         break;
       case LCMP:
         masm.cmpq(asLongReg(x), asLongReg(y));
         break;
       case ACMP:
         masm.cmpptr(asObjectReg(x), asObjectReg(y));
         break;
       case FCMP:
         masm.ucomiss(asFloatReg(x), asFloatReg(y));
         break;
       case DCMP:
         masm.ucomisd(asDoubleReg(x), asDoubleReg(y));
         break;
       default:
         throw GraalInternalError.shouldNotReachHere();
     }
   } else if (isConstant(y)) {
     switch (opcode) {
       case ICMP:
         masm.cmpl(asIntReg(x), tasm.asIntConst(y));
         break;
       case LCMP:
         masm.cmpq(asLongReg(x), tasm.asIntConst(y));
         break;
       case ACMP:
         if (((Constant) y).isNull()) {
           masm.cmpq(asObjectReg(x), 0);
           break;
         } else {
           throw GraalInternalError.shouldNotReachHere(
               "Only null object constants are allowed in comparisons");
         }
       case FCMP:
         masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatConstRef(y));
         break;
       case DCMP:
         masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleConstRef(y));
         break;
       default:
         throw GraalInternalError.shouldNotReachHere();
     }
   } else {
     switch (opcode) {
       case ICMP:
         masm.cmpl(asIntReg(x), (AMD64Address) tasm.asIntAddr(y));
         break;
       case LCMP:
         masm.cmpq(asLongReg(x), (AMD64Address) tasm.asLongAddr(y));
         break;
       case ACMP:
         masm.cmpptr(asObjectReg(x), (AMD64Address) tasm.asObjectAddr(y));
         break;
       case FCMP:
         masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatAddr(y));
         break;
       case DCMP:
         masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleAddr(y));
         break;
       default:
         throw GraalInternalError.shouldNotReachHere();
     }
   }
 }