50
50
#include " llvm/Support/Casting.h"
51
51
#include " llvm/Support/Debug.h"
52
52
#include " llvm/Support/FileSystem.h"
53
+ #include " llvm/Support/Path.h"
53
54
#include " llvm/Support/Process.h"
54
55
#include " llvm/Support/SHA256.h"
55
56
#include " llvm/Support/raw_ostream.h"
@@ -68,15 +69,16 @@ using namespace llvm;
68
69
namespace {
69
70
70
71
static cl::opt<float > LargeKernelFactor (
71
- " amdgpu-module-splitting-large-kernel-threshold" , cl::init(2.0 ), cl::Hidden,
72
+ " amdgpu-module-splitting-large-kernel-threshold" , cl::init(2 .0f ),
73
+ cl::Hidden,
72
74
cl::desc(
73
75
" consider a kernel as large and needing special treatment when it "
74
76
" exceeds the average cost of a partition by this factor; e;g. 2.0 "
75
77
" means if the kernel and its dependencies is 2 times bigger than "
76
78
" an average partition; 0 disables large kernels handling entirely" ));
77
79
78
80
static cl::opt<float > LargeKernelOverlapForMerge (
79
- " amdgpu-module-splitting-large-kernel-merge-overlap" , cl::init(0.8 ),
81
+ " amdgpu-module-splitting-large-kernel-merge-overlap" , cl::init(0 .8f ),
80
82
cl::Hidden,
81
83
cl::desc(" defines how much overlap between two large kernel's dependencies "
82
84
" is needed to put them in the same partition" ));
@@ -112,7 +114,7 @@ static std::string getName(const Value &V) {
112
114
if (!*HideNames)
113
115
return V.getName ().str ();
114
116
return toHex (SHA256::hash (arrayRefFromStringRef (V.getName ())),
115
- /* LowerCase*/ true );
117
+ /* LowerCase= */ true );
116
118
}
117
119
118
120
// / Main logging helper.
@@ -168,18 +170,19 @@ class SplitModuleLogger {
168
170
169
171
// If a log directory is specified, create a new file with a unique name in
170
172
// that directory.
171
- SmallString<0 > FilePath;
172
173
int Fd;
173
- std::string LogFile = (LogDir + " /" + " Module-%%-%%-%%-%%-%%-%%-%%.txt" );
174
- if (auto Err = sys::fs::createUniqueFile (LogFile, Fd, FilePath)) {
175
- dbgs () << LogFile << " \n " ;
174
+ SmallString<0 > PathTemplate;
175
+ SmallString<0 > RealPath;
176
+ sys::path::append (PathTemplate, LogDir, " Module-%%-%%-%%-%%-%%-%%-%%.txt" );
177
+ if (auto Err =
178
+ sys::fs::createUniqueFile (PathTemplate.str (), Fd, RealPath)) {
176
179
std::string Msg =
177
180
" Failed to create log file at '" + LogDir + " ': " + Err.message ();
178
181
report_fatal_error (StringRef (Msg),
179
182
/* CrashDiag=*/ false );
180
183
}
181
184
182
- FileOS = std::make_unique<raw_fd_ostream>(Fd, /* shouldClose*/ true );
185
+ FileOS = std::make_unique<raw_fd_ostream>(Fd, /* shouldClose= */ true );
183
186
}
184
187
185
188
bool hasLogFile () const { return FileOS != nullptr ; }
@@ -304,15 +307,23 @@ static void addAllDependencies(SplitModuleLogger &SML, const CallGraph &CG,
304
307
SmallVector<const Function *> WorkList ({&Fn});
305
308
while (!WorkList.empty ()) {
306
309
const auto &CurFn = *WorkList.pop_back_val ();
310
+ assert (!CurFn.isDeclaration ());
307
311
308
312
// Scan for an indirect call. If such a call is found, we have to
309
313
// conservatively assume this can call all non-entrypoint functions in the
310
314
// module.
311
- for (const auto &BB : CurFn) {
312
- for (const auto &I : BB) {
313
- const auto *CB = dyn_cast<CallBase>(&I);
314
- if (!CB || !CB->isIndirectCall ())
315
- continue ;
315
+
316
+ for (auto &CGEntry : *CG[&CurFn]) {
317
+ auto *CGNode = CGEntry.second ;
318
+ auto *Callee = CGNode->getFunction ();
319
+ if (!Callee) {
320
+ // Functions have an edge towards CallsExternalNode if they're external
321
+ // declarations, or if they do an indirect call. As we only process
322
+ // definitions here, we know this means the function has an indirect
323
+ // call. We then have to conservatively assume this can call all
324
+ // non-entrypoint functions in the module.
325
+ if (CGNode != CG.getCallsExternalNode ())
326
+ continue ; // this is another function-less node we don't care about.
316
327
317
328
SML << " Indirect call detected in " << getName (CurFn)
318
329
<< " - treating all non-entrypoint functions as "
@@ -323,15 +334,8 @@ static void addAllDependencies(SplitModuleLogger &SML, const CallGraph &CG,
323
334
HadIndirectCall = true ;
324
335
return ;
325
336
}
326
- }
327
-
328
- for (auto &CGEntry : *CG[&CurFn]) {
329
- auto *Callee = CGEntry.second ->getFunction ();
330
- if (!Callee)
331
- continue ;
332
337
333
338
assert (!AMDGPU::isKernelCC (Callee));
334
-
335
339
if (Callee->isDeclaration ())
336
340
continue ;
337
341
@@ -399,7 +403,7 @@ static float calculateOverlap(const DenseSet<const Function *> &A,
399
403
++NumCommon;
400
404
}
401
405
402
- return float (NumCommon) / Total.size ();
406
+ return static_cast < float > (NumCommon) / Total.size ();
403
407
}
404
408
405
409
// / Performs all of the partitioning work on \p M.
0 commit comments