Skip to content

Commit acf5c0e

Browse files
authored
Global variables as type descriptors (#173)
1 parent f4d0ba9 commit acf5c0e

106 files changed

Lines changed: 1936 additions & 367 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.clang-tidy

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,performance-*,modernize-*,llvm-namespace-comment,google-explicit-constructor,bugprone-*,misc-*,readability-*, -readability-named-parameter,-modernize-use-trailing-return-type,-modernize-use-using'
33
WarningsAsErrors: ''
44
HeaderFilterRegex: ''
5-
AnalyzeTemporaryDtors: false
65
CheckOptions:
76
- key: google-readability-braces-around-statements.ShortStatementLines
87
value: '1'

.github/workflows/basic-ci.yml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,22 @@ env:
1212

1313
jobs:
1414
format-check:
15-
runs-on: ubuntu-22.04
15+
runs-on: ubuntu-24.04
1616

1717
steps:
18-
- uses: actions/checkout@v4
18+
- uses: actions/checkout@v5
19+
20+
- run: |
21+
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
22+
echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-18 main" | sudo tee /etc/apt/sources.list.d/llvm-18.list
23+
24+
- name: Update apt
25+
run: sudo apt-get update
26+
27+
- name: Install clang-format
28+
run: |
29+
sudo apt-get remove clang-format-*
30+
sudo apt-get install -t llvm-toolchain-noble-18 clang-format-18
1931
2032
- name: Format source code
2133
run: |
@@ -24,7 +36,7 @@ jobs:
2436
-a \( -name "*.c" -o -name "*.cpp" -o -name "*.h" \) \
2537
-not -path "*/lulesh/*" -not -path "*/CallSite.h" \
2638
-print0 \
27-
| xargs -0 clang-format-14 -i
39+
| xargs -0 clang-format-18 -i
2840
2941
- name: Format check
3042
run: |
@@ -35,7 +47,7 @@ jobs:
3547
runs-on: ubuntu-22.04
3648

3749
steps:
38-
- uses: actions/checkout@v4
50+
- uses: actions/checkout@v5
3951
- uses: codespell-project/actions-codespell@v2
4052

4153
lit-suite:
@@ -73,7 +85,7 @@ jobs:
7385
runs-on: ${{ matrix.os }}
7486

7587
steps:
76-
- uses: actions/checkout@v4
88+
- uses: actions/checkout@v5
7789

7890
- name: LLVM apt
7991
if: ${{ matrix.llvm-version == 19 }}

.github/workflows/ext-ci.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ jobs:
3131
runs-on: ${{ matrix.os }}
3232

3333
steps:
34-
- uses: actions/checkout@v4
34+
- uses: actions/checkout@v5
3535

3636
- name: Checkout test-bench
37-
uses: actions/checkout@v4
37+
uses: actions/checkout@v5
3838
with:
3939
repository: tudasc/typeart-bench
4040
ssh-key: ${{ secrets.AUTH_SSH_CI_EXT }}
@@ -129,10 +129,10 @@ jobs:
129129
runs-on: ${{ matrix.os }}
130130

131131
steps:
132-
- uses: actions/checkout@v4
132+
- uses: actions/checkout@v5
133133

134134
- name: Checkout AD test-bench
135-
uses: actions/checkout@v4
135+
uses: actions/checkout@v5
136136
with:
137137
repository: ahueck/typeart-ad-benchmarks
138138
ssh-key: ${{ secrets.AUTH_SSH_CI_EXT_AD }}
@@ -215,10 +215,10 @@ jobs:
215215
runs-on: ${{ matrix.os }}
216216

217217
steps:
218-
- uses: actions/checkout@v4
218+
- uses: actions/checkout@v5
219219

220220
- name: Checkout OMP test-bench
221-
uses: actions/checkout@v4
221+
uses: actions/checkout@v5
222222
with:
223223
repository: tudasc/typeart-bench
224224
ssh-key: ${{ secrets.AUTH_SSH_CI_EXT }}

demo/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
MPIRUN ?= mpirun
44
MPICC ?= typeart-mpicc # instead of standard mpicc
55

6-
all: libtool.so 01_ex 02_ex toy toy-stack
6+
all: libtool.so demo demo_broken
77

88
libtool.so: tool.c
99
$(MPICC) -shared -fPIC $< -o $@

externals/abseil/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ set(ABSL_PROPAGATE_CXX_STD ON)
33
FetchContent_Declare(
44
cpp-abseil
55
GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git
6-
GIT_TAG 20240722.1
6+
GIT_TAG 20250814.1
77
GIT_SHALLOW 1
88
)
99

lib/passes/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ set(PASS_SOURCES
1212
instrumentation/MemOpArgCollector.cpp
1313
instrumentation/MemOpInstrumentation.cpp
1414
instrumentation/Instrumentation.cpp
15+
instrumentation/TypeIDProvider.cpp
16+
instrumentation/CallBackFunctionInserter.cpp
1517
TypeARTConfiguration.cpp
1618
Commandline.cpp
1719
)

lib/passes/Commandline.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "analysis/MemInstFinder.h"
1616
#include "configuration/Configuration.h"
1717
#include "configuration/EnvironmentConfiguration.h"
18+
#include "instrumentation/TypeIDProvider.h"
1819
#include "support/ConfigurationBase.h"
1920
#include "support/Logger.h"
2021
#include "typegen/TypeGenerator.h"
@@ -83,6 +84,15 @@ static cl::opt<ConfigStdArgTypes::stack_ty> cl_typeart_instrument_stack(Commandl
8384
cl::init(ConfigStdArgValues::stack),
8485
cl::cat(typeart_category));
8586

87+
static cl::opt<typeart::TypeSerializationImplementation> cl_typeart_type_serialization(
88+
CommandlineStdArgs::type_serialization, cl::desc(ConfigStdArgDescriptions::type_serialization),
89+
cl::values(clEnumValN(typeart::TypeSerializationImplementation::FILE, "file", "File based type serialization"),
90+
clEnumValN(typeart::TypeSerializationImplementation::INLINE, "inline",
91+
"Type descriptors through global variables"),
92+
clEnumValN(typeart::TypeSerializationImplementation::HYBRID, "hybrid",
93+
"Type descriptors through global variables except for C/C++ built-in types")),
94+
cl::Hidden, cl::init(typeart::TypeSerializationImplementation::FILE), cl::cat(typeart_category));
95+
8696
static cl::opt<ConfigStdArgTypes::stack_lifetime_ty> cl_typeart_instrument_stack_lifetime(
8797
CommandlineStdArgs::stack_lifetime, cl::desc(ConfigStdArgDescriptions::stack_lifetime),
8898
cl::init(ConfigStdArgValues::stack_lifetime), cl::cat(typeart_category));
@@ -198,6 +208,7 @@ CommandLineOptions::CommandLineOptions() {
198208
make_entry(ConfigStdArgs::heap, cl_typeart_instrument_heap),
199209
make_entry(ConfigStdArgs::global, cl_typeart_instrument_global),
200210
make_entry(ConfigStdArgs::stack, cl_typeart_instrument_stack),
211+
make_entry(ConfigStdArgs::type_serialization, cl_typeart_type_serialization),
201212
make_entry(ConfigStdArgs::stack_lifetime, cl_typeart_instrument_stack_lifetime),
202213
make_entry(ConfigStdArgs::typegen, cl_typeart_typegen_implementation),
203214
make_entry(ConfigStdArgs::filter, cl_typeart_call_filter),
@@ -217,6 +228,7 @@ CommandLineOptions::CommandLineOptions() {
217228
make_occurr_entry(ConfigStdArgs::heap, cl_typeart_instrument_heap),
218229
make_occurr_entry(ConfigStdArgs::global, cl_typeart_instrument_global),
219230
make_occurr_entry(ConfigStdArgs::stack, cl_typeart_instrument_stack),
231+
make_occurr_entry(ConfigStdArgs::type_serialization, cl_typeart_type_serialization),
220232
make_occurr_entry(ConfigStdArgs::stack_lifetime, cl_typeart_instrument_stack_lifetime),
221233
make_occurr_entry(ConfigStdArgs::typegen, cl_typeart_typegen_implementation),
222234
make_occurr_entry(ConfigStdArgs::filter, cl_typeart_call_filter),

lib/passes/TypeARTPass.cpp

Lines changed: 47 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
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"
@@ -48,7 +50,9 @@
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;

lib/passes/analysis/MemInstFinder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ bool MemInstFinderPass::runOnModule(Module& module) {
193193
}
194194

195195
if (util::starts_with_any_of(name, "llvm.", "__llvm_gcov", "__llvm_gcda", "__profn", "___asan",
196-
"__msan", "__tsan")) {
196+
"__msan", "__tsan", "__typeart", "_typeart")) {
197197
LOG_DEBUG("Prefixed matched on " << name)
198198
return true;
199199
}

lib/passes/configuration/EnvironmentConfiguration.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "OptionsUtil.h"
1717
#include "PassConfiguration.h"
1818
#include "configuration/TypeARTOptions.h"
19+
#include "instrumentation/TypeIDProvider.h"
1920
#include "support/ConfigurationBase.h"
2021
#include "support/Logger.h"
2122
#include "support/Util.h"
@@ -113,6 +114,9 @@ EnvironmentFlagsOptions::EnvironmentFlagsOptions() {
113114
EnvironmentStdArgsValues::global),
114115
make_entry<ConfigStdArgTypes::stack_ty>(ConfigStdArgs::stack, EnvironmentStdArgs::stack,
115116
EnvironmentStdArgsValues::stack),
117+
make_entry<typeart::TypeSerializationImplementation>(ConfigStdArgs::type_serialization,
118+
EnvironmentStdArgs::type_serialization,
119+
EnvironmentStdArgsValues::type_serialization),
116120
make_entry<ConfigStdArgTypes::stack_lifetime_ty>(
117121
ConfigStdArgs::stack_lifetime, EnvironmentStdArgs::stack_lifetime, EnvironmentStdArgsValues::stack_lifetime),
118122
make_entry<typeart::TypegenImplementation>(ConfigStdArgs::typegen, EnvironmentStdArgs::typegen,
@@ -148,6 +152,7 @@ EnvironmentFlagsOptions::EnvironmentFlagsOptions() {
148152
make_occurr_entry(ConfigStdArgs::heap, EnvironmentStdArgs::heap),
149153
make_occurr_entry(ConfigStdArgs::global, EnvironmentStdArgs::global),
150154
make_occurr_entry(ConfigStdArgs::stack, EnvironmentStdArgs::stack),
155+
make_occurr_entry(ConfigStdArgs::type_serialization, EnvironmentStdArgs::type_serialization),
151156
make_occurr_entry(ConfigStdArgs::stack_lifetime, EnvironmentStdArgs::stack_lifetime),
152157
make_occurr_entry(ConfigStdArgs::typegen, EnvironmentStdArgs::typegen),
153158
make_occurr_entry(ConfigStdArgs::filter, EnvironmentStdArgs::filter),

0 commit comments

Comments
 (0)