Skip to content
Merged
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
23 changes: 21 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,19 @@ 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 +244,18 @@ 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
21 changes: 19 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,13 @@ 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 +190,14 @@ 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 +368,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
68 changes: 64 additions & 4 deletions profile_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,19 +149,77 @@ class SymbolTraverser {

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

// Store a mapping from function names back to file names (with faster lookup
// using file_map_ -> file_names_). The ordering of file_names_ is not stable,
// it can vary across invocations depending on the order of symbol traversal.
class FileIndexMap {
// The de-duplicated list of file names found in the program.
std::vector<std::string> file_names_;
// The map from function name string to an index in file_names_.
std::unordered_map<std::string, uint32_t> name_map_;
// The map from file name string to an index in file_names_.
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 "";
}

// Add a new function name -> file name mapping. This de-duplicates the file
// names by re-assigning the same index if the file name already exists.
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 +236,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
Loading