//-----------------------------memory_inputs-------------------------------- const MachOper* MachNode::memory_inputs(Node* &base, Node* &index) const { const MachOper* oper = memory_operand(); if (oper == (MachOper*)-1) { base = NodeSentinel; index = NodeSentinel; } else { base = NULL; index = NULL; if (oper != NULL) { // It has a unique memory operand. Find its index. int oper_idx = num_opnds(); while (--oper_idx >= 0) { if (_opnds[oper_idx] == oper) break; } int oper_pos = operand_index(oper_idx); int base_pos = oper->base_position(); if (base_pos >= 0) { base = _in[oper_pos+base_pos]; } int index_pos = oper->index_position(); if (index_pos >= 0) { index = _in[oper_pos+index_pos]; } } } return oper; }
//------------------------------hash------------------------------------------- uint MachNode::hash() const { uint no = num_opnds(); uint sum = rule(); for( uint i=0; i<no; i++ ) sum += _opnds[i]->hash(); return sum+Node::hash(); }
//-----------------------------cmp--------------------------------------------- uint MachNode::cmp( const Node &node ) const { MachNode& n = *((Node&)node).as_Mach(); uint no = num_opnds(); if( no != n.num_opnds() ) return 0; if( rule() != n.rule() ) return 0; for( uint i=0; i<no; i++ ) // All operands must match if( !_opnds[i]->cmp( *n._opnds[i] ) ) return 0; // mis-matched operands return 1; // match }
int MachNode::operand_index(const MachOper *oper) const { uint skipped = oper_input_base(); // Sum of leaves skipped so far uint opcnt; for (opcnt = 1; opcnt < num_opnds(); opcnt++) { if (_opnds[opcnt] == oper) break; uint num_edges = _opnds[opcnt]->num_edges(); // leaves for operand skipped += num_edges; } if (_opnds[opcnt] != oper) return -1; return skipped; }
//------------------------------dump_spec-------------------------------------- // Print any per-operand special info void MachNode::dump_spec(outputStream *st) const { uint cnt = num_opnds(); for( uint i=0; i<cnt; i++ ) _opnds[i]->dump_spec(st); const TypePtr *t = adr_type(); if( t ) { Compile* C = Compile::current(); if( C->alias_type(t)->is_volatile() ) st->print(" Volatile!"); } }
//-----------------------------operand_index--------------------------------- int MachNode::operand_index( uint operand ) const { if( operand < 1 ) return -1; assert(operand < num_opnds(), "oob"); if( _opnds[operand]->num_edges() == 0 ) return -1; uint skipped = oper_input_base(); // Sum of leaves skipped so far for (uint opcnt = 1; opcnt < operand; opcnt++) { uint num_edges = _opnds[opcnt]->num_edges(); // leaves for operand skipped += num_edges; } return skipped; }
//-----------------------------in_RegMask-------------------------------------- const RegMask &MachNode::in_RegMask( uint idx ) const { uint numopnds = num_opnds(); // Virtual call for number of operands uint skipped = oper_input_base(); // Sum of leaves skipped so far if( idx < skipped ) { assert( ideal_Opcode() == Op_AddP, "expected base ptr here" ); assert( idx == 1, "expected base ptr here" ); // debug info can be anywhere return *Compile::current()->matcher()->idealreg2spillmask[Op_RegP]; } uint opcnt = 1; // First operand uint num_edges = _opnds[1]->num_edges(); // leaves for first operand while( idx >= skipped+num_edges ) { skipped += num_edges; opcnt++; // Bump operand count assert( opcnt < numopnds, "Accessing non-existent operand" ); num_edges = _opnds[opcnt]->num_edges(); // leaves for next operand } const RegMask *rm = cisc_RegMask(); if( rm == NULL || (int)opcnt != cisc_operand() ) { rm = _opnds[opcnt]->in_RegMask(idx-skipped); } return *rm; }