Skip to content

Commit

Permalink
Updated code base to use length attribute of ASR::dimension_t
Browse files Browse the repository at this point in the history
  • Loading branch information
czgdp1807 committed Jul 19, 2022
1 parent 064bdfc commit 984965d
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 93 deletions.
53 changes: 48 additions & 5 deletions src/libasr/asr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -604,14 +604,14 @@ static inline bool extract_value(ASR::expr_t* value_expr, T& value) {
static inline std::string type_python_1dim_helper(const std::string & res,
const ASR::dimension_t* e )
{
if( !e->m_end && !e->m_start ) {
if( !e->m_length && !e->m_start ) {
return res + "[:]";
}

if( ASRUtils::expr_value(e->m_end) ) {
int64_t end_dim = -1;
ASRUtils::extract_value(ASRUtils::expr_value(e->m_end), end_dim);
return res + "[" + std::to_string(end_dim + 1) + "]";
if( ASRUtils::expr_value(e->m_length) ) {
int64_t length_dim = -1;
ASRUtils::extract_value(ASRUtils::expr_value(e->m_length), length_dim);
return res + "[" + std::to_string(length_dim + 1) + "]";
}

return res;
Expand Down Expand Up @@ -1401,6 +1401,49 @@ class LabelGenerator {
ASR::asr_t* make_Cast_t_value(Allocator &al, const Location &a_loc,
ASR::expr_t* a_arg, ASR::cast_kindType a_kind, ASR::ttype_t* a_type);

static inline ASR::expr_t* compute_end_from_start_length(Allocator& al, ASR::expr_t* start, ASR::expr_t* length) {
ASR::expr_t* start_value = ASRUtils::expr_value(start);
ASR::expr_t* length_value = ASRUtils::expr_value(length);
ASR::expr_t* end_value = nullptr;
if( start_value && length_value ) {
int64_t start_int, length_int;
ASRUtils::extract_value(start_value, start_int);
ASRUtils::extract_value(length_value, length_int);
end_value = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, start->base.loc,
length_int + start_int - 1,
ASRUtils::expr_type(start)));
}
ASR::expr_t* diff = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, length->base.loc, length,
ASR::binopType::Add, start, ASRUtils::expr_type(length),
nullptr));
ASR::expr_t *constant_one = ASR::down_cast<ASR::expr_t>(ASR::make_IntegerConstant_t(
al, diff->base.loc, 1, ASRUtils::expr_type(diff)));
return ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, length->base.loc, diff,
ASR::binopType::Sub, constant_one, ASRUtils::expr_type(length),
end_value));
}

static inline ASR::expr_t* compute_length_from_start_end(Allocator& al, ASR::expr_t* start, ASR::expr_t* end) {
ASR::expr_t* start_value = ASRUtils::expr_value(start);
ASR::expr_t* end_value = ASRUtils::expr_value(end);
ASR::expr_t* length_value = nullptr;
if( start_value && end_value ) {
int64_t start_int, end_int;
ASRUtils::extract_value(start_value, start_int);
ASRUtils::extract_value(end_value, end_int);
length_value = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, start->base.loc,
end_int - start_int + 1,
ASRUtils::expr_type(start)));
}
ASR::expr_t* diff = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, end->base.loc, end,
ASR::binopType::Sub, start, ASRUtils::expr_type(end),
nullptr));
ASR::expr_t *constant_one = ASR::down_cast<ASR::expr_t>(ASR::make_IntegerConstant_t(
al, diff->base.loc, 1, ASRUtils::expr_type(diff)));
return ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, end->base.loc, diff,
ASR::binopType::Add, constant_one, ASRUtils::expr_type(end),
length_value));
}

} // namespace ASRUtils

