Revert "[ThinLTO] Emit individual index files for distributed backends"
MemorySanitizer: use-of-uninitialized-value in lib/Bitcode/Writer/BitcodeWriter.cpp:364:70 http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/12544/steps/check-llvm%20msan/logs/stdio This reverts commit 0c4a898ea550699d1b2f4fe3767251c8f9a48d52. llvm-svn: 268660
This commit is contained in:
@@ -263,10 +263,6 @@ class IndexBitcodeWriter : public BitcodeWriter {
|
||||
/// The combined index to write to bitcode.
|
||||
const ModuleSummaryIndex &Index;
|
||||
|
||||
/// When writing a subset of the index for distributed backends, client
|
||||
/// provides a map of modules to the corresponding GUIDs/summaries to write.
|
||||
std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex;
|
||||
|
||||
/// Map that holds the correspondence between the GUID used in the combined
|
||||
/// index and a value id generated by this class to use in references.
|
||||
std::map<GlobalValue::GUID, unsigned> GUIDToValueIdMap;
|
||||
@@ -276,142 +272,18 @@ class IndexBitcodeWriter : public BitcodeWriter {
|
||||
|
||||
public:
|
||||
/// Constructs a IndexBitcodeWriter object for the given combined index,
|
||||
/// writing to the provided \p Buffer. When writing a subset of the index
|
||||
/// for a distributed backend, provide a \p ModuleToSummariesForIndex map.
|
||||
/// writing to the provided \p Buffer.
|
||||
IndexBitcodeWriter(SmallVectorImpl<char> &Buffer,
|
||||
const ModuleSummaryIndex &Index,
|
||||
std::map<std::string, GVSummaryMapTy>
|
||||
*ModuleToSummariesForIndex = nullptr)
|
||||
: BitcodeWriter(Buffer), Index(Index),
|
||||
ModuleToSummariesForIndex(ModuleToSummariesForIndex) {
|
||||
// Assign unique value ids to all summaries to be written, for use
|
||||
const ModuleSummaryIndex &Index)
|
||||
: BitcodeWriter(Buffer), Index(Index) {
|
||||
// Assign unique value ids to all functions in the index for use
|
||||
// in writing out the call graph edges. Save the mapping from GUID
|
||||
// to the new global value id to use when writing those edges, which
|
||||
// are currently saved in the index in terms of GUID.
|
||||
for (const auto &I : *this)
|
||||
GUIDToValueIdMap[I.first] = ++GlobalValueId;
|
||||
for (auto &II : Index)
|
||||
GUIDToValueIdMap[II.first] = ++GlobalValueId;
|
||||
}
|
||||
|
||||
/// The below iterator returns the GUID and associated summary.
|
||||
typedef std::pair<GlobalValue::GUID, GlobalValueSummary *> GVInfo;
|
||||
|
||||
/// Iterator over the value GUID and summaries to be written to bitcode,
|
||||
/// hides the details of whether they are being pulled from the entire
|
||||
/// index or just those in a provided ModuleToSummariesForIndex map.
|
||||
class iterator
|
||||
: public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
|
||||
GVInfo> {
|
||||
/// Enables access to parent class.
|
||||
const IndexBitcodeWriter &Writer;
|
||||
|
||||
// Iterators used when writing only those summaries in a provided
|
||||
// ModuleToSummariesForIndex map:
|
||||
|
||||
/// Points to the last element in outer ModuleToSummariesForIndex map.
|
||||
std::map<std::string, GVSummaryMapTy>::iterator ModuleSummariesBack;
|
||||
/// Iterator on outer ModuleToSummariesForIndex map.
|
||||
std::map<std::string, GVSummaryMapTy>::iterator ModuleSummariesIter;
|
||||
/// Iterator on an inner global variable summary map.
|
||||
GVSummaryMapTy::iterator ModuleGVSummariesIter;
|
||||
|
||||
// Iterators used when writing all summaries in the index:
|
||||
|
||||
/// Points to the last element in the Index outer GlobalValueMap.
|
||||
const_gvsummary_iterator IndexSummariesBack;
|
||||
/// Iterator on outer GlobalValueMap.
|
||||
const_gvsummary_iterator IndexSummariesIter;
|
||||
/// Iterator on an inner GlobalValueSummaryList.
|
||||
GlobalValueSummaryList::const_iterator IndexGVSummariesIter;
|
||||
|
||||
public:
|
||||
/// Construct iterator from parent \p Writer and indicate if we are
|
||||
/// constructing the end iterator.
|
||||
iterator(const IndexBitcodeWriter &Writer, bool IsAtEnd) : Writer(Writer) {
|
||||
// Set up the appropriate set of iterators given whether we are writing
|
||||
// the full index or just a subset.
|
||||
// Can't setup the Back or inner iterators if the corresponding map
|
||||
// is empty. This will be handled specially in operator== as well.
|
||||
if (Writer.ModuleToSummariesForIndex &&
|
||||
!Writer.ModuleToSummariesForIndex->empty()) {
|
||||
ModuleSummariesBack =
|
||||
std::prev(Writer.ModuleToSummariesForIndex->end());
|
||||
ModuleSummariesIter = Writer.ModuleToSummariesForIndex->begin();
|
||||
ModuleGVSummariesIter = !IsAtEnd ? ModuleSummariesIter->second.begin()
|
||||
: ModuleSummariesBack->second.end();
|
||||
} else if (!Writer.ModuleToSummariesForIndex &&
|
||||
Writer.Index.begin() != Writer.Index.end()) {
|
||||
IndexSummariesBack = std::prev(Writer.Index.end());
|
||||
IndexSummariesIter = Writer.Index.begin();
|
||||
IndexGVSummariesIter = !IsAtEnd ? IndexSummariesIter->second.begin()
|
||||
: IndexSummariesBack->second.end();
|
||||
}
|
||||
}
|
||||
|
||||
/// Increment the appropriate set of iterators.
|
||||
iterator &operator++() {
|
||||
// First the inner iterator is incremented, then if it is at the end
|
||||
// and there are more outer iterations to go, the inner is reset to
|
||||
// the start of the next inner list.
|
||||
if (Writer.ModuleToSummariesForIndex) {
|
||||
++ModuleGVSummariesIter;
|
||||
if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
|
||||
ModuleSummariesIter != ModuleSummariesBack) {
|
||||
++ModuleSummariesIter;
|
||||
ModuleGVSummariesIter = ModuleSummariesIter->second.begin();
|
||||
}
|
||||
} else {
|
||||
++IndexGVSummariesIter;
|
||||
if (IndexGVSummariesIter == IndexSummariesIter->second.end() &&
|
||||
IndexSummariesIter != IndexSummariesBack) {
|
||||
++IndexSummariesIter;
|
||||
IndexGVSummariesIter = IndexSummariesIter->second.begin();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Access the <GUID,GlobalValueSummary*> pair corresponding to the current
|
||||
/// outer and inner iterator positions.
|
||||
GVInfo operator*() {
|
||||
if (Writer.ModuleToSummariesForIndex)
|
||||
return std::make_pair(ModuleGVSummariesIter->first,
|
||||
ModuleGVSummariesIter->second);
|
||||
return std::make_pair(IndexSummariesIter->first,
|
||||
IndexGVSummariesIter->get());
|
||||
}
|
||||
|
||||
/// Checks if the iterators are equal, with special handling for empty
|
||||
/// indexes.
|
||||
bool operator==(const iterator &RHS) const {
|
||||
if (Writer.ModuleToSummariesForIndex) {
|
||||
// First ensure that both are writing the same subset.
|
||||
if (Writer.ModuleToSummariesForIndex !=
|
||||
RHS.Writer.ModuleToSummariesForIndex)
|
||||
return false;
|
||||
// Already determined above that maps are the same, so if one is
|
||||
// empty, they both are.
|
||||
if (Writer.ModuleToSummariesForIndex->empty())
|
||||
return true;
|
||||
return ModuleGVSummariesIter == RHS.ModuleGVSummariesIter;
|
||||
}
|
||||
// First ensure RHS also writing the full index, and that both are
|
||||
// writing the same full index.
|
||||
if (RHS.Writer.ModuleToSummariesForIndex ||
|
||||
&Writer.Index != &RHS.Writer.Index)
|
||||
return false;
|
||||
// Already determined above that maps are the same, so if one is
|
||||
// empty, they both are.
|
||||
if (Writer.Index.begin() == Writer.Index.end())
|
||||
return true;
|
||||
return IndexGVSummariesIter == RHS.IndexGVSummariesIter;
|
||||
}
|
||||
};
|
||||
|
||||
/// Obtain the start iterator over the summaries to be written.
|
||||
iterator begin() { return iterator(*this, /*IsAtEnd=*/false); }
|
||||
/// Obtain the end iterator over the summaries to be written.
|
||||
iterator end() { return iterator(*this, /*IsAtEnd=*/true); }
|
||||
|
||||
private:
|
||||
/// Main entry point for writing a combined index to bitcode, invoked by
|
||||
/// BitcodeWriter::write() after it writes the header.
|
||||
@@ -422,14 +294,6 @@ private:
|
||||
void writeCombinedValueSymbolTable();
|
||||
void writeCombinedGlobalValueSummary();
|
||||
|
||||
/// Indicates whether the provided \p ModulePath should be written into
|
||||
/// the module string table, e.g. if full index written or if it is in
|
||||
/// the provided subset.
|
||||
bool doIncludeModule(StringRef ModulePath) {
|
||||
return !ModuleToSummariesForIndex ||
|
||||
ModuleToSummariesForIndex->count(ModulePath);
|
||||
}
|
||||
|
||||
bool hasValueId(GlobalValue::GUID ValGUID) {
|
||||
const auto &VMI = GUIDToValueIdMap.find(ValGUID);
|
||||
return VMI != GUIDToValueIdMap.end();
|
||||
@@ -3099,8 +2963,6 @@ void IndexBitcodeWriter::writeModStrings() {
|
||||
|
||||
SmallVector<unsigned, 64> Vals;
|
||||
for (const auto &MPSE : Index.modulePaths()) {
|
||||
if (!doIncludeModule(MPSE.getKey()))
|
||||
continue;
|
||||
StringEncoding Bits =
|
||||
getStringEncoding(MPSE.getKey().data(), MPSE.getKey().size());
|
||||
unsigned AbbrevToUse = Abbrev8Bit;
|
||||
@@ -3356,75 +3218,78 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
||||
NameVals.clear();
|
||||
};
|
||||
|
||||
for (const auto &I : *this) {
|
||||
GlobalValueSummary *S = I.second;
|
||||
assert(S);
|
||||
for (const auto &GSI : Index) {
|
||||
for (auto &SI : GSI.second) {
|
||||
GlobalValueSummary *S = SI.get();
|
||||
assert(S);
|
||||
|
||||
assert(hasValueId(I.first));
|
||||
unsigned ValueId = getValueId(I.first);
|
||||
SummaryToValueIdMap[S] = ValueId;
|
||||
assert(hasValueId(GSI.first));
|
||||
unsigned ValueId = getValueId(GSI.first);
|
||||
SummaryToValueIdMap[S] = ValueId;
|
||||
|
||||
if (auto *AS = dyn_cast<AliasSummary>(S)) {
|
||||
// Will process aliases as a post-pass because the reader wants all
|
||||
// global to be loaded first.
|
||||
Aliases.push_back(AS);
|
||||
continue;
|
||||
}
|
||||
if (auto *AS = dyn_cast<AliasSummary>(S)) {
|
||||
// Will process aliases as a post-pass because the reader wants all
|
||||
// global to be loaded first.
|
||||
Aliases.push_back(AS);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto *VS = dyn_cast<GlobalVarSummary>(S)) {
|
||||
if (auto *VS = dyn_cast<GlobalVarSummary>(S)) {
|
||||
NameVals.push_back(ValueId);
|
||||
NameVals.push_back(Index.getModuleId(VS->modulePath()));
|
||||
NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
|
||||
for (auto &RI : VS->refs()) {
|
||||
NameVals.push_back(getValueId(RI.getGUID()));
|
||||
}
|
||||
|
||||
// Emit the finished record.
|
||||
Stream.EmitRecord(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS, NameVals,
|
||||
FSModRefsAbbrev);
|
||||
NameVals.clear();
|
||||
MaybeEmitOriginalName(*S);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto *FS = cast<FunctionSummary>(S);
|
||||
NameVals.push_back(ValueId);
|
||||
NameVals.push_back(Index.getModuleId(VS->modulePath()));
|
||||
NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
|
||||
for (auto &RI : VS->refs()) {
|
||||
NameVals.push_back(Index.getModuleId(FS->modulePath()));
|
||||
NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
|
||||
NameVals.push_back(FS->instCount());
|
||||
NameVals.push_back(FS->refs().size());
|
||||
|
||||
for (auto &RI : FS->refs()) {
|
||||
NameVals.push_back(getValueId(RI.getGUID()));
|
||||
}
|
||||
|
||||
bool HasProfileData = false;
|
||||
for (auto &EI : FS->calls()) {
|
||||
HasProfileData |= EI.second.ProfileCount != 0;
|
||||
if (HasProfileData)
|
||||
break;
|
||||
}
|
||||
|
||||
for (auto &EI : FS->calls()) {
|
||||
// If this GUID doesn't have a value id, it doesn't have a function
|
||||
// summary and we don't need to record any calls to it.
|
||||
if (!hasValueId(EI.first.getGUID()))
|
||||
continue;
|
||||
NameVals.push_back(getValueId(EI.first.getGUID()));
|
||||
assert(EI.second.CallsiteCount > 0 && "Expected at least one callsite");
|
||||
NameVals.push_back(EI.second.CallsiteCount);
|
||||
if (HasProfileData)
|
||||
NameVals.push_back(EI.second.ProfileCount);
|
||||
}
|
||||
|
||||
unsigned FSAbbrev =
|
||||
(HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
|
||||
unsigned Code =
|
||||
(HasProfileData ? bitc::FS_COMBINED_PROFILE : bitc::FS_COMBINED);
|
||||
|
||||
// Emit the finished record.
|
||||
Stream.EmitRecord(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS, NameVals,
|
||||
FSModRefsAbbrev);
|
||||
Stream.EmitRecord(Code, NameVals, FSAbbrev);
|
||||
NameVals.clear();
|
||||
MaybeEmitOriginalName(*S);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto *FS = cast<FunctionSummary>(S);
|
||||
NameVals.push_back(ValueId);
|
||||
NameVals.push_back(Index.getModuleId(FS->modulePath()));
|
||||
NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
|
||||
NameVals.push_back(FS->instCount());
|
||||
NameVals.push_back(FS->refs().size());
|
||||
|
||||
for (auto &RI : FS->refs()) {
|
||||
NameVals.push_back(getValueId(RI.getGUID()));
|
||||
}
|
||||
|
||||
bool HasProfileData = false;
|
||||
for (auto &EI : FS->calls()) {
|
||||
HasProfileData |= EI.second.ProfileCount != 0;
|
||||
if (HasProfileData)
|
||||
break;
|
||||
}
|
||||
|
||||
for (auto &EI : FS->calls()) {
|
||||
// If this GUID doesn't have a value id, it doesn't have a function
|
||||
// summary and we don't need to record any calls to it.
|
||||
if (!hasValueId(EI.first.getGUID()))
|
||||
continue;
|
||||
NameVals.push_back(getValueId(EI.first.getGUID()));
|
||||
assert(EI.second.CallsiteCount > 0 && "Expected at least one callsite");
|
||||
NameVals.push_back(EI.second.CallsiteCount);
|
||||
if (HasProfileData)
|
||||
NameVals.push_back(EI.second.ProfileCount);
|
||||
}
|
||||
|
||||
unsigned FSAbbrev = (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
|
||||
unsigned Code =
|
||||
(HasProfileData ? bitc::FS_COMBINED_PROFILE : bitc::FS_COMBINED);
|
||||
|
||||
// Emit the finished record.
|
||||
Stream.EmitRecord(Code, NameVals, FSAbbrev);
|
||||
NameVals.clear();
|
||||
MaybeEmitOriginalName(*S);
|
||||
}
|
||||
|
||||
for (auto *AS : Aliases) {
|
||||
@@ -3698,15 +3563,12 @@ void IndexBitcodeWriter::writeIndex() {
|
||||
|
||||
// Write the specified module summary index to the given raw output stream,
|
||||
// where it will be written in a new bitcode block. This is used when
|
||||
// writing the combined index file for ThinLTO. When writing a subset of the
|
||||
// index for a distributed backend, provide a \p ModuleToSummariesForIndex map.
|
||||
void llvm::WriteIndexToFile(
|
||||
const ModuleSummaryIndex &Index, raw_ostream &Out,
|
||||
std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex) {
|
||||
// writing the combined index file for ThinLTO.
|
||||
void llvm::WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out) {
|
||||
SmallVector<char, 0> Buffer;
|
||||
Buffer.reserve(256 * 1024);
|
||||
|
||||
IndexBitcodeWriter IndexWriter(Buffer, Index, ModuleToSummariesForIndex);
|
||||
IndexBitcodeWriter IndexWriter(Buffer, Index);
|
||||
IndexWriter.write();
|
||||
|
||||
Out.write((char *)&Buffer.front(), Buffer.size());
|
||||
|
||||
Reference in New Issue
Block a user