1
Fork 0

Use callback-based interface to load ThinLTO import data into rustc.

This commit is contained in:
Michael Woerister 2018-07-13 12:41:22 +02:00
parent dd3f445ed2
commit e045a6cd8c
4 changed files with 56 additions and 94 deletions

View file

@ -798,11 +798,6 @@ LLVMRustPGOAvailable() {
#endif
}
// We encode the ThinLTO module import map as a nested null-terminated list to
// get it into Rust.
typedef const char* LLVMRustThinLTOModuleName;
typedef LLVMRustThinLTOModuleName* LLVMRustThinLTOModuleImports;
#if LLVM_VERSION_GE(4, 0)
// Here you'll find an implementation of ThinLTO as used by the Rust compiler
@ -1104,50 +1099,28 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
return true;
}
/// Converts the LLVMRustThinLTOData::ImportLists map into a nested list. The
/// first level is a null-terminated array with an entry for each module. Each
/// entry is a pointer that points to a null-termined array of module names. The
/// first entry is always the name of the *importing* module, the following
/// entries are the names of the modules it imports from. Each module name is
/// a regular C string.
extern "C" LLVMRustThinLTOModuleImports*
LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *Data) {
// Allocate number of module +1. This is a null-terminated array.
LLVMRustThinLTOModuleImports* thinLTOModuleImports =
new LLVMRustThinLTOModuleImports[Data->ImportLists.size() + 1];
size_t module_index = 0;
extern "C" typedef void (*LLVMRustModuleNameCallback)(void*, // payload
const char*, // importing module name
const char*); // imported module name
for (const auto & module : Data->ImportLists) {
StringRef module_id = module.getKey();
const auto& imports = module.getValue();
// Calls `module_name_callback` for each module import done by ThinLTO.
// The callback is provided with regular null-terminated C strings.
extern "C" void
LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *data,
LLVMRustModuleNameCallback module_name_callback,
void* callback_payload) {
for (const auto& importing_module : data->ImportLists) {
const std::string importing_module_id = importing_module.getKey().str();
// Allocate number of imported module + 2, one extra for the name of the
// importing module and another one for null-termination.
LLVMRustThinLTOModuleImports imports_array =
new LLVMRustThinLTOModuleName[imports.size() + 2];
const auto& imports = importing_module.getValue();
// The first value is always the name of the *importing* module.
imports_array[0] = strndup(module_id.data(), module_id.size());
size_t imports_array_index = 1;
for (const auto imported_module_id : imports.keys()) {
// The following values are the names of the imported modules.
imports_array[imports_array_index] = strndup(imported_module_id.data(),
imported_module_id.size());
imports_array_index += 1;
for (const auto& imported_module : imports) {
const std::string imported_module_id = imported_module.getKey().str();
module_name_callback(callback_payload,
importing_module_id.c_str(),
imported_module_id.c_str());
}
assert(imports_array_index == imports.size() + 1);
imports_array[imports_array_index] = nullptr;
thinLTOModuleImports[module_index] = imports_array;
module_index += 1;
}
assert(module_index == Data->ImportLists.size());
thinLTOModuleImports[module_index] = nullptr;
return thinLTOModuleImports;
}
// This struct and various functions are sort of a hack right now, but the