src/share/vm/opto/mulnode.hpp

changeset 435
a61af66fc99e
child 580
f3de1255b035
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/opto/mulnode.hpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,247 @@
     1.4 +/*
     1.5 + * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.24 + * have any questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +// Portions of code courtesy of Clifford Click
    1.29 +
    1.30 +class PhaseTransform;
    1.31 +
    1.32 +//------------------------------MulNode----------------------------------------
    1.33 +// Classic MULTIPLY functionality.  This covers all the usual 'multiply'
    1.34 +// behaviors for an algebraic ring.  Multiply-integer, multiply-float,
    1.35 +// multiply-double, and binary-and are all inherited from this class.  The
    1.36 +// various identity values are supplied by virtual functions.
    1.37 +class MulNode : public Node {
    1.38 +  virtual uint hash() const;
    1.39 +public:
    1.40 +  MulNode( Node *in1, Node *in2 ): Node(0,in1,in2) {
    1.41 +    init_class_id(Class_Mul);
    1.42 +  }
    1.43 +
    1.44 +  // Handle algebraic identities here.  If we have an identity, return the Node
    1.45 +  // we are equivalent to.  We look for "add of zero" as an identity.
    1.46 +  virtual Node *Identity( PhaseTransform *phase );
    1.47 +
    1.48 +  // We also canonicalize the Node, moving constants to the right input,
    1.49 +  // and flatten expressions (so that 1+x+2 becomes x+3).
    1.50 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
    1.51 +
    1.52 +  // Compute a new Type for this node.  Basically we just do the pre-check,
    1.53 +  // then call the virtual add() to set the type.
    1.54 +  virtual const Type *Value( PhaseTransform *phase ) const;
    1.55 +
    1.56 +  // Supplied function returns the product of the inputs.
    1.57 +  // This also type-checks the inputs for sanity.  Guaranteed never to
    1.58 +  // be passed a TOP or BOTTOM type, these are filtered out by a pre-check.
    1.59 +  // This call recognizes the multiplicative zero type.
    1.60 +  virtual const Type *mul_ring( const Type *, const Type * ) const = 0;
    1.61 +
    1.62 +  // Supplied function to return the multiplicative identity type
    1.63 +  virtual const Type *mul_id() const = 0;
    1.64 +
    1.65 +  // Supplied function to return the additive identity type
    1.66 +  virtual const Type *add_id() const = 0;
    1.67 +
    1.68 +  // Supplied function to return the additive opcode
    1.69 +  virtual int add_opcode() const = 0;
    1.70 +
    1.71 +  // Supplied function to return the multiplicative opcode
    1.72 +  virtual int mul_opcode() const = 0;
    1.73 +
    1.74 +};
    1.75 +
    1.76 +//------------------------------MulINode---------------------------------------
    1.77 +// Multiply 2 integers
    1.78 +class MulINode : public MulNode {
    1.79 +public:
    1.80 +  MulINode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
    1.81 +  virtual int Opcode() const;
    1.82 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
    1.83 +  virtual const Type *mul_ring( const Type *, const Type * ) const;
    1.84 +  const Type *mul_id() const { return TypeInt::ONE; }
    1.85 +  const Type *add_id() const { return TypeInt::ZERO; }
    1.86 +  int add_opcode() const { return Op_AddI; }
    1.87 +  int mul_opcode() const { return Op_MulI; }
    1.88 +  const Type *bottom_type() const { return TypeInt::INT; }
    1.89 +  virtual uint ideal_reg() const { return Op_RegI; }
    1.90 +};
    1.91 +
    1.92 +//------------------------------MulLNode---------------------------------------
    1.93 +// Multiply 2 longs
    1.94 +class MulLNode : public MulNode {
    1.95 +public:
    1.96 +  MulLNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
    1.97 +  virtual int Opcode() const;
    1.98 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
    1.99 +  virtual const Type *mul_ring( const Type *, const Type * ) const;
   1.100 +  const Type *mul_id() const { return TypeLong::ONE; }
   1.101 +  const Type *add_id() const { return TypeLong::ZERO; }
   1.102 +  int add_opcode() const { return Op_AddL; }
   1.103 +  int mul_opcode() const { return Op_MulL; }
   1.104 +  const Type *bottom_type() const { return TypeLong::LONG; }
   1.105 +  virtual uint ideal_reg() const { return Op_RegL; }
   1.106 +};
   1.107 +
   1.108 +
   1.109 +//------------------------------MulFNode---------------------------------------
   1.110 +// Multiply 2 floats
   1.111 +class MulFNode : public MulNode {
   1.112 +public:
   1.113 +  MulFNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
   1.114 +  virtual int Opcode() const;
   1.115 +  virtual const Type *mul_ring( const Type *, const Type * ) const;
   1.116 +  const Type *mul_id() const { return TypeF::ONE; }
   1.117 +  const Type *add_id() const { return TypeF::ZERO; }
   1.118 +  int add_opcode() const { return Op_AddF; }
   1.119 +  int mul_opcode() const { return Op_MulF; }
   1.120 +  const Type *bottom_type() const { return Type::FLOAT; }
   1.121 +  virtual uint ideal_reg() const { return Op_RegF; }
   1.122 +};
   1.123 +
   1.124 +//------------------------------MulDNode---------------------------------------
   1.125 +// Multiply 2 doubles
   1.126 +class MulDNode : public MulNode {
   1.127 +public:
   1.128 +  MulDNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
   1.129 +  virtual int Opcode() const;
   1.130 +  virtual const Type *mul_ring( const Type *, const Type * ) const;
   1.131 +  const Type *mul_id() const { return TypeD::ONE; }
   1.132 +  const Type *add_id() const { return TypeD::ZERO; }
   1.133 +  int add_opcode() const { return Op_AddD; }
   1.134 +  int mul_opcode() const { return Op_MulD; }
   1.135 +  const Type *bottom_type() const { return Type::DOUBLE; }
   1.136 +  virtual uint ideal_reg() const { return Op_RegD; }
   1.137 +};
   1.138 +
   1.139 +
   1.140 +//------------------------------AndINode---------------------------------------
   1.141 +// Logically AND 2 integers.  Included with the MUL nodes because it inherits
   1.142 +// all the behavior of multiplication on a ring.
   1.143 +class AndINode : public MulINode {
   1.144 +public:
   1.145 +  AndINode( Node *in1, Node *in2 ) : MulINode(in1,in2) {}
   1.146 +  virtual int Opcode() const;
   1.147 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   1.148 +  virtual Node *Identity( PhaseTransform *phase );
   1.149 +  virtual const Type *mul_ring( const Type *, const Type * ) const;
   1.150 +  const Type *mul_id() const { return TypeInt::MINUS_1; }
   1.151 +  const Type *add_id() const { return TypeInt::ZERO; }
   1.152 +  int add_opcode() const { return Op_OrI; }
   1.153 +  int mul_opcode() const { return Op_AndI; }
   1.154 +  virtual uint ideal_reg() const { return Op_RegI; }
   1.155 +};
   1.156 +
   1.157 +//------------------------------AndINode---------------------------------------
   1.158 +// Logically AND 2 longs.  Included with the MUL nodes because it inherits
   1.159 +// all the behavior of multiplication on a ring.
   1.160 +class AndLNode : public MulLNode {
   1.161 +public:
   1.162 +  AndLNode( Node *in1, Node *in2 ) : MulLNode(in1,in2) {}
   1.163 +  virtual int Opcode() const;
   1.164 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   1.165 +  virtual Node *Identity( PhaseTransform *phase );
   1.166 +  virtual const Type *mul_ring( const Type *, const Type * ) const;
   1.167 +  const Type *mul_id() const { return TypeLong::MINUS_1; }
   1.168 +  const Type *add_id() const { return TypeLong::ZERO; }
   1.169 +  int add_opcode() const { return Op_OrL; }
   1.170 +  int mul_opcode() const { return Op_AndL; }
   1.171 +  virtual uint ideal_reg() const { return Op_RegL; }
   1.172 +};
   1.173 +
   1.174 +//------------------------------LShiftINode------------------------------------
   1.175 +// Logical shift left
   1.176 +class LShiftINode : public Node {
   1.177 +public:
   1.178 +  LShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {}
   1.179 +  virtual int Opcode() const;
   1.180 +  virtual Node *Identity( PhaseTransform *phase );
   1.181 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   1.182 +  virtual const Type *Value( PhaseTransform *phase ) const;
   1.183 +  const Type *bottom_type() const { return TypeInt::INT; }
   1.184 +  virtual uint ideal_reg() const { return Op_RegI; }
   1.185 +};
   1.186 +
   1.187 +//------------------------------LShiftLNode------------------------------------
   1.188 +// Logical shift left
   1.189 +class LShiftLNode : public Node {
   1.190 +public:
   1.191 +  LShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {}
   1.192 +  virtual int Opcode() const;
   1.193 +  virtual Node *Identity( PhaseTransform *phase );
   1.194 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   1.195 +  virtual const Type *Value( PhaseTransform *phase ) const;
   1.196 +  const Type *bottom_type() const { return TypeLong::LONG; }
   1.197 +  virtual uint ideal_reg() const { return Op_RegL; }
   1.198 +};
   1.199 +
   1.200 +//------------------------------RShiftINode------------------------------------
   1.201 +// Signed shift right
   1.202 +class RShiftINode : public Node {
   1.203 +public:
   1.204 +  RShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {}
   1.205 +  virtual int Opcode() const;
   1.206 +  virtual Node *Identity( PhaseTransform *phase );
   1.207 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   1.208 +  virtual const Type *Value( PhaseTransform *phase ) const;
   1.209 +  const Type *bottom_type() const { return TypeInt::INT; }
   1.210 +  virtual uint ideal_reg() const { return Op_RegI; }
   1.211 +};
   1.212 +
   1.213 +//------------------------------RShiftLNode------------------------------------
   1.214 +// Signed shift right
   1.215 +class RShiftLNode : public Node {
   1.216 +public:
   1.217 +  RShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {}
   1.218 +  virtual int Opcode() const;
   1.219 +  virtual Node *Identity( PhaseTransform *phase );
   1.220 +  virtual const Type *Value( PhaseTransform *phase ) const;
   1.221 +  const Type *bottom_type() const { return TypeLong::LONG; }
   1.222 +  virtual uint ideal_reg() const { return Op_RegL; }
   1.223 +};
   1.224 +
   1.225 +
   1.226 +//------------------------------URShiftINode-----------------------------------
   1.227 +// Logical shift right
   1.228 +class URShiftINode : public Node {
   1.229 +public:
   1.230 +  URShiftINode( Node *in1, Node *in2 ) : Node(0,in1,in2) {}
   1.231 +  virtual int Opcode() const;
   1.232 +  virtual Node *Identity( PhaseTransform *phase );
   1.233 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   1.234 +  virtual const Type *Value( PhaseTransform *phase ) const;
   1.235 +  const Type *bottom_type() const { return TypeInt::INT; }
   1.236 +  virtual uint ideal_reg() const { return Op_RegI; }
   1.237 +};
   1.238 +
   1.239 +//------------------------------URShiftLNode-----------------------------------
   1.240 +// Logical shift right
   1.241 +class URShiftLNode : public Node {
   1.242 +public:
   1.243 +  URShiftLNode( Node *in1, Node *in2 ) : Node(0,in1,in2) {}
   1.244 +  virtual int Opcode() const;
   1.245 +  virtual Node *Identity( PhaseTransform *phase );
   1.246 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   1.247 +  virtual const Type *Value( PhaseTransform *phase ) const;
   1.248 +  const Type *bottom_type() const { return TypeLong::LONG; }
   1.249 +  virtual uint ideal_reg() const { return Op_RegL; }
   1.250 +};

mercurial