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);
}