@@ -1428,33 +1428,183 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
1428
1428
from_std_vector_helper.clear ();
1429
1429
}
1430
1430
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
1450
1463
}
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]);
1454
1518
}
1455
- c += left + " :" + right + " :" + step + " ," ;
1456
1519
}
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);
1458
1608
} else {
1459
1609
throw CodeGenError (" Associate only implemented for ArraySection so far" );
1460
1610
}
0 commit comments