Path: blob/master/src/hotspot/share/opto/addnode.hpp
64440 views
/*1* Copyright (c) 1997, 2021, 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_ADDNODE_HPP25#define SHARE_OPTO_ADDNODE_HPP2627#include "opto/node.hpp"28#include "opto/opcodes.hpp"29#include "opto/type.hpp"3031// Portions of code courtesy of Clifford Click3233class PhaseTransform;3435//------------------------------AddNode----------------------------------------36// Classic Add functionality. This covers all the usual 'add' behaviors for37// an algebraic ring. Add-integer, add-float, add-double, and binary-or are38// all inherited from this class. The various identity values are supplied39// by virtual functions.40class AddNode : public Node {41virtual uint hash() const;42public:43AddNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {44init_class_id(Class_Add);45}4647// Handle algebraic identities here. If we have an identity, return the Node48// we are equivalent to. We look for "add of zero" as an identity.49virtual Node* Identity(PhaseGVN* phase);5051// We also canonicalize the Node, moving constants to the right input,52// and flatten expressions (so that 1+x+2 becomes x+3).53virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);5455// Compute a new Type for this node. Basically we just do the pre-check,56// then call the virtual add() to set the type.57virtual const Type* Value(PhaseGVN* phase) const;5859// Check if this addition involves the additive identity60virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const;6162// Supplied function returns the sum of the inputs.63// This also type-checks the inputs for sanity. Guaranteed never to64// be passed a TOP or BOTTOM type, these are filtered out by a pre-check.65virtual const Type *add_ring( const Type *, const Type * ) const = 0;6667// Supplied function to return the additive identity type68virtual const Type *add_id() const = 0;6970// Supplied function to return the additive opcode71virtual int max_opcode() const = 0;7273// Supplied function to return the multiplicative opcode74virtual int min_opcode() const = 0;7576virtual bool operates_on(BasicType bt, bool signed_int) const {77assert(bt == T_INT || bt == T_LONG, "unsupported");78return false;79}80static AddNode* make(Node* in1, Node* in2, BasicType bt);81};8283//------------------------------AddINode---------------------------------------84// Add 2 integers85class AddINode : public AddNode {86public:87AddINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}88virtual int Opcode() const;89virtual const Type *add_ring( const Type *, const Type * ) const;90virtual const Type *add_id() const { return TypeInt::ZERO; }91virtual const Type *bottom_type() const { return TypeInt::INT; }92int max_opcode() const { return Op_MaxI; }93int min_opcode() const { return Op_MinI; }94virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);95virtual Node* Identity(PhaseGVN* phase);96virtual bool operates_on(BasicType bt, bool signed_int) const {97assert(bt == T_INT || bt == T_LONG, "unsupported");98return bt == T_INT;99}100virtual uint ideal_reg() const { return Op_RegI; }101};102103//------------------------------AddLNode---------------------------------------104// Add 2 longs105class AddLNode : public AddNode {106public:107AddLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}108virtual int Opcode() const;109virtual const Type *add_ring( const Type *, const Type * ) const;110virtual const Type *add_id() const { return TypeLong::ZERO; }111virtual const Type *bottom_type() const { return TypeLong::LONG; }112int max_opcode() const { return Op_MaxL; }113int min_opcode() const { return Op_MinL; }114virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);115virtual Node* Identity(PhaseGVN* phase);116virtual bool operates_on(BasicType bt, bool signed_int) const {117assert(bt == T_INT || bt == T_LONG, "unsupported");118return bt == T_LONG;119}120virtual uint ideal_reg() const { return Op_RegL; }121};122123//------------------------------AddFNode---------------------------------------124// Add 2 floats125class AddFNode : public AddNode {126public:127AddFNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}128virtual int Opcode() const;129virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);130virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const;131virtual const Type *add_ring( const Type *, const Type * ) const;132virtual const Type *add_id() const { return TypeF::ZERO; }133virtual const Type *bottom_type() const { return Type::FLOAT; }134int max_opcode() const { return Op_MaxF; }135int min_opcode() const { return Op_MinF; }136virtual Node* Identity(PhaseGVN* phase) { return this; }137virtual uint ideal_reg() const { return Op_RegF; }138};139140//------------------------------AddDNode---------------------------------------141// Add 2 doubles142class AddDNode : public AddNode {143public:144AddDNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}145virtual int Opcode() const;146virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);147virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const;148virtual const Type *add_ring( const Type *, const Type * ) const;149virtual const Type *add_id() const { return TypeD::ZERO; }150virtual const Type *bottom_type() const { return Type::DOUBLE; }151int max_opcode() const { return Op_MaxD; }152int min_opcode() const { return Op_MinD; }153virtual Node* Identity(PhaseGVN* phase) { return this; }154virtual uint ideal_reg() const { return Op_RegD; }155};156157//------------------------------AddPNode---------------------------------------158// Add pointer plus integer to get pointer. NOT commutative, really.159// So not really an AddNode. Lives here, because people associate it with160// an add.161class AddPNode : public Node {162public:163enum { Control, // When is it safe to do this add?164Base, // Base oop, for GC purposes165Address, // Actually address, derived from base166Offset } ; // Offset added to address167AddPNode( Node *base, Node *ptr, Node *off ) : Node(0,base,ptr,off) {168init_class_id(Class_AddP);169}170virtual int Opcode() const;171virtual Node* Identity(PhaseGVN* phase);172virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);173virtual const Type* Value(PhaseGVN* phase) const;174virtual const Type *bottom_type() const;175virtual uint ideal_reg() const { return Op_RegP; }176Node *base_node() { assert( req() > Base, "Missing base"); return in(Base); }177static Node* Ideal_base_and_offset(Node* ptr, PhaseTransform* phase,178// second return value:179intptr_t& offset);180181// Collect the AddP offset values into the elements array, giving up182// if there are more than length.183int unpack_offsets(Node* elements[], int length);184185// Do not match base-ptr edge186virtual uint match_edge(uint idx) const;187};188189//------------------------------OrINode----------------------------------------190// Logically OR 2 integers. Included with the ADD nodes because it inherits191// all the behavior of addition on a ring.192class OrINode : public AddNode {193public:194OrINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}195virtual int Opcode() const;196virtual const Type *add_ring( const Type *, const Type * ) const;197virtual const Type *add_id() const { return TypeInt::ZERO; }198virtual const Type *bottom_type() const { return TypeInt::INT; }199int max_opcode() const { return Op_MaxI; }200int min_opcode() const { return Op_MinI; }201virtual Node* Identity(PhaseGVN* phase);202virtual uint ideal_reg() const { return Op_RegI; }203virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);204};205206//------------------------------OrLNode----------------------------------------207// Logically OR 2 longs. Included with the ADD nodes because it inherits208// all the behavior of addition on a ring.209class OrLNode : public AddNode {210public:211OrLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}212virtual int Opcode() const;213virtual const Type *add_ring( const Type *, const Type * ) const;214virtual const Type *add_id() const { return TypeLong::ZERO; }215virtual const Type *bottom_type() const { return TypeLong::LONG; }216int max_opcode() const { return Op_MaxL; }217int min_opcode() const { return Op_MinL; }218virtual Node* Identity(PhaseGVN* phase);219virtual uint ideal_reg() const { return Op_RegL; }220virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);221};222223//------------------------------XorINode---------------------------------------224// XOR'ing 2 integers225class XorINode : public AddNode {226public:227XorINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}228virtual int Opcode() const;229virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);230virtual const Type *add_ring( const Type *, const Type * ) const;231virtual const Type *add_id() const { return TypeInt::ZERO; }232virtual const Type *bottom_type() const { return TypeInt::INT; }233int max_opcode() const { return Op_MaxI; }234int min_opcode() const { return Op_MinI; }235virtual const Type *Value(PhaseGVN *phase) const;236virtual uint ideal_reg() const { return Op_RegI; }237};238239//------------------------------XorINode---------------------------------------240// XOR'ing 2 longs241class XorLNode : public AddNode {242public:243XorLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}244virtual int Opcode() const;245virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);246virtual const Type *add_ring( const Type *, const Type * ) const;247virtual const Type *add_id() const { return TypeLong::ZERO; }248virtual const Type *bottom_type() const { return TypeLong::LONG; }249int max_opcode() const { return Op_MaxL; }250int min_opcode() const { return Op_MinL; }251virtual const Type *Value(PhaseGVN *phase) const;252virtual uint ideal_reg() const { return Op_RegL; }253};254255//------------------------------MaxNode----------------------------------------256// Max (or min) of 2 values. Included with the ADD nodes because it inherits257// all the behavior of addition on a ring. Only new thing is that we allow258// 2 equal inputs to be equal.259class MaxNode : public AddNode {260private:261static Node* build_min_max(Node* a, Node* b, bool is_max, bool is_unsigned, const Type* t, PhaseGVN& gvn);262static Node* build_min_max_diff_with_zero(Node* a, Node* b, bool is_max, const Type* t, PhaseGVN& gvn);263264public:265MaxNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}266virtual int Opcode() const = 0;267virtual int max_opcode() const = 0;268virtual int min_opcode() const = 0;269270static Node* unsigned_max(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {271return build_min_max(a, b, true, true, t, gvn);272}273274static Node* unsigned_min(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {275return build_min_max(a, b, false, true, t, gvn);276}277278static Node* signed_max(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {279return build_min_max(a, b, true, false, t, gvn);280}281282static Node* signed_min(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {283return build_min_max(a, b, false, false, t, gvn);284}285286// max(a-b, 0)287static Node* max_diff_with_zero(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {288return build_min_max_diff_with_zero(a, b, true, t, gvn);289}290291// min(a-b, 0)292static Node* min_diff_with_zero(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {293return build_min_max_diff_with_zero(a, b, false, t, gvn);294}295};296297//------------------------------MaxINode---------------------------------------298// Maximum of 2 integers. Included with the ADD nodes because it inherits299// all the behavior of addition on a ring.300class MaxINode : public MaxNode {301public:302MaxINode( Node *in1, Node *in2 ) : MaxNode(in1,in2) {}303virtual int Opcode() const;304virtual const Type *add_ring( const Type *, const Type * ) const;305virtual const Type *add_id() const { return TypeInt::make(min_jint); }306virtual const Type *bottom_type() const { return TypeInt::INT; }307virtual uint ideal_reg() const { return Op_RegI; }308int max_opcode() const { return Op_MaxI; }309int min_opcode() const { return Op_MinI; }310};311312//------------------------------MinINode---------------------------------------313// MINimum of 2 integers. Included with the ADD nodes because it inherits314// all the behavior of addition on a ring.315class MinINode : public MaxNode {316public:317MinINode( Node *in1, Node *in2 ) : MaxNode(in1,in2) {}318virtual int Opcode() const;319virtual const Type *add_ring( const Type *, const Type * ) const;320virtual const Type *add_id() const { return TypeInt::make(max_jint); }321virtual const Type *bottom_type() const { return TypeInt::INT; }322virtual uint ideal_reg() const { return Op_RegI; }323int max_opcode() const { return Op_MaxI; }324int min_opcode() const { return Op_MinI; }325virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);326};327328//------------------------------MaxLNode---------------------------------------329// MAXimum of 2 longs.330class MaxLNode : public MaxNode {331public:332MaxLNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}333virtual int Opcode() const;334virtual const Type *add_ring(const Type*, const Type*) const { return TypeLong::LONG; }335virtual const Type *add_id() const { return TypeLong::make(min_jlong); }336virtual const Type *bottom_type() const { return TypeLong::LONG; }337virtual uint ideal_reg() const { return Op_RegL; }338int max_opcode() const { return Op_MaxL; }339int min_opcode() const { return Op_MinL; }340};341342//------------------------------MinLNode---------------------------------------343// MINimum of 2 longs.344class MinLNode : public MaxNode {345public:346MinLNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}347virtual int Opcode() const;348virtual const Type *add_ring(const Type*, const Type*) const { return TypeLong::LONG; }349virtual const Type *add_id() const { return TypeLong::make(max_jlong); }350virtual const Type *bottom_type() const { return TypeLong::LONG; }351virtual uint ideal_reg() const { return Op_RegL; }352int max_opcode() const { return Op_MaxL; }353int min_opcode() const { return Op_MinL; }354};355356//------------------------------MaxFNode---------------------------------------357// Maximum of 2 floats.358class MaxFNode : public MaxNode {359public:360MaxFNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}361virtual int Opcode() const;362virtual const Type *add_ring(const Type*, const Type*) const;363virtual const Type *add_id() const { return TypeF::NEG_INF; }364virtual const Type *bottom_type() const { return Type::FLOAT; }365virtual uint ideal_reg() const { return Op_RegF; }366int max_opcode() const { return Op_MaxF; }367int min_opcode() const { return Op_MinF; }368};369370//------------------------------MinFNode---------------------------------------371// Minimum of 2 floats.372class MinFNode : public MaxNode {373public:374MinFNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}375virtual int Opcode() const;376virtual const Type *add_ring(const Type*, const Type*) const;377virtual const Type *add_id() const { return TypeF::POS_INF; }378virtual const Type *bottom_type() const { return Type::FLOAT; }379virtual uint ideal_reg() const { return Op_RegF; }380int max_opcode() const { return Op_MaxF; }381int min_opcode() const { return Op_MinF; }382};383384//------------------------------MaxDNode---------------------------------------385// Maximum of 2 doubles.386class MaxDNode : public MaxNode {387public:388MaxDNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}389virtual int Opcode() const;390virtual const Type *add_ring(const Type*, const Type*) const;391virtual const Type *add_id() const { return TypeD::NEG_INF; }392virtual const Type *bottom_type() const { return Type::DOUBLE; }393virtual uint ideal_reg() const { return Op_RegD; }394int max_opcode() const { return Op_MaxD; }395int min_opcode() const { return Op_MinD; }396};397398//------------------------------MinDNode---------------------------------------399// Minimum of 2 doubles.400class MinDNode : public MaxNode {401public:402MinDNode(Node *in1, Node *in2) : MaxNode(in1, in2) {}403virtual int Opcode() const;404virtual const Type *add_ring(const Type*, const Type*) const;405virtual const Type *add_id() const { return TypeD::POS_INF; }406virtual const Type *bottom_type() const { return Type::DOUBLE; }407virtual uint ideal_reg() const { return Op_RegD; }408int max_opcode() const { return Op_MaxD; }409int min_opcode() const { return Op_MinD; }410};411412#endif // SHARE_OPTO_ADDNODE_HPP413414415