Skip to content

Commit cff53ce

Browse files
committed
Linking: perform macro expansion and type updates just once
This reduces the Linux kernel link time by more than 90% as the previous approach would repeatedly attempt renamings and replacements across all hitherto read goto program instructions.
1 parent 1d9584e commit cff53ce

File tree

3 files changed

+65
-43
lines changed

3 files changed

+65
-43
lines changed

src/goto-programs/link_goto_model.cpp

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ static bool link_functions(
5555
const symbol_tablet &src_symbol_table,
5656
goto_functionst &src_functions,
5757
const rename_symbolt &rename_symbol,
58-
const std::unordered_set<irep_idt> &weak_symbols,
59-
const replace_symbolt &object_type_updates)
58+
const std::unordered_set<irep_idt> &weak_symbols)
6059
{
6160
namespacet ns(dest_symbol_table);
6261
namespacet src_ns(src_symbol_table);
@@ -110,6 +109,51 @@ static bool link_functions(
110109
}
111110
}
112111

112+
return false;
113+
}
114+
115+
void link_goto_model(
116+
goto_modelt &dest,
117+
goto_modelt &src,
118+
unchecked_replace_symbolt &object_type_updates,
119+
message_handlert &message_handler)
120+
{
121+
std::unordered_set<irep_idt> weak_symbols;
122+
123+
for(const auto &symbol_pair : dest.symbol_table.symbols)
124+
{
125+
if(symbol_pair.second.is_weak)
126+
weak_symbols.insert(symbol_pair.first);
127+
}
128+
129+
linkingt linking(dest.symbol_table, src.symbol_table, message_handler);
130+
131+
if(linking.typecheck_main())
132+
throw invalid_source_file_exceptiont("typechecking main failed");
133+
134+
if(link_functions(
135+
dest.symbol_table,
136+
dest.goto_functions,
137+
src.symbol_table,
138+
src.goto_functions,
139+
linking.rename_symbol,
140+
weak_symbols))
141+
{
142+
throw invalid_source_file_exceptiont("linking failed");
143+
}
144+
145+
object_type_updates.get_expr_map().insert(
146+
linking.object_type_updates.get_expr_map().begin(),
147+
linking.object_type_updates.get_expr_map().end());
148+
}
149+
150+
void finalize_linking(
151+
goto_modelt &dest,
152+
const unchecked_replace_symbolt &object_type_updates)
153+
{
154+
goto_functionst &dest_functions = dest.goto_functions;
155+
symbol_tablet &dest_symbol_table = dest.symbol_table;
156+
113157
// apply macros
114158
rename_symbolt macro_application;
115159

@@ -158,40 +202,4 @@ static bool link_functions(
158202
}
159203
}
160204
}
161-
162-
return false;
163-
}
164-
165-
void link_goto_model(
166-
goto_modelt &dest,
167-
goto_modelt &src,
168-
message_handlert &message_handler)
169-
{
170-
std::unordered_set<irep_idt> weak_symbols;
171-
172-
for(const auto &symbol_pair : dest.symbol_table.symbols)
173-
{
174-
if(symbol_pair.second.is_weak)
175-
weak_symbols.insert(symbol_pair.first);
176-
}
177-
178-
linkingt linking(dest.symbol_table,
179-
src.symbol_table,
180-
message_handler);
181-
182-
if(linking.typecheck_main())
183-
{
184-
throw invalid_source_file_exceptiont("typechecking main failed");
185-
}
186-
if(link_functions(
187-
dest.symbol_table,
188-
dest.goto_functions,
189-
src.symbol_table,
190-
src.goto_functions,
191-
linking.rename_symbol,
192-
weak_symbols,
193-
linking.object_type_updates))
194-
{
195-
throw invalid_source_file_exceptiont("linking failed");
196-
}
197205
}

src/goto-programs/link_goto_model.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@ Author: Daniel Kroening, [email protected]
1414

1515
class goto_modelt;
1616
class message_handlert;
17+
class replace_symbolt;
1718

1819
void link_goto_model(
1920
goto_modelt &dest,
2021
goto_modelt &src,
22+
unchecked_replace_symbolt &object_type_updates,
2123
message_handlert &);
2224

25+
void finalize_linking(
26+
goto_modelt &dest,
27+
const replace_symbolt &object_type_updates);
28+
2329
#endif // CPROVER_GOTO_PROGRAMS_LINK_GOTO_MODEL_H

src/goto-programs/read_goto_binary.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ Module: Read Goto Programs
1414
#include <fstream>
1515
#include <unordered_set>
1616

17+
#include <util/config.h>
1718
#include <util/message.h>
18-
#include <util/unicode.h>
19-
#include <util/tempfile.h>
2019
#include <util/rename_symbol.h>
21-
#include <util/config.h>
20+
#include <util/replace_symbol.h>
21+
#include <util/tempfile.h>
22+
#include <util/unicode.h>
2223

2324
#include "goto_model.h"
2425
#include "link_goto_model.h"
@@ -268,11 +269,13 @@ bool is_goto_binary(
268269
/// \brief reads an object file, and also updates config
269270
/// \param file_name: file name of the goto binary
270271
/// \param dest: the goto model returned
272+
/// \param [out] object_type_updates: collects type replacements to be applied
271273
/// \param message_handler: for diagnostics
272274
/// \return true on error, false otherwise
273275
static bool read_object_and_link(
274276
const std::string &file_name,
275277
goto_modelt &dest,
278+
unchecked_replace_symbolt &object_type_updates,
276279
message_handlert &message_handler)
277280
{
278281
messaget(message_handler).status()
@@ -285,7 +288,7 @@ static bool read_object_and_link(
285288

286289
try
287290
{
288-
link_goto_model(dest, *temp_model, message_handler);
291+
link_goto_model(dest, *temp_model, object_type_updates, message_handler);
289292
}
290293
catch(...)
291294
{
@@ -303,14 +306,19 @@ bool read_objects_and_link(
303306
if(file_names.empty())
304307
return false;
305308

309+
unchecked_replace_symbolt object_type_updates;
310+
306311
for(const auto &file_name : file_names)
307312
{
308-
const bool failed = read_object_and_link(file_name, dest, message_handler);
313+
const bool failed = read_object_and_link(
314+
file_name, dest, object_type_updates, message_handler);
309315

310316
if(failed)
311317
return true;
312318
}
313319

320+
finalize_linking(dest, object_type_updates);
321+
314322
// reading successful, let's update config
315323
config.set_from_symbol_table(dest.symbol_table);
316324

0 commit comments

Comments
 (0)