1414// ===----------------------------------------------------------------------===//
1515
1616#include " llvm/CGData/StableFunctionMap.h"
17+ #include " llvm/ADT/SmallSet.h"
1718#include " llvm/Support/CommandLine.h"
1819#include " llvm/Support/Debug.h"
1920
@@ -35,21 +36,30 @@ static cl::opt<unsigned> GlobalMergingMaxParams(
3536 cl::desc (
3637 " The maximum number of parameters allowed when merging functions." ),
3738 cl::init(std::numeric_limits<unsigned >::max()), cl::Hidden);
38- static cl::opt<unsigned > GlobalMergingParamOverhead (
39+ static cl::opt<bool > GlobalMergingSkipNoParams (
40+ " global-merging-skip-no-params" ,
41+ cl::desc (" Skip merging functions with no parameters." ), cl::init(true ),
42+ cl::Hidden);
43+ static cl::opt<double > GlobalMergingInstOverhead (
44+ " global-merging-inst-overhead" ,
45+ cl::desc (" The overhead cost associated with each instruction when lowering "
46+ " to machine instruction." ),
47+ cl::init(1.2 ), cl::Hidden);
48+ static cl::opt<double > GlobalMergingParamOverhead (
3949 " global-merging-param-overhead" ,
4050 cl::desc (" The overhead cost associated with each parameter when merging "
4151 " functions." ),
42- cl::init(2 ), cl::Hidden);
43- static cl::opt<unsigned >
52+ cl::init(2.0 ), cl::Hidden);
53+ static cl::opt<double >
4454 GlobalMergingCallOverhead (" global-merging-call-overhead" ,
4555 cl::desc (" The overhead cost associated with each "
4656 " function call when merging functions." ),
47- cl::init(1 ), cl::Hidden);
48- static cl::opt<unsigned > GlobalMergingExtraThreshold (
57+ cl::init(1.0 ), cl::Hidden);
58+ static cl::opt<double > GlobalMergingExtraThreshold (
4959 " global-merging-extra-threshold" ,
5060 cl::desc (" An additional cost threshold that must be exceeded for merging "
5161 " to be considered beneficial." ),
52- cl::init(0 ), cl::Hidden);
62+ cl::init(0.0 ), cl::Hidden);
5363
5464unsigned StableFunctionMap::getIdOrCreateForName (StringRef Name) {
5565 auto It = NameToId.find (Name);
@@ -160,21 +170,32 @@ static bool isProfitable(
160170 if (InstCount < GlobalMergingMinInstrs)
161171 return false ;
162172
163- unsigned ParamCount = SFS[0 ]->IndexOperandHashMap ->size ();
164- if (ParamCount > GlobalMergingMaxParams)
165- return false ;
166-
167- unsigned Benefit = InstCount * (StableFunctionCount - 1 );
168- unsigned Cost =
169- (GlobalMergingParamOverhead * ParamCount + GlobalMergingCallOverhead) *
170- StableFunctionCount +
171- GlobalMergingExtraThreshold;
173+ double Cost = 0.0 ;
174+ SmallSet<stable_hash, 8 > UniqueHashVals;
175+ for (auto &SF : SFS) {
176+ UniqueHashVals.clear ();
177+ for (auto &[IndexPair, Hash] : *SF->IndexOperandHashMap )
178+ UniqueHashVals.insert (Hash);
179+ unsigned ParamCount = UniqueHashVals.size ();
180+ if (ParamCount > GlobalMergingMaxParams)
181+ return false ;
182+ // Theoretically, if ParamCount is 0, it results in identical code folding
183+ // (ICF), which we can skip merging here since the linker already handles
184+ // ICF. This pass would otherwise introduce unnecessary thunks that are
185+ // merely direct jumps. However, enabling this could be beneficial depending
186+ // on downstream passes, so we provide an option for it.
187+ if (GlobalMergingSkipNoParams && ParamCount == 0 )
188+ return false ;
189+ Cost += ParamCount * GlobalMergingParamOverhead + GlobalMergingCallOverhead;
190+ }
191+ Cost += GlobalMergingExtraThreshold;
172192
193+ double Benefit =
194+ InstCount * (StableFunctionCount - 1 ) * GlobalMergingInstOverhead;
173195 bool Result = Benefit > Cost;
174196 LLVM_DEBUG (dbgs () << " isProfitable: Hash = " << SFS[0 ]->Hash << " , "
175197 << " StableFunctionCount = " << StableFunctionCount
176198 << " , InstCount = " << InstCount
177- << " , ParamCount = " << ParamCount
178199 << " , Benefit = " << Benefit << " , Cost = " << Cost
179200 << " , Result = " << (Result ? " true" : " false" ) << " \n " );
180201 return Result;
0 commit comments