1 /*
2 * Copyright (c) 1998, 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 *
240 #endif
241 };
242
243 //------------------------------CountedLoopEndNode-----------------------------
244 // CountedLoopEndNodes end simple trip counted loops. They act much like
245 // IfNodes.
246 class CountedLoopEndNode : public IfNode {
247 public:
248 enum { TestControl, TestValue };
249
250 CountedLoopEndNode( Node *control, Node *test, float prob, float cnt )
251 : IfNode( control, test, prob, cnt) {
252 init_class_id(Class_CountedLoopEnd);
253 }
254 virtual int Opcode() const;
255
256 Node *cmp_node() const { return (in(TestValue)->req() >=2) ? in(TestValue)->in(1) : NULL; }
257 Node *incr() const { Node *tmp = cmp_node(); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
258 Node *limit() const { Node *tmp = cmp_node(); return (tmp && tmp->req()==3) ? tmp->in(2) : NULL; }
259 Node *stride() const { Node *tmp = incr (); return (tmp && tmp->req()==3) ? tmp->in(2) : NULL; }
260 Node *phi() const { Node *tmp = incr (); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
261 Node *init_trip() const { Node *tmp = phi (); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
262 int stride_con() const;
263 bool stride_is_con() const { Node *tmp = stride (); return (tmp != NULL && tmp->is_Con()); }
264 BoolTest::mask test_trip() const { return in(TestValue)->as_Bool()->_test._test; }
265 CountedLoopNode *loopnode() const {
266 // The CountedLoopNode that goes with this CountedLoopEndNode may
267 // have been optimized out by the IGVN so be cautious with the
268 // pattern matching on the graph
269 if (phi() == NULL) {
270 return NULL;
271 }
272 Node *ln = phi()->in(0);
273 if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit() == this) {
274 return (CountedLoopNode*)ln;
275 }
276 return NULL;
277 }
278
279 #ifndef PRODUCT
280 virtual void dump_spec(outputStream *st) const;
281 #endif
282 };
283
284
285 inline CountedLoopEndNode *CountedLoopNode::loopexit() const {
286 Node *bc = back_control();
287 if( bc == NULL ) return NULL;
288 Node *le = bc->in(0);
289 if( le->Opcode() != Op_CountedLoopEnd )
290 return NULL;
291 return (CountedLoopEndNode*)le;
292 }
|
1 /*
2 * Copyright (c) 1998, 2017, 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 *
240 #endif
241 };
242
243 //------------------------------CountedLoopEndNode-----------------------------
244 // CountedLoopEndNodes end simple trip counted loops. They act much like
245 // IfNodes.
246 class CountedLoopEndNode : public IfNode {
247 public:
248 enum { TestControl, TestValue };
249
250 CountedLoopEndNode( Node *control, Node *test, float prob, float cnt )
251 : IfNode( control, test, prob, cnt) {
252 init_class_id(Class_CountedLoopEnd);
253 }
254 virtual int Opcode() const;
255
256 Node *cmp_node() const { return (in(TestValue)->req() >=2) ? in(TestValue)->in(1) : NULL; }
257 Node *incr() const { Node *tmp = cmp_node(); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
258 Node *limit() const { Node *tmp = cmp_node(); return (tmp && tmp->req()==3) ? tmp->in(2) : NULL; }
259 Node *stride() const { Node *tmp = incr (); return (tmp && tmp->req()==3) ? tmp->in(2) : NULL; }
260 Node *init_trip() const { Node *tmp = phi (); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
261 int stride_con() const;
262 bool stride_is_con() const { Node *tmp = stride (); return (tmp != NULL && tmp->is_Con()); }
263 BoolTest::mask test_trip() const { return in(TestValue)->as_Bool()->_test._test; }
264 PhiNode *phi() const {
265 Node *tmp = incr();
266 if (tmp && tmp->req() == 3) {
267 Node* phi = tmp->in(1);
268 if (phi->is_Phi()) {
269 return phi->as_Phi();
270 }
271 }
272 return NULL;
273 }
274 CountedLoopNode *loopnode() const {
275 // The CountedLoopNode that goes with this CountedLoopEndNode may
276 // have been optimized out by the IGVN so be cautious with the
277 // pattern matching on the graph
278 PhiNode* iv_phi = phi();
279 if (iv_phi == NULL) {
280 return NULL;
281 }
282 Node *ln = iv_phi->in(0);
283 if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit() == this) {
284 return (CountedLoopNode*)ln;
285 }
286 return NULL;
287 }
288
289 #ifndef PRODUCT
290 virtual void dump_spec(outputStream *st) const;
291 #endif
292 };
293
294
295 inline CountedLoopEndNode *CountedLoopNode::loopexit() const {
296 Node *bc = back_control();
297 if( bc == NULL ) return NULL;
298 Node *le = bc->in(0);
299 if( le->Opcode() != Op_CountedLoopEnd )
300 return NULL;
301 return (CountedLoopEndNode*)le;
302 }
|