Skip to content

Commit 145b8ae

Browse files
committed
LLVMMergeFunctions: allow more parameters if the function is bigger
We had a fixed limit of 4 added parameters for merged functions. But if a function is big, it makes sense to allow more parameters to be added. Now, derived the maximum number of parameters from the function size. This increases the chances that big functions (which likely require more parameters) are merged.
1 parent 2b62570 commit 145b8ae

File tree

1 file changed

+35
-26
lines changed

1 file changed

+35
-26
lines changed

lib/LLVMPasses/LLVMMergeFunctions.cpp

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,6 @@ class SwiftMergeFunctions : public ModulePass {
222222
bool runOnModule(Module &M) override;
223223

224224
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-
231225
struct FunctionEntry;
232226

233227
/// Describes the set of functions which are considered as "equivalent" (i.e.
@@ -359,7 +353,7 @@ class SwiftMergeFunctions : public ModulePass {
359353
}
360354
};
361355

362-
using ParamInfos = SmallVector<ParamInfo, maxAddedParams>;
356+
using ParamInfos = SmallVector<ParamInfo, 16>;
363357

364358
GlobalNumberState GlobalNumbers;
365359

@@ -398,14 +392,15 @@ class SwiftMergeFunctions : public ModulePass {
398392

399393
FunctionInfo removeFuncWithMostParams(FunctionInfos &FInfos);
400394

401-
bool deriveParams(ParamInfos &Params, FunctionInfos &FInfos);
395+
bool deriveParams(ParamInfos &Params, FunctionInfos &FInfos,
396+
unsigned maxParams);
402397

403398
bool numOperandsDiffer(FunctionInfos &FInfos);
404399

405400
bool constsDiffer(const FunctionInfos &FInfos, unsigned OpIdx);
406401

407402
bool tryMapToParameter(FunctionInfos &FInfos, unsigned OpIdx,
408-
ParamInfos &Params);
403+
ParamInfos &Params, unsigned maxParams);
409404

410405
void mergeWithParams(const FunctionInfos &FInfos, ParamInfos &Params);
411406

@@ -524,17 +519,9 @@ static bool mayMergeCallsToFunction(Function &F) {
524519
return true;
525520
}
526521

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) {
538525
unsigned Benefit = 0;
539526

540527
// We don't want to merge very small functions, because the overhead of
@@ -545,7 +532,7 @@ static bool isEligibleFunction(Function *F) {
545532
if (CallBase *CB = dyn_cast<CallBase>(&I)) {
546533
Function *Callee = CB->getCalledFunction();
547534
if (Callee && !mayMergeCallsToFunction(*Callee))
548-
return false;
535+
return 0;
549536
if (!Callee || !Callee->isIntrinsic()) {
550537
Benefit += 5;
551538
continue;
@@ -554,6 +541,21 @@ static bool isEligibleFunction(Function *F) {
554541
Benefit += 1;
555542
}
556543
}
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);
557559
if (Benefit < FunctionMergeThreshold)
558560
return false;
559561

@@ -723,12 +725,17 @@ bool SwiftMergeFunctions::tryMergeEquivalenceClass(FunctionEntry *FirstInClass)
723725
bool Changed = false;
724726
int Try = 0;
725727

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+
726733
// We need multiple tries if there are some functions in FInfos which differ
727734
// too much from the first function in FInfos. But we limit the number of
728735
// tries to a small number, because this is quadratic.
729736
while (FInfos.size() >= 2 && Try++ < 4) {
730737
ParamInfos Params;
731-
bool Merged = deriveParams(Params, FInfos);
738+
bool Merged = deriveParams(Params, FInfos, maxParams);
732739
if (Merged) {
733740
mergeWithParams(FInfos, Params);
734741
Changed = true;
@@ -767,7 +774,8 @@ removeFuncWithMostParams(FunctionInfos &FInfos) {
767774
/// Returns true on success, i.e. the functions in \p FInfos can be merged with
768775
/// the parameters returned in \p Params.
769776
bool SwiftMergeFunctions::deriveParams(ParamInfos &Params,
770-
FunctionInfos &FInfos) {
777+
FunctionInfos &FInfos,
778+
unsigned maxParams) {
771779
for (FunctionInfo &FI : FInfos)
772780
FI.init();
773781

@@ -796,7 +804,7 @@ bool SwiftMergeFunctions::deriveParams(ParamInfos &Params,
796804
if (constsDiffer(FInfos, OpIdx)) {
797805
// This instruction has operands which differ in at least some
798806
// functions. So we need to parameterize it.
799-
if (!tryMapToParameter(FInfos, OpIdx, Params)) {
807+
if (!tryMapToParameter(FInfos, OpIdx, Params, maxParams)) {
800808
// We ran out of parameters.
801809
return false;
802810
}
@@ -845,7 +853,8 @@ bool SwiftMergeFunctions::constsDiffer(const FunctionInfos &FInfos,
845853
/// Returns true if a parameter could be created or found without exceeding the
846854
/// maximum number of parameters.
847855
bool SwiftMergeFunctions::tryMapToParameter(FunctionInfos &FInfos,
848-
unsigned OpIdx, ParamInfos &Params) {
856+
unsigned OpIdx, ParamInfos &Params,
857+
unsigned maxParams) {
849858
ParamInfo *Matching = nullptr;
850859
// Try to find an existing parameter which exactly matches the differing
851860
// operands of the current instruction.
@@ -858,7 +867,7 @@ bool SwiftMergeFunctions::tryMapToParameter(FunctionInfos &FInfos,
858867
if (!Matching) {
859868
// We need a new parameter.
860869
// Check if we are within the limit.
861-
if (Params.size() >= maxAddedParams)
870+
if (Params.size() >= maxParams)
862871
return false;
863872

864873
Params.resize(Params.size() + 1);

0 commit comments

Comments
 (0)