roland@7041: /* roland@7041: * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. roland@7041: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. roland@7041: * roland@7041: * This code is free software; you can redistribute it and/or modify it roland@7041: * under the terms of the GNU General Public License version 2 only, as roland@7041: * published by the Free Software Foundation. roland@7041: * roland@7041: * This code is distributed in the hope that it will be useful, but WITHOUT roland@7041: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or roland@7041: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License roland@7041: * version 2 for more details (a copy is included in the LICENSE file that roland@7041: * accompanied this code). roland@7041: * roland@7041: * You should have received a copy of the GNU General Public License version roland@7041: * 2 along with this work; if not, write to the Free Software Foundation, roland@7041: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. roland@7041: * roland@7041: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA roland@7041: * or visit www.oracle.com if you need additional information or have any roland@7041: * questions. roland@7041: * roland@7041: */ roland@7041: roland@7041: #ifndef SHARE_VM_OPTO_REPLACEDNODES_HPP roland@7041: #define SHARE_VM_OPTO_REPLACEDNODES_HPP roland@7041: roland@7041: #include "opto/connode.hpp" roland@7041: roland@7041: // During parsing, when a node is "improved", roland@7041: // GraphKit::replace_in_map() is called to update the current map so roland@7041: // that the improved node is used from that point roland@7041: // on. GraphKit::replace_in_map() doesn't operate on the callers maps roland@7041: // and so some optimization opportunities may be lost. The roland@7041: // ReplacedNodes class addresses that problem. roland@7041: // roland@7041: // A ReplacedNodes object is a list of pair of nodes. Every roland@7041: // SafePointNode carries a ReplacedNodes object. Every time roland@7041: // GraphKit::replace_in_map() is called, a new pair of nodes is pushed roland@7041: // on the list of replaced nodes. When control flow paths merge, their roland@7041: // replaced nodes are also merged. When parsing exits a method to roland@7041: // return to a caller, the replaced nodes on the exit path are used to roland@7041: // update the caller's map. roland@7041: class ReplacedNodes VALUE_OBJ_CLASS_SPEC { roland@7041: private: roland@7041: class ReplacedNode VALUE_OBJ_CLASS_SPEC { roland@7041: private: roland@7041: Node* _initial; roland@7041: Node* _improved; roland@7041: public: roland@7041: ReplacedNode() : _initial(NULL), _improved(NULL) {} roland@7041: ReplacedNode(Node* initial, Node* improved) : _initial(initial), _improved(improved) {} roland@7041: Node* initial() const { return _initial; } roland@7041: Node* improved() const { return _improved; } roland@7041: roland@7041: bool operator==(const ReplacedNode& other) { roland@7041: return _initial == other._initial && _improved == other._improved; roland@7041: } roland@7041: }; roland@7041: GrowableArray* _replaced_nodes; roland@7041: roland@7041: void allocate_if_necessary(); roland@7041: bool has_node(const ReplacedNode& r) const; roland@7041: bool has_target_node(Node* n) const; roland@7041: roland@7041: public: roland@7041: ReplacedNodes() roland@7041: : _replaced_nodes(NULL) {} roland@7041: roland@7041: void clone(); roland@7041: void record(Node* initial, Node* improved); roland@7041: void transfer_from(const ReplacedNodes& other, uint idx); roland@7041: void reset(); roland@7041: void apply(Node* n); roland@7041: void merge_with(const ReplacedNodes& other); roland@7041: bool is_empty() const; roland@7041: void dump(outputStream *st) const; roland@7041: void apply(Compile* C, Node* ctl); roland@7041: }; roland@7041: roland@7041: #endif // SHARE_VM_OPTO_REPLACEDNODES_HPP