Path: blob/master/src/hotspot/share/opto/divnode.hpp
40930 views
/*1* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_OPTO_DIVNODE_HPP25#define SHARE_OPTO_DIVNODE_HPP2627#include "opto/multnode.hpp"28#include "opto/node.hpp"29#include "opto/opcodes.hpp"30#include "opto/type.hpp"3132// Portions of code courtesy of Clifford Click3334// Optimization - Graph Style353637//------------------------------DivINode---------------------------------------38// Integer division39// Note: this is division as defined by JVMS, i.e., MinInt/-1 == MinInt.40// On processors which don't naturally support this special case (e.g., x86),41// the matcher or runtime system must take care of this.42class DivINode : public Node {43public:44DivINode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor ) {}45virtual int Opcode() const;46virtual Node* Identity(PhaseGVN* phase);47virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);48virtual const Type* Value(PhaseGVN* phase) const;49virtual const Type *bottom_type() const { return TypeInt::INT; }50virtual uint ideal_reg() const { return Op_RegI; }51};5253//------------------------------DivLNode---------------------------------------54// Long division55class DivLNode : public Node {56public:57DivLNode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor ) {}58virtual int Opcode() const;59virtual Node* Identity(PhaseGVN* phase);60virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);61virtual const Type* Value(PhaseGVN* phase) const;62virtual const Type *bottom_type() const { return TypeLong::LONG; }63virtual uint ideal_reg() const { return Op_RegL; }64};6566//------------------------------DivFNode---------------------------------------67// Float division68class DivFNode : public Node {69public:70DivFNode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor) {}71virtual int Opcode() const;72virtual Node* Identity(PhaseGVN* phase);73virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);74virtual const Type* Value(PhaseGVN* phase) const;75virtual const Type *bottom_type() const { return Type::FLOAT; }76virtual uint ideal_reg() const { return Op_RegF; }77};7879//------------------------------DivDNode---------------------------------------80// Double division81class DivDNode : public Node {82public:83DivDNode( Node *c, Node *dividend, Node *divisor ) : Node(c,dividend, divisor) {}84virtual int Opcode() const;85virtual Node* Identity(PhaseGVN* phase);86virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);87virtual const Type* Value(PhaseGVN* phase) const;88virtual const Type *bottom_type() const { return Type::DOUBLE; }89virtual uint ideal_reg() const { return Op_RegD; }90};9192//------------------------------ModINode---------------------------------------93// Integer modulus94class ModINode : public Node {95public:96ModINode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {}97virtual int Opcode() const;98virtual const Type* Value(PhaseGVN* phase) const;99virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);100virtual const Type *bottom_type() const { return TypeInt::INT; }101virtual uint ideal_reg() const { return Op_RegI; }102};103104//------------------------------ModLNode---------------------------------------105// Long modulus106class ModLNode : public Node {107public:108ModLNode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {}109virtual int Opcode() const;110virtual const Type* Value(PhaseGVN* phase) const;111virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);112virtual const Type *bottom_type() const { return TypeLong::LONG; }113virtual uint ideal_reg() const { return Op_RegL; }114};115116//------------------------------ModFNode---------------------------------------117// Float Modulus118class ModFNode : public Node {119public:120ModFNode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {}121virtual int Opcode() const;122virtual const Type* Value(PhaseGVN* phase) const;123virtual const Type *bottom_type() const { return Type::FLOAT; }124virtual uint ideal_reg() const { return Op_RegF; }125};126127//------------------------------ModDNode---------------------------------------128// Double Modulus129class ModDNode : public Node {130public:131ModDNode( Node *c, Node *in1, Node *in2 ) : Node(c, in1, in2) {}132virtual int Opcode() const;133virtual const Type* Value(PhaseGVN* phase) const;134virtual const Type *bottom_type() const { return Type::DOUBLE; }135virtual uint ideal_reg() const { return Op_RegD; }136};137138//------------------------------DivModNode---------------------------------------139// Division with remainder result.140class DivModNode : public MultiNode {141protected:142DivModNode( Node *c, Node *dividend, Node *divisor );143public:144enum {145div_proj_num = 0, // quotient146mod_proj_num = 1 // remainder147};148virtual int Opcode() const;149virtual Node* Identity(PhaseGVN* phase) { return this; }150virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) { return NULL; }151virtual const Type* Value(PhaseGVN* phase) const { return bottom_type(); }152virtual uint hash() const { return Node::hash(); }153virtual bool is_CFG() const { return false; }154virtual uint ideal_reg() const { return NotAMachineReg; }155156ProjNode* div_proj() { return proj_out_or_null(div_proj_num); }157ProjNode* mod_proj() { return proj_out_or_null(mod_proj_num); }158};159160//------------------------------DivModINode---------------------------------------161// Integer division with remainder result.162class DivModINode : public DivModNode {163public:164DivModINode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}165virtual int Opcode() const;166virtual const Type *bottom_type() const { return TypeTuple::INT_PAIR; }167virtual Node *match( const ProjNode *proj, const Matcher *m );168169// Make a divmod and associated projections from a div or mod.170static DivModINode* make(Node* div_or_mod);171};172173//------------------------------DivModLNode---------------------------------------174// Long division with remainder result.175class DivModLNode : public DivModNode {176public:177DivModLNode( Node *c, Node *dividend, Node *divisor ) : DivModNode(c, dividend, divisor) {}178virtual int Opcode() const;179virtual const Type *bottom_type() const { return TypeTuple::LONG_PAIR; }180virtual Node *match( const ProjNode *proj, const Matcher *m );181182// Make a divmod and associated projections from a div or mod.183static DivModLNode* make(Node* div_or_mod);184};185186#endif // SHARE_OPTO_DIVNODE_HPP187188189