32 #include "opto/convertnode.hpp"
33 #include "opto/escape.hpp"
34 #include "opto/locknode.hpp"
35 #include "opto/machnode.hpp"
36 #include "opto/matcher.hpp"
37 #include "opto/parse.hpp"
38 #include "opto/regalloc.hpp"
39 #include "opto/regmask.hpp"
40 #include "opto/rootnode.hpp"
41 #include "opto/runtime.hpp"
42
43 // Portions of code courtesy of Clifford Click
44
45 // Optimization - Graph Style
46
47 //=============================================================================
48 uint StartNode::size_of() const { return sizeof(*this); }
49 uint StartNode::cmp( const Node &n ) const
50 { return _domain == ((StartNode&)n)._domain; }
51 const Type *StartNode::bottom_type() const { return _domain; }
52 const Type *StartNode::Value(PhaseTransform *phase) const { return _domain; }
53 #ifndef PRODUCT
54 void StartNode::dump_spec(outputStream *st) const { st->print(" #"); _domain->dump_on(st);}
55 void StartNode::dump_compact_spec(outputStream *st) const { /* empty */ }
56 #endif
57
58 //------------------------------Ideal------------------------------------------
59 Node *StartNode::Ideal(PhaseGVN *phase, bool can_reshape){
60 return remove_dead_region(phase, can_reshape) ? this : NULL;
61 }
62
63 //------------------------------calling_convention-----------------------------
64 void StartNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
65 Matcher::calling_convention( sig_bt, parm_regs, argcnt, false );
66 }
67
68 //------------------------------Registers--------------------------------------
69 const RegMask &StartNode::in_RegMask(uint) const {
70 return RegMask::Empty;
71 }
72
156 return t->ideal_reg();
157 }
158 }
159 ShouldNotReachHere();
160 return 0;
161 }
162
163 //=============================================================================
164 ReturnNode::ReturnNode(uint edges, Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *retadr ) : Node(edges) {
165 init_req(TypeFunc::Control,cntrl);
166 init_req(TypeFunc::I_O,i_o);
167 init_req(TypeFunc::Memory,memory);
168 init_req(TypeFunc::FramePtr,frameptr);
169 init_req(TypeFunc::ReturnAdr,retadr);
170 }
171
172 Node *ReturnNode::Ideal(PhaseGVN *phase, bool can_reshape){
173 return remove_dead_region(phase, can_reshape) ? this : NULL;
174 }
175
176 const Type *ReturnNode::Value( PhaseTransform *phase ) const {
177 return ( phase->type(in(TypeFunc::Control)) == Type::TOP)
178 ? Type::TOP
179 : Type::BOTTOM;
180 }
181
182 // Do we Match on this edge index or not? No edges on return nodes
183 uint ReturnNode::match_edge(uint idx) const {
184 return 0;
185 }
186
187
188 #ifndef PRODUCT
189 void ReturnNode::dump_req(outputStream *st) const {
190 // Dump the required inputs, enclosed in '(' and ')'
191 uint i; // Exit value of loop
192 for (i = 0; i < req(); i++) { // For all required inputs
193 if (i == TypeFunc::Parms) st->print("returns");
194 if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
195 else st->print("_ ");
196 }
201 RethrowNode::RethrowNode(
202 Node* cntrl,
203 Node* i_o,
204 Node* memory,
205 Node* frameptr,
206 Node* ret_adr,
207 Node* exception
208 ) : Node(TypeFunc::Parms + 1) {
209 init_req(TypeFunc::Control , cntrl );
210 init_req(TypeFunc::I_O , i_o );
211 init_req(TypeFunc::Memory , memory );
212 init_req(TypeFunc::FramePtr , frameptr );
213 init_req(TypeFunc::ReturnAdr, ret_adr);
214 init_req(TypeFunc::Parms , exception);
215 }
216
217 Node *RethrowNode::Ideal(PhaseGVN *phase, bool can_reshape){
218 return remove_dead_region(phase, can_reshape) ? this : NULL;
219 }
220
221 const Type *RethrowNode::Value( PhaseTransform *phase ) const {
222 return (phase->type(in(TypeFunc::Control)) == Type::TOP)
223 ? Type::TOP
224 : Type::BOTTOM;
225 }
226
227 uint RethrowNode::match_edge(uint idx) const {
228 return 0;
229 }
230
231 #ifndef PRODUCT
232 void RethrowNode::dump_req(outputStream *st) const {
233 // Dump the required inputs, enclosed in '(' and ')'
234 uint i; // Exit value of loop
235 for (i = 0; i < req(); i++) { // For all required inputs
236 if (i == TypeFunc::Parms) st->print("exception");
237 if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
238 else st->print("_ ");
239 }
240 }
241 #endif
668 void CallNode::dump_req(outputStream *st) const {
669 // Dump the required inputs, enclosed in '(' and ')'
670 uint i; // Exit value of loop
671 for (i = 0; i < req(); i++) { // For all required inputs
672 if (i == TypeFunc::Parms) st->print("(");
673 if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
674 else st->print("_ ");
675 }
676 st->print(")");
677 }
678
679 void CallNode::dump_spec(outputStream *st) const {
680 st->print(" ");
681 if (tf() != NULL) tf()->dump_on(st);
682 if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt);
683 if (jvms() != NULL) jvms()->dump_spec(st);
684 }
685 #endif
686
687 const Type *CallNode::bottom_type() const { return tf()->range(); }
688 const Type *CallNode::Value(PhaseTransform *phase) const {
689 if (phase->type(in(0)) == Type::TOP) return Type::TOP;
690 return tf()->range();
691 }
692
693 //------------------------------calling_convention-----------------------------
694 void CallNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
695 // Use the standard compiler calling convention
696 Matcher::calling_convention( sig_bt, parm_regs, argcnt, true );
697 }
698
699
700 //------------------------------match------------------------------------------
701 // Construct projections for control, I/O, memory-fields, ..., and
702 // return result(s) along with their RegMask info
703 Node *CallNode::match( const ProjNode *proj, const Matcher *match ) {
704 switch (proj->_con) {
705 case TypeFunc::Control:
706 case TypeFunc::I_O:
707 case TypeFunc::Memory:
708 return new MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
1116 //----------------------------next_exception-----------------------------------
1117 SafePointNode* SafePointNode::next_exception() const {
1118 if (len() == req()) {
1119 return NULL;
1120 } else {
1121 Node* n = in(req());
1122 assert(n == NULL || n->Opcode() == Op_SafePoint, "no other uses of prec edges");
1123 return (SafePointNode*) n;
1124 }
1125 }
1126
1127
1128 //------------------------------Ideal------------------------------------------
1129 // Skip over any collapsed Regions
1130 Node *SafePointNode::Ideal(PhaseGVN *phase, bool can_reshape) {
1131 return remove_dead_region(phase, can_reshape) ? this : NULL;
1132 }
1133
1134 //------------------------------Identity---------------------------------------
1135 // Remove obviously duplicate safepoints
1136 Node *SafePointNode::Identity( PhaseTransform *phase ) {
1137
1138 // If you have back to back safepoints, remove one
1139 if( in(TypeFunc::Control)->is_SafePoint() )
1140 return in(TypeFunc::Control);
1141
1142 if( in(0)->is_Proj() ) {
1143 Node *n0 = in(0)->in(0);
1144 // Check if he is a call projection (except Leaf Call)
1145 if( n0->is_Catch() ) {
1146 n0 = n0->in(0)->in(0);
1147 assert( n0->is_Call(), "expect a call here" );
1148 }
1149 if( n0->is_Call() && n0->as_Call()->guaranteed_safepoint() ) {
1150 // Useless Safepoint, so remove it
1151 return in(TypeFunc::Control);
1152 }
1153 }
1154
1155 return this;
1156 }
1157
1158 //------------------------------Value------------------------------------------
1159 const Type *SafePointNode::Value( PhaseTransform *phase ) const {
1160 if( phase->type(in(0)) == Type::TOP ) return Type::TOP;
1161 if( phase->eqv( in(0), this ) ) return Type::TOP; // Dead infinite loop
1162 return Type::CONTROL;
1163 }
1164
1165 #ifndef PRODUCT
1166 void SafePointNode::dump_spec(outputStream *st) const {
1167 st->print(" SafePoint ");
1168 _replaced_nodes.dump(st);
1169 }
1170
1171 // The related nodes of a SafepointNode are all data inputs, excluding the
1172 // control boundary, as well as all outputs till level 2 (to include projection
1173 // nodes and targets). In compact mode, just include inputs till level 1 and
1174 // outputs as before.
1175 void SafePointNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
1176 if (compact) {
1177 this->collect_nodes(in_rel, 1, false, false);
1178 } else {
1179 this->collect_nodes_in_all_data(in_rel, false);
|
32 #include "opto/convertnode.hpp"
33 #include "opto/escape.hpp"
34 #include "opto/locknode.hpp"
35 #include "opto/machnode.hpp"
36 #include "opto/matcher.hpp"
37 #include "opto/parse.hpp"
38 #include "opto/regalloc.hpp"
39 #include "opto/regmask.hpp"
40 #include "opto/rootnode.hpp"
41 #include "opto/runtime.hpp"
42
43 // Portions of code courtesy of Clifford Click
44
45 // Optimization - Graph Style
46
47 //=============================================================================
48 uint StartNode::size_of() const { return sizeof(*this); }
49 uint StartNode::cmp( const Node &n ) const
50 { return _domain == ((StartNode&)n)._domain; }
51 const Type *StartNode::bottom_type() const { return _domain; }
52 const Type* StartNode::Value(PhaseGVN* phase) const { return _domain; }
53 #ifndef PRODUCT
54 void StartNode::dump_spec(outputStream *st) const { st->print(" #"); _domain->dump_on(st);}
55 void StartNode::dump_compact_spec(outputStream *st) const { /* empty */ }
56 #endif
57
58 //------------------------------Ideal------------------------------------------
59 Node *StartNode::Ideal(PhaseGVN *phase, bool can_reshape){
60 return remove_dead_region(phase, can_reshape) ? this : NULL;
61 }
62
63 //------------------------------calling_convention-----------------------------
64 void StartNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
65 Matcher::calling_convention( sig_bt, parm_regs, argcnt, false );
66 }
67
68 //------------------------------Registers--------------------------------------
69 const RegMask &StartNode::in_RegMask(uint) const {
70 return RegMask::Empty;
71 }
72
156 return t->ideal_reg();
157 }
158 }
159 ShouldNotReachHere();
160 return 0;
161 }
162
163 //=============================================================================
164 ReturnNode::ReturnNode(uint edges, Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *retadr ) : Node(edges) {
165 init_req(TypeFunc::Control,cntrl);
166 init_req(TypeFunc::I_O,i_o);
167 init_req(TypeFunc::Memory,memory);
168 init_req(TypeFunc::FramePtr,frameptr);
169 init_req(TypeFunc::ReturnAdr,retadr);
170 }
171
172 Node *ReturnNode::Ideal(PhaseGVN *phase, bool can_reshape){
173 return remove_dead_region(phase, can_reshape) ? this : NULL;
174 }
175
176 const Type* ReturnNode::Value(PhaseGVN* phase) const {
177 return ( phase->type(in(TypeFunc::Control)) == Type::TOP)
178 ? Type::TOP
179 : Type::BOTTOM;
180 }
181
182 // Do we Match on this edge index or not? No edges on return nodes
183 uint ReturnNode::match_edge(uint idx) const {
184 return 0;
185 }
186
187
188 #ifndef PRODUCT
189 void ReturnNode::dump_req(outputStream *st) const {
190 // Dump the required inputs, enclosed in '(' and ')'
191 uint i; // Exit value of loop
192 for (i = 0; i < req(); i++) { // For all required inputs
193 if (i == TypeFunc::Parms) st->print("returns");
194 if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
195 else st->print("_ ");
196 }
201 RethrowNode::RethrowNode(
202 Node* cntrl,
203 Node* i_o,
204 Node* memory,
205 Node* frameptr,
206 Node* ret_adr,
207 Node* exception
208 ) : Node(TypeFunc::Parms + 1) {
209 init_req(TypeFunc::Control , cntrl );
210 init_req(TypeFunc::I_O , i_o );
211 init_req(TypeFunc::Memory , memory );
212 init_req(TypeFunc::FramePtr , frameptr );
213 init_req(TypeFunc::ReturnAdr, ret_adr);
214 init_req(TypeFunc::Parms , exception);
215 }
216
217 Node *RethrowNode::Ideal(PhaseGVN *phase, bool can_reshape){
218 return remove_dead_region(phase, can_reshape) ? this : NULL;
219 }
220
221 const Type* RethrowNode::Value(PhaseGVN* phase) const {
222 return (phase->type(in(TypeFunc::Control)) == Type::TOP)
223 ? Type::TOP
224 : Type::BOTTOM;
225 }
226
227 uint RethrowNode::match_edge(uint idx) const {
228 return 0;
229 }
230
231 #ifndef PRODUCT
232 void RethrowNode::dump_req(outputStream *st) const {
233 // Dump the required inputs, enclosed in '(' and ')'
234 uint i; // Exit value of loop
235 for (i = 0; i < req(); i++) { // For all required inputs
236 if (i == TypeFunc::Parms) st->print("exception");
237 if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
238 else st->print("_ ");
239 }
240 }
241 #endif
668 void CallNode::dump_req(outputStream *st) const {
669 // Dump the required inputs, enclosed in '(' and ')'
670 uint i; // Exit value of loop
671 for (i = 0; i < req(); i++) { // For all required inputs
672 if (i == TypeFunc::Parms) st->print("(");
673 if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
674 else st->print("_ ");
675 }
676 st->print(")");
677 }
678
679 void CallNode::dump_spec(outputStream *st) const {
680 st->print(" ");
681 if (tf() != NULL) tf()->dump_on(st);
682 if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt);
683 if (jvms() != NULL) jvms()->dump_spec(st);
684 }
685 #endif
686
687 const Type *CallNode::bottom_type() const { return tf()->range(); }
688 const Type* CallNode::Value(PhaseGVN* phase) const {
689 if (phase->type(in(0)) == Type::TOP) return Type::TOP;
690 return tf()->range();
691 }
692
693 //------------------------------calling_convention-----------------------------
694 void CallNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
695 // Use the standard compiler calling convention
696 Matcher::calling_convention( sig_bt, parm_regs, argcnt, true );
697 }
698
699
700 //------------------------------match------------------------------------------
701 // Construct projections for control, I/O, memory-fields, ..., and
702 // return result(s) along with their RegMask info
703 Node *CallNode::match( const ProjNode *proj, const Matcher *match ) {
704 switch (proj->_con) {
705 case TypeFunc::Control:
706 case TypeFunc::I_O:
707 case TypeFunc::Memory:
708 return new MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
1116 //----------------------------next_exception-----------------------------------
1117 SafePointNode* SafePointNode::next_exception() const {
1118 if (len() == req()) {
1119 return NULL;
1120 } else {
1121 Node* n = in(req());
1122 assert(n == NULL || n->Opcode() == Op_SafePoint, "no other uses of prec edges");
1123 return (SafePointNode*) n;
1124 }
1125 }
1126
1127
1128 //------------------------------Ideal------------------------------------------
1129 // Skip over any collapsed Regions
1130 Node *SafePointNode::Ideal(PhaseGVN *phase, bool can_reshape) {
1131 return remove_dead_region(phase, can_reshape) ? this : NULL;
1132 }
1133
1134 //------------------------------Identity---------------------------------------
1135 // Remove obviously duplicate safepoints
1136 Node* SafePointNode::Identity(PhaseGVN* phase) {
1137
1138 // If you have back to back safepoints, remove one
1139 if( in(TypeFunc::Control)->is_SafePoint() )
1140 return in(TypeFunc::Control);
1141
1142 if( in(0)->is_Proj() ) {
1143 Node *n0 = in(0)->in(0);
1144 // Check if he is a call projection (except Leaf Call)
1145 if( n0->is_Catch() ) {
1146 n0 = n0->in(0)->in(0);
1147 assert( n0->is_Call(), "expect a call here" );
1148 }
1149 if( n0->is_Call() && n0->as_Call()->guaranteed_safepoint() ) {
1150 // Useless Safepoint, so remove it
1151 return in(TypeFunc::Control);
1152 }
1153 }
1154
1155 return this;
1156 }
1157
1158 //------------------------------Value------------------------------------------
1159 const Type* SafePointNode::Value(PhaseGVN* phase) const {
1160 if( phase->type(in(0)) == Type::TOP ) return Type::TOP;
1161 if( phase->eqv( in(0), this ) ) return Type::TOP; // Dead infinite loop
1162 return Type::CONTROL;
1163 }
1164
1165 #ifndef PRODUCT
1166 void SafePointNode::dump_spec(outputStream *st) const {
1167 st->print(" SafePoint ");
1168 _replaced_nodes.dump(st);
1169 }
1170
1171 // The related nodes of a SafepointNode are all data inputs, excluding the
1172 // control boundary, as well as all outputs till level 2 (to include projection
1173 // nodes and targets). In compact mode, just include inputs till level 1 and
1174 // outputs as before.
1175 void SafePointNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
1176 if (compact) {
1177 this->collect_nodes(in_rel, 1, false, false);
1178 } else {
1179 this->collect_nodes_in_all_data(in_rel, false);
|