Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions gcov.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ void gcov_write_string(const char *string) {

if (string) {
length = strlen(string);
if (absl::GetFlag(FLAGS_gcov_version) == 2) {
if (absl::GetFlag(FLAGS_gcov_version) >= 2) {
// Length includes the terminating 0 and is saved in bytes.
alloc = length + 1;
char *byte_buffer = gcov_write_bytes(4 + alloc);
Expand Down Expand Up @@ -229,7 +229,7 @@ const char * gcov_read_string(void) {
return 0;
}

if (absl::GetFlag(FLAGS_gcov_version) == 2) {
if (absl::GetFlag(FLAGS_gcov_version) >= 2) {
return gcov_read_bytes (length);
}
else {
Expand Down
20 changes: 18 additions & 2 deletions legacy_addr2line.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ void Google3Addr2line::GetInlineStack(uint64_t address,
const SubprogramInfo *subprog =
inline_stack_handler_->GetSubprogramForAddress(address);

const char *comp_dir = NULL;
const char *function_name = NULL;
uint32_t start_line = 0;
if (subprog != NULL) {
Expand All @@ -214,10 +215,17 @@ void Google3Addr2line::GetInlineStack(uint64_t address,
inline_stack_handler_->GetAbstractOrigin(subprog)->callsite_line();
if (start_line == 0)
start_line = declaration->callsite_line();
comp_dir = subprog->comp_directory();
if (comp_dir == 0)
comp_dir = inline_stack_handler_->GetAbstractOrigin(subprog)->comp_directory();
}

std::filesystem::path dir_name = LI.file.first;
if (!dir_name.is_absolute() && comp_dir != nullptr)
dir_name = comp_dir / dir_name;

stack->push_back(SourceInfo(function_name,
LI.file.first,
dir_name,
LI.file.second,
start_line,
LI.line,
Expand All @@ -234,9 +242,17 @@ void Google3Addr2line::GetInlineStack(uint64_t address,
if (start_line == 0)
start_line = subprog->callsite_line();

dir_name = subprog->callsite_directory();
if (!dir_name.is_absolute()) {
if (subprog->comp_directory())
dir_name = subprog->comp_directory() / dir_name;
else if (const char *abstract_comp = inline_stack_handler_->GetAbstractOrigin(subprog)->comp_directory())
dir_name = abstract_comp / dir_name;
}

stack->push_back(SourceInfo(
canonical_parent->name().c_str(),
subprog->callsite_directory(),
dir_name,
subprog->callsite_filename(),
start_line,
subprog->callsite_line(),
Expand Down
3 changes: 2 additions & 1 deletion llvm_profile_writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ bool LLVMProfileWriter::WriteToFile(const std::string &output_filename) {
// Populate the symbol table. This table contains all the symbols
// for functions found in the binary.
StringIndexMap name_table;
StringTableUpdater::Update(*symbol_map_, &name_table);
FileIndexMap file_table;
StringTableUpdater::Update(*symbol_map_, &name_table, &file_table);

// If the underlying llvm profile writer has not been created yet,
// create it here.
Expand Down
6 changes: 4 additions & 2 deletions llvm_profile_writer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ TEST(LlvmProfileWriterTest, ReadProfile) {
ASSERT_TRUE(creator.ComputeProfile(&symbol_map, true));

StringIndexMap name_table;
StringTableUpdater::Update(symbol_map, &name_table);
FileIndexMap file_table;
StringTableUpdater::Update(symbol_map, &name_table, &file_table);

LLVMProfileBuilder builder(name_table);
const auto &profiles = builder.ConvertProfiles(symbol_map);
Expand Down Expand Up @@ -98,7 +99,8 @@ TEST(LlvmProfileWriterTest, ConvertProfile) {
symbol_map.AddSourceCount("foo", src2, 200, 1);

StringIndexMap name_table;
StringTableUpdater::Update(symbol_map, &name_table);
FileIndexMap file_table;
StringTableUpdater::Update(symbol_map, &name_table, &file_table);
LLVMProfileBuilder builder(name_table);
const auto &profiles = builder.ConvertProfiles(symbol_map);
// LLVM_BEFORE_SAMPLEFDO_SPLIT_CONTEXT is defined when llvm version is before
Expand Down
23 changes: 20 additions & 3 deletions profile_reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,17 @@ void AutoFDOProfileReader::ReadSymbolProfile(const SourceStack &stack,
} else {
head_count = 0;
}
const char *name = names_.at(gcov_read_unsigned()).c_str();
uint32_t name_index = gcov_read_unsigned();
const char *name = names_.at(name_index).first.c_str();
uint32_t file_index = names_.at(name_index).second;
const std::string &file_name =
file_index < file_names_.size() ? file_names_.at(file_index) : "";
uint32_t num_pos_counts = gcov_read_unsigned();
uint32_t num_callsites = gcov_read_unsigned();
if (stack.size() == 0) {
symbol_map_->AddSymbol(name);
const_cast<Symbol *>(symbol_map_->GetSymbolByName(name))->info.file_name =
file_name;
if (!force_update_ && symbol_map_->GetSymbolByName(name)->total_count > 0) {
update = false;
}
Expand All @@ -55,6 +61,7 @@ void AutoFDOProfileReader::ReadSymbolProfile(const SourceStack &stack,
uint32_t num_targets = gcov_read_unsigned();
uint64_t count = gcov_read_counter();
SourceInfo info(name, "", "", 0, offset >> 16, offset & 0xffff);
info.file_name = file_name;
SourceStack new_stack;
new_stack.push_back(info);
new_stack.insert(new_stack.end(), stack.begin(), stack.end());
Expand All @@ -65,7 +72,7 @@ void AutoFDOProfileReader::ReadSymbolProfile(const SourceStack &stack,
for (int j = 0; j < num_targets; j++) {
// Only indirect call target histogram is supported now.
CHECK_EQ(gcov_read_unsigned(), HIST_TYPE_INDIR_CALL_TOPN);
const std::string &target_name = names_.at(gcov_read_counter());
const std::string &target_name = names_.at(gcov_read_counter()).first;
uint64_t target_count = gcov_read_counter();
if (force_update_ || update) {
symbol_map_->AddIndirectCallTarget(
Expand All @@ -80,6 +87,7 @@ void AutoFDOProfileReader::ReadSymbolProfile(const SourceStack &stack,
// lower 16 bits: discriminator.
uint32_t offset = gcov_read_unsigned();
SourceInfo info(name, "", "", 0, offset >> 16, offset & 0xffff);
info.file_name = file_name;
SourceStack new_stack;
new_stack.push_back(info);
new_stack.insert(new_stack.end(), stack.begin(), stack.end());
Expand All @@ -90,9 +98,18 @@ void AutoFDOProfileReader::ReadSymbolProfile(const SourceStack &stack,
void AutoFDOProfileReader::ReadNameTable() {
CHECK_EQ(gcov_read_unsigned(), GCOV_TAG_AFDO_FILE_NAMES);
gcov_read_unsigned();
if (absl::GetFlag(FLAGS_gcov_version) >= 3) {
uint32_t file_name_vector_size = gcov_read_unsigned();
for (uint32_t i = 0; i < file_name_vector_size; i++) {
file_names_.push_back(gcov_read_string());
}
}
uint32_t name_vector_size = gcov_read_unsigned();
for (uint32_t i = 0; i < name_vector_size; i++) {
names_.push_back(gcov_read_string());
const char *name = gcov_read_string();
uint32_t file_index =
absl::GetFlag(FLAGS_gcov_version) >= 3 ? gcov_read_unsigned() : -1;
names_.emplace_back(name, file_index);
}
}

Expand Down
3 changes: 2 additions & 1 deletion profile_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ class AutoFDOProfileReader : public ProfileReader {

SymbolMap *symbol_map_;
bool force_update_;
std::vector<std::string> names_;
std::vector<std::pair<std::string, int>> names_;
std::vector<std::string> file_names_;
};

} // namespace devtools_crosstool_autofdo
Expand Down
19 changes: 17 additions & 2 deletions profile_writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ void AutoFDOProfileWriter::WriteFunctionProfile() {
int length_4bytes = 0, current_name_index = 0;
string_index_map[std::string()] = 0;

StringTableUpdater::Update(*symbol_map_, &string_index_map);
FileIndexMap file_map;
StringTableUpdater::Update(*symbol_map_, &string_index_map, &file_map);

for (auto &name_index : string_index_map) {
name_index.second = current_name_index++;
Expand All @@ -166,6 +167,12 @@ void AutoFDOProfileWriter::WriteFunctionProfile() {
// Writes the GCOV_TAG_AFDO_FILE_NAMES section.
gcov_write_unsigned(GCOV_TAG_AFDO_FILE_NAMES);
gcov_write_unsigned(length_4bytes);
// File names in the profile are a feature of GCOV version 3.
if (absl::GetFlag(FLAGS_gcov_version) >= 3) {
gcov_write_unsigned(file_map.Size());
for (const auto &file_name : file_map.GetFileNames())
gcov_write_string(file_name.c_str());
}
gcov_write_unsigned(string_index_map.size());
for (const auto &[name, index] : string_index_map) {
char *c = strdup(name.c_str());
Expand All @@ -182,6 +189,13 @@ void AutoFDOProfileWriter::WriteFunctionProfile() {
c[len - 10] = '2';
}
gcov_write_string(c);
if (absl::GetFlag(FLAGS_gcov_version) >= 3) {
if (int lookup = file_map.GetFileIndex(name); lookup != -1)
gcov_write_unsigned(lookup);
else
gcov_write_unsigned(-1);
}

free(c);
}

Expand Down Expand Up @@ -352,7 +366,8 @@ class ProfileDumper : public SymbolTraverser {
// Emit a dump of the input profile on stdout.
void ProfileWriter::Dump() {
StringIndexMap string_index_map;
StringTableUpdater::Update(*symbol_map_, &string_index_map);
FileIndexMap file_map;
StringTableUpdater::Update(*symbol_map_, &string_index_map, &file_map);
SourceProfileLengther length(*symbol_map_);
printf("Length of symbol map: %d\n", length.length() + 1);
printf("Number of functions: %d\n", length.num_functions());
Expand Down
59 changes: 55 additions & 4 deletions profile_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,19 +149,68 @@ class SymbolTraverser {

typedef std::map<std::string, int> StringIndexMap;

class FileIndexMap {
std::vector<std::string> file_names_;
std::unordered_map<std::string, uint32_t> name_map_;
std::unordered_map<std::string, uint32_t> file_map_;

public:
int GetFileIndex(const std::string &symbol_name) {
if (auto it = name_map_.find(symbol_name); it != name_map_.end())
return it->second;
else
return -1;
}

std::string_view GetFileName(const std::string &symbol_name) {
if (auto it = name_map_.find(symbol_name); it != name_map_.end())
return file_names_[it->second];
else
return "";
}

void AddFileName(const std::string &symbol_name,
const std::string &file_name) {
if (auto it = file_map_.find(file_name); it != file_map_.end())
name_map_[symbol_name] = it->second;
else {
file_names_.emplace_back(file_name);
file_map_[file_names_.back()] = file_names_.size() - 1;
name_map_[symbol_name] = file_names_.size() - 1;
}
}

size_t Size() const {
return file_names_.size();
}

const std::vector<std::string> &GetFileNames() const {
return file_names_;
}
};

class StringTableUpdater: public SymbolTraverser {
public:
// This type is neither copyable nor movable.
StringTableUpdater(const StringTableUpdater &) = delete;
StringTableUpdater &operator=(const StringTableUpdater &) = delete;

static void Update(const SymbolMap &symbol_map, StringIndexMap *map) {
StringTableUpdater updater(map);
static void Update(const SymbolMap &symbol_map, StringIndexMap *map,
FileIndexMap *file_map) {
StringTableUpdater updater(map, file_map);
updater.Start(symbol_map);
}

protected:
void Visit(const Symbol *node) override {
if (node->info.func_name != nullptr) {
if (node->info.dir_name != "")
file_map_->AddFileName(node->info.func_name,
std::filesystem::path(node->info.dir_name) /
node->info.file_name);
else
file_map_->AddFileName(node->info.func_name, node->info.file_name);
}
for (const auto &pos_count : node->pos_counts) {
for (const auto &name_count : pos_count.second.target_map) {
(*map_)[name_count.first] = 0;
Expand All @@ -178,8 +227,10 @@ class StringTableUpdater: public SymbolTraverser {
}

private:
explicit StringTableUpdater(StringIndexMap *map) : map_(map) {}
StringIndexMap *map_;
explicit StringTableUpdater(StringIndexMap *map, FileIndexMap *file_map)
: map_(map), file_map_(file_map) {}
StringIndexMap *map_;
FileIndexMap *file_map_;
};

} // namespace devtools_crosstool_autofdo
Expand Down
17 changes: 9 additions & 8 deletions symbol_map.cc
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,8 @@ void Symbol::DumpBody(int indent, bool for_analysis) const {
GetSortedTargetCountPairs(ret->second.target_map, &target_count_pairs);
for (const auto &target_count : target_count_pairs) {
const std::string printed_name = getPrintName(target_count.first.data());
absl::PrintF(" %s:%u", printed_name, target_count.second);
absl::PrintF(" %s:%s:%u", printed_name, info.file_name,
target_count.second);
}
printf("\n");
}
Expand All @@ -655,10 +656,10 @@ void Symbol::DumpBody(int indent, bool for_analysis) const {
void Symbol::Dump(int indent) const {
const std::string printed_name = getPrintName(info.func_name);
if (indent == 0) {
absl::PrintF("%s total:%u head:%u\n", printed_name, total_count,
head_count);
absl::PrintF("%s:%s total:%u head:%u\n", printed_name, info.file_name,
total_count, head_count);
} else {
absl::PrintF("%s total:%u\n", printed_name, total_count);
absl::PrintF("%s:%s total:%u\n", printed_name, info.file_name, total_count);
}
DumpBody(indent, false);
}
Expand All @@ -667,12 +668,12 @@ void Symbol::DumpForAnalysis(int indent) const {
const std::string printed_name = getPrintName(info.func_name);
if (indent == 0) {
absl::PrintF(
"%s total:%u head:%u total_incl:%u total_incl_per_iter:%.2f\n",
printed_name, total_count, head_count, total_count_incl,
"%s:%s total:%u head:%u total_incl:%u total_incl_per_iter:%.2f\n",
printed_name, info.file_name, total_count, head_count, total_count_incl,
head_count ? static_cast<float>(total_count_incl) / head_count : 0);
} else {
absl::PrintF("%s total:%u total_incl:%u\n", printed_name, total_count,
total_count_incl);
absl::PrintF("%s:%s total:%u total_incl:%u\n", printed_name, info.file_name,
total_count, total_count_incl);
}
DumpBody(indent, true);
}
Expand Down