Expand Down
29 changes: 13 additions & 16 deletions src/libasr/codegen/asr_to_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,22 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
int64_t default_lower_bound)
: BaseCCPPVisitor(diag, platform, false, false, true, default_lower_bound),
array_types_decls(std::string("\nstruct dimension_descriptor\n"
"{\n int32_t lower_bound, upper_bound;\n};\n")) {
"{\n int32_t lower_bound, length;\n};\n")) {
}

std::string convert_dims_c(size_t n_dims, ASR::dimension_t *m_dims)
{
std::string dims;
for (size_t i=0; i<n_dims; i++) {
ASR::expr_t *start = m_dims[i].m_start;
ASR::expr_t *end = m_dims[i].m_end;
if (!start && !end) {
ASR::expr_t *length = m_dims[i].m_length;
if (!length) {
dims += "*";
} else if (start && end) {
ASR::expr_t* start_value = ASRUtils::expr_value(start);
ASR::expr_t* end_value = ASRUtils::expr_value(end);
if( start_value && end_value ) {
int64_t start_int = -1, end_int = -1;
ASRUtils::extract_value(start_value, start_int);
ASRUtils::extract_value(end_value, end_int);
dims += "[" + std::to_string(end_int - start_int + 1) + "]";
} else if (length) {
ASR::expr_t* length_value = ASRUtils::expr_value(length);
if( length_value ) {
int64_t length_int = -1;
ASRUtils::extract_value(length_value, length_int);
dims += "[" + std::to_string(length_int) + "]";
} else {
dims += "[ /* FIXME symbolic dimensions */ ]";
}
Expand Down Expand Up @@ -124,13 +121,13 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
sub += indent + std::string(v_m_name) +
"->dims[" + std::to_string(i) + "].lower_bound = 0" + ";\n";
}
if( m_dims[i].m_end ) {
this->visit_expr(*m_dims[i].m_end);
if( m_dims[i].m_length ) {
this->visit_expr(*m_dims[i].m_length);
sub += indent + std::string(v_m_name) +
"->dims[" + std::to_string(i) + "].upper_bound = " + src + ";\n";
"->dims[" + std::to_string(i) + "].length = " + src + ";\n";
} else {
sub += indent + std::string(v_m_name) +
"->dims[" + std::to_string(i) + "].upper_bound = -1" + ";\n";
"->dims[" + std::to_string(i) + "].length = 0" + ";\n";
}
}
sub.pop_back();
Expand Down
30 changes: 14 additions & 16 deletions src/libasr/codegen/asr_to_cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,26 +68,24 @@ class ASRToCPPVisitor : public BaseCCPPVisitor<ASRToCPPVisitor>
: BaseCCPPVisitor(diag, platform, true, true, false,
default_lower_bound),
array_types_decls(std::string("\nstruct dimension_descriptor\n"
"{\n int32_t lower_bound, upper_bound;\n};\n")) {}
"{\n int32_t lower_bound, length;\n};\n")) {}

std::string convert_dims(size_t n_dims, ASR::dimension_t *m_dims, size_t& size)
{
std::string dims;
size = 1;
for (size_t i=0; i<n_dims; i++) {
ASR::expr_t *start = m_dims[i].m_start;
ASR::expr_t *end = m_dims[i].m_end;
if (!start && !end) {
ASR::expr_t *length = m_dims[i].m_length;
if (!length) {
dims += "*";
} else if (start && end) {
ASR::expr_t* start_value = ASRUtils::expr_value(start);
ASR::expr_t* end_value = ASRUtils::expr_value(end);
if( start_value && end_value ) {
int64_t start_int = -1, end_int = -1;
ASRUtils::extract_value(start_value, start_int);
ASRUtils::extract_value(end_value, end_int);
size *= (end_int - start_int + 1);
dims += "[" + std::to_string(end_int - start_int + 1) + "]";
} else if (length) {
ASR::expr_t* length_value = ASRUtils::expr_value(length);
if( length_value ) {
int64_t length_int = -1;
ASRUtils::extract_value(length_value, length_int);
size *= (length_int);
dims += "[" + std::to_string(length_int) + "]";
} else {
size = 0;
dims += "[ /* FIXME symbolic dimensions */ ]";
Expand Down Expand Up @@ -175,13 +173,13 @@ class ASRToCPPVisitor : public BaseCCPPVisitor<ASRToCPPVisitor>
sub += indent + std::string(v_m_name) +
"->dims[" + std::to_string(i) + "].lower_bound = 0" + ";\n";
}
if( m_dims[i].m_end ) {
this->visit_expr(*m_dims[i].m_end);
if( m_dims[i].m_length ) {
this->visit_expr(*m_dims[i].m_length);
sub += indent + std::string(v_m_name) +
"->dims[" + std::to_string(i) + "].upper_bound = " + src + ";\n";
"->dims[" + std::to_string(i) + "].length = " + src + ";\n";
} else {
sub += indent + std::string(v_m_name) +
"->dims[" + std::to_string(i) + "].upper_bound = -1" + ";\n";
"->dims[" + std::to_string(i) + "].length = 0" + ";\n";
}
}
sub.pop_back();
Expand Down
8 changes: 3 additions & 5 deletions src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
}
bool is_ok = true;
for( int r = 0; r < n_dims; r++ ) {
if( m_dims[r].m_end == nullptr ) {
if( m_dims[r].m_length == nullptr ) {
is_ok = false;
break;
}
Expand Down Expand Up @@ -382,7 +382,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
ASR::dimension_t m_dim = m_dims[r];
visit_expr(*(m_dim.m_start));
llvm::Value* start = tmp;
visit_expr(*(m_dim.m_end));
visit_expr(*(m_dim.m_length));
llvm::Value* end = tmp;
llvm_dims.push_back(std::make_pair(start, end));
}
Expand All @@ -401,7 +401,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
ASR::dimension_t m_dim = m_dims[r];
visit_expr(*(m_dim.m_start));
llvm::Value* start = tmp;
visit_expr(*(m_dim.m_end));
visit_expr(*(m_dim.m_length));
llvm::Value* end = tmp;
llvm_dims.push_back(std::make_pair(start, end));
}
Expand Down Expand Up @@ -2762,13 +2762,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
llvm::Value* curr_dim = llvm::ConstantInt::get(context, llvm::APInt(32, i));
llvm::Value* desi = arr_descr->get_pointer_to_dimension_descriptor(fptr_des, curr_dim);
llvm::Value* desi_lb = arr_descr->get_lower_bound(desi, false);
llvm::Value* desi_ub = arr_descr->get_upper_bound(desi, false);
llvm::Value* desi_size = arr_descr->get_dimension_size(fptr_des, curr_dim, false);
llvm::Value* i32_one = llvm::ConstantInt::get(context, llvm::APInt(32, 1));
llvm::Value* new_lb = i32_one;
llvm::Value* new_ub = shape_data ? builder->CreateLoad(llvm_utils->create_ptr_gep(shape_data, i)) : i32_one;
builder->CreateStore(new_lb, desi_lb);
builder->CreateStore(new_ub, desi_ub);
builder->CreateStore(builder->CreateAdd(builder->CreateSub(new_ub, new_lb), i32_one), desi_size);
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/libasr/codegen/asr_to_py.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ class ASRToPyVisitor : public ASR::BaseVisitor<ASRToPyVisitor>
if (down_cast<ASR::IntegerConstant_t>(lbound_ptr)->m_n != 1) { \
throw CodeGenError(errmsg1); \
} \
if (is_a<ASR::Var_t>(*tmp_arg->m_dims[j].m_end)) { \
ASR::Variable_t *dimvar = ASRUtils::EXPR2VAR(tmp_arg->m_dims[j].m_end); \
if (is_a<ASR::Var_t>(*tmp_arg->m_dims[j].m_length)) { \
ASR::Variable_t *dimvar = ASRUtils::EXPR2VAR(tmp_arg->m_dims[j].m_length); \
this_arg_info.ubound_varnames.push_back(dimvar->m_name); \
} else if (!is_a<ASR::IntegerConstant_t>(*lbound_ptr)) { \
throw CodeGenError(errmsg2); \
Expand Down
51 changes: 15 additions & 36 deletions src/libasr/codegen/llvm_array_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ namespace LFortran {
}
bool is_ok = true;
for( int r = 0; r < n_dims; r++ ) {
if( m_dims[r].m_end == nullptr &&
if( m_dims[r].m_length == nullptr &&
m_dims[r].m_start == nullptr ) {
is_ok = false;
break;
}
if( (m_dims[r].m_end != nullptr &&
m_dims[r].m_end->type != ASR::exprType::IntegerConstant) ||
if( (m_dims[r].m_length != nullptr &&
m_dims[r].m_length->type != ASR::exprType::IntegerConstant) ||
(m_dims[r].m_start != nullptr &&
m_dims[r].m_start->type != ASR::exprType::IntegerConstant) ) {
is_ok = false;
Expand Down Expand Up @@ -108,7 +108,6 @@ namespace LFortran {
context,
std::vector<llvm::Type*>(
{llvm::Type::getInt32Ty(context),
llvm::Type::getInt32Ty(context),
llvm::Type::getInt32Ty(context),
llvm::Type::getInt32Ty(context)}),
"dimension_descriptor")
Expand Down Expand Up @@ -284,7 +283,7 @@ namespace LFortran {

llvm::Value* SimpleCMODescriptor::
get_dimension_size(llvm::Value* dim_des_arr, llvm::Value* dim, bool load) {
llvm::Value* dim_size = llvm_utils->create_gep(llvm_utils->create_ptr_gep(dim_des_arr, dim), 3);
llvm::Value* dim_size = llvm_utils->create_gep(llvm_utils->create_ptr_gep(dim_des_arr, dim), 2);
if( !load ) {
return dim_size;
}
Expand All @@ -308,32 +307,18 @@ namespace LFortran {
llvm::Value* dim_val = llvm_utils->create_ptr_gep(dim_des_val, r);
llvm::Value* s_val = llvm_utils->create_gep(dim_val, 0);
llvm::Value* l_val = llvm_utils->create_gep(dim_val, 1);
llvm::Value* u_val = llvm_utils->create_gep(dim_val, 2);
llvm::Value* dim_size_ptr = llvm_utils->create_gep(dim_val, 3);
llvm::Value* dim_size_ptr = llvm_utils->create_gep(dim_val, 2);
builder->CreateStore(llvm::ConstantInt::get(context, llvm::APInt(32, 1)), s_val);
builder->CreateStore(llvm_dims[r].first, l_val);
builder->CreateStore(llvm_dims[r].second, u_val);
u_val = LLVM::CreateLoad(*builder, u_val);
l_val = LLVM::CreateLoad(*builder, l_val);
llvm::Value* dim_size = builder->CreateAdd(builder->CreateSub(u_val, l_val),
llvm::ConstantInt::get(context, llvm::APInt(32, 1)));
llvm::Value* dim_size = llvm_dims[r].second;
builder->CreateStore(dim_size, dim_size_ptr);
}

llvm::Value* llvm_size = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr);
llvm::Value* const_1 = llvm::ConstantInt::get(context, llvm::APInt(32, 1));
llvm::Value* prod = const_1;
for( int r = 0; r < n_dims; r++ ) {
llvm::Value *m_start, *m_end;
ASR::dimension_t m_dim = m_dims[r];
if( m_dim.m_start != nullptr ) {
m_start = llvm_dims[r].first;
} else {
m_start = const_1;
}
m_end = llvm_dims[r].second;
llvm::Value* dim_size_1 = builder->CreateSub(m_end, m_start);
llvm::Value* dim_size = builder->CreateAdd(dim_size_1, const_1);
llvm::Value* dim_size = llvm_dims[r].second;
prod = builder->CreateMul(prod, dim_size);
}
builder->CreateStore(prod, llvm_size);
Expand All @@ -359,15 +344,10 @@ namespace LFortran {
llvm::Value* dim_val = llvm_utils->create_ptr_gep(dim_des_val, r);
llvm::Value* s_val = llvm_utils->create_gep(dim_val, 0);
llvm::Value* l_val = llvm_utils->create_gep(dim_val, 1);
llvm::Value* u_val = llvm_utils->create_gep(dim_val, 2);
llvm::Value* dim_size_ptr = llvm_utils->create_gep(dim_val, 3);
llvm::Value* dim_size_ptr = llvm_utils->create_gep(dim_val, 2);
builder->CreateStore(llvm::ConstantInt::get(context, llvm::APInt(32, 1)), s_val);
builder->CreateStore(llvm_dims[r].first, l_val);
builder->CreateStore(llvm_dims[r].second, u_val);
u_val = LLVM::CreateLoad(*builder, u_val);
l_val = LLVM::CreateLoad(*builder, l_val);
llvm::Value* dim_size = builder->CreateAdd(builder->CreateSub(u_val, l_val),
llvm::ConstantInt::get(context, llvm::APInt(32, 1)));
llvm::Value* dim_size = llvm_dims[r].second;
num_elements = builder->CreateMul(num_elements, dim_size);
builder->CreateStore(dim_size, dim_size_ptr);
}
Expand Down Expand Up @@ -419,12 +399,11 @@ namespace LFortran {
return LLVM::CreateLoad(*builder, lb);
}

llvm::Value* SimpleCMODescriptor::get_upper_bound(llvm::Value* dim_des, bool load) {
llvm::Value* ub = llvm_utils->create_gep(dim_des, 2);
if( !load ) {
return ub;
}
return LLVM::CreateLoad(*builder, ub);
llvm::Value* SimpleCMODescriptor::get_upper_bound(llvm::Value* dim_des) {
llvm::Value* lb = LLVM::CreateLoad(*builder, llvm_utils->create_gep(dim_des, 1));
llvm::Value* dim_size = LLVM::CreateLoad(*builder, llvm_utils->create_gep(dim_des, 2));
return builder->CreateSub(builder->CreateAdd(dim_size, lb),
llvm::ConstantInt::get(context, llvm::APInt(32, 1)));
}

llvm::Value* SimpleCMODescriptor::get_stride(llvm::Value*) {
Expand All @@ -450,7 +429,7 @@ namespace LFortran {
// check_single_element(curr_llvm_idx, arr); TODO: To be implemented
}
idx = builder->CreateAdd(idx, builder->CreateMul(prod, curr_llvm_idx));
llvm::Value* dim_size = LLVM::CreateLoad(*builder, llvm_utils->create_gep(dim_des_ptr, 3));
llvm::Value* dim_size = LLVM::CreateLoad(*builder, llvm_utils->create_gep(dim_des_ptr, 2));
prod = builder->CreateMul(prod, dim_size);
}
return idx;
Expand Down
4 changes: 2 additions & 2 deletions src/libasr/codegen/llvm_array_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ namespace LFortran {
* implemented by current class.
*/
virtual
llvm::Value* get_upper_bound(llvm::Value* dim_des, bool load=true) = 0;
llvm::Value* get_upper_bound(llvm::Value* dim_des) = 0;

/*
* Returns stride in the input
Expand Down Expand Up @@ -338,7 +338,7 @@ namespace LFortran {
llvm::Value* get_lower_bound(llvm::Value* dim_des, bool load=true);

virtual
llvm::Value* get_upper_bound(llvm::Value* dim_des, bool load=true);
llvm::Value* get_upper_bound(llvm::Value* dim_des);

virtual
llvm::Value* get_dimension_size(llvm::Value* dim_des_arr,
Expand Down
Loading

0 comments on commit 984965d

Please sign in to comment.