+static sampleprof::SampleProfileFormat FormatMap[] = {
+ sampleprof::SPF_None, sampleprof::SPF_Text, sampleprof::SPF_Binary,
+ sampleprof::SPF_GCC};
+
+static void mergeSampleProfile(const WeightedFileVector &Inputs,
+ StringRef OutputFilename,
+ ProfileFormat OutputFormat) {
+ using namespace sampleprof;
+ auto WriterOrErr =
+ SampleProfileWriter::create(OutputFilename, FormatMap[OutputFormat]);
+ if (std::error_code EC = WriterOrErr.getError())
+ exitWithErrorCode(EC, OutputFilename);
+
+ auto Writer = std::move(WriterOrErr.get());
+ StringMap<FunctionSamples> ProfileMap;
+ SmallVector<std::unique_ptr<sampleprof::SampleProfileReader>, 5> Readers;
+ for (const auto &Input : Inputs) {
+ auto ReaderOrErr =
+ SampleProfileReader::create(Input.Filename, getGlobalContext());
+ if (std::error_code EC = ReaderOrErr.getError())
+ exitWithErrorCode(EC, Input.Filename);
+
+ // We need to keep the readers around until after all the files are
+ // read so that we do not lose the function names stored in each
+ // reader's memory. The function names are needed to write out the
+ // merged profile map.
+ Readers.push_back(std::move(ReaderOrErr.get()));
+ const auto Reader = Readers.back().get();
+ if (std::error_code EC = Reader->read())
+ exitWithErrorCode(EC, Input.Filename);
+
+ StringMap<FunctionSamples> &Profiles = Reader->getProfiles();
+ for (StringMap<FunctionSamples>::iterator I = Profiles.begin(),
+ E = Profiles.end();
+ I != E; ++I) {
+ StringRef FName = I->first();
+ FunctionSamples &Samples = I->second;
+ sampleprof_error Result = ProfileMap[FName].merge(Samples, Input.Weight);
+ if (Result != sampleprof_error::success) {
+ std::error_code EC = make_error_code(Result);
+ handleMergeWriterError(EC, Input.Filename, FName);
+ }
+ }