@@ -77,6 +77,7 @@ typedef struct lprofFilename {
7777 char Hostname [COMPILER_RT_MAX_HOSTLEN ];
7878 unsigned NumPids ;
7979 unsigned NumHosts ;
80+ unsigned NumBinaryIds ;
8081 /* When in-process merging is enabled, this parameter specifies
8182 * the total number of profile data files shared by all the processes
8283 * spawned from the same binary. By default the value is 1. If merging
@@ -88,8 +89,8 @@ typedef struct lprofFilename {
8889 ProfileNameSpecifier PNS ;
8990} lprofFilename ;
9091
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 };
9394
9495static int ProfileMergeRequested = 0 ;
9596static int getProfileFileSizeForMerging (FILE * ProfileFile ,
@@ -790,7 +791,7 @@ static int checkBounds(int Idx, int Strlen) {
790791 * lprofcurFilename structure. */
791792static int parseFilenamePattern (const char * FilenamePat ,
792793 unsigned CopyFilenamePat ) {
793- int NumPids = 0 , NumHosts = 0 , I ;
794+ int NumPids = 0 , NumHosts = 0 , NumBinaryIds = 0 , I ;
794795 char * PidChars = & lprofCurFilename .PidChars [0 ];
795796 char * Hostname = & lprofCurFilename .Hostname [0 ];
796797 int MergingEnabled = 0 ;
@@ -855,6 +856,15 @@ static int parseFilenamePattern(const char *FilenamePat,
855856 FilenamePat );
856857 return -1 ;
857858 }
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+ }
858868 } else if (FilenamePat [I ] == 'c' ) {
859869 if (__llvm_profile_is_continuous_mode_enabled ()) {
860870 PROF_WARN ("%%c specifier can only be specified once in %s.\n" ,
@@ -887,6 +897,7 @@ static int parseFilenamePattern(const char *FilenamePat,
887897
888898 lprofCurFilename .NumPids = NumPids ;
889899 lprofCurFilename .NumHosts = NumHosts ;
900+ lprofCurFilename .NumBinaryIds = NumBinaryIds ;
890901 return 0 ;
891902}
892903
@@ -934,24 +945,53 @@ static void parseAndSetFilename(const char *FilenamePat,
934945 * filename with PID and hostname substitutions. */
935946/* The length to hold uint64_t followed by 3 digits pool id including '_' */
936947#define SIGLEN 24
948+ /* The length to hold 160-bit hash in hexadecimal form */
949+ #define BINARY_ID_LEN 40
937950static int getCurFilenameLength (void ) {
938951 int Len ;
939952 if (!lprofCurFilename .FilenamePat || !lprofCurFilename .FilenamePat [0 ])
940953 return 0 ;
941954
942955 if (!(lprofCurFilename .NumPids || lprofCurFilename .NumHosts ||
943- lprofCurFilename .TmpDir || lprofCurFilename .MergePoolSize ))
956+ lprofCurFilename .NumBinaryIds || lprofCurFilename .TmpDir ||
957+ lprofCurFilename .MergePoolSize ))
944958 return strlen (lprofCurFilename .FilenamePat );
945959
946960 Len = strlen (lprofCurFilename .FilenamePat ) +
947961 lprofCurFilename .NumPids * (strlen (lprofCurFilename .PidChars ) - 2 ) +
948962 lprofCurFilename .NumHosts * (strlen (lprofCurFilename .Hostname ) - 2 ) +
963+ lprofCurFilename .NumBinaryIds * BINARY_ID_LEN +
949964 (lprofCurFilename .TmpDir ? (strlen (lprofCurFilename .TmpDir ) - 1 ) : 0 );
950965 if (lprofCurFilename .MergePoolSize )
951966 Len += SIGLEN ;
952967 return Len ;
953968}
954969
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+
955995/* Return the pointer to the current profile file name (after substituting
956996 * PIDs and Hostnames in filename pattern. \p FilenameBuf is the buffer
957997 * to store the resulting filename. If no substitution is needed, the
@@ -965,7 +1005,8 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
9651005 return 0 ;
9661006
9671007 if (!(lprofCurFilename .NumPids || lprofCurFilename .NumHosts ||
968- lprofCurFilename .TmpDir || lprofCurFilename .MergePoolSize ||
1008+ lprofCurFilename .NumBinaryIds || lprofCurFilename .TmpDir ||
1009+ lprofCurFilename .MergePoolSize ||
9691010 __llvm_profile_is_continuous_mode_enabled ())) {
9701011 if (!ForceUseBuf )
9711012 return lprofCurFilename .FilenamePat ;
@@ -992,6 +1033,12 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
9921033 memcpy (FilenameBuf + J , lprofCurFilename .TmpDir , TmpDirLength );
9931034 FilenameBuf [J + TmpDirLength ] = DIR_SEPARATOR ;
9941035 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 ;
9951042 } else {
9961043 if (!getMergePoolSize (FilenamePat , & I ))
9971044 continue ;
0 commit comments