Esempio n. 1
0
//=============================================================================
ReturnNode::ReturnNode(Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *retadr ) : Node(TypeFunc::Parms) {
    set_req(TypeFunc::Control,cntrl);
    set_req(TypeFunc::I_O,i_o);
    set_req(TypeFunc::Memory,memory);
    set_req(TypeFunc::FramePtr,frameptr);
    set_req(TypeFunc::ReturnAdr,retadr);
}
Esempio n. 2
0
//=============================================================================
HaltNode::HaltNode( Node *ctrl, Node *frameptr ) : Node(TypeFunc::Parms) { 
  Node* top = Compile::current()->top();
  set_req(TypeFunc::Control,  ctrl        ); 
  set_req(TypeFunc::I_O,      top);
  set_req(TypeFunc::Memory,   top);
  set_req(TypeFunc::FramePtr, frameptr    );
  set_req(TypeFunc::ReturnAdr,top);
}
Esempio n. 3
0
//=============================================================================
//------------------------------Ideal------------------------------------------
// Check for power-of-2 multiply, then try the regular MulNode::Ideal
Node *MulLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  // Swap constant to right
  if( in(1)->is_Con() ) {
    Node *t = in(1);
    set_req(1,in(2));
    set_req(2,t);
    
  } else if( !in(2)->is_Con() ) 
    return MulNode::Ideal(phase, can_reshape);
 
  // Now we have a constant Node on the right and the constant in con
  const TypeLong *tl2 = phase->type( in(2) )->isa_long();
  if( !tl2 ) return NULL;       // Might be top
  jlong con = tl2->isa_long()->get_con();
  if( con == CONST64(0) ) return NULL;  // By zero is handled by Value call
  if( con == CONST64(1) ) return NULL;  // By one  is handled by Identity call

  // Check for negative constant; if so negate the final result
  bool sign_flip = false;
  if( con < 0 ) {
    con = -con;
    sign_flip = true;
  }

  // Get low bit; check for being the only bit
  Node *res = NULL;
  jlong bit1 = con & -con;      // Extract low bit
  if( bit1 == con ) {           // Found a power of 2?
    res = new (3) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) );
  } else {

    // Check for constant with 2 bits set
    jlong bit2 = con-bit1;
    bit2 = bit2 & -bit2;          // Extract 2nd bit
    if( bit2 + bit1 == con ) {    // Found all bits in con?
      Node *n1 = phase->transform( new (3) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) );
      Node *n2 = phase->transform( new (3) LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) );
      res = new (3) AddLNode( n2, n1 );

    } else {
      // Sleezy: power-of-2 -1.  Next time be generic.
      jlong temp = con + 1;
      if( temp == (temp & -temp) ) {
        Node *n1 = phase->transform( new (3) LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) );
        res = new (3) SubLNode( n1, in(1) );
      } else {
        return MulNode::Ideal(phase, can_reshape);
      }
    }
  }

  if( sign_flip ) {             // Need to negate result?
    res = phase->transform(res);// Transform, before making the zero con
    res = new (3) SubLNode(phase->makecon(TypeLong::ZERO),res);
  }

  return res;                   // Return final result
}
Esempio n. 4
0
/*
 * Creates peudo DEV:DFx files.
 */
