Mercurial > hg > graal-compiler
annotate src/share/vm/shark/sharkInliner.cpp @ 14562:45812e05cdb3
Move narrow oop handling in reference maps to hotspot specific code.
author | Roland Schatz <roland.schatz@oracle.com> |
---|---|
date | Mon, 17 Mar 2014 12:07:49 +0100 |
parents | de6a9e811145 |
children | 81ccf2c854c7 4ca6dc0799b6 |
rev | line source |
---|---|
1692 | 1 /* |
14223
de6a9e811145
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
7601
diff
changeset
|
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. |
1692 | 3 * Copyright 2009 Red Hat, Inc. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 * | |
6 * This code is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License version 2 only, as | |
8 * published by the Free Software Foundation. | |
9 * | |
10 * This code is distributed in the hope that it will be useful, but WITHOUT | |
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 * version 2 for more details (a copy is included in the LICENSE file that | |
14 * accompanied this code). | |
15 * | |
16 * You should have received a copy of the GNU General Public License version | |
17 * 2 along with this work; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 * | |
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
21 * or visit www.oracle.com if you need additional information or have any | |
22 * questions. | |
23 * | |
24 */ | |
25 | |
1972 | 26 #include "precompiled.hpp" |
27 #include "ci/ciField.hpp" | |
28 #include "ci/ciMethod.hpp" | |
29 #include "ci/ciStreams.hpp" | |
30 #include "interpreter/bytecodes.hpp" | |
31 #include "memory/allocation.hpp" | |
32 #include "shark/sharkBlock.hpp" | |
33 #include "shark/sharkConstant.hpp" | |
34 #include "shark/sharkInliner.hpp" | |
35 #include "shark/sharkIntrinsics.hpp" | |
36 #include "shark/sharkState.hpp" | |
37 #include "shark/sharkValue.hpp" | |
38 #include "shark/shark_globals.hpp" | |
1692 | 39 |
40 using namespace llvm; | |
41 | |
42 class SharkInlineBlock : public SharkBlock { | |
43 public: | |
44 SharkInlineBlock(ciMethod* target, SharkState* state) | |
45 : SharkBlock(state, target), | |
46 _outer_state(state), | |
47 _entry_state(new SharkState(this)) { | |
48 for (int i = target->max_locals() - 1; i >= 0; i--) { | |
49 SharkValue *value = NULL; | |
50 if (i < target->arg_size()) | |
51 value = outer_state()->pop(); | |
52 entry_state()->set_local(i, value); | |
53 } | |
54 } | |
55 | |
56 private: | |
57 SharkState* _outer_state; | |
58 SharkState* _entry_state; | |
59 | |
60 private: | |
61 SharkState* outer_state() { | |
62 return _outer_state; | |
63 } | |
64 SharkState* entry_state() { | |
65 return _entry_state; | |
66 } | |
67 | |
68 public: | |
69 void emit_IR() { | |
70 parse_bytecode(0, target()->code_size()); | |
71 } | |
72 | |
73 private: | |
74 void do_return(BasicType type) { | |
75 if (type != T_VOID) { | |
76 SharkValue *result = pop_result(type); | |
77 outer_state()->push(result); | |
78 if (result->is_two_word()) | |
79 outer_state()->push(NULL); | |
80 } | |
81 } | |
82 }; | |
83 | |
84 class SharkInlinerHelper : public StackObj { | |
85 public: | |
86 SharkInlinerHelper(ciMethod* target, SharkState* entry_state) | |
87 : _target(target), | |
88 _entry_state(entry_state), | |
89 _iter(target) {} | |
90 | |
91 private: | |
92 ciBytecodeStream _iter; | |
93 SharkState* _entry_state; | |
94 ciMethod* _target; | |
95 | |
96 public: | |
97 ciBytecodeStream* iter() { | |
98 return &_iter; | |
99 } | |
100 SharkState* entry_state() const { | |
101 return _entry_state; | |
102 } | |
103 ciMethod* target() const { | |
104 return _target; | |
105 } | |
106 | |
107 public: | |
108 Bytecodes::Code bc() { | |
109 return iter()->cur_bc(); | |
110 } | |
111 int max_locals() const { | |
112 return target()->max_locals(); | |
113 } | |
114 int max_stack() const { | |
115 return target()->max_stack(); | |
116 } | |
117 | |
118 // Inlinability check | |
119 public: | |
120 bool is_inlinable(); | |
121 | |
122 private: | |
123 void initialize_for_check(); | |
124 | |
125 bool do_getstatic() { | |
126 return do_field_access(true, false); | |
127 } | |
128 bool do_getfield() { | |
129 return do_field_access(true, true); | |
130 } | |
131 bool do_putfield() { | |
132 return do_field_access(false, true); | |
133 } | |
134 bool do_field_access(bool is_get, bool is_field); | |
135 | |
136 // Local variables for inlinability check | |
137 private: | |
138 bool* _locals; | |
139 | |
140 public: | |
141 bool* local_addr(int index) const { | |
142 assert(index >= 0 && index < max_locals(), "bad local variable index"); | |
143 return &_locals[index]; | |
144 } | |
145 bool local(int index) const { | |
146 return *local_addr(index); | |
147 } | |
148 void set_local(int index, bool value) { | |
149 *local_addr(index) = value; | |
150 } | |
151 | |
152 // Expression stack for inlinability check | |
153 private: | |
154 bool* _stack; | |
155 bool* _sp; | |
156 | |
157 public: | |
158 int stack_depth() const { | |
159 return _sp - _stack; | |
160 } | |
161 bool* stack_addr(int slot) const { | |
162 assert(slot >= 0 && slot < stack_depth(), "bad stack slot"); | |
163 return &_sp[-(slot + 1)]; | |
164 } | |
165 void push(bool value) { | |
166 assert(stack_depth() < max_stack(), "stack overrun"); | |
167 *(_sp++) = value; | |
168 } | |
169 bool pop() { | |
170 assert(stack_depth() > 0, "stack underrun"); | |
171 return *(--_sp); | |
172 } | |
173 | |
174 // Methods for two-word locals | |
175 public: | |
176 void push_pair_local(int index) { | |
177 push(local(index)); | |
178 push(local(index + 1)); | |
179 } | |
180 void pop_pair_local(int index) { | |
181 set_local(index + 1, pop()); | |
182 set_local(index, pop()); | |
183 } | |
184 | |
185 // Code generation | |
186 public: | |
187 void do_inline() { | |
188 (new SharkInlineBlock(target(), entry_state()))->emit_IR(); | |
189 } | |
190 }; | |
191 | |
192 // Quick checks so we can bail out before doing too much | |
193 bool SharkInliner::may_be_inlinable(ciMethod *target) { | |
194 // We can't inline native methods | |
195 if (target->is_native()) | |
196 return false; | |
197 | |
198 // Not much point inlining abstract ones, and in any | |
199 // case we'd need a stack frame to throw the exception | |
200 if (target->is_abstract()) | |
201 return false; | |
202 | |
203 // Don't inline anything huge | |
204 if (target->code_size() > SharkMaxInlineSize) | |
205 return false; | |
206 | |
207 // Monitors aren't allowed without a frame to put them in | |
208 if (target->is_synchronized() || target->has_monitor_bytecodes()) | |
209 return false; | |
210 | |
211 // We don't do control flow | |
212 if (target->has_exception_handlers() || target->has_jsrs()) | |
213 return false; | |
214 | |
215 // Don't try to inline constructors, as they must | |
216 // eventually call Object.<init> which we can't inline. | |
217 // Note that this catches <clinit> too, but why would | |
218 // we be compiling that? | |
219 if (target->is_initializer()) | |
220 return false; | |
221 | |
222 // Mustn't inline Object.<init> | |
223 // Should be caught by the above, but just in case... | |
224 if (target->intrinsic_id() == vmIntrinsics::_Object_init) | |
225 return false; | |
226 | |
227 return true; | |
228 } | |
229 | |
230 // Full-on detailed check, for methods that pass the quick checks | |
231 // Inlined methods have no stack frame, so we can't do anything | |
232 // that would require one. This means no safepoints (and hence | |
233 // no loops) and no VM calls. No VM calls means, amongst other | |
234 // things, that no exceptions can be created, which means no null | |
235 // checks or divide-by-zero checks are allowed. The lack of null | |
236 // checks in particular would eliminate practically everything, | |
237 // but we can get around that restriction by relying on the zero- | |
238 // check eliminator to strip the checks. To do that, we need to | |
239 // walk through the method, tracking which values are and are not | |
240 // zero-checked. | |
241 bool SharkInlinerHelper::is_inlinable() { | |
242 ResourceMark rm; | |
243 initialize_for_check(); | |
244 | |
245 SharkConstant *sc; | |
246 bool a, b, c, d; | |
247 | |
248 iter()->reset_to_bci(0); | |
249 while (iter()->next() != ciBytecodeStream::EOBC()) { | |
250 switch (bc()) { | |
251 case Bytecodes::_nop: | |
252 break; | |
253 | |
254 case Bytecodes::_aconst_null: | |
255 push(false); | |
256 break; | |
257 | |
258 case Bytecodes::_iconst_0: | |
259 push(false); | |
260 break; | |
261 case Bytecodes::_iconst_m1: | |
262 case Bytecodes::_iconst_1: | |
263 case Bytecodes::_iconst_2: | |
264 case Bytecodes::_iconst_3: | |
265 case Bytecodes::_iconst_4: | |
266 case Bytecodes::_iconst_5: | |
267 push(true); | |
268 break; | |
269 | |
270 case Bytecodes::_lconst_0: | |
271 push(false); | |
272 push(false); | |
273 break; | |
274 case Bytecodes::_lconst_1: | |
275 push(true); | |
276 push(false); | |
277 break; | |
278 | |
279 case Bytecodes::_fconst_0: | |
280 case Bytecodes::_fconst_1: | |
281 case Bytecodes::_fconst_2: | |
282 push(false); | |
283 break; | |
284 | |
285 case Bytecodes::_dconst_0: | |
286 case Bytecodes::_dconst_1: | |
287 push(false); | |
288 push(false); | |
289 break; | |
290 | |
291 case Bytecodes::_bipush: | |
292 push(iter()->get_constant_u1() != 0); | |
293 break; | |
294 case Bytecodes::_sipush: | |
295 push(iter()->get_constant_u2() != 0); | |
296 break; | |
297 | |
298 case Bytecodes::_ldc: | |
299 case Bytecodes::_ldc_w: | |
300 case Bytecodes::_ldc2_w: | |
301 sc = SharkConstant::for_ldc(iter()); | |
302 if (!sc->is_loaded()) | |
303 return false; | |
304 push(sc->is_nonzero()); | |
305 if (sc->is_two_word()) | |
306 push(false); | |
307 break; | |
308 | |
309 case Bytecodes::_iload_0: | |
310 case Bytecodes::_fload_0: | |
311 case Bytecodes::_aload_0: | |
312 push(local(0)); | |
313 break; | |
314 case Bytecodes::_lload_0: | |
315 case Bytecodes::_dload_0: | |
316 push_pair_local(0); | |
317 break; | |
318 | |
319 case Bytecodes::_iload_1: | |
320 case Bytecodes::_fload_1: | |
321 case Bytecodes::_aload_1: | |
322 push(local(1)); | |
323 break; | |
324 case Bytecodes::_lload_1: | |
325 case Bytecodes::_dload_1: | |
326 push_pair_local(1); | |
327 break; | |
328 | |
329 case Bytecodes::_iload_2: | |
330 case Bytecodes::_fload_2: | |
331 case Bytecodes::_aload_2: | |
332 push(local(2)); | |
333 break; | |
334 case Bytecodes::_lload_2: | |
335 case Bytecodes::_dload_2: | |
336 push_pair_local(2); | |
337 break; | |
338 | |
339 case Bytecodes::_iload_3: | |
340 case Bytecodes::_fload_3: | |
341 case Bytecodes::_aload_3: | |
342 push(local(3)); | |
343 break; | |
344 case Bytecodes::_lload_3: | |
345 case Bytecodes::_dload_3: | |
346 push_pair_local(3); | |
347 break; | |
348 | |
349 case Bytecodes::_iload: | |
350 case Bytecodes::_fload: | |
351 case Bytecodes::_aload: | |
352 push(local(iter()->get_index())); | |
353 break; | |
354 case Bytecodes::_lload: | |
355 case Bytecodes::_dload: | |
356 push_pair_local(iter()->get_index()); | |
357 break; | |
358 | |
359 case Bytecodes::_istore_0: | |
360 case Bytecodes::_fstore_0: | |
361 case Bytecodes::_astore_0: | |
362 set_local(0, pop()); | |
363 break; | |
364 case Bytecodes::_lstore_0: | |
365 case Bytecodes::_dstore_0: | |
366 pop_pair_local(0); | |
367 break; | |
368 | |
369 case Bytecodes::_istore_1: | |
370 case Bytecodes::_fstore_1: | |
371 case Bytecodes::_astore_1: | |
372 set_local(1, pop()); | |
373 break; | |
374 case Bytecodes::_lstore_1: | |
375 case Bytecodes::_dstore_1: | |
376 pop_pair_local(1); | |
377 break; | |
378 | |
379 case Bytecodes::_istore_2: | |
380 case Bytecodes::_fstore_2: | |
381 case Bytecodes::_astore_2: | |
382 set_local(2, pop()); | |
383 break; | |
384 case Bytecodes::_lstore_2: | |
385 case Bytecodes::_dstore_2: | |
386 pop_pair_local(2); | |
387 break; | |
388 | |
389 case Bytecodes::_istore_3: | |
390 case Bytecodes::_fstore_3: | |
391 case Bytecodes::_astore_3: | |
392 set_local(3, pop()); | |
393 break; | |
394 case Bytecodes::_lstore_3: | |
395 case Bytecodes::_dstore_3: | |
396 pop_pair_local(3); | |
397 break; | |
398 | |
399 case Bytecodes::_istore: | |
400 case Bytecodes::_fstore: | |
401 case Bytecodes::_astore: | |
402 set_local(iter()->get_index(), pop()); | |
403 break; | |
404 case Bytecodes::_lstore: | |
405 case Bytecodes::_dstore: | |
406 pop_pair_local(iter()->get_index()); | |
407 break; | |
408 | |
409 case Bytecodes::_pop: | |
410 pop(); | |
411 break; | |
412 case Bytecodes::_pop2: | |
413 pop(); | |
414 pop(); | |
415 break; | |
416 case Bytecodes::_swap: | |
417 a = pop(); | |
418 b = pop(); | |
419 push(a); | |
420 push(b); | |
421 break; | |
422 case Bytecodes::_dup: | |
423 a = pop(); | |
424 push(a); | |
425 push(a); | |
426 break; | |
427 case Bytecodes::_dup_x1: | |
428 a = pop(); | |
429 b = pop(); | |
430 push(a); | |
431 push(b); | |
432 push(a); | |
433 break; | |
434 case Bytecodes::_dup_x2: | |
435 a = pop(); | |
436 b = pop(); | |
437 c = pop(); | |
438 push(a); | |
439 push(c); | |
440 push(b); | |
441 push(a); | |
442 break; | |
443 case Bytecodes::_dup2: | |
444 a = pop(); | |
445 b = pop(); | |
446 push(b); | |
447 push(a); | |
448 push(b); | |
449 push(a); | |
450 break; | |
451 case Bytecodes::_dup2_x1: | |
452 a = pop(); | |
453 b = pop(); | |
454 c = pop(); | |
455 push(b); | |
456 push(a); | |
457 push(c); | |
458 push(b); | |
459 push(a); | |
460 break; | |
461 case Bytecodes::_dup2_x2: | |
462 a = pop(); | |
463 b = pop(); | |
464 c = pop(); | |
465 d = pop(); | |
466 push(b); | |
467 push(a); | |
468 push(d); | |
469 push(c); | |
470 push(b); | |
471 push(a); | |
472 break; | |
473 | |
474 case Bytecodes::_getfield: | |
475 if (!do_getfield()) | |
476 return false; | |
477 break; | |
478 case Bytecodes::_getstatic: | |
479 if (!do_getstatic()) | |
480 return false; | |
481 break; | |
482 case Bytecodes::_putfield: | |
483 if (!do_putfield()) | |
484 return false; | |
485 break; | |
486 | |
487 case Bytecodes::_iadd: | |
488 case Bytecodes::_isub: | |
489 case Bytecodes::_imul: | |
490 case Bytecodes::_iand: | |
491 case Bytecodes::_ixor: | |
492 case Bytecodes::_ishl: | |
493 case Bytecodes::_ishr: | |
494 case Bytecodes::_iushr: | |
495 pop(); | |
496 pop(); | |
497 push(false); | |
498 break; | |
499 case Bytecodes::_ior: | |
500 a = pop(); | |
501 b = pop(); | |
502 push(a && b); | |
503 break; | |
504 case Bytecodes::_idiv: | |
505 case Bytecodes::_irem: | |
506 if (!pop()) | |
507 return false; | |
508 pop(); | |
509 push(false); | |
510 break; | |
511 case Bytecodes::_ineg: | |
512 break; | |
513 | |
514 case Bytecodes::_ladd: | |
515 case Bytecodes::_lsub: | |
516 case Bytecodes::_lmul: | |
517 case Bytecodes::_land: | |
518 case Bytecodes::_lxor: | |
519 pop(); | |
520 pop(); | |
521 pop(); | |
522 pop(); | |
523 push(false); | |
524 push(false); | |
525 break; | |
526 case Bytecodes::_lor: | |
527 a = pop(); | |
528 b = pop(); | |
529 push(a && b); | |
530 break; | |
531 case Bytecodes::_ldiv: | |
532 case Bytecodes::_lrem: | |
533 pop(); | |
534 if (!pop()) | |
535 return false; | |
536 pop(); | |
537 pop(); | |
538 push(false); | |
539 push(false); | |
540 break; | |
541 case Bytecodes::_lneg: | |
542 break; | |
543 case Bytecodes::_lshl: | |
544 case Bytecodes::_lshr: | |
545 case Bytecodes::_lushr: | |
546 pop(); | |
547 pop(); | |
548 pop(); | |
549 push(false); | |
550 push(false); | |
551 break; | |
552 | |
553 case Bytecodes::_fadd: | |
554 case Bytecodes::_fsub: | |
555 case Bytecodes::_fmul: | |
556 case Bytecodes::_fdiv: | |
557 case Bytecodes::_frem: | |
558 pop(); | |
559 pop(); | |
560 push(false); | |
561 break; | |
562 case Bytecodes::_fneg: | |
563 break; | |
564 | |
565 case Bytecodes::_dadd: | |
566 case Bytecodes::_dsub: | |
567 case Bytecodes::_dmul: | |
568 case Bytecodes::_ddiv: | |
569 case Bytecodes::_drem: | |
570 pop(); | |
571 pop(); | |
572 pop(); | |
573 pop(); | |
574 push(false); | |
575 push(false); | |
576 break; | |
577 case Bytecodes::_dneg: | |
578 break; | |
579 | |
580 case Bytecodes::_iinc: | |
581 set_local(iter()->get_index(), false); | |
582 break; | |
583 | |
584 case Bytecodes::_lcmp: | |
585 pop(); | |
586 pop(); | |
587 pop(); | |
588 pop(); | |
589 push(false); | |
590 break; | |
591 | |
592 case Bytecodes::_fcmpl: | |
593 case Bytecodes::_fcmpg: | |
594 pop(); | |
595 pop(); | |
596 push(false); | |
597 break; | |
598 | |
599 case Bytecodes::_dcmpl: | |
600 case Bytecodes::_dcmpg: | |
601 pop(); | |
602 pop(); | |
603 pop(); | |
604 pop(); | |
605 push(false); | |
606 break; | |
607 | |
608 case Bytecodes::_i2l: | |
609 push(false); | |
610 break; | |
611 case Bytecodes::_i2f: | |
612 pop(); | |
613 push(false); | |
614 break; | |
615 case Bytecodes::_i2d: | |
616 pop(); | |
617 push(false); | |
618 push(false); | |
619 break; | |
620 | |
621 case Bytecodes::_l2i: | |
622 case Bytecodes::_l2f: | |
623 pop(); | |
624 pop(); | |
625 push(false); | |
626 break; | |
627 case Bytecodes::_l2d: | |
628 pop(); | |
629 pop(); | |
630 push(false); | |
631 push(false); | |
632 break; | |
633 | |
634 case Bytecodes::_f2i: | |
635 pop(); | |
636 push(false); | |
637 break; | |
638 case Bytecodes::_f2l: | |
639 case Bytecodes::_f2d: | |
640 pop(); | |
641 push(false); | |
642 push(false); | |
643 break; | |
644 | |
645 case Bytecodes::_d2i: | |
646 case Bytecodes::_d2f: | |
647 pop(); | |
648 pop(); | |
649 push(false); | |
650 break; | |
651 case Bytecodes::_d2l: | |
652 pop(); | |
653 pop(); | |
654 push(false); | |
655 push(false); | |
656 break; | |
657 | |
658 case Bytecodes::_i2b: | |
659 case Bytecodes::_i2c: | |
660 case Bytecodes::_i2s: | |
661 pop(); | |
662 push(false); | |
663 break; | |
664 | |
665 case Bytecodes::_return: | |
666 case Bytecodes::_ireturn: | |
667 case Bytecodes::_lreturn: | |
668 case Bytecodes::_freturn: | |
669 case Bytecodes::_dreturn: | |
670 case Bytecodes::_areturn: | |
671 break; | |
672 | |
673 default: | |
674 return false; | |
675 } | |
676 } | |
677 | |
678 return true; | |
679 } | |
680 | |
681 void SharkInlinerHelper::initialize_for_check() { | |
682 _locals = NEW_RESOURCE_ARRAY(bool, max_locals()); | |
683 _stack = NEW_RESOURCE_ARRAY(bool, max_stack()); | |
684 | |
685 memset(_locals, 0, max_locals() * sizeof(bool)); | |
686 for (int i = 0; i < target()->arg_size(); i++) { | |
687 SharkValue *arg = entry_state()->stack(target()->arg_size() - 1 - i); | |
688 if (arg && arg->zero_checked()) | |
689 set_local(i, true); | |
690 } | |
691 | |
692 _sp = _stack; | |
693 } | |
694 | |
695 bool SharkInlinerHelper::do_field_access(bool is_get, bool is_field) { | |
696 assert(is_get || is_field, "can't inline putstatic"); | |
697 | |
698 // If the holder isn't linked then there isn't a lot we can do | |
699 if (!target()->holder()->is_linked()) | |
700 return false; | |
701 | |
702 // Get the field | |
703 bool will_link; | |
704 ciField *field = iter()->get_field(will_link); | |
705 if (!will_link) | |
706 return false; | |
707 | |
708 // If the field is mismatched then an exception needs throwing | |
709 if (is_field == field->is_static()) | |
710 return false; | |
711 | |
712 // Pop the value off the stack if necessary | |
713 if (!is_get) { | |
714 pop(); | |
715 if (field->type()->is_two_word()) | |
716 pop(); | |
717 } | |
718 | |
719 // Pop and null-check the receiver if necessary | |
720 if (is_field) { | |
721 if (!pop()) | |
722 return false; | |
723 } | |
724 | |
725 // Push the result if necessary | |
726 if (is_get) { | |
727 bool result_pushed = false; | |
7601 | 728 if (field->is_constant() && field->is_static()) { |
1692 | 729 SharkConstant *sc = SharkConstant::for_field(iter()); |
730 if (sc->is_loaded()) { | |
731 push(sc->is_nonzero()); | |
732 result_pushed = true; | |
733 } | |
734 } | |
735 | |
736 if (!result_pushed) | |
737 push(false); | |
738 | |
739 if (field->type()->is_two_word()) | |
740 push(false); | |
741 } | |
742 | |
743 return true; | |
744 } | |
745 | |
746 bool SharkInliner::attempt_inline(ciMethod *target, SharkState *state) { | |
747 if (SharkIntrinsics::is_intrinsic(target)) { | |
748 SharkIntrinsics::inline_intrinsic(target, state); | |
749 return true; | |
750 } | |
751 | |
752 if (may_be_inlinable(target)) { | |
753 SharkInlinerHelper inliner(target, state); | |
754 if (inliner.is_inlinable()) { | |
755 inliner.do_inline(); | |
756 return true; | |
757 } | |
758 } | |
759 return false; | |
760 } |