diff --git a/lib/Transforms/Scalar/SampleProfile.cpp b/lib/Transforms/Scalar/SampleProfile.cpp index 221aa0a1861..20d6daab24b 100644 --- a/lib/Transforms/Scalar/SampleProfile.cpp +++ b/lib/Transforms/Scalar/SampleProfile.cpp @@ -251,7 +251,7 @@ public: return Profiles[F.getName()]; } - /// \brief Report a parse error message and stop compilation. + /// \brief Report a parse error message. void reportParseError(int64_t LineNumber, Twine Msg) const { DiagnosticInfoSampleProfile Diag(Filename.data(), LineNumber, Msg); M.getContext().diagnose(Diag); @@ -462,15 +462,21 @@ bool SampleModuleProfile::loadText() { // Read the profile of each function. Since each function may be // mentioned more than once, and we are collecting flat profiles, // accumulate samples as we parse them. - Regex HeadRE("^([^:]+):([0-9]+):([0-9]+)$"); + Regex HeadRE("^([^0-9].*):([0-9]+):([0-9]+)$"); Regex LineSample("^([0-9]+)\\.?([0-9]+)?: ([0-9]+)(.*)$"); while (!LineIt.is_at_eof()) { - // Read the header of each function. The function header should - // have this format: + // Read the header of each function. // - // function_name:total_samples:total_head_samples + // Note that for function identifiers we are actually expecting + // mangled names, but we may not always get them. This happens when + // the compiler decides not to emit the function (e.g., it was inlined + // and removed). In this case, the binary will not have the linkage + // name for the function, so the profiler will emit the function's + // unmangled name, which may contain characters like ':' and '>' in its + // name (member functions, templates, etc). // - // See above for an explanation of each field. + // The only requirement we place on the identifier, then, is that it + // should not begin with a number. SmallVector Matches; if (!HeadRE.match(*LineIt, &Matches)) { reportParseError(LineIt.line_number(), diff --git a/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof b/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof index 763956f0688..abcb0ba3841 100644 --- a/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof +++ b/test/Transforms/SampleProfile/Inputs/bad_fn_header.prof @@ -1,3 +1,3 @@ -empty:100:BAD +3empty:100:BAD 0: 0 1: 100 diff --git a/test/Transforms/SampleProfile/Inputs/bad_mangle.prof b/test/Transforms/SampleProfile/Inputs/bad_mangle.prof new file mode 100644 index 00000000000..50fe86119b7 --- /dev/null +++ b/test/Transforms/SampleProfile/Inputs/bad_mangle.prof @@ -0,0 +1,3 @@ +double convert(float):2909472:181842 +0: 181842 +1: 181842 diff --git a/test/Transforms/SampleProfile/syntax.ll b/test/Transforms/SampleProfile/syntax.ll index e08234e1626..53c65f44239 100644 --- a/test/Transforms/SampleProfile/syntax.ll +++ b/test/Transforms/SampleProfile/syntax.ll @@ -5,6 +5,7 @@ ; RUN: not opt < %s -sample-profile -sample-profile-file=%S/Inputs/bad_line_values.prof 2>&1 | FileCheck -check-prefix=BAD-LINE-VALUES %s ; RUN: not opt < %s -sample-profile -sample-profile-file=%S/Inputs/bad_discriminator_value.prof 2>&1 | FileCheck -check-prefix=BAD-DISCRIMINATOR-VALUE %s ; RUN: not opt < %s -sample-profile -sample-profile-file=%S/Inputs/bad_samples.prof 2>&1 | FileCheck -check-prefix=BAD-SAMPLES %s +; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/bad_mangle.prof 2>&1 >/dev/null define void @empty() { entry: @@ -12,7 +13,7 @@ entry: } ; NO-DEBUG: error: No debug information found in function empty ; MISSING-FILE: error: missing.prof: -; BAD-FN-HEADER: error: {{.*}}bad_fn_header.prof:1: Expected 'mangled_name:NUM:NUM', found empty:100:BAD +; BAD-FN-HEADER: error: {{.*}}bad_fn_header.prof:1: Expected 'mangled_name:NUM:NUM', found 3empty:100:BAD ; BAD-SAMPLE-LINE: error: {{.*}}bad_sample_line.prof:3: Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found 1: BAD ; BAD-LINE-VALUES: error: {{.*}}bad_line_values.prof:2: Expected 'mangled_name:NUM:NUM', found -1: 10 ; BAD-DISCRIMINATOR-VALUE: error: {{.*}}bad_discriminator_value.prof:2: Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found 1.-3: 10