@@ -541,6 +541,17 @@ static FILE *getFileObject(const char *OutputName) {
541541 return fopen (OutputName , "ab" );
542542}
543543
544+ static void closeFileObject (FILE * OutputFile ) {
545+ if (OutputFile == getProfileFile ()) {
546+ fflush (OutputFile );
547+ if (doMerging () && !__llvm_profile_is_continuous_mode_enabled ()) {
548+ lprofUnlockFileHandle (OutputFile );
549+ }
550+ } else {
551+ fclose (OutputFile );
552+ }
553+ }
554+
544555/* Write profile data to file \c OutputName. */
545556static int writeFile (const char * OutputName ) {
546557 int RetVal ;
@@ -562,15 +573,7 @@ static int writeFile(const char *OutputName) {
562573 initFileWriter (& fileWriter , OutputFile );
563574 RetVal = lprofWriteData (& fileWriter , lprofGetVPDataReader (), MergeDone );
564575
565- if (OutputFile == getProfileFile ()) {
566- fflush (OutputFile );
567- if (doMerging () && !__llvm_profile_is_continuous_mode_enabled ()) {
568- lprofUnlockFileHandle (OutputFile );
569- }
570- } else {
571- fclose (OutputFile );
572- }
573-
576+ closeFileObject (OutputFile );
574577 return RetVal ;
575578}
576579
@@ -1359,4 +1362,107 @@ COMPILER_RT_VISIBILITY int __llvm_profile_set_file_object(FILE *File,
13591362 return 0 ;
13601363}
13611364
1365+ int __llvm_write_custom_profile (const char * Target ,
1366+ const __llvm_profile_data * DataBegin ,
1367+ const __llvm_profile_data * DataEnd ,
1368+ const char * CountersBegin ,
1369+ const char * CountersEnd , const char * NamesBegin ,
1370+ const char * NamesEnd ) {
1371+ int ReturnValue = 0 , FilenameLength , TargetLength ;
1372+ char * FilenameBuf , * TargetFilename ;
1373+ const char * Filename ;
1374+
1375+ /* Save old profile data */
1376+ FILE * oldFile = getProfileFile ();
1377+
1378+ // Temporarily suspend getting SIGKILL when the parent exits.
1379+ int PDeathSig = lprofSuspendSigKill ();
1380+
1381+ if (lprofProfileDumped () || __llvm_profile_is_continuous_mode_enabled ()) {
1382+ PROF_NOTE ("Profile data not written to file: %s.\n" , "already written" );
1383+ if (PDeathSig == 1 )
1384+ lprofRestoreSigKill ();
1385+ return 0 ;
1386+ }
1387+
1388+ /* Check if there is llvm/runtime version mismatch. */
1389+ if (GET_VERSION (__llvm_profile_get_version ()) != INSTR_PROF_RAW_VERSION ) {
1390+ PROF_ERR ("Runtime and instrumentation version mismatch : "
1391+ "expected %d, but get %d\n" ,
1392+ INSTR_PROF_RAW_VERSION ,
1393+ (int )GET_VERSION (__llvm_profile_get_version ()));
1394+ if (PDeathSig == 1 )
1395+ lprofRestoreSigKill ();
1396+ return -1 ;
1397+ }
1398+
1399+ /* Get current filename */
1400+ FilenameLength = getCurFilenameLength ();
1401+ FilenameBuf = (char * )COMPILER_RT_ALLOCA (FilenameLength + 1 );
1402+ Filename = getCurFilename (FilenameBuf , 0 );
1403+
1404+ /* Check the filename. */
1405+ if (!Filename ) {
1406+ PROF_ERR ("Failed to write file : %s\n" , "Filename not set" );
1407+ if (PDeathSig == 1 )
1408+ lprofRestoreSigKill ();
1409+ return -1 ;
1410+ }
1411+
1412+ /* Allocate new space for our target-specific PGO filename */
1413+ TargetLength = strlen (Target );
1414+ TargetFilename =
1415+ (char * )COMPILER_RT_ALLOCA (FilenameLength + TargetLength + 2 );
1416+
1417+ /* Find file basename and path sizes */
1418+ int32_t DirEnd = FilenameLength - 1 ;
1419+ while (DirEnd >= 0 && !IS_DIR_SEPARATOR (Filename [DirEnd ])) {
1420+ DirEnd -- ;
1421+ }
1422+ uint32_t DirSize = DirEnd + 1 , BaseSize = FilenameLength - DirSize ;
1423+
1424+ /* Prepend "TARGET." to current filename */
1425+ if (DirSize > 0 ) {
1426+ memcpy (TargetFilename , Filename , DirSize );
1427+ }
1428+ memcpy (TargetFilename + DirSize , Target , TargetLength );
1429+ TargetFilename [TargetLength + DirSize ] = '.' ;
1430+ memcpy (TargetFilename + DirSize + 1 + TargetLength , Filename + DirSize ,
1431+ BaseSize );
1432+ TargetFilename [FilenameLength + 1 + TargetLength ] = 0 ;
1433+
1434+ /* Open and truncate target-specific PGO file */
1435+ FILE * OutputFile = fopen (TargetFilename , "w" );
1436+ setProfileFile (OutputFile );
1437+
1438+ if (!OutputFile ) {
1439+ PROF_ERR ("Failed to open file : %s\n" , TargetFilename );
1440+ if (PDeathSig == 1 )
1441+ lprofRestoreSigKill ();
1442+ return -1 ;
1443+ }
1444+
1445+ FreeHook = & free ;
1446+ setupIOBuffer ();
1447+
1448+ /* Write custom data */
1449+ ProfDataWriter fileWriter ;
1450+ initFileWriter (& fileWriter , OutputFile );
1451+
1452+ /* Write custom data to the file */
1453+ ReturnValue = lprofWriteDataImpl (
1454+ & fileWriter , DataBegin , DataEnd , CountersBegin , CountersEnd , NULL , NULL ,
1455+ lprofGetVPDataReader (), NULL , NULL , NULL , NULL , NamesBegin , NamesEnd , 0 );
1456+ closeFileObject (OutputFile );
1457+
1458+ // Restore SIGKILL.
1459+ if (PDeathSig == 1 )
1460+ lprofRestoreSigKill ();
1461+
1462+ /* Restore old profiling file */
1463+ setProfileFile (oldFile );
1464+
1465+ return ReturnValue ;
1466+ }
1467+
13621468#endif
0 commit comments