void initpseudodevices(void)
{
    ULONG lock;
    int i;

    pseudo_dev_created  = 0;
    pseudo_dev_assigned = 0;
    for(i=0;i<4;++i) dfx_done[i]=0;

    /* check if dev: already exists */
    set_req(0);lock = Lock(amiga_dev_path,SHARED_LOCK);set_req(1);
    if(!lock) {
	char name[80];
	set_req(0);lock = Lock(pseudo_dev_path,SHARED_LOCK);set_req(1);
	if(!lock) {
	    /* create it */
	    lock = CreateDir(pseudo_dev_path);
	    if(!lock) goto fail;
	    UnLock(lock);lock = Lock(pseudo_dev_path,SHARED_LOCK);
	    pseudo_dev_created = 1;
	}
	strcpy(name,amiga_dev_path);
	if(*name && name[strlen(name)-1]==':') name[strlen(name)-1]='\0';
	if(!AssignLock(name,lock)) {UnLock(lock);goto fail;}
	/* the lock is the assign now */
	pseudo_dev_assigned = 1;
    } else UnLock(lock);

    /* Create the dev:DFi entry */
    for(i=0;i<4;++i) if(device_exists("trackdisk.device",i)) {
	ULONG fd;
	char name[80];

	sprintf(name,"%sDF%d",amiga_dev_path,i);
	fd = Open(name,MODE_NEWFILE);
	if(fd) {Close(fd);dfx_done[i]=1;}
    }

    return;
 fail:
    fprintf(stderr,"Failed to create pseudo dev: entry!\n");
}
Esempio n. 5
0
//=============================================================================
RethrowNode::RethrowNode(
    Node* cntrl,
    Node* i_o,
    Node* memory,
    Node* frameptr,
    Node* ret_adr,
    Node* exception
) : Node(TypeFunc::Parms + 1) {
    set_req(TypeFunc::Control  , cntrl    );
    set_req(TypeFunc::I_O      , i_o      );
    set_req(TypeFunc::Memory   , memory   );
    set_req(TypeFunc::FramePtr , frameptr );
    set_req(TypeFunc::ReturnAdr, ret_adr);
    set_req(TypeFunc::Parms    , exception);
}
 void  set_monitor(const JVMState* jvms, uint idx, Node *c) {
   assert(verify_jvms(jvms), "jvms must match");
   set_req(_jvmadj + jvms->monoff() + idx, c);
 }
