@@ -77,6 +77,7 @@ typedef struct lprofFilename {
77
77
char Hostname [COMPILER_RT_MAX_HOSTLEN ];
78
78
unsigned NumPids ;
79
79
unsigned NumHosts ;
80
+ unsigned NumBinaryIds ;
80
81
/* When in-process merging is enabled, this parameter specifies
81
82
* the total number of profile data files shared by all the processes
82
83
* spawned from the same binary. By default the value is 1. If merging
@@ -88,8 +89,8 @@ typedef struct lprofFilename {
88
89
ProfileNameSpecifier PNS ;
89
90
} lprofFilename ;
90
91
91
- static lprofFilename lprofCurFilename = {0 , 0 , 0 , {0 }, NULL ,
92
- { 0 } , 0 , 0 , 0 , PNS_unknown };
92
+ static lprofFilename lprofCurFilename = {0 , 0 , 0 , {0 }, NULL , { 0 } ,
93
+ 0 , 0 , 0 , 0 , PNS_unknown };
93
94
94
95
static int ProfileMergeRequested = 0 ;
95
96
static int getProfileFileSizeForMerging (FILE * ProfileFile ,
@@ -790,7 +791,7 @@ static int checkBounds(int Idx, int Strlen) {
790
791
* lprofcurFilename structure. */
791
792
static int parseFilenamePattern (const char * FilenamePat ,
792
793
unsigned CopyFilenamePat ) {
793
- int NumPids = 0 , NumHosts = 0 , I ;
794
+ int NumPids = 0 , NumHosts = 0 , NumBinaryIds = 0 , I ;
794
795
char * PidChars = & lprofCurFilename .PidChars [0 ];
795
796
char * Hostname = & lprofCurFilename .Hostname [0 ];
796
797
int MergingEnabled = 0 ;
@@ -855,6 +856,15 @@ static int parseFilenamePattern(const char *FilenamePat,
855
856
FilenamePat );
856
857
return -1 ;
857
858
}
859
+ } else if (FilenamePat [I ] == 'b' ) {
860
+ if (!NumBinaryIds ++ ) {
861
+ if (__llvm_write_binary_ids (NULL ) <= 0 ) {
862
+ PROF_WARN ("Unable to get binary ID for filename pattern %s. Using "
863
+ "the default name." ,
864
+ FilenamePat );
865
+ return -1 ;
866
+ }
867
+ }
858
868
} else if (FilenamePat [I ] == 'c' ) {
859
869
if (__llvm_profile_is_continuous_mode_enabled ()) {
860
870
PROF_WARN ("%%c specifier can only be specified once in %s.\n" ,
@@ -887,6 +897,7 @@ static int parseFilenamePattern(const char *FilenamePat,
887
897
888
898
lprofCurFilename .NumPids = NumPids ;
889
899
lprofCurFilename .NumHosts = NumHosts ;
900
+ lprofCurFilename .NumBinaryIds = NumBinaryIds ;
890
901
return 0 ;
891
902
}
892
903
@@ -934,24 +945,53 @@ static void parseAndSetFilename(const char *FilenamePat,
934
945
* filename with PID and hostname substitutions. */
935
946
/* The length to hold uint64_t followed by 3 digits pool id including '_' */
936
947
#define SIGLEN 24
948
+ /* The length to hold 160-bit hash in hexadecimal form */
949
+ #define BINARY_ID_LEN 40
937
950
static int getCurFilenameLength (void ) {
938
951
int Len ;
939
952
if (!lprofCurFilename .FilenamePat || !lprofCurFilename .FilenamePat [0 ])
940
953
return 0 ;
941
954
942
955
if (!(lprofCurFilename .NumPids || lprofCurFilename .NumHosts ||
943
- lprofCurFilename .TmpDir || lprofCurFilename .MergePoolSize ))
956
+ lprofCurFilename .NumBinaryIds || lprofCurFilename .TmpDir ||
957
+ lprofCurFilename .MergePoolSize ))
944
958
return strlen (lprofCurFilename .FilenamePat );
945
959
946
960
Len = strlen (lprofCurFilename .FilenamePat ) +
947
961
lprofCurFilename .NumPids * (strlen (lprofCurFilename .PidChars ) - 2 ) +
948
962
lprofCurFilename .NumHosts * (strlen (lprofCurFilename .Hostname ) - 2 ) +
963
+ lprofCurFilename .NumBinaryIds * BINARY_ID_LEN +
949
964
(lprofCurFilename .TmpDir ? (strlen (lprofCurFilename .TmpDir ) - 1 ) : 0 );
950
965
if (lprofCurFilename .MergePoolSize )
951
966
Len += SIGLEN ;
952
967
return Len ;
953
968
}
954
969
970
+ typedef struct lprofBinaryIdsBuffer {
971
+ char String [BINARY_ID_LEN + 1 ];
972
+ int Length ;
973
+ } lprofBinaryIdsBuffer ;
974
+
975
+ /* Reads binary ID length and then its data, writes it into lprofBinaryIdsBuffer
976
+ * in hexadecimal form. */
977
+ static uint32_t binaryIdsStringWriter (ProfDataWriter * This ,
978
+ ProfDataIOVec * IOVecs ,
979
+ uint32_t NumIOVecs ) {
980
+ if (NumIOVecs < 2 || IOVecs [0 ].ElmSize != sizeof (uint64_t ))
981
+ return -1 ;
982
+ uint64_t BinaryIdLen = * (const uint64_t * )IOVecs [0 ].Data ;
983
+ if (IOVecs [1 ].ElmSize != sizeof (uint8_t ) || IOVecs [1 ].NumElm != BinaryIdLen )
984
+ return -1 ;
985
+ const uint8_t * BinaryIdData = (const uint8_t * )IOVecs [1 ].Data ;
986
+ lprofBinaryIdsBuffer * Data = (lprofBinaryIdsBuffer * )This -> WriterCtx ;
987
+ for (uint64_t I = 0 ; I < BinaryIdLen ; I ++ ) {
988
+ Data -> Length +=
989
+ snprintf (Data -> String + Data -> Length , BINARY_ID_LEN + 1 - Data -> Length ,
990
+ "%02hhx" , BinaryIdData [I ]);
991
+ }
992
+ return 0 ;
993
+ }
994
+
955
995
/* Return the pointer to the current profile file name (after substituting
956
996
* PIDs and Hostnames in filename pattern. \p FilenameBuf is the buffer
957
997
* to store the resulting filename. If no substitution is needed, the
@@ -965,7 +1005,8 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
965
1005
return 0 ;
966
1006
967
1007
if (!(lprofCurFilename .NumPids || lprofCurFilename .NumHosts ||
968
- lprofCurFilename .TmpDir || lprofCurFilename .MergePoolSize ||
1008
+ lprofCurFilename .NumBinaryIds || lprofCurFilename .TmpDir ||
1009
+ lprofCurFilename .MergePoolSize ||
969
1010
__llvm_profile_is_continuous_mode_enabled ())) {
970
1011
if (!ForceUseBuf )
971
1012
return lprofCurFilename .FilenamePat ;
@@ -992,6 +1033,12 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
992
1033
memcpy (FilenameBuf + J , lprofCurFilename .TmpDir , TmpDirLength );
993
1034
FilenameBuf [J + TmpDirLength ] = DIR_SEPARATOR ;
994
1035
J += TmpDirLength + 1 ;
1036
+ } else if (FilenamePat [I ] == 'b' ) {
1037
+ lprofBinaryIdsBuffer Data = {{0 }, 0 };
1038
+ ProfDataWriter Writer = {binaryIdsStringWriter , & Data };
1039
+ __llvm_write_binary_ids (& Writer );
1040
+ memcpy (FilenameBuf + J , Data .String , Data .Length );
1041
+ J += Data .Length ;
995
1042
} else {
996
1043
if (!getMergePoolSize (FilenamePat , & I ))
997
1044
continue ;
0 commit comments