1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_OPTO_OPAQUENODE_HPP
  26 #define SHARE_VM_OPTO_OPAQUENODE_HPP
  27 
  28 #include "opto/node.hpp"
  29 #include "opto/opcodes.hpp"
  30 
  31 //------------------------------Opaque1Node------------------------------------
  32 // A node to prevent unwanted optimizations.  Allows constant folding.
  33 // Stops value-numbering, Ideal calls or Identity functions.
  34 class Opaque1Node : public Node {
  35   virtual uint hash() const ;                  // { return NO_HASH; }
  36   virtual uint cmp( const Node &n ) const;
  37   public:
  38   Opaque1Node( Compile* C, Node *n ) : Node(0,n) {
  39     // Put it on the Macro nodes list to removed during macro nodes expansion.
  40     init_flags(Flag_is_macro);
  41     C->add_macro_node(this);
  42   }
  43   // Special version for the pre-loop to hold the original loop limit
  44   // which is consumed by range check elimination.
  45   Opaque1Node( Compile* C, Node *n, Node* orig_limit ) : Node(0,n,orig_limit) {
  46     // Put it on the Macro nodes list to removed during macro nodes expansion.
  47     init_flags(Flag_is_macro);
  48     C->add_macro_node(this);
  49   }
  50   Node* original_loop_limit() { return req()==3 ? in(2) : NULL; }
  51   virtual int Opcode() const;
  52   virtual const Type *bottom_type() const { return TypeInt::INT; }
  53   virtual Node *Identity( PhaseTransform *phase );
  54 };
  55 
  56 //------------------------------Opaque2Node------------------------------------
  57 // A node to prevent unwanted optimizations.  Allows constant folding.  Stops
  58 // value-numbering, most Ideal calls or Identity functions.  This Node is
  59 // specifically designed to prevent the pre-increment value of a loop trip
  60 // counter from being live out of the bottom of the loop (hence causing the
  61 // pre- and post-increment values both being live and thus requiring an extra
  62 // temp register and an extra move).  If we "accidentally" optimize through
  63 // this kind of a Node, we'll get slightly pessimal, but correct, code.  Thus
  64 // it's OK to be slightly sloppy on optimizations here.
  65 class Opaque2Node : public Node {
  66   virtual uint hash() const ;                  // { return NO_HASH; }
  67   virtual uint cmp( const Node &n ) const;
  68   public:
  69   Opaque2Node( Compile* C, Node *n ) : Node(0,n) {
  70     // Put it on the Macro nodes list to removed during macro nodes expansion.
  71     init_flags(Flag_is_macro);
  72     C->add_macro_node(this);
  73   }
  74   virtual int Opcode() const;
  75   virtual const Type *bottom_type() const { return TypeInt::INT; }
  76 };
  77 
  78 //------------------------------Opaque3Node------------------------------------
  79 // A node to prevent unwanted optimizations. Will be optimized only during
  80 // macro nodes expansion.
  81 class Opaque3Node : public Opaque2Node {
  82   int _opt; // what optimization it was used for
  83   public:
  84   enum { RTM_OPT };
  85   Opaque3Node(Compile* C, Node *n, int opt) : Opaque2Node(C, n), _opt(opt) {}
  86   virtual int Opcode() const;
  87   bool rtm_opt() const { return (_opt == RTM_OPT); }
  88 };
  89 
  90 //------------------------------Opaque4Node------------------------------------
  91 // The node can store branch frequencies during parsing.
  92 // Once parsing is over, the node goes away (during IGVN).
  93 class Opaque4Node : public Node {
  94   uint _taken;
  95   uint _not_taken;
  96   bool _consumed;
  97   bool _delay_removal;
  98   virtual uint hash() const ;                  // { return NO_HASH; }
  99   virtual uint cmp( const Node &n ) const;
 100   public:
 101   Opaque4Node(Node *n, uint taken, uint not_taken) : Node(0, n),
 102           _taken(taken), _not_taken(not_taken), _delay_removal(true), _consumed(false) {}
 103   virtual int Opcode() const;
 104   uint     taken() const { return     _taken; }
 105   uint not_taken() const { return _not_taken; }
 106   void   consume()       { _consumed = true;  }
 107 
 108   virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
 109   virtual Node *Identity(PhaseTransform *phase);
 110   virtual const Type *bottom_type() const { return TypeInt::INT; }
 111 };
 112 
 113 #endif // SHARE_VM_OPTO_OPAQUENODE_HPP
 114