src/share/vm/opto/callnode.hpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/share/vm/opto/callnode.hpp
src/share/vm/opto/callnode.hpp
Print this page
rev 6447 : 8026796: Make replace_in_map() on parent maps generic
Summary: propagate node replacements along control flow edges to callers
Reviewed-by:
rev 6448 : [mq]: replaceinmap-8026796-reviews
*** 310,319 ****
--- 310,370 ----
dump_on(tty);
}
#endif
};
+ // During parsing, when a node is "improved",
+ // GraphKit::replace_in_map() is called to update the current map so
+ // that the improved node is used from that point
+ // on. GraphKit::replace_in_map() doesn't operate on the callers maps
+ // and so some optimization opportunities may be lost. The
+ // ReplacedNodes class addresses that problem.
+ //
+ // A ReplacedNodes object is a list of pair of nodes. Every
+ // SafePointNode carries a ReplacedNodes object. Every time
+ // GraphKit::replace_in_map() is called, a new pair of nodes is pushed
+ // on the list of replaced nodes. When control flow paths merge, their
+ // replaced nodes are also merged. When parsing exits a method to
+ // return to a caller, the replaced nodes on the exit path are used to
+ // update the caller's map.
+ class ReplacedNodes VALUE_OBJ_CLASS_SPEC {
+ private:
+ class ReplacedNode VALUE_OBJ_CLASS_SPEC {
+ private:
+ Node* _initial;
+ Node* _improved;
+ public:
+ ReplacedNode() : _initial(NULL), _improved(NULL) {}
+ ReplacedNode(Node* initial, Node* improved) : _initial(initial), _improved(improved) {}
+ Node* initial() const { return _initial; }
+ Node* improved() const { return _improved; }
+
+ bool operator==(const ReplacedNode& other) {
+ return _initial == other._initial && _improved == other._improved;
+ }
+ };
+ GrowableArray<ReplacedNode>* _replaced_nodes;
+
+ void allocate_if_necessary();
+ bool has_node(ReplacedNode r) const;
+ bool has_target_node(Node* n) const;
+
+ public:
+ ReplacedNodes()
+ : _replaced_nodes(NULL) {}
+
+ void clone();
+ void record(Node* initial, Node* improved);
+ void transfer_from(ReplacedNodes other, uint idx);
+ void reset();
+ void apply(Node* n);
+ void merge_with(ReplacedNodes other);
+ bool is_empty() const;
+ void dump(outputStream *st) const;
+ void apply(Compile* C, Node* ctl);
+ };
+
//------------------------------SafePointNode----------------------------------
// A SafePointNode is a subclass of a MultiNode for convenience (and
// potential code sharing) only - conceptually it is independent of
// the Node semantics.
class SafePointNode : public MultiNode {
*** 333,342 ****
--- 384,394 ----
}
OopMap* _oop_map; // Array of OopMap info (8-bit char) for GC
JVMState* const _jvms; // Pointer to list of JVM State objects
const TypePtr* _adr_type; // What type of memory does this node produce?
+ ReplacedNodes _replaced_nodes; // During parsing: list of pair of nodes from calls to GraphKit::replace_in_map()
// Many calls take *all* of memory as input,
// but some produce a limited subset of that memory as output.
// The adr_type reports the call's behavior as a store, not a load.
*** 424,433 ****
--- 476,516 ----
// for JVM states during parsing, intrinsic expansion, etc.
SafePointNode* next_exception() const;
void set_next_exception(SafePointNode* n);
bool has_exceptions() const { return next_exception() != NULL; }
+ // Helper methods to operate on replaced nodes
+ ReplacedNodes replaced_nodes() const {
+ return _replaced_nodes;
+ }
+
+ void set_replaced_nodes(ReplacedNodes replaced_nodes) {
+ _replaced_nodes = replaced_nodes;
+ }
+
+ void clone_replaced_nodes() {
+ _replaced_nodes.clone();
+ }
+ void record_replaced_node(Node* initial, Node* improved) {
+ _replaced_nodes.record(initial, improved);
+ }
+ void transfer_replaced_nodes_from(SafePointNode* sfpt, uint idx = 0) {
+ _replaced_nodes.transfer_from(sfpt->_replaced_nodes, idx);
+ }
+ void delete_replaced_nodes() {
+ _replaced_nodes.reset();
+ }
+ void apply_replaced_nodes() {
+ _replaced_nodes.apply(this);
+ }
+ void merge_replaced_nodes_with(SafePointNode* sfpt) {
+ _replaced_nodes.merge_with(sfpt->_replaced_nodes);
+ }
+ bool has_replaced_nodes() const {
+ return !_replaced_nodes.is_empty();
+ }
+
// Standard Node stuff
virtual int Opcode() const;
virtual bool pinned() const { return true; }
virtual const Type *Value( PhaseTransform *phase ) const;
virtual const Type *bottom_type() const { return Type::CONTROL; }
src/share/vm/opto/callnode.hpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File