336 Node** out = _out;
337 // Assign a limit pointer to the reference argument:
338 max = out + (ptrdiff_t)_outcnt;
339 // Return the base pointer:
340 return out;
341 }
342 Node* fast_out(DUIterator_Fast i) const { return *i; }
343 // Iterate over the out-edges of this node, deleting one at a time.
344 // This iteration uses a pointer internal to the out array.
345 DUIterator_Last last_outs(DUIterator_Last& min) const {
346 Node** out = _out;
347 // Assign a limit pointer to the reference argument:
348 min = out;
349 // Return the pointer to the start of the iteration:
350 return out + (ptrdiff_t)_outcnt - 1;
351 }
352 Node* last_out(DUIterator_Last i) const { return *i; }
353 #endif
354
355 // Reference to the i'th input Node. Error if out of bounds.
356 Node* in(uint i) const { assert(i < _max, err_msg_res("oob: i=%d, _max=%d", i, _max)); return _in[i]; }
357 // Reference to the i'th input Node. NULL if out of bounds.
358 Node* lookup(uint i) const { return ((i < _max) ? _in[i] : NULL); }
359 // Reference to the i'th output Node. Error if out of bounds.
360 // Use this accessor sparingly. We are going trying to use iterators instead.
361 Node* raw_out(uint i) const { assert(i < _outcnt,"oob"); return _out[i]; }
362 // Return the unique out edge.
363 Node* unique_out() const { assert(_outcnt==1,"not unique"); return _out[0]; }
364 // Delete out edge at position 'i' by moving last out edge to position 'i'
365 void raw_del_out(uint i) {
366 assert(i < _outcnt,"oob");
367 assert(_outcnt > 0,"oob");
368 #if OPTO_DU_ITERATOR_ASSERT
369 // Record that a change happened here.
370 debug_only(_last_del = _out[i]; ++_del_tick);
371 #endif
372 _out[i] = _out[--_outcnt];
373 // Smash the old edge so it can't be used accidentally.
374 debug_only(_out[_outcnt] = (Node *)(uintptr_t)0xdeadbeef);
375 }
376
377 #ifdef ASSERT
378 bool is_dead() const;
379 #define is_not_dead(n) ((n) == NULL || !VerifyIterativeGVN || !((n)->is_dead()))
380 #endif
381 // Check whether node has become unreachable
382 bool is_unreachable(PhaseIterGVN &igvn) const;
383
384 // Set a required input edge, also updates corresponding output edge
385 void add_req( Node *n ); // Append a NEW required input
386 void add_req( Node *n0, Node *n1 ) {
387 add_req(n0); add_req(n1); }
388 void add_req( Node *n0, Node *n1, Node *n2 ) {
389 add_req(n0); add_req(n1); add_req(n2); }
390 void add_req_batch( Node* n, uint m ); // Append m NEW required inputs (all n).
391 void del_req( uint idx ); // Delete required edge & compact
392 void del_req_ordered( uint idx ); // Delete required edge & compact with preserved order
393 void ins_req( uint i, Node *n ); // Insert a NEW required input
394 void set_req( uint i, Node *n ) {
395 assert( is_not_dead(n), "can not use dead node");
396 assert( i < _cnt, err_msg_res("oob: i=%d, _cnt=%d", i, _cnt));
397 assert( !VerifyHashTableKeys || _hash_lock == 0,
398 "remove node from hash table before modifying it");
399 Node** p = &_in[i]; // cache this._in, across the del_out call
400 if (*p != NULL) (*p)->del_out((Node *)this);
401 (*p) = n;
402 if (n != NULL) n->add_out((Node *)this);
403 Compile::current()->record_modified_node(this);
404 }
405 // Light version of set_req() to init inputs after node creation.
406 void init_req( uint i, Node *n ) {
407 assert( i == 0 && this == n ||
408 is_not_dead(n), "can not use dead node");
409 assert( i < _cnt, "oob");
410 assert( !VerifyHashTableKeys || _hash_lock == 0,
411 "remove node from hash table before modifying it");
412 assert( _in[i] == NULL, "sanity");
413 _in[i] = n;
414 if (n != NULL) n->add_out((Node *)this);
415 Compile::current()->record_modified_node(this);
416 }
|
336 Node** out = _out;
337 // Assign a limit pointer to the reference argument:
338 max = out + (ptrdiff_t)_outcnt;
339 // Return the base pointer:
340 return out;
341 }
342 Node* fast_out(DUIterator_Fast i) const { return *i; }
343 // Iterate over the out-edges of this node, deleting one at a time.
344 // This iteration uses a pointer internal to the out array.
345 DUIterator_Last last_outs(DUIterator_Last& min) const {
346 Node** out = _out;
347 // Assign a limit pointer to the reference argument:
348 min = out;
349 // Return the pointer to the start of the iteration:
350 return out + (ptrdiff_t)_outcnt - 1;
351 }
352 Node* last_out(DUIterator_Last i) const { return *i; }
353 #endif
354
355 // Reference to the i'th input Node. Error if out of bounds.
356 Node* in(uint i) const { assert(i < _max, "oob: i=%d, _max=%d", i, _max); return _in[i]; }
357 // Reference to the i'th input Node. NULL if out of bounds.
358 Node* lookup(uint i) const { return ((i < _max) ? _in[i] : NULL); }
359 // Reference to the i'th output Node. Error if out of bounds.
360 // Use this accessor sparingly. We are going trying to use iterators instead.
361 Node* raw_out(uint i) const { assert(i < _outcnt,"oob"); return _out[i]; }
362 // Return the unique out edge.
363 Node* unique_out() const { assert(_outcnt==1,"not unique"); return _out[0]; }
364 // Delete out edge at position 'i' by moving last out edge to position 'i'
365 void raw_del_out(uint i) {
366 assert(i < _outcnt,"oob");
367 assert(_outcnt > 0,"oob");
368 #if OPTO_DU_ITERATOR_ASSERT
369 // Record that a change happened here.
370 debug_only(_last_del = _out[i]; ++_del_tick);
371 #endif
372 _out[i] = _out[--_outcnt];
373 // Smash the old edge so it can't be used accidentally.
374 debug_only(_out[_outcnt] = (Node *)(uintptr_t)0xdeadbeef);
375 }
376
377 #ifdef ASSERT
378 bool is_dead() const;
379 #define is_not_dead(n) ((n) == NULL || !VerifyIterativeGVN || !((n)->is_dead()))
380 #endif
381 // Check whether node has become unreachable
382 bool is_unreachable(PhaseIterGVN &igvn) const;
383
384 // Set a required input edge, also updates corresponding output edge
385 void add_req( Node *n ); // Append a NEW required input
386 void add_req( Node *n0, Node *n1 ) {
387 add_req(n0); add_req(n1); }
388 void add_req( Node *n0, Node *n1, Node *n2 ) {
389 add_req(n0); add_req(n1); add_req(n2); }
390 void add_req_batch( Node* n, uint m ); // Append m NEW required inputs (all n).
391 void del_req( uint idx ); // Delete required edge & compact
392 void del_req_ordered( uint idx ); // Delete required edge & compact with preserved order
393 void ins_req( uint i, Node *n ); // Insert a NEW required input
394 void set_req( uint i, Node *n ) {
395 assert( is_not_dead(n), "can not use dead node");
396 assert( i < _cnt, "oob: i=%d, _cnt=%d", i, _cnt);
397 assert( !VerifyHashTableKeys || _hash_lock == 0,
398 "remove node from hash table before modifying it");
399 Node** p = &_in[i]; // cache this._in, across the del_out call
400 if (*p != NULL) (*p)->del_out((Node *)this);
401 (*p) = n;
402 if (n != NULL) n->add_out((Node *)this);
403 Compile::current()->record_modified_node(this);
404 }
405 // Light version of set_req() to init inputs after node creation.
406 void init_req( uint i, Node *n ) {
407 assert( i == 0 && this == n ||
408 is_not_dead(n), "can not use dead node");
409 assert( i < _cnt, "oob");
410 assert( !VerifyHashTableKeys || _hash_lock == 0,
411 "remove node from hash table before modifying it");
412 assert( _in[i] == NULL, "sanity");
413 _in[i] = n;
414 if (n != NULL) n->add_out((Node *)this);
415 Compile::current()->record_modified_node(this);
416 }
|