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
22 changes: 22 additions & 0 deletions include/builder/dyn_var.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,17 @@ class dyn_var_impl : public var {
var_name = v.name;
}

dyn_var_impl(const with_block_var& v) {
create_dyn_var(!v.with_decl);
// Swap out the variable
block_var = v.var;
var_name = v.var->var_name;
// If a declaration was created, swap out the var too
if (v.with_decl) {
block_decl_stmt->decl_var = v.var;
}
}

dyn_var_impl(const defer_init &) {
// Do nothing here
// Defer init "automatically" supports custom types
Expand Down Expand Up @@ -343,6 +354,17 @@ class dyn_var_impl : public var {
// TODO: Consider using dynamic_cast here
return (const dyn_var<T> *)this;
}

void add_attribute(std::string s) {
std::vector<std::string> attrs;
if (block_var->hasMetadata<std::vector<std::string>>("attributes")) {
attrs = block_var->getMetadata<std::vector<std::string>>("attributes");
}
if (std::find(attrs.begin(), attrs.end(), s) == attrs.end()) {
attrs.push_back(s);
}
block_var->setMetadata<std::vector<std::string>>("attributes", attrs);
}
};

template <typename T, typename V>
Expand Down
6 changes: 6 additions & 0 deletions include/builder/forward_declarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ struct with_name {
with_name(const std::string &n, bool wd = false) : name(n), with_decl(wd) {}
};

struct with_block_var {
block::var::Ptr var;
bool with_decl;
with_block_var(block::var::Ptr v, bool wd = false): var(v), with_decl(wd) {}
};

// Generator states for non-deterministic values
struct nd_var_gen_base;

Expand Down
8 changes: 4 additions & 4 deletions include/builder/signature_extract.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ struct extract_signature_impl<std::tuple<ProcessedArgTypes...>, std::tuple<NextA
// The dyn_var version doesn't need any NextParam to exist or be used
template <typename F, typename...OtherParams>
static void fill_invocation(invocation_state* i_state, F func, int arg_index, ProcessedArgTypes...processed_args, OtherParams&&...other_params) {
// We don't need to heap allocate objects anymore, just throw in a with_name, it has all
// We don't need to heap allocate objects anymore, just throw in a with_block_var, it has all
// the information to create the dyn_var when invoking the actual funciton
std::string arg_name = "arg" + std::to_string(arg_index);
auto var = std::make_shared<block::var>();
var->var_name = arg_name;
var->var_type = dyn_var<NextArg>::create_block_type();
var->var_type->static_offset = var->static_offset = tracer::get_unique_tag();
i_state->generated_func_decl->args.push_back(var);
// We explain below by with_name is wrapped in a tuple
extract_signature_impl<std::tuple<ProcessedArgTypes..., std::tuple<with_name>>, std::tuple<RemainingArgTypes...>, ReturnType>::fill_invocation(i_state, func, arg_index + 1, std::forward<ProcessedArgTypes>(processed_args)..., std::tuple<with_name>(with_name(arg_name)), std::forward<OtherParams>(other_params)...);
// We explain below by with_block_var is wrapped in a tuple
extract_signature_impl<std::tuple<ProcessedArgTypes..., std::tuple<with_block_var>>, std::tuple<RemainingArgTypes...>, ReturnType>::fill_invocation(i_state, func, arg_index + 1, std::forward<ProcessedArgTypes>(processed_args)..., std::tuple<with_block_var>(with_block_var(var)), std::forward<OtherParams>(other_params)...);
}
};

Expand All @@ -82,7 +82,7 @@ struct extract_signature_impl<std::tuple<ProcessedArgTypes...>, std::tuple<>, vo
// Take other_args but discard them
template <typename F, typename...OtherParams>
static void fill_invocation(invocation_state* i_state, F func, int arg_index, ProcessedArgTypes...processed_args, OtherParams&&...other_params) {
// All conversions from with_name to dyn_var will happen INSIDE the lambda and hence the lifetype of the
// All conversions from with_block_var to dyn_var will happen INSIDE the lambda and hence the lifetype of the
// dyn_var will be valid for the run
// Mark the lambda to be mutable otherwise if func accepts a reference it won't bind correctly
// since captured variables are const when captured by value
Expand Down
6 changes: 6 additions & 0 deletions samples/outputs.var_names/sample69
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
void bar (int* restrict arg0, int* restrict arg1, int arg2) {
for (int i_0 = 0; i_0 < arg2; (i_0 = i_0 + 1) - 1) {
arg0[i_0] = arg1[i_0];
}
}

6 changes: 6 additions & 0 deletions samples/outputs/sample69
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
void bar (int* restrict arg0, int* restrict arg1, int arg2) {
for (int var0 = 0; var0 < arg2; (var0 = var0 + 1) - 1) {
arg0[var0] = arg1[var0];
}
}

27 changes: 27 additions & 0 deletions samples/sample69.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Include the headers
#include "blocks/c_code_generator.h"
#include "builder/static_var.h"
#include "builder/dyn_var.h"
#include <iostream>

// Include the BuildIt types
using builder::dyn_var;
using builder::static_var;


static void bar(dyn_var<int*> x, dyn_var<int*> y, dyn_var<int> size) {
x.add_attribute("restrict");
y.add_attribute("restrict");
for (builder::dyn_var<int> i = 0; i < size; i++) {
x[i] = y[i];
}
}

int main(int argc, char* argv[]) {
builder::builder_context context;
auto ast = context.extract_function_ast(bar, "bar");
auto fd = block::to<block::func_decl>(ast);
block::c_code_generator::generate_code(ast, std::cout, 0);
return 0;
}

10 changes: 9 additions & 1 deletion src/blocks/c_code_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,15 @@ void c_code_generator::visit(func_decl::Ptr a) {
if (printDelim)
oss << ", ";
printDelim = true;
oss << complex_type_helper(arg->var_type, " " + arg->var_name);
std::string name = "";
if (arg->hasMetadata<std::vector<std::string>>("attributes")) {
const auto &attributes = arg->getMetadata<std::vector<std::string>>("attributes");
for (auto attr : attributes) {
name = name + " " + attr;
}
}
name = name + " " + arg->var_name;
oss << complex_type_helper(arg->var_type, name);
}
if (a->is_variadic) {
oss << ", ...";
Expand Down