@@ -222,12 +222,6 @@ class SwiftMergeFunctions : public ModulePass {
222
222
bool runOnModule (Module &M) override ;
223
223
224
224
private:
225
- enum {
226
- // / The maximum number of parameters added to a merged functions. This
227
- // / roughly corresponds to the number of differing constants.
228
- maxAddedParams = 4
229
- };
230
-
231
225
struct FunctionEntry ;
232
226
233
227
// / Describes the set of functions which are considered as "equivalent" (i.e.
@@ -359,7 +353,7 @@ class SwiftMergeFunctions : public ModulePass {
359
353
}
360
354
};
361
355
362
- using ParamInfos = SmallVector<ParamInfo, maxAddedParams >;
356
+ using ParamInfos = SmallVector<ParamInfo, 16 >;
363
357
364
358
GlobalNumberState GlobalNumbers;
365
359
@@ -398,14 +392,15 @@ class SwiftMergeFunctions : public ModulePass {
398
392
399
393
FunctionInfo removeFuncWithMostParams (FunctionInfos &FInfos);
400
394
401
- bool deriveParams (ParamInfos &Params, FunctionInfos &FInfos);
395
+ bool deriveParams (ParamInfos &Params, FunctionInfos &FInfos,
396
+ unsigned maxParams);
402
397
403
398
bool numOperandsDiffer (FunctionInfos &FInfos);
404
399
405
400
bool constsDiffer (const FunctionInfos &FInfos, unsigned OpIdx);
406
401
407
402
bool tryMapToParameter (FunctionInfos &FInfos, unsigned OpIdx,
408
- ParamInfos &Params);
403
+ ParamInfos &Params, unsigned maxParams );
409
404
410
405
void mergeWithParams (const FunctionInfos &FInfos, ParamInfos &Params);
411
406
@@ -524,17 +519,9 @@ static bool mayMergeCallsToFunction(Function &F) {
524
519
return true ;
525
520
}
526
521
527
- // / Returns true if function \p F is eligible for merging.
528
- static bool isEligibleFunction (Function *F) {
529
- if (F->isDeclaration ())
530
- return false ;
531
-
532
- if (F->hasAvailableExternallyLinkage ())
533
- return false ;
534
-
535
- if (F->getFunctionType ()->isVarArg ())
536
- return false ;
537
-
522
+ // / Returns the benefit, which is approximately the size of the function.
523
+ // / Return 0, if the function should not be merged.
524
+ static unsigned getBenefit (Function *F) {
538
525
unsigned Benefit = 0 ;
539
526
540
527
// We don't want to merge very small functions, because the overhead of
@@ -545,7 +532,7 @@ static bool isEligibleFunction(Function *F) {
545
532
if (CallBase *CB = dyn_cast<CallBase>(&I)) {
546
533
Function *Callee = CB->getCalledFunction ();
547
534
if (Callee && !mayMergeCallsToFunction (*Callee))
548
- return false ;
535
+ return 0 ;
549
536
if (!Callee || !Callee->isIntrinsic ()) {
550
537
Benefit += 5 ;
551
538
continue ;
@@ -554,6 +541,21 @@ static bool isEligibleFunction(Function *F) {
554
541
Benefit += 1 ;
555
542
}
556
543
}
544
+ return Benefit;
545
+ }
546
+
547
+ // / Returns true if function \p F is eligible for merging.
548
+ static bool isEligibleFunction (Function *F) {
549
+ if (F->isDeclaration ())
550
+ return false ;
551
+
552
+ if (F->hasAvailableExternallyLinkage ())
553
+ return false ;
554
+
555
+ if (F->getFunctionType ()->isVarArg ())
556
+ return false ;
557
+
558
+ unsigned Benefit = getBenefit (F);
557
559
if (Benefit < FunctionMergeThreshold)
558
560
return false ;
559
561
@@ -723,12 +725,17 @@ bool SwiftMergeFunctions::tryMergeEquivalenceClass(FunctionEntry *FirstInClass)
723
725
bool Changed = false ;
724
726
int Try = 0 ;
725
727
728
+ unsigned Benefit = getBenefit (FirstInClass->F );
729
+
730
+ // The bigger the function, the more parameters are allowed.
731
+ unsigned maxParams = std::max (4u , Benefit / 100 );
732
+
726
733
// We need multiple tries if there are some functions in FInfos which differ
727
734
// too much from the first function in FInfos. But we limit the number of
728
735
// tries to a small number, because this is quadratic.
729
736
while (FInfos.size () >= 2 && Try++ < 4 ) {
730
737
ParamInfos Params;
731
- bool Merged = deriveParams (Params, FInfos);
738
+ bool Merged = deriveParams (Params, FInfos, maxParams );
732
739
if (Merged) {
733
740
mergeWithParams (FInfos, Params);
734
741
Changed = true ;
@@ -767,7 +774,8 @@ removeFuncWithMostParams(FunctionInfos &FInfos) {
767
774
// / Returns true on success, i.e. the functions in \p FInfos can be merged with
768
775
// / the parameters returned in \p Params.
769
776
bool SwiftMergeFunctions::deriveParams (ParamInfos &Params,
770
- FunctionInfos &FInfos) {
777
+ FunctionInfos &FInfos,
778
+ unsigned maxParams) {
771
779
for (FunctionInfo &FI : FInfos)
772
780
FI.init ();
773
781
@@ -796,7 +804,7 @@ bool SwiftMergeFunctions::deriveParams(ParamInfos &Params,
796
804
if (constsDiffer (FInfos, OpIdx)) {
797
805
// This instruction has operands which differ in at least some
798
806
// functions. So we need to parameterize it.
799
- if (!tryMapToParameter (FInfos, OpIdx, Params)) {
807
+ if (!tryMapToParameter (FInfos, OpIdx, Params, maxParams )) {
800
808
// We ran out of parameters.
801
809
return false ;
802
810
}
@@ -845,7 +853,8 @@ bool SwiftMergeFunctions::constsDiffer(const FunctionInfos &FInfos,
845
853
// / Returns true if a parameter could be created or found without exceeding the
846
854
// / maximum number of parameters.
847
855
bool SwiftMergeFunctions::tryMapToParameter (FunctionInfos &FInfos,
848
- unsigned OpIdx, ParamInfos &Params) {
856
+ unsigned OpIdx, ParamInfos &Params,
857
+ unsigned maxParams) {
849
858
ParamInfo *Matching = nullptr ;
850
859
// Try to find an existing parameter which exactly matches the differing
851
860
// operands of the current instruction.
@@ -858,7 +867,7 @@ bool SwiftMergeFunctions::tryMapToParameter(FunctionInfos &FInfos,
858
867
if (!Matching) {
859
868
// We need a new parameter.
860
869
// Check if we are within the limit.
861
- if (Params.size () >= maxAddedParams )
870
+ if (Params.size () >= maxParams )
862
871
return false ;
863
872
864
873
Params.resize (Params.size () + 1 );
0 commit comments