1 /*
   2  * Copyright (c) 2013, 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 #include "precompiled.hpp"
  26 #include "memory/allocation.inline.hpp"
  27 #include "opto/addnode.hpp"
  28 #include "opto/cfgnode.hpp"
  29 #include "opto/machnode.hpp"
  30 #include "opto/matcher.hpp"
  31 #include "opto/mathexactnode.hpp"
  32 #include "opto/subnode.hpp"
  33 
  34 MathExactNode::MathExactNode(Node* ctrl, Node* n1, Node* n2) : MultiNode(3) {
  35   init_req(0, ctrl);
  36   init_req(1, n1);
  37   init_req(2, n2);
  38 }
  39 
  40 BoolNode* MathExactNode::bool_node() const {
  41   Node* flags = flags_node();
  42   BoolNode* boolnode = flags->unique_out()->as_Bool();
  43   assert(boolnode != NULL, "must have BoolNode");
  44   return boolnode;
  45 }
  46 
  47 IfNode* MathExactNode::if_node() const {
  48   BoolNode* boolnode = bool_node();
  49   IfNode* ifnode = boolnode->unique_out()->as_If();
  50   assert(ifnode != NULL, "must have IfNode");
  51   return ifnode;
  52 }
  53 
  54 Node* MathExactNode::control_node() const {
  55   IfNode* ifnode = if_node();
  56   return ifnode->in(0);
  57 }
  58 
  59 Node* MathExactNode::non_throwing_branch() const {
  60   IfNode* ifnode = if_node();
  61   if (bool_node()->_test._test == BoolTest::overflow) {
  62     return ifnode->proj_out(0);
  63   }
  64   return ifnode->proj_out(1);
  65 }
  66 
  67 Node* AddExactINode::match(const ProjNode* proj, const Matcher* m) {
  68   uint ideal_reg = proj->ideal_reg();
  69   RegMask rm;
  70   if (proj->_con == result_proj_node) {
  71     rm = m->mathExactI_result_proj_mask();
  72   } else {
  73     assert(proj->_con == flags_proj_node, "must be result or flags");
  74     assert(ideal_reg == Op_RegFlags, "sanity");
  75     rm = m->mathExactI_flags_proj_mask();
  76   }
  77   return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
  78 }
  79 
  80 // If the MathExactNode won't overflow we have to replace the
  81 // FlagsProjNode and ProjNode that is generated by the MathExactNode
  82 Node* MathExactNode::no_overflow(PhaseGVN *phase, Node* new_result) {
  83   PhaseIterGVN *igvn = phase->is_IterGVN();
  84   if (igvn) {
  85     ProjNode* result = result_node();
  86     ProjNode* flags = flags_node();
  87 
  88     if (result != NULL) {
  89       igvn->replace_node(result, new_result);
  90     }
  91 
  92     if (flags != NULL) {
  93       BoolNode* boolnode = bool_node();
  94       switch (boolnode->_test._test) {
  95         case BoolTest::overflow:
  96           // if the check is for overflow - never taken
  97           igvn->replace_node(boolnode, phase->intcon(0));
  98           break;
  99         case BoolTest::no_overflow:
 100           // if the check is for no overflow - always taken
 101           igvn->replace_node(boolnode, phase->intcon(1));
 102           break;
 103         default:
 104           fatal("Unexpected value of BoolTest");
 105           break;
 106       }
 107       flags->del_req(0);
 108     }
 109   }
 110   return new_result;
 111 }
 112 
 113 Node *AddExactINode::Ideal(PhaseGVN *phase, bool can_reshape) {
 114   Node *arg1 = in(1);
 115   Node *arg2 = in(2);
 116 
 117   const Type* type1 = phase->type(arg1);
 118   const Type* type2 = phase->type(arg2);
 119 
 120   if (type1 != Type::TOP && type1->singleton() &&
 121       type2 != Type::TOP && type2->singleton()) {
 122     jint val1 = arg1->get_int();
 123     jint val2 = arg2->get_int();
 124     jint result = val1 + val2;
 125     // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
 126     if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) {
 127       Node* con_result = ConINode::make(phase->C, result);
 128       return no_overflow(phase, con_result);
 129     }
 130     return NULL;
 131   }
 132 
 133   if (type1 == TypeInt::ZERO) { // (Add 0 x) == x
 134     Node* add_result = new (phase->C) AddINode(arg1, arg2);
 135     return no_overflow(phase, add_result);
 136   }
 137 
 138   if (type2 == TypeInt::ZERO) { // (Add x 0) == x
 139     Node* add_result = new (phase->C) AddINode(arg1, arg2);
 140     return no_overflow(phase, add_result);
 141   }
 142 
 143   if (type2->singleton()) {
 144     return NULL; // no change - keep constant on the right
 145   }
 146 
 147   if (type1->singleton()) {
 148     // Make it x + Constant - move constant to the right
 149     swap_edges(1, 2);
 150     return this;
 151   }
 152 
 153   if (arg2->is_Load()) {
 154     return NULL; // no change - keep load on the right
 155   }
 156 
 157   if (arg1->is_Load()) {
 158     // Make it x + Load - move load to the right
 159     swap_edges(1, 2);
 160     return this;
 161   }
 162 
 163   if (arg1->_idx > arg2->_idx) {
 164     // Sort the edges
 165     swap_edges(1, 2);
 166     return this;
 167   }
 168 
 169   return NULL;
 170 }
 171