Esempio n. 7
0
//=============================================================================
//------------------------------Idealize---------------------------------------
// MINs show up in range-check loop limit calculations.  Look for
// "MIN2(x+c0,MIN2(y,x+c1))".  Pick the smaller constant: "MIN2(x+c0,y)"
Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
  Node *progress = NULL;
  // Force a right-spline graph
  Node *l = in(1);
  Node *r = in(2);
  // Transform  MinI1( MinI2(a,b), c)  into  MinI1( a, MinI2(b,c) )
  // to force a right-spline graph for the rest of MinINode::Ideal().
  if( l->Opcode() == Op_MinI ) {
    assert( l != l->in(1), "dead loop in MinINode::Ideal" );
    r = phase->transform(new (phase->C) MinINode(l->in(2),r));
    l = l->in(1);
    set_req(1, l);
    set_req(2, r);
    return this;
  }

  // Get left input & constant
  Node *x = l;
  int x_off = 0;
  if( x->Opcode() == Op_AddI && // Check for "x+c0" and collect constant
      x->in(2)->is_Con() ) {
    const Type *t = x->in(2)->bottom_type();
    if( t == Type::TOP ) return NULL;  // No progress
    x_off = t->is_int()->get_con();
    x = x->in(1);
  }

  // Scan a right-spline-tree for MINs
  Node *y = r;
  int y_off = 0;
  // Check final part of MIN tree
  if( y->Opcode() == Op_AddI && // Check for "y+c1" and collect constant
      y->in(2)->is_Con() ) {
    const Type *t = y->in(2)->bottom_type();
    if( t == Type::TOP ) return NULL;  // No progress
    y_off = t->is_int()->get_con();
    y = y->in(1);
  }
  if( x->_idx > y->_idx && r->Opcode() != Op_MinI ) {
    swap_edges(1, 2);
    return this;
  }


  if( r->Opcode() == Op_MinI ) {
    assert( r != r->in(2), "dead loop in MinINode::Ideal" );
    y = r->in(1);
    // Check final part of MIN tree
    if( y->Opcode() == Op_AddI &&// Check for "y+c1" and collect constant
        y->in(2)->is_Con() ) {
      const Type *t = y->in(2)->bottom_type();
      if( t == Type::TOP ) return NULL;  // No progress
      y_off = t->is_int()->get_con();
      y = y->in(1);
    }

    if( x->_idx > y->_idx )
      return new (phase->C) MinINode(r->in(1),phase->transform(new (phase->C) MinINode(l,r->in(2))));

    // See if covers: MIN2(x+c0,MIN2(y+c1,z))
    if( !phase->eqv(x,y) ) return NULL;
    // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into
    // MIN2(x+c0 or x+c1 which less, z).
    return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2));
  } else {
    // See if covers: MIN2(x+c0,y+c1)
    if( !phase->eqv(x,y) ) return NULL;
    // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less.
    return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)));
  }

}
Esempio n. 8
0
//------------------------------Idealize---------------------------------------
Node *AddPNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  // Bail out if dead inputs
  if( phase->type( in(Address) ) == Type::TOP ) return NULL;

  // If the left input is an add of a constant, flatten the expression tree.
  const Node *n = in(Address);
  if (n->is_AddP() && n->in(Base) == in(Base)) {
    const AddPNode *addp = n->as_AddP(); // Left input is an AddP
    assert( !addp->in(Address)->is_AddP() ||
             addp->in(Address)->as_AddP() != addp,
            "dead loop in AddPNode::Ideal" );
    // Type of left input's right input
    const Type *t = phase->type( addp->in(Offset) );
    if( t == Type::TOP ) return NULL;
    const TypeX *t12 = t->is_intptr_t();
    if( t12->is_con() ) {       // Left input is an add of a constant?
      // If the right input is a constant, combine constants
      const Type *temp_t2 = phase->type( in(Offset) );
      if( temp_t2 == Type::TOP ) return NULL;
      const TypeX *t2 = temp_t2->is_intptr_t();
      Node* address;
      Node* offset;
      if( t2->is_con() ) {
        // The Add of the flattened expression
        address = addp->in(Address);
        offset  = phase->MakeConX(t2->get_con() + t12->get_con());
      } else {
        // Else move the constant to the right.  ((A+con)+B) into ((A+B)+con)
        address = phase->transform(new (phase->C) AddPNode(in(Base),addp->in(Address),in(Offset)));
        offset  = addp->in(Offset);
      }
      PhaseIterGVN *igvn = phase->is_IterGVN();
      if( igvn ) {
        set_req_X(Address,address,igvn);
        set_req_X(Offset,offset,igvn);
      } else {
        set_req(Address,address);
        set_req(Offset,offset);
      }
      return this;
    }
  }

  // Raw pointers?
  if( in(Base)->bottom_type() == Type::TOP ) {
    // If this is a NULL+long form (from unsafe accesses), switch to a rawptr.
    if (phase->type(in(Address)) == TypePtr::NULL_PTR) {
      Node* offset = in(Offset);
      return new (phase->C) CastX2PNode(offset);
    }
  }

  // If the right is an add of a constant, push the offset down.
  // Convert: (ptr + (offset+con)) into (ptr+offset)+con.
  // The idea is to merge array_base+scaled_index groups together,
  // and only have different constant offsets from the same base.
  const Node *add = in(Offset);
  if( add->Opcode() == Op_AddX && add->in(1) != add ) {
    const Type *t22 = phase->type( add->in(2) );
    if( t22->singleton() && (t22 != Type::TOP) ) {  // Right input is an add of a constant?
      set_req(Address, phase->transform(new (phase->C) AddPNode(in(Base),in(Address),add->in(1))));
      set_req(Offset, add->in(2));
      PhaseIterGVN *igvn = phase->is_IterGVN();
      if (add->outcnt() == 0 && igvn) {
        // add disconnected.
        igvn->_worklist.push((Node*)add);
      }
      return this;              // Made progress
    }
  }

  return NULL;                  // No progress
}
Esempio n. 9
0
//------------------------------Idealize---------------------------------------
// If we get here, we assume we are associative!
Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  const Type *t1 = phase->type( in(1) );
  const Type *t2 = phase->type( in(2) );
  int con_left  = t1->singleton();
  int con_right = t2->singleton();

  // Check for commutative operation desired
  if( commute(this,con_left,con_right) ) return this;

  AddNode *progress = NULL;             // Progress flag

  // Convert "(x+1)+2" into "x+(1+2)".  If the right input is a
  // constant, and the left input is an add of a constant, flatten the
  // expression tree.
  Node *add1 = in(1);
  Node *add2 = in(2);
  int add1_op = add1->Opcode();
  int this_op = Opcode();
  if( con_right && t2 != Type::TOP && // Right input is a constant?
      add1_op == this_op ) { // Left input is an Add?

    // Type of left _in right input
    const Type *t12 = phase->type( add1->in(2) );
    if( t12->singleton() && t12 != Type::TOP ) { // Left input is an add of a constant?
      // Check for rare case of closed data cycle which can happen inside
      // unreachable loops. In these cases the computation is undefined.
#ifdef ASSERT
      Node *add11    = add1->in(1);
      int   add11_op = add11->Opcode();
      if( (add1 == add1->in(1))
         || (add11_op == this_op && add11->in(1) == add1) ) {
        assert(false, "dead loop in AddNode::Ideal");
      }
#endif
      // The Add of the flattened expression
      Node *x1 = add1->in(1);
      Node *x2 = phase->makecon( add1->as_Add()->add_ring( t2, t12 ));
      PhaseIterGVN *igvn = phase->is_IterGVN();
      if( igvn ) {
        set_req_X(2,x2,igvn);
        set_req_X(1,x1,igvn);
      } else {
        set_req(2,x2);
        set_req(1,x1);
      }
      progress = this;            // Made progress
      add1 = in(1);
      add1_op = add1->Opcode();
    }
  }

  // Convert "(x+1)+y" into "(x+y)+1".  Push constants down the expression tree.
  if( add1_op == this_op && !con_right ) {
    Node *a12 = add1->in(2);
    const Type *t12 = phase->type( a12 );
    if( t12->singleton() && t12 != Type::TOP && (add1 != add1->in(1)) &&
       !(add1->in(1)->is_Phi() && add1->in(1)->as_Phi()->is_tripcount()) ) {
      assert(add1->in(1) != this, "dead loop in AddNode::Ideal");
      add2 = add1->clone();
      add2->set_req(2, in(2));
      add2 = phase->transform(add2);
      set_req(1, add2);
      set_req(2, a12);
      progress = this;
      add2 = a12;
    }
  }

  // Convert "x+(y+1)" into "(x+y)+1".  Push constants down the expression tree.
  int add2_op = add2->Opcode();
  if( add2_op == this_op && !con_left ) {
    Node *a22 = add2->in(2);
    const Type *t22 = phase->type( a22 );
    if( t22->singleton() && t22 != Type::TOP && (add2 != add2->in(1)) &&
       !(add2->in(1)->is_Phi() && add2->in(1)->as_Phi()->is_tripcount()) ) {
      assert(add2->in(1) != this, "dead loop in AddNode::Ideal");
      Node *addx = add2->clone();
      addx->set_req(1, in(1));
      addx->set_req(2, add2->in(1));
      addx = phase->transform(addx);
      set_req(1, addx);
      set_req(2, a22);
      progress = this;
      PhaseIterGVN *igvn = phase->is_IterGVN();
      if (add2->outcnt() == 0 && igvn) {
        // add disconnected.
        igvn->_worklist.push(add2);
      }
    }
  }

  return progress;
}
Esempio n. 10
0
 void  set_box_node(Node* box) { set_req(2, box); }
Esempio n. 11
0
//------------------------------Ideal------------------------------------------
// We also canonicalize the Node, moving constants to the right input, 
// and flatten expressions (so that 1+x+2 becomes x+3).
Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  const Type *t1 = phase->type( in(1) );
  const Type *t2 = phase->type( in(2) );
  Node *progress = NULL;        // Progress flag
  // We are OK if right is a constant, or right is a load and
  // left is a non-constant.
  if( !(t2->singleton() ||
        (in(2)->is_Load() && !(t1->singleton() || in(1)->is_Load())) ) ) {
    if( t1->singleton() ||       // Left input is a constant?
        // Otherwise, sort inputs (commutativity) to help value numbering.
        (in(1)->_idx > in(2)->_idx) ) {
      swap_edges(1, 2);
      const Type *t = t1;
      t1 = t2;
      t2 = t;
      progress = this;            // Made progress
    }
  }

  // If the right input is a constant, and the left input is a product of a
  // constant, flatten the expression tree.
  uint op = Opcode();
  if( t2->singleton() &&        // Right input is a constant?
      op != Op_MulF &&          // Float & double cannot reassociate
      op != Op_MulD ) { 
    if( t2 == Type::TOP ) return NULL;
    Node *mul1 = in(1);
    if( mul1 == this ) {        // Check for dead cycle
      set_req(1, phase->C->top());
      return this;              // Make it trivially dead
    }
    if( mul1->Opcode() == mul_opcode() ) {  // Left input is a multiply?
      // Mul of a constant?
      const Type *t12 = phase->type( mul1->in(2) ); 
      if( t12->singleton() && t12 != Type::TOP) { // Left input is an add of a constant?
        // Compute new constant; check for overflow
        const Type *tcon01 = mul1->is_Mul()->mul_ring(t2,t12);
        if( tcon01->singleton() ) {
          // The Mul of the flattened expression
          set_req(1, mul1->in(1));
          set_req(2, phase->makecon( tcon01 ));
          t2 = tcon01;
          progress = this;      // Made progress
        }
      }
    }
    // If the right input is a constant, and the left input is an add of a 
    // constant, flatten the tree: (X+con1)*con0 ==> X*con0 + con1*con0
    const Node *add1 = in(1);
    if( add1->Opcode() == add_opcode() ) {      // Left input is an add?
      // Add of a constant?
      const Type *t12 = phase->type( add1->in(2) ); 
      if( t12->singleton() && t12 != Type::TOP ) { // Left input is an add of a constant?
        // Check if the add node is dead and self-referencing, 
        // to avoid infinite loop (no progress).
        if( add1->in(1) == add1 ) return progress;
        // Compute new constant; check for overflow
        const Type *tcon01 = mul_ring(t2,t12);
        if( tcon01->singleton() ) {
        
        // Convert (X+con1)*con0 into X*con0
          Node *mul = clone();    // mul = ()*con0
          mul->set_req(1,add1->in(1));  // mul = X*con0
          mul = phase->transform(mul);

          Node *add2 = add1->clone();
          add2->set_req(1, mul);        // X*con0 + con0*con1
          add2->set_req(2, phase->makecon(tcon01) );
          progress = add2;
        }
      }
    } // End of is left input an add
  } // End of is right input a Mul

  return progress;
}
 void set_memory   ( Node *c ) { set_req(TypeFunc::Memory ,c); }
 void set_i_o      ( Node *c ) { set_req(TypeFunc::I_O    ,c); }
 void set_control  ( Node *c ) { set_req(TypeFunc::Control,c); }
 void  set_argument(JVMState* jvms, uint idx, Node *c) {
   assert(verify_jvms(jvms), "jvms must match");
   set_req(jvms->argoff() + idx, c);
 }
 void  set_stack(JVMState* jvms, uint idx, Node *c) {
   assert(verify_jvms(jvms), "jvms must match");
   set_req(jvms->stkoff() + idx, c);
 }