1919#include " configuration/PassBuilderUtil.h"
2020#include " configuration/PassConfiguration.h"
2121#include " configuration/TypeARTOptions.h"
22+ #include " instrumentation/CallBackFunctionInserter.h"
2223#include " instrumentation/MemOpArgCollector.h"
2324#include " instrumentation/MemOpInstrumentation.h"
2425#include " instrumentation/TypeARTFunctions.h"
26+ #include " instrumentation/TypeIDProvider.h"
2527#include " support/ConfigurationBase.h"
2628#include " support/Logger.h"
2729#include " support/ModuleDumper.h"
4850
4951#include < cassert>
5052#include < cstddef>
53+ #include < llvm/Config/llvm-config.h>
5154#include < llvm/Support/Error.h>
55+ #include < memory>
5256#include < optional>
5357#include < sstream>
5458#include < string>
@@ -95,26 +99,10 @@ class TypeArtPass : public llvm::PassInfoMixin<TypeArtPass> {
9599 std::optional<config::TypeARTConfigOptions> pass_opts{std::nullopt };
96100 std::unique_ptr<config::Configuration> pass_config;
97101
98- struct TypeArtFunc {
99- const std::string name;
100- llvm::Value* f{nullptr };
101- };
102-
103- TypeArtFunc typeart_alloc{" __typeart_alloc" };
104- TypeArtFunc typeart_alloc_global{" __typeart_alloc_global" };
105- TypeArtFunc typeart_alloc_stack{" __typeart_alloc_stack" };
106- TypeArtFunc typeart_free{" __typeart_free" };
107- TypeArtFunc typeart_leave_scope{" __typeart_leave_scope" };
108-
109- TypeArtFunc typeart_alloc_omp = typeart_alloc;
110- TypeArtFunc typeart_alloc_stacks_omp = typeart_alloc_stack;
111- TypeArtFunc typeart_free_omp = typeart_free;
112- TypeArtFunc typeart_leave_scope_omp = typeart_leave_scope;
113-
114102 std::unique_ptr<analysis::MemInstFinder> meminst_finder;
115103 std::unique_ptr<TypeGenerator> typeManager;
116104 InstrumentationHelper instrumentation_helper;
117- TAFunctions functions;
105+ std::unique_ptr<TAFunctionQuery> functions;
118106 std::unique_ptr<InstrumentationContext> instrumentation_context;
119107
120108 const config::Configuration& configuration () const {
@@ -168,32 +156,48 @@ class TypeArtPass : public llvm::PassInfoMixin<TypeArtPass> {
168156
169157 instrumentation_helper.setModule (m);
170158 ModuleData mdata{&m};
171- typeManager->registerModule (mdata);
159+ const auto has_cu_types = typeManager->registerModule (mdata);
160+
161+ declareInstrumentationFunctions (m);
162+ {
163+ auto type_id_handler = get_type_id_handler (m, &typeManager->getTypeDatabase (), configuration (), functions.get ());
164+ // const bool heap = configuration()[config::ConfigStdArgs::heap];
165+ if (has_cu_types) {
166+ LOG_DEBUG (" Registering compilation unit types list" )
167+ type_id_handler->registerModule (mdata);
168+ }
172169
173- auto arg_collector =
174- std::make_unique<MemOpArgCollector>(configuration (), typeManager.get (), instrumentation_helper);
175- // const bool instrument_stack_lifetime = configuration()[config::ConfigStdArgs::stack_lifetime];
176- auto mem_instrument = std::make_unique<MemOpInstrumentation> (configuration (), functions, instrumentation_helper );
177- instrumentation_context =
178- std::make_unique<InstrumentationContext>( std::move (arg_collector) , std::move (mem_instrument ));
170+ auto arg_collector =
171+ std::make_unique<MemOpArgCollector>(configuration (), typeManager.get (), instrumentation_helper);
172+ // const bool instrument_stack_lifetime = configuration()[config::ConfigStdArgs::stack_lifetime];
173+ auto cb_provider = make_callback_inserter (configuration (), std::move (type_id_handler), functions. get () );
174+ auto mem_instrument = std::make_unique<MemOpInstrumentation>( configuration (), functions. get (),
175+ instrumentation_helper , std::move (cb_provider ));
179176
177+ instrumentation_context =
178+ std::make_unique<InstrumentationContext>(std::move (arg_collector), std::move (mem_instrument));
179+ }
180180 return true ;
181181 }
182182
183183 bool doFinalization () {
184184 /*
185185 * Persist the accumulated type definition information for this module.
186186 */
187- const std::string types_file = configuration ()[config::ConfigStdArgs::types];
188- LOG_DEBUG (" Writing type file to " << types_file);
189-
190- const auto [stored, error] = typeManager->store ();
191- if (stored) {
192- LOG_DEBUG (" Success!" );
193- } else {
194- LOG_FATAL (" Failed writing type config to " << types_file << " . Reason: " << error.message ());
187+ // TODO: inline/hybrid types not supported in non-opaque mode
188+ const bool emit_type_file_always = bool (LLVM_VERSION_MAJOR < 15 );
189+ TypeSerializationImplementation mode = configuration ()[config::ConfigStdArgs::type_serialization];
190+ if (emit_type_file_always || mode == TypeSerializationImplementation::FILE) {
191+ const std::string types_file = configuration ()[config::ConfigStdArgs::types];
192+ LOG_DEBUG (" Writing type file to " << types_file);
193+
194+ const auto [stored, error] = typeManager->store ();
195+ if (stored) {
196+ LOG_DEBUG (" Success!" );
197+ } else {
198+ LOG_FATAL (" Failed writing type config to " << types_file << " . Reason: " << error.message ());
199+ }
195200 }
196-
197201 const bool print_stats = configuration ()[config::ConfigStdArgs::stats];
198202 if (print_stats) {
199203 auto & out = llvm::errs ();
@@ -203,30 +207,7 @@ class TypeArtPass : public llvm::PassInfoMixin<TypeArtPass> {
203207 }
204208
205209 void declareInstrumentationFunctions (Module& m) {
206- // Remove this return if problems come up during compilation
207- if (typeart_alloc_global.f != nullptr && typeart_alloc_stack.f != nullptr && typeart_alloc.f != nullptr &&
208- typeart_free.f != nullptr && typeart_leave_scope.f != nullptr ) {
209- return ;
210- }
211-
212- TAFunctionDeclarator decl (m, instrumentation_helper, functions);
213-
214- auto alloc_arg_types = instrumentation_helper.make_parameters (IType::ptr, IType::type_id, IType::extent);
215- auto free_arg_types = instrumentation_helper.make_parameters (IType::ptr);
216- auto leavescope_arg_types = instrumentation_helper.make_parameters (IType::stack_count);
217-
218- typeart_alloc.f = decl.make_function (IFunc::heap, typeart_alloc.name , alloc_arg_types);
219- typeart_alloc_stack.f = decl.make_function (IFunc::stack, typeart_alloc_stack.name , alloc_arg_types);
220- typeart_alloc_global.f = decl.make_function (IFunc::global, typeart_alloc_global.name , alloc_arg_types);
221- typeart_free.f = decl.make_function (IFunc::free, typeart_free.name , free_arg_types);
222- typeart_leave_scope.f = decl.make_function (IFunc::scope, typeart_leave_scope.name , leavescope_arg_types);
223-
224- typeart_alloc_omp.f = decl.make_function (IFunc::heap_omp, typeart_alloc_omp.name , alloc_arg_types, true );
225- typeart_alloc_stacks_omp.f =
226- decl.make_function (IFunc::stack_omp, typeart_alloc_stacks_omp.name , alloc_arg_types, true );
227- typeart_free_omp.f = decl.make_function (IFunc::free_omp, typeart_free_omp.name , free_arg_types, true );
228- typeart_leave_scope_omp.f =
229- decl.make_function (IFunc::scope_omp, typeart_leave_scope_omp.name , leavescope_arg_types, true );
210+ functions = declare_instrumentation_functions (m, configuration ());
230211 }
231212
232213 void printStats (llvm::raw_ostream& out) {
@@ -292,7 +273,7 @@ class TypeArtPass : public llvm::PassInfoMixin<TypeArtPass> {
292273 const bool instrument_global = configuration ()[config::ConfigStdArgs::global];
293274 bool globals_were_instrumented{false };
294275 if (instrument_global) {
295- declareInstrumentationFunctions (m);
276+ // declareInstrumentationFunctions(m);
296277
297278 const auto & globalsList = meminst_finder->getModuleGlobals ();
298279 if (!globalsList.empty ()) {
@@ -322,7 +303,7 @@ class TypeArtPass : public llvm::PassInfoMixin<TypeArtPass> {
322303
323304 // FIXME this is required when "PassManagerBuilder::EP_OptimizerLast" is used as the function (constant) pointer are
324305 // nullpointer/invalidated
325- declareInstrumentationFunctions (*f.getParent ());
306+ // declareInstrumentationFunctions(*f.getParent());
326307
327308 bool mod{false };
328309 // auto& c = f.getContext();
@@ -364,7 +345,7 @@ class LegacyTypeArtPass : public llvm::ModulePass {
364345 public:
365346 static char ID; // NOLINT
366347
367- LegacyTypeArtPass () : ModulePass(ID){};
348+ LegacyTypeArtPass () : ModulePass(ID) {};
368349
369350 bool doInitialization (llvm::Module&) override ;
370351
@@ -399,17 +380,19 @@ llvm::PassPluginLibraryInfo getTypeartPassPluginInfo() {
399380 using namespace llvm ;
400381 return {LLVM_PLUGIN_API_VERSION, " TypeART" , LLVM_VERSION_STRING, [](PassBuilder& pass_builder) {
401382 pass_builder.registerPipelineStartEPCallback ([](auto & MPM, OptimizationLevel) {
402- auto parameters = typeart::util::pass::parsePassParameters (typeart::config::pass::parse_typeart_config,
403- " typeart<heap;stats>" , " typeart" );
383+ auto parameters =
384+ typeart::util::pass::parsePassParameters (typeart::config::pass::parse_typeart_config,
385+ " typeart<heap;stats;type-serialization=hybrid>" , " typeart" );
404386 if (!parameters) {
405387 LOG_FATAL (" Error parsing heap params: " << parameters.takeError ())
406388 return ;
407389 }
408390 MPM.addPass (typeart::pass::TypeArtPass (typeart::pass::TypeArtPass (parameters.get ())));
409391 });
410392 pass_builder.registerOptimizerLastEPCallback ([](auto & MPM, OptimizationLevel) {
411- auto parameters = typeart::util::pass::parsePassParameters (typeart::config::pass::parse_typeart_config,
412- " typeart<no-heap;stack;stats>" , " typeart" );
393+ auto parameters = typeart::util::pass::parsePassParameters (
394+ typeart::config::pass::parse_typeart_config, " typeart<no-heap;stack;stats;type-serialization=hybrid>" ,
395+ " typeart" );
413396 if (!parameters) {
414397 LOG_FATAL (" Error parsing stack params: " << parameters.takeError ())
415398 return ;
0 commit comments