Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c59581e

Browse files
ubaidskAgent-Hellboy
authored andcommitted
C: Support visit_Associate()
1 parent 1740e1d commit c59581e

File tree

1 file changed

+174
-24
lines changed

1 file changed

+174
-24
lines changed

src/libasr/codegen/asr_to_c_cpp.h

Lines changed: 174 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,33 +1428,183 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
14281428
from_std_vector_helper.clear();
14291429
}
14301430

1431-
void visit_Associate(const ASR::Associate_t &x) {
1432-
std::string indent(indentation_level*indentation_spaces, ' ');
1433-
if (ASR::is_a<ASR::ArraySection_t>(*x.m_value)) {
1434-
self().visit_expr(*x.m_target);
1435-
std::string target = std::move(src);
1436-
// ArraySection(expr v, array_index* args, ttype type, expr? value)
1437-
ASR::ArraySection_t *as = ASR::down_cast<ASR::ArraySection_t>(x.m_value);
1438-
self().visit_expr(*as->m_v);
1439-
std::string value = std::move(src);
1440-
std::string c = "";
1441-
for( size_t i = 0; i < as->n_args; i++ ) {
1442-
std::string left, right, step;
1443-
if (as->m_args[i].m_left) {
1444-
self().visit_expr(*as->m_args[i].m_left);
1445-
left = std::move(src);
1446-
}
1447-
if (as->m_args[i].m_right) {
1448-
self().visit_expr(*as->m_args[i].m_right);
1449-
right = std::move(src);
1431+
std::string cmo_convertor_single_element(
1432+
std::string arr, std::vector<std::string>& m_args,
1433+
int n_args, bool check_for_bounds) {
1434+
std::string dim_des_arr_ptr = arr + "->dims";
1435+
std::string idx = "0";
1436+
for( int r = 0; r < n_args; r++ ) {
1437+
std::string curr_llvm_idx = m_args[r];
1438+
std::string dim_des_ptr = dim_des_arr_ptr + "[" + std::to_string(r) + "]";
1439+
std::string lval = dim_des_ptr + ".lower_bound";
1440+
curr_llvm_idx = "(" + curr_llvm_idx + " - " + lval + ")";
1441+
if( check_for_bounds ) {
1442+
// check_single_element(curr_llvm_idx, arr); TODO: To be implemented
1443+
}
1444+
std::string stride = dim_des_ptr + ".stride";
1445+
idx = "(" + idx + " + (" + stride + " * " + curr_llvm_idx + "))";
1446+
}
1447+
std::string offset_val = arr + "->offset";
1448+
return "(" + idx + " + " + offset_val + ")";
1449+
}
1450+
1451+
std::string cmo_convertor_single_element_data_only(
1452+
std::vector<std::string>& diminfo, std::vector<std::string>& m_args,
1453+
int n_args, bool check_for_bounds, bool is_unbounded_pointer_to_data) {
1454+
std::string prod = "1";
1455+
std::string idx = "0";
1456+
if (is_unbounded_pointer_to_data) {
1457+
for (int r = 0; r < n_args; r++) {
1458+
std::string curr_llvm_idx = m_args[r];
1459+
std::string lval = diminfo[r];
1460+
curr_llvm_idx = "(" + curr_llvm_idx + " - " + lval + ")";
1461+
if( check_for_bounds ) {
1462+
// check_single_element(curr_llvm_idx, arr); TODO: To be implemented
14501463
}
1451-
if (as->m_args[i].m_step) {
1452-
self().visit_expr(*as->m_args[i].m_step);
1453-
step = std::move(src);
1464+
idx = "(" + idx + " + " + "(" + curr_llvm_idx + ")" + ")";
1465+
}
1466+
return idx;
1467+
}
1468+
for( int r = n_args - 1, r1 = 2 * n_args - 1; r >= 0; r--, r1 -= 2) {
1469+
std::string curr_llvm_idx = m_args[r];
1470+
std::string lval = diminfo[r1 - 1];
1471+
curr_llvm_idx = "(" + curr_llvm_idx + " - " + lval + ")";
1472+
if( check_for_bounds ) {
1473+
// check_single_element(curr_llvm_idx, arr); TODO: To be implemented
1474+
}
1475+
idx = "(" + idx + " + " + "(" + prod + " * " + curr_llvm_idx + ")" + ")";
1476+
std::string dim_size = diminfo[r1];
1477+
prod = "(" + prod + " * " + dim_size + ")";
1478+
}
1479+
return idx;
1480+
}
1481+
1482+
std::string arr_get_single_element(std::string array,
1483+
std::vector<std::string>& m_args, int n_args, bool data_only,
1484+
bool is_fixed_size, std::vector<std::string>& diminfo, bool is_unbounded_pointer_to_data) {
1485+
std::string tmp = "";
1486+
// TODO: Uncomment later
1487+
// bool check_for_bounds = is_explicit_shape(v);
1488+
bool check_for_bounds = false;
1489+
std::string idx = "";
1490+
if( data_only || is_fixed_size ) {
1491+
LCOMPILERS_ASSERT(diminfo.size() > 0);
1492+
idx = cmo_convertor_single_element_data_only(diminfo, m_args, n_args, check_for_bounds, is_unbounded_pointer_to_data);
1493+
if( is_fixed_size ) {
1494+
tmp = array + "->data[" + idx + "]" ;
1495+
} else {
1496+
tmp = array + "->data[" + idx + "]";
1497+
}
1498+
} else {
1499+
idx = cmo_convertor_single_element(array, m_args, n_args, check_for_bounds);
1500+
std::string full_array = array + "->data";
1501+
tmp = full_array + "[" + idx + "]";
1502+
}
1503+
return tmp;
1504+
}
1505+
1506+
void fill_descriptor_for_array_section_data_only(std::string value_desc, std::string target_desc,
1507+
std::vector<std::string>& lbs, std::vector<std::string>& ubs, std::vector<std::string>& ds, std::vector<std::string>& non_sliced_indices,
1508+
std::vector<std::string>& diminfo, int value_rank, int target_rank) {
1509+
std::string indent(indentation_level * indentation_spaces, ' ');
1510+
std::vector<std::string> section_first_indices;
1511+
for( int i = 0; i < value_rank; i++ ) {
1512+
if( ds[i] != "" ) {
1513+
LCOMPILERS_ASSERT(lbs[i] != "");
1514+
section_first_indices.push_back(lbs[i]);
1515+
} else {
1516+
LCOMPILERS_ASSERT(non_sliced_indices[i] != "");
1517+
section_first_indices.push_back(non_sliced_indices[i]);
14541518
}
1455-
c += left + ":" + right + ":" + step + ",";
14561519
}
1457-
src = indent + target + "= " + value + "; // TODO: " + value + "(" + c + ")\n";
1520+
std::string target_offset = cmo_convertor_single_element_data_only(
1521+
diminfo, section_first_indices, value_rank, false, false);
1522+
1523+
value_desc = "(" + value_desc + " + " + target_offset + ")";
1524+
std::string update_target_desc = "";
1525+
update_target_desc += indent + target_desc + "->data = " + value_desc + ";\n";
1526+
1527+
update_target_desc += indent + target_desc + "->offset = 0;\n"; // offset not available yet
1528+
1529+
std::string target_dim_des_array = target_desc + "->dims";
1530+
int j = target_rank - 1;
1531+
int r = (int)diminfo.size() - 1;
1532+
std::string stride = "1";
1533+
for( int i = value_rank - 1; i >= 0; i-- ) {
1534+
if( ds[i] != "" ) {
1535+
std::string dim_length = "(((" + ubs[i] + " - " + lbs[i] + ")" + "/" + ds[i] + ") + 1)";
1536+
std::string target_dim_des = target_dim_des_array + "[" + std::to_string(j) + "]";
1537+
update_target_desc += indent + target_dim_des + ".stride = " + stride + ";\n";
1538+
update_target_desc += indent + target_dim_des + ".lower_bound = 1;\n";
1539+
update_target_desc += indent + target_dim_des + ".length = " + dim_length + ";\n";
1540+
j--;
1541+
}
1542+
stride = "(" + stride + "*" + diminfo[r] + ")";
1543+
r -= 2;
1544+
}
1545+
LCOMPILERS_ASSERT(j == -1);
1546+
update_target_desc += indent + target_desc + "->n_dims = " + std::to_string(target_rank) + ";\n";
1547+
src = update_target_desc;
1548+
}
1549+
1550+
void handle_array_section_association_to_pointer(const ASR::Associate_t& x) {
1551+
ASR::ArraySection_t* array_section = ASR::down_cast<ASR::ArraySection_t>(x.m_value);
1552+
self().visit_expr(*array_section->m_v);
1553+
std::string value_desc = src;
1554+
1555+
self().visit_expr(*x.m_target);
1556+
std::string target_desc = src;
1557+
1558+
int value_rank = array_section->n_args, target_rank = 0;
1559+
std::vector<std::string> lbs(value_rank);
1560+
std::vector<std::string> ubs(value_rank);
1561+
std::vector<std::string> ds(value_rank);
1562+
std::vector<std::string> non_sliced_indices(value_rank);
1563+
for( int i = 0; i < value_rank; i++ ) {
1564+
lbs[i] = ""; ubs[i] = ""; ds[i] = "";
1565+
non_sliced_indices[i] = "";
1566+
if( array_section->m_args[i].m_step != nullptr ) {
1567+
self().visit_expr(*array_section->m_args[i].m_left);
1568+
lbs[i] = src;
1569+
self().visit_expr(*array_section->m_args[i].m_right);
1570+
ubs[i] = src;
1571+
self().visit_expr(*array_section->m_args[i].m_step);
1572+
ds[i] = src;
1573+
target_rank++;
1574+
} else {
1575+
self().visit_expr(*array_section->m_args[i].m_right);
1576+
non_sliced_indices[i] = src;
1577+
}
1578+
}
1579+
LCOMPILERS_ASSERT(target_rank > 0);
1580+
1581+
ASR::ttype_t* array_type = ASRUtils::expr_type(array_section->m_v);
1582+
if( ASRUtils::extract_physical_type(array_type) == ASR::array_physical_typeType::PointerToDataArray ||
1583+
ASRUtils::extract_physical_type(array_type) == ASR::array_physical_typeType::FixedSizeArray ) {
1584+
value_desc = value_desc + "->data";
1585+
ASR::dimension_t* m_dims = nullptr;
1586+
// Fill in m_dims:
1587+
[[maybe_unused]] int array_value_rank = ASRUtils::extract_dimensions_from_ttype(array_type, m_dims);
1588+
LCOMPILERS_ASSERT(array_value_rank == value_rank);
1589+
std::vector<std::string> diminfo;
1590+
diminfo.reserve(value_rank * 2);
1591+
for( int i = 0; i < value_rank; i++ ) {
1592+
self().visit_expr(*m_dims[i].m_start);
1593+
diminfo.push_back(src);
1594+
self().visit_expr(*m_dims[i].m_length);
1595+
diminfo.push_back(src);
1596+
}
1597+
fill_descriptor_for_array_section_data_only(value_desc, target_desc,
1598+
lbs, ubs, ds, non_sliced_indices,
1599+
diminfo, value_rank, target_rank);
1600+
} else {
1601+
throw CodeGenError("Only Pointer to Data Array or Fixed Size array supported for now");
1602+
}
1603+
}
1604+
1605+
void visit_Associate(const ASR::Associate_t &x) {
1606+
if (ASR::is_a<ASR::ArraySection_t>(*x.m_value)) {
1607+
handle_array_section_association_to_pointer(x);
14581608
} else {
14591609
throw CodeGenError("Associate only implemented for ArraySection so far");
14601610
}

0 commit comments

Comments
 (0)