Skip to content

Commit 81cf7de

Browse files
authored
Merge pull request #1346 from czgdp1807/i8_array
Create "char buffer[...]" for "i8[...]" typed arrays
2 parents db69dd6 + 9b94176 commit 81cf7de

File tree

10 files changed

+345
-70
lines changed

10 files changed

+345
-70
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ RUN(NAME structs_11 LABELS cpython llvm c)
328328
RUN(NAME structs_12 LABELS cpython llvm c)
329329
RUN(NAME structs_13 LABELS llvm c
330330
EXTRAFILES structs_13b.c)
331+
RUN(NAME structs_14 LABELS cpython llvm c)
331332
RUN(NAME structs_15 LABELS cpython llvm c)
332333
RUN(NAME sizeof_01 LABELS llvm c
333334
EXTRAFILES sizeof_01b.c)

integration_tests/structs_14.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from ltypes import i8, dataclass, i32, ccallable
2+
from numpy import empty, int8
3+
from copy import deepcopy
4+
5+
@dataclass
6+
class buffer_struct:
7+
buffer: i8[32]
8+
9+
@ccallable
10+
@dataclass
11+
class buffer_struct_clink:
12+
buffer: i8[32]
13+
14+
def f():
15+
i: i32
16+
buffer_var: i8[32] = empty(32, dtype=int8)
17+
buffer_: buffer_struct = buffer_struct(deepcopy(buffer_var))
18+
buffer_clink_: buffer_struct_clink = buffer_struct_clink(deepcopy(buffer_var))
19+
print(buffer_.buffer[15])
20+
print(buffer_clink_.buffer[15])
21+
22+
for i in range(32):
23+
buffer_.buffer[i] = i8(i + 1)
24+
buffer_clink_.buffer[i] = i8(i + 2)
25+
26+
for i in range(32):
27+
print(i, buffer_.buffer[i], buffer_clink_.buffer[i])
28+
assert buffer_.buffer[i] == i8(i + 1)
29+
assert buffer_clink_.buffer[i] == i8(i + 2)
30+
assert buffer_clink_.buffer[i] - buffer_.buffer[i] == i8(1)
31+
32+
f()

src/libasr/asr_utils.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,23 @@ static inline ASR::ttype_t* symbol_type(const ASR::symbol_t *f)
111111
return nullptr;
112112
}
113113

114+
static inline ASR::abiType symbol_abi(const ASR::symbol_t *f)
115+
{
116+
switch( f->type ) {
117+
case ASR::symbolType::Variable: {
118+
return ASR::down_cast<ASR::Variable_t>(f)->m_abi;
119+
}
120+
case ASR::symbolType::EnumType: {
121+
return ASR::down_cast<ASR::EnumType_t>(f)->m_abi;
122+
}
123+
default: {
124+
throw LCompilersException("Cannot return ABI of, " +
125+
std::to_string(f->type) + " symbol.");
126+
}
127+
}
128+
return ASR::abiType::Source;
129+
}
130+
114131
static inline ASR::ttype_t* get_contained_type(ASR::ttype_t* asr_type) {
115132
switch( asr_type->type ) {
116133
case ASR::ttypeType::List: {
@@ -138,6 +155,20 @@ static inline ASR::ttype_t* get_contained_type(ASR::ttype_t* asr_type) {
138155
}
139156
}
140157

158+
static inline ASR::abiType expr_abi(ASR::expr_t* e) {
159+
switch( e->type ) {
160+
case ASR::exprType::Var: {
161+
return ASRUtils::symbol_abi(ASR::down_cast<ASR::Var_t>(e)->m_v);
162+
}
163+
case ASR::exprType::StructInstanceMember: {
164+
return ASRUtils::symbol_abi(ASR::down_cast<ASR::StructInstanceMember_t>(e)->m_m);
165+
}
166+
default:
167+
throw LCompilersException("Cannot extract the ABI of " +
168+
std::to_string(e->type) + " expression.");
169+
}
170+
}
171+
141172
static inline std::string type_to_str(const ASR::ttype_t *t)
142173
{
143174
switch (t->type) {
@@ -1369,6 +1400,19 @@ inline int extract_dimensions_from_ttype(ASR::ttype_t *x,
13691400
return n_dims;
13701401
}
13711402

1403+
static inline bool is_fixed_size_array(ASR::dimension_t* m_dims, size_t n_dims) {
1404+
if( n_dims == 0 ) {
1405+
return false;
1406+
}
1407+
for( size_t i = 0; i < n_dims; i++ ) {
1408+
int64_t dim_size = -1;
1409+
if( !ASRUtils::extract_value(ASRUtils::expr_value(m_dims[i].m_length), dim_size) ) {
1410+
return false;
1411+
}
1412+
}
1413+
return true;
1414+
}
1415+
13721416
inline int extract_n_dims_from_ttype(ASR::ttype_t *x) {
13731417
ASR::dimension_t* m_dims_temp = nullptr;
13741418
return extract_dimensions_from_ttype(x, m_dims_temp);

src/libasr/codegen/asr_to_c.cpp

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,13 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
147147
std::string mem_var_name = current_scope->get_unique_name(itr.first + std::to_string(counter));
148148
counter += 1;
149149
sub += indent + convert_variable_decl(*mem_var, true, true, true, true, mem_var_name) + ";\n";
150-
sub += indent + name + "->" + itr.first + " = " + mem_var_name + ";\n";
150+
if( mem_var->m_abi == ASR::abiType::BindC &&
151+
ASR::is_a<ASR::Integer_t>(*mem_var->m_type) &&
152+
ASRUtils::extract_kind_from_ttype_t(mem_var->m_type) == 1 ) {
153+
sub += indent + "strcpy(" + name + "->" + itr.first + ", " + mem_var_name + ");\n";
154+
} else {
155+
sub += indent + name + "->" + itr.first + " = " + mem_var_name + ";\n";
156+
}
151157
} else if( ASR::is_a<ASR::Struct_t>(*mem_type) ) {
152158
ASR::Struct_t* struct_t = ASR::down_cast<ASR::Struct_t>(mem_type);
153159
ASR::StructType_t* struct_type_t = ASR::down_cast<ASR::StructType_t>(
@@ -238,16 +244,26 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
238244
if( is_array ) {
239245
bool is_fixed_size = true;
240246
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size, true);
241-
std::string encoded_type_name = "i" + std::to_string(t->m_kind * 8);
242-
bool is_struct_type_member = ASR::is_a<ASR::StructType_t>(
243-
*ASR::down_cast<ASR::symbol_t>(v.m_parent_symtab->asr_owner));
244-
generate_array_decl(sub, std::string(v.m_name), type_name, dims,
245-
encoded_type_name, t->m_dims, t->n_dims,
246-
use_ref, dummy,
247-
(v.m_intent != ASRUtils::intent_in &&
248-
v.m_intent != ASRUtils::intent_inout &&
249-
v.m_intent != ASRUtils::intent_out &&
250-
!is_struct_type_member) || force_declare, is_fixed_size);
247+
if( t->m_kind == 1 && v.m_abi == ASR::abiType::BindC && is_fixed_size ) {
248+
if( !force_declare ) {
249+
force_declare_name = std::string(v.m_name);
250+
}
251+
sub = "char " + force_declare_name + dims;
252+
} else {
253+
std::string encoded_type_name = "i" + std::to_string(t->m_kind * 8);
254+
bool is_struct_type_member = ASR::is_a<ASR::StructType_t>(
255+
*ASR::down_cast<ASR::symbol_t>(v.m_parent_symtab->asr_owner));
256+
if( !force_declare ) {
257+
force_declare_name = std::string(v.m_name);
258+
}
259+
generate_array_decl(sub, force_declare_name, type_name, dims,
260+
encoded_type_name, t->m_dims, t->n_dims,
261+
use_ref, dummy,
262+
(v.m_intent != ASRUtils::intent_in &&
263+
v.m_intent != ASRUtils::intent_inout &&
264+
v.m_intent != ASRUtils::intent_out &&
265+
!is_struct_type_member) || force_declare, is_fixed_size);
266+
}
251267
} else {
252268
bool is_fixed_size = true;
253269
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
@@ -1024,9 +1040,18 @@ R"(
10241040
this->visit_expr(*x.m_v);
10251041
std::string array = src;
10261042
std::string out = array;
1043+
ASR::ttype_t* x_mv_type = ASRUtils::expr_type(x.m_v);
10271044
ASR::dimension_t* m_dims;
1028-
ASRUtils::extract_dimensions_from_ttype(ASRUtils::expr_type(x.m_v), m_dims);
1029-
out += "->data[";
1045+
int n_dims = ASRUtils::extract_dimensions_from_ttype(x_mv_type, m_dims);
1046+
bool is_i8_array = (ASR::is_a<ASR::Integer_t>(*x_mv_type) &&
1047+
ASRUtils::extract_kind_from_ttype_t(x_mv_type) == 1 &&
1048+
ASRUtils::is_fixed_size_array(m_dims, n_dims) &&
1049+
ASRUtils::expr_abi(x.m_v) == ASR::abiType::BindC);
1050+
if( is_i8_array ) {
1051+
out += "[";
1052+
} else {
1053+
out += "->data[";
1054+
}
10301055
std::string index = "";
10311056
for (size_t i=0; i<x.n_args; i++) {
10321057
std::string current_index = "";
@@ -1036,13 +1061,24 @@ R"(
10361061
src = "/* FIXME right index */";
10371062
}
10381063

1039-
current_index += "(" + src + " - " + array + "->dims["
1040-
+ std::to_string(i) + "].lower_bound)";
1041-
for( size_t j = i + 1; j < x.n_args; j++ ) {
1042-
std::string length = array + "->dims[" + std::to_string(j) + "].length";
1043-
current_index += " * " + length;
1064+
if( is_i8_array ) {
1065+
current_index += src;
1066+
for( size_t j = i + 1; j < x.n_args; j++ ) {
1067+
int64_t dim_size;
1068+
ASRUtils::extract_value(m_dims[j].m_length, dim_size);
1069+
std::string length = std::to_string(dim_size);
1070+
current_index += " * " + length;
1071+
}
1072+
index += current_index;
1073+
} else {
1074+
current_index += "(" + src + " - " + array + "->dims["
1075+
+ std::to_string(i) + "].lower_bound)";
1076+
for( size_t j = i + 1; j < x.n_args; j++ ) {
1077+
std::string length = array + "->dims[" + std::to_string(j) + "].length";
1078+
current_index += " * " + length;
1079+
}
1080+
index += current_index;
10441081
}
1045-
index += current_index;
10461082
if (i < x.n_args - 1) {
10471083
index += " + ";
10481084
}

src/libasr/codegen/asr_to_c_cpp.h

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,41 @@ R"(#include <stdio.h>
719719
alloc = indent + target + " = " + "(char *) malloc((strlen(" +
720720
value + ") + 1 ) * sizeof(char));\n";
721721
}
722-
src += alloc + indent + c_ds_api->get_deepcopy(m_target_type, value, target) + "\n";
722+
if( ASRUtils::is_array(m_target_type) && ASRUtils::is_array(m_value_type) ) {
723+
bool is_target_i8_array = (ASR::is_a<ASR::Integer_t>(*m_target_type) &&
724+
ASRUtils::extract_kind_from_ttype_t(m_target_type) == 1 &&
725+
ASRUtils::expr_abi(x.m_target) == ASR::abiType::BindC);
726+
bool is_value_i8_array = (ASR::is_a<ASR::Integer_t>(*m_value_type) &&
727+
ASRUtils::extract_kind_from_ttype_t(m_value_type) == 1 &&
728+
ASRUtils::expr_abi(x.m_value) == ASR::abiType::BindC);
729+
bool is_target_fixed_size = false, is_value_fixed_size = false;
730+
if( is_target_i8_array ) {
731+
ASR::Integer_t* target_integer_t = ASR::down_cast<ASR::Integer_t>(m_target_type);
732+
if( ASRUtils::is_fixed_size_array(target_integer_t->m_dims, target_integer_t->n_dims) ) {
733+
is_target_fixed_size = true;
734+
}
735+
}
736+
if( is_value_i8_array ) {
737+
ASR::Integer_t* value_integer_t = ASR::down_cast<ASR::Integer_t>(m_value_type);
738+
if( ASRUtils::is_fixed_size_array(value_integer_t->m_dims, value_integer_t->n_dims) ) {
739+
is_value_fixed_size = true;
740+
}
741+
}
742+
if( (is_target_i8_array && is_target_fixed_size) ||
743+
(is_value_i8_array && is_value_fixed_size) ) {
744+
if( !(is_target_i8_array && is_target_fixed_size) ) {
745+
target = "(char*) " + target + "->data";
746+
}
747+
if( !(is_value_i8_array && is_value_fixed_size) ) {
748+
value = "(char*) " + value + "->data";
749+
}
750+
src += indent + "strcpy(" + target + ", " + value + ");\n";
751+
} else {
752+
src += alloc + indent + c_ds_api->get_deepcopy(m_target_type, value, target) + "\n";
753+
}
754+
} else {
755+
src += alloc + indent + c_ds_api->get_deepcopy(m_target_type, value, target) + "\n";
756+
}
723757
} else {
724758
src += indent + c_ds_api->get_deepcopy(m_target_type, value, target) + "\n";
725759
}
@@ -879,7 +913,7 @@ R"(#include <stdio.h>
879913
step = "1";
880914
}
881915
self().visit_expr(*x.m_a);
882-
916+
883917
ASR::ttype_t* t_ttype = ASRUtils::expr_type(x.m_a);
884918
ASR::List_t* t = ASR::down_cast<ASR::List_t>(t_ttype);
885919
std::string list_var = std::move(src);

0 commit comments

Comments
 (0)