24
24
#include " hphp/runtime/vm/func.h"
25
25
#include " hphp/runtime/vm/hhbc.h"
26
26
#include " hphp/runtime/vm/jit/irgen.h"
27
+ #include " hphp/runtime/vm/jit/irgen-inlining.h"
27
28
#include " hphp/runtime/vm/jit/location.h"
28
29
#include " hphp/runtime/vm/jit/irlower.h"
29
30
#include " hphp/runtime/vm/jit/mcgen.h"
@@ -299,43 +300,30 @@ using InlineCostCache = folly::ConcurrentHashMap<
299
300
>;
300
301
301
302
Vcost computeTranslationCostSlow (SrcKey at,
302
- const RegionDesc& region ,
303
+ const irgen::RegionAndLazyUnit& regionAndLazyUnit ,
303
304
AnnotationData* annotationData) {
304
- TransContext ctx {
305
- TransIDSet{},
306
- 0 , // optIndex
307
- TransKind::Optimize,
308
- at,
309
- ®ion,
310
- at.packageInfo (),
311
- PrologueID (),
312
- };
313
-
314
- tracing::Block _{" compute-inline-cost" , [&] { return traceProps (ctx); }};
315
-
316
- rqtrace::DisableTracing notrace;
317
- auto const unbumper = mcgen::unbumpFunctions ();
318
-
319
- auto const unit = irGenInlineRegion (ctx, region);
305
+ auto const unit = regionAndLazyUnit.unit ();
320
306
if (!unit) return {0 , true };
321
307
322
308
// TODO(T52856776) - annotations should be copied from unit into outer unit
323
309
// via annotationData
324
-
310
+ rqtrace::DisableTracing notrace;
311
+ auto const unbumper = mcgen::unbumpFunctions ();
325
312
SCOPE_ASSERT_DETAIL (" Inline-IRUnit" ) { return show (*unit); };
326
313
return irlower::computeIRUnitCost (*unit);
327
314
}
328
315
329
316
InlineCostCache s_inlCostCache;
330
317
331
318
int computeTranslationCost (SrcKey at,
332
- const RegionDesc& region ,
319
+ const irgen::RegionAndLazyUnit& regionAndLazyUnit ,
333
320
AnnotationData* annotationData) {
321
+ auto const region = *regionAndLazyUnit.region ();
334
322
InlineRegionKey irk{region};
335
323
auto f = s_inlCostCache.find (irk);
336
324
if (f != s_inlCostCache.end ()) return f->second ;
337
325
338
- auto const info = computeTranslationCostSlow (at, region , annotationData);
326
+ auto const info = computeTranslationCostSlow (at, regionAndLazyUnit , annotationData);
339
327
auto cost = info.cost ;
340
328
341
329
// We normally store the computed cost into the cache. However, if the region
@@ -420,7 +408,7 @@ uint64_t adjustedMaxVasmCost(const irgen::IRGS& env,
420
408
*/
421
409
int costOfInlining (SrcKey callerSk,
422
410
const Func* callee,
423
- const RegionDesc& region ,
411
+ const irgen::RegionAndLazyUnit& regionAndLazyUnit ,
424
412
AnnotationData* annotationData) {
425
413
auto const alwaysInl =
426
414
(!Cfg::HHIR::InliningIgnoreHints &&
@@ -430,7 +418,7 @@ int costOfInlining(SrcKey callerSk,
430
418
// Functions marked as always inline don't contribute to overall cost
431
419
return alwaysInl ?
432
420
0 :
433
- computeTranslationCost (callerSk, region , annotationData);
421
+ computeTranslationCost (callerSk, regionAndLazyUnit , annotationData);
434
422
}
435
423
436
424
bool isCoeffectsBackdoor (SrcKey callerSk, const Func* callee) {
@@ -463,8 +451,9 @@ bool isCoeffectsBackdoor(SrcKey callerSk, const Func* callee) {
463
451
bool shouldInline (const irgen::IRGS& irgs,
464
452
SrcKey callerSk,
465
453
const Func* callee,
466
- const RegionDesc& region ,
454
+ const irgen::RegionAndLazyUnit& regionAndUnit ,
467
455
int & cost) {
456
+ auto const region = *regionAndUnit.region ();
468
457
auto sk = region.empty () ? SrcKey () : region.start ();
469
458
assertx (callee);
470
459
assertx (sk.func () == callee);
@@ -581,7 +570,7 @@ bool shouldInline(const irgen::IRGS& irgs,
581
570
// In debug builds compute the cost anyway to catch bugs in the inlining
582
571
// machinery. Many inlining tests utilize the __ALWAYS_INLINE attribute.
583
572
if (debug) {
584
- computeTranslationCost (callerSk, region , annotationsPtr);
573
+ computeTranslationCost (callerSk, regionAndUnit , annotationsPtr);
585
574
}
586
575
return accept (" callee marked as __ALWAYS_INLINE" );
587
576
}
@@ -590,7 +579,7 @@ bool shouldInline(const irgen::IRGS& irgs,
590
579
// We measure the cost of inlining each callstack and stop when it exceeds a
591
580
// certain threshold. (Note that we do not measure the total cost of all the
592
581
// inlined calls for a given caller---just the cost of each nested stack.)
593
- cost = costOfInlining (callerSk, callee, region , annotationsPtr);
582
+ cost = costOfInlining (callerSk, callee, regionAndUnit , annotationsPtr);
594
583
if (cost <= Cfg::HHIR::AlwaysInlineVasmCostLimit) {
595
584
return accept (folly::sformat (" cost={} within always-inline limit" , cost));
596
585
}
@@ -744,10 +733,10 @@ RegionDescPtr selectCalleeCFG(SrcKey callerSk, SrcKey entry,
744
733
}
745
734
}
746
735
747
- RegionDescPtr selectCalleeRegion (const irgen::IRGS& irgs,
748
- SrcKey entry,
749
- Type ctxType,
750
- SrcKey callerSk) {
736
+ irgen::RegionAndLazyUnit selectCalleeRegion (const irgen::IRGS& irgs,
737
+ SrcKey entry,
738
+ Type ctxType,
739
+ SrcKey callerSk) {
751
740
assertx (entry.funcEntry ());
752
741
auto const callee = entry.func ();
753
742
@@ -761,7 +750,7 @@ RegionDescPtr selectCalleeRegion(const irgen::IRGS& irgs,
761
750
762
751
if (ctxType == TBottom) {
763
752
traceRefusal (callerSk, callee, " ctx is TBottom" , annotationsPtr);
764
- return nullptr ;
753
+ return {callerSk, nullptr } ;
765
754
}
766
755
if (callee->isClosureBody ()) {
767
756
if (!callee->cls ()) {
@@ -778,21 +767,21 @@ RegionDescPtr selectCalleeRegion(const irgen::IRGS& irgs,
778
767
(!callerSk.hasThis () && isFCallClsMethod (callerSk.op ())))) {
779
768
traceRefusal (callerSk, callee, " calling static method with an object" ,
780
769
annotationsPtr);
781
- return nullptr ;
770
+ return {callerSk, nullptr } ;
782
771
}
783
772
}
784
773
785
774
if (callee->cls ()) {
786
775
if (callee->isStatic () && !ctxType.maybe (TCls)) {
787
776
traceRefusal (callerSk, callee, " calling a static method with an instance" ,
788
777
annotationsPtr);
789
- return nullptr ;
778
+ return {callerSk, nullptr } ;
790
779
}
791
780
if (!callee->isStatic () && !ctxType.maybe (TObj)) {
792
781
traceRefusal (callerSk, callee,
793
782
" calling an instance method without an instance" ,
794
783
annotationsPtr);
795
- return nullptr ;
784
+ return {callerSk, nullptr } ;
796
785
}
797
786
}
798
787
@@ -808,7 +797,7 @@ RegionDescPtr selectCalleeRegion(const irgen::IRGS& irgs,
808
797
809
798
// If we don't have sufficient type information to inline the region return
810
799
// early
811
- if (type == TBottom) return nullptr ;
800
+ if (type == TBottom) return {callerSk, nullptr } ;
812
801
FTRACE (2 , " input {}: {}\n " , i + 1 , type);
813
802
inputTypes.push_back (type);
814
803
}
@@ -823,21 +812,22 @@ RegionDescPtr selectCalleeRegion(const irgen::IRGS& irgs,
823
812
if (profData ()) {
824
813
auto region = selectCalleeCFG (callerSk, entry, ctxType, inputTypes,
825
814
Cfg::Jit::MaxInlineRegionInstrs, annotationsPtr);
826
- if (region) return region;
815
+ if (region) return {callerSk, region} ;
827
816
// Special case: even if we don't have prof data for this func, if
828
817
// it takes no arguments and returns a constant, it might be a
829
818
// trivial function (IE, "return 123;"). Attempt to inline it
830
819
// anyways using the tracelet selector.
831
- if (callee->numFuncEntryInputs () > 0 ) return nullptr ;
820
+ if (callee->numFuncEntryInputs () > 0 ) return {callerSk, nullptr } ;
832
821
auto const retType =
833
822
typeFromRAT (callee->repoReturnType (), callerSk.func ()->cls ());
834
823
// Deliberately using hasConstVal, not admitsSingleVal, since we
835
824
// don't want TInitNull, etc.
836
- if (!retType.hasConstVal ()) return nullptr ;
825
+ if (!retType.hasConstVal ()) return {callerSk, nullptr } ;
837
826
}
838
827
839
- return selectCalleeTracelet (entry, ctxType, inputTypes,
840
- Cfg::Jit::MaxInlineRegionInstrs);
828
+ auto region = selectCalleeTracelet (entry, ctxType, inputTypes,
829
+ Cfg::Jit::MaxInlineRegionInstrs);
830
+ return {callerSk, region};
841
831
}
842
832
843
833
void setBaseInliningProfCount (uint64_t value) {
0 commit comments