draft of arithmetic overflow support code in C2 (original) (raw)

//-----------------------------AddOverflowNode-----------------------------------

// Addition with overflow condition

class AddOverflowNode : public MultiNode {

protected:

AddOverflowNode(Node* c, Node* sum, Node* overflow);

public:

enum {

sum_proj_num = 0, // sum

overflow_proj_num = 1 // overflow condition

};

virtual int Opcode() const;

virtual Node* Identity(PhaseTransform* phase) { return this; }

virtual Node* Ideal(PhaseGVN* phase, bool can_reshape) { return NULL; }

virtual const Type* Value(PhaseTransform* phase) const { return bottom_type(); }

virtual uint hash() const { return Node::hash(); }

virtual bool is_CFG() const { return false; }

virtual uint ideal_reg() const { return NotAMachineReg; }

ProjNode* sum_proj() { return proj_out(sum_proj_num); }

ProjNode* overflow_proj() { return proj_out(overflow_proj_num); }

};

//-----------------------------AddIOverflowNode----------------------------------

// Integer addition with overflow condition

class AddIOverflowNode : public AddOverflowNode {

public:

AddIOverflowNode(Node* c, Node* sum, Node* overflow) : AddOverflowNode(c, sum, oveflow) {}

virtual int Opcode() const;

virtual const Type* bottom_type() const { return TypeTuple::INT_CC; }

virtual Node* match( const ProjNode *proj, const Matcher *m );

static AddIOverflowNode* make(Compile* C, Node* overflow);

};

//=============================================================================

AddOverflowNode::AddOverflowNode(Node* c, Node* sum, Node* overflow) : MultiNode(3) {

init_req(0, c);

init_req(1, sum);

init_req(2, overflow);

}

//------------------------------make------------------------------------------

AddIOverflowNode* AddIOverflowNode::make(Compile* C, Node* overflow) {

Node* n = overflow;

assert(n->Opcode() == Op_CheckAddIOverflow, "only add overflow accepted");

AddIOverflowNode* addovf = new (C, 3) AddIOverflowNode(n->in(0), n->in(1), n->in(2));

Node* sproj = new (C, 1) ProjNode(addovf, AddOverflowNode::sum_proj_num);

Node* oproj = new (C, 1) ProjNode(addovf, AddOverflowNode::overflow_proj_num);

return addovf;

}

//------------------------------match------------------------------------------

// return result(s) along with their RegMask info

Node *AddIOverflowNode::match(const ProjNode* proj, const Matcher* match) {

uint ideal_reg = proj->ideal_reg();

RegMask rm;

if (proj->_con == sum_proj_num) {

rm = RegMask::EMPTY;

} else {

assert(proj->_con == overflow_proj_num, "must be sum or overflow projection");

ideal_reg = Op_RegFlags;

rm = match->overflow_proj_mask();

}

return new (match->C, 1) MachProjNode(this, proj->_con, rm, ideal_reg);

}