1 /*
2 * Copyright (c) 1999, 2015, 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 *
36 int _nesting;
37 ValueMapEntry* _next;
38
39 public:
40 ValueMapEntry(intx hash, Value value, int nesting, ValueMapEntry* next)
41 : _hash(hash)
42 , _value(value)
43 , _nesting(nesting)
44 , _next(next)
45 {
46 }
47
48 intx hash() { return _hash; }
49 Value value() { return _value; }
50 int nesting() { return _nesting; }
51 ValueMapEntry* next() { return _next; }
52
53 void set_next(ValueMapEntry* next) { _next = next; }
54 };
55
56 define_array(ValueMapEntryArray, ValueMapEntry*)
57 define_stack(ValueMapEntryList, ValueMapEntryArray)
58
59 // ValueMap implements nested hash tables for value numbering. It
60 // maintains a set _killed_values which represents the instructions
61 // which have been killed so far and an array of linked lists of
62 // ValueMapEntries names _entries. Each ValueMapEntry has a nesting
63 // which indicates what ValueMap nesting it belongs to. Higher
64 // nesting values are always before lower values in the linked list.
65 // This allows cloning of parent ValueMaps by simply copying the heads
66 // of the list. _entry_count represents the number of reachable
67 // entries in the ValueMap. A ValueMap is only allowed to mutate
68 // ValueMapEntries with the same nesting level. Adding or removing
69 // entries at the current nesting level requires updating
70 // _entry_count. Elements in the parent's list that get killed can be
71 // skipped if they are at the head of the list by simply moving to the
72 // next element in the list and decrementing _entry_count.
73
74 class ValueMap: public CompilationResourceObj {
75 private:
76 int _nesting;
77 ValueMapEntryArray _entries;
112
113 // manipulation
114 Value find_insert(Value x);
115
116 void kill_memory();
117 void kill_field(ciField* field, bool all_offsets);
118 void kill_array(ValueType* type);
119 void kill_exception();
120 void kill_map(ValueMap* map);
121 void kill_all();
122
123 #ifndef PRODUCT
124 // debugging/printing
125 void print();
126
127 static void reset_statistics();
128 static void print_statistics();
129 #endif
130 };
131
132 define_array(ValueMapArray, ValueMap*)
133
134
135 class ValueNumberingVisitor: public InstructionVisitor {
136 protected:
137 // called by visitor functions for instructions that kill values
138 virtual void kill_memory() = 0;
139 virtual void kill_field(ciField* field, bool all_offsets) = 0;
140 virtual void kill_array(ValueType* type) = 0;
141
142 // visitor functions
143 void do_StoreField (StoreField* x) {
144 if (x->is_init_point() || // putstatic is an initialization point so treat it as a wide kill
145 // This is actually too strict and the JMM doesn't require
146 // this in all cases (e.g. load a; volatile store b; load a)
147 // but possible future optimizations might require this.
148 x->field()->is_volatile()) {
149 kill_memory();
150 } else {
151 kill_field(x->field(), x->needs_patching());
152 }
153 }
|
1 /*
2 * Copyright (c) 1999, 2016, 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 *
36 int _nesting;
37 ValueMapEntry* _next;
38
39 public:
40 ValueMapEntry(intx hash, Value value, int nesting, ValueMapEntry* next)
41 : _hash(hash)
42 , _value(value)
43 , _nesting(nesting)
44 , _next(next)
45 {
46 }
47
48 intx hash() { return _hash; }
49 Value value() { return _value; }
50 int nesting() { return _nesting; }
51 ValueMapEntry* next() { return _next; }
52
53 void set_next(ValueMapEntry* next) { _next = next; }
54 };
55
56 typedef GrowableArray<ValueMapEntry*> ValueMapEntryArray;
57 typedef GrowableArray<ValueMapEntry*> ValueMapEntryList;
58
59 // ValueMap implements nested hash tables for value numbering. It
60 // maintains a set _killed_values which represents the instructions
61 // which have been killed so far and an array of linked lists of
62 // ValueMapEntries names _entries. Each ValueMapEntry has a nesting
63 // which indicates what ValueMap nesting it belongs to. Higher
64 // nesting values are always before lower values in the linked list.
65 // This allows cloning of parent ValueMaps by simply copying the heads
66 // of the list. _entry_count represents the number of reachable
67 // entries in the ValueMap. A ValueMap is only allowed to mutate
68 // ValueMapEntries with the same nesting level. Adding or removing
69 // entries at the current nesting level requires updating
70 // _entry_count. Elements in the parent's list that get killed can be
71 // skipped if they are at the head of the list by simply moving to the
72 // next element in the list and decrementing _entry_count.
73
74 class ValueMap: public CompilationResourceObj {
75 private:
76 int _nesting;
77 ValueMapEntryArray _entries;
112
113 // manipulation
114 Value find_insert(Value x);
115
116 void kill_memory();
117 void kill_field(ciField* field, bool all_offsets);
118 void kill_array(ValueType* type);
119 void kill_exception();
120 void kill_map(ValueMap* map);
121 void kill_all();
122
123 #ifndef PRODUCT
124 // debugging/printing
125 void print();
126
127 static void reset_statistics();
128 static void print_statistics();
129 #endif
130 };
131
132 typedef GrowableArray<ValueMap*> ValueMapArray;
133
134 class ValueNumberingVisitor: public InstructionVisitor {
135 protected:
136 // called by visitor functions for instructions that kill values
137 virtual void kill_memory() = 0;
138 virtual void kill_field(ciField* field, bool all_offsets) = 0;
139 virtual void kill_array(ValueType* type) = 0;
140
141 // visitor functions
142 void do_StoreField (StoreField* x) {
143 if (x->is_init_point() || // putstatic is an initialization point so treat it as a wide kill
144 // This is actually too strict and the JMM doesn't require
145 // this in all cases (e.g. load a; volatile store b; load a)
146 // but possible future optimizations might require this.
147 x->field()->is_volatile()) {
148 kill_memory();
149 } else {
150 kill_field(x->field(), x->needs_patching());
151 }
152 }
|