14
14
// ===----------------------------------------------------------------------===//
15
15
16
16
#include " llvm/CGData/StableFunctionMap.h"
17
+ #include " llvm/ADT/SmallSet.h"
17
18
#include " llvm/Support/CommandLine.h"
18
19
#include " llvm/Support/Debug.h"
19
20
@@ -35,21 +36,30 @@ static cl::opt<unsigned> GlobalMergingMaxParams(
35
36
cl::desc (
36
37
" The maximum number of parameters allowed when merging functions." ),
37
38
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 (
39
49
" global-merging-param-overhead" ,
40
50
cl::desc (" The overhead cost associated with each parameter when merging "
41
51
" functions." ),
42
- cl::init(2 ), cl::Hidden);
43
- static cl::opt<unsigned >
52
+ cl::init(2.0 ), cl::Hidden);
53
+ static cl::opt<double >
44
54
GlobalMergingCallOverhead (" global-merging-call-overhead" ,
45
55
cl::desc (" The overhead cost associated with each "
46
56
" 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 (
49
59
" global-merging-extra-threshold" ,
50
60
cl::desc (" An additional cost threshold that must be exceeded for merging "
51
61
" to be considered beneficial." ),
52
- cl::init(0 ), cl::Hidden);
62
+ cl::init(0.0 ), cl::Hidden);
53
63
54
64
unsigned StableFunctionMap::getIdOrCreateForName (StringRef Name) {
55
65
auto It = NameToId.find (Name);
@@ -160,21 +170,32 @@ static bool isProfitable(
160
170
if (InstCount < GlobalMergingMinInstrs)
161
171
return false ;
162
172
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;
172
192
193
+ double Benefit =
194
+ InstCount * (StableFunctionCount - 1 ) * GlobalMergingInstOverhead;
173
195
bool Result = Benefit > Cost;
174
196
LLVM_DEBUG (dbgs () << " isProfitable: Hash = " << SFS[0 ]->Hash << " , "
175
197
<< " StableFunctionCount = " << StableFunctionCount
176
198
<< " , InstCount = " << InstCount
177
- << " , ParamCount = " << ParamCount
178
199
<< " , Benefit = " << Benefit << " , Cost = " << Cost
179
200
<< " , Result = " << (Result ? " true" : " false" ) << " \n " );
180
201
return Result;
0 commit comments