Skip to content

Commit 5901096

Browse files
authored
Merge pull request #42 from czgdp1807/lc_24
Ported ``integration_tests/arrays_op_29.f90`` from LFortran and improve LC to support it
2 parents 3aa037f + 5afbd51 commit 5901096

File tree

4 files changed

+80
-9
lines changed

4 files changed

+80
-9
lines changed

integration_tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,5 @@ RUN(NAME array_11.cpp LABELS gcc llvm NOFAST
202202
EXTRA_ARGS --extra-arg=-I${CONDA_PREFIX}/include)
203203
RUN(NAME array_12.cpp LABELS gcc llvm NOFAST
204204
EXTRA_ARGS --extra-arg=-I${CONDA_PREFIX}/include)
205+
RUN(NAME array_13.cpp LABELS gcc llvm NOFAST
206+
EXTRA_ARGS --extra-arg=-I${CONDA_PREFIX}/include)

integration_tests/array_13.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <iostream>
2+
#include <cmath>
3+
#include <xtensor/xtensor.hpp>
4+
#include <xtensor/xfixed.hpp>
5+
#include "xtensor/xio.hpp"
6+
#include "xtensor/xview.hpp"
7+
8+
xt::xtensor<double, 1> R3(const xt::xtensor<double, 1>& x) {
9+
xt::xtensor<double, 1> R3_ = xt::empty<double>({x.size()});
10+
11+
double a, b;
12+
const double c = 2.0;
13+
a = x(0);
14+
b = x(1);
15+
R3_.fill(std::pow(a, 2.0) + std::pow(b, 2.0) - std::pow(c, 2.0));
16+
17+
return R3_;
18+
}
19+
20+
int main() {
21+
22+
xt::xtensor_fixed<double, xt::xshape<2>> x = {0.5, 0.5};
23+
std::cout << R3(x) << std::endl;
24+
if( xt::any(xt::not_equal(R3(x), -3.5)) ) {
25+
exit(2);
26+
}
27+
28+
return 0;
29+
30+
}

src/lc/clang_ast_to_asr.h

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ enum SpecialFunc {
4545
AMax,
4646
Sum,
4747
Range,
48+
Size,
49+
Pow,
4850
};
4951

5052
std::map<std::string, SpecialFunc> special_function_map = {
@@ -62,6 +64,8 @@ std::map<std::string, SpecialFunc> special_function_map = {
6264
{"amax", SpecialFunc::AMax},
6365
{"sum", SpecialFunc::Sum},
6466
{"range", SpecialFunc::Range},
67+
{"size", SpecialFunc::Size},
68+
{"pow", SpecialFunc::Pow},
6569
};
6670

6771
class OneTimeUseString {
@@ -438,6 +442,9 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
438442
intent_type = ASR::intentType::In;
439443
type = ASRUtils::type_get_past_const(type);
440444
}
445+
if( ASRUtils::is_allocatable(type) ) {
446+
type = ASRUtils::type_get_past_allocatable(type);
447+
}
441448
if( x->getType()->getTypeClass() != clang::Type::LValueReference &&
442449
ASRUtils::is_array(type) ) {
443450
throw std::runtime_error("Array objects should be passed by reference only.");
@@ -496,7 +503,8 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
496503
TraverseStmt(callee);
497504
ASR::expr_t* asr_callee = ASRUtils::EXPR(tmp.get());
498505
if( !check_and_handle_special_function(x, asr_callee) ) {
499-
throw std::runtime_error("Only xt::xtensor::shape, xt::xtensor::fill is supported.");
506+
throw std::runtime_error("Only xt::xtensor::shape, "
507+
"xt::xtensor::fill, xt::xtensor::size is supported.");
500508
}
501509

502510
return true;
@@ -764,6 +772,14 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
764772
tmp = ASR::make_ArraySize_t(al, Lloc(x), callee, dim,
765773
ASRUtils::TYPE(ASR::make_Integer_t(al, Lloc(x), 4)),
766774
nullptr);
775+
} else if (sf == SpecialFunc::Size) {
776+
if( args.size() != 0 ) {
777+
throw std::runtime_error("xt::xtensor::size should be called with only one argument.");
778+
}
779+
780+
tmp = ASR::make_ArraySize_t(al, Lloc(x), callee, nullptr,
781+
ASRUtils::TYPE(ASR::make_Integer_t(al, Lloc(x), 4)),
782+
nullptr);
767783
} else if (sf == SpecialFunc::Fill) {
768784
if( args.size() != 1 ) {
769785
throw std::runtime_error("xt::xtensor::fill should be called with only one argument.");
@@ -804,6 +820,12 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
804820
tmp = ASRUtils::make_IntrinsicScalarFunction_t_util(al, Lloc(x),
805821
static_cast<int64_t>(ASRUtils::IntrinsicScalarFunctions::Exp),
806822
args.p, args.size(), 0, ASRUtils::expr_type(args.p[0]), nullptr);
823+
} else if( sf == SpecialFunc::Pow ) {
824+
if( args.size() != 2 ) {
825+
throw std::runtime_error("Pow accepts exactly two arguments.");
826+
}
827+
828+
CreateBinOp(args.p[0], args.p[1], ASR::binopType::Pow, Lloc(x));
807829
} else if( sf == SpecialFunc::Abs ) {
808830
tmp = ASRUtils::make_IntrinsicScalarFunction_t_util(al, Lloc(x),
809831
static_cast<int64_t>(ASRUtils::IntrinsicScalarFunctions::Abs),
@@ -1215,6 +1237,19 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
12151237
}
12161238
}
12171239

1240+
void CreateUnaryMinus(ASR::expr_t* op, const Location& loc) {
1241+
if( ASRUtils::is_integer(*ASRUtils::expr_type(op)) ) {
1242+
tmp = ASR::make_IntegerUnaryMinus_t(al, loc, op,
1243+
ASRUtils::expr_type(op), nullptr);
1244+
} else if( ASRUtils::is_real(*ASRUtils::expr_type(op)) ) {
1245+
tmp = ASR::make_RealUnaryMinus_t(al, loc, op,
1246+
ASRUtils::expr_type(op), nullptr);
1247+
} else {
1248+
throw std::runtime_error("Only integer and real types are supported so "
1249+
"far for unary operator, found: " + ASRUtils::type_to_str(ASRUtils::expr_type(op)));
1250+
}
1251+
}
1252+
12181253
bool TraverseBinaryOperator(clang::BinaryOperator *x) {
12191254
clang::BinaryOperatorKind op = x->getOpcode();
12201255
TraverseStmt(x->getLHS());
@@ -1311,7 +1346,7 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
13111346
name == "exit" || name == "printf" || name == "exp" ||
13121347
name == "sum" || name == "amax" || name == "abs" ||
13131348
name == "operator-" || name == "operator/" || name == "operator>" ||
1314-
name == "range" ) {
1349+
name == "range" || name == "pow" ) {
13151350
if( sym != nullptr && ASR::is_a<ASR::Function_t>(
13161351
*ASRUtils::symbol_get_past_external(sym)) ) {
13171352
throw std::runtime_error("Special function " + name + " cannot be overshadowed yet.");
@@ -1431,11 +1466,11 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
14311466

14321467
bool TraverseUnaryOperator(clang::UnaryOperator* x) {
14331468
clang::UnaryOperatorKind op = x->getOpcode();
1469+
clang::Expr* expr = x->getSubExpr();
1470+
TraverseStmt(expr);
1471+
ASR::expr_t* var = ASRUtils::EXPR(tmp.get());
14341472
switch( op ) {
14351473
case clang::UnaryOperatorKind::UO_PostInc: {
1436-
clang::Expr* expr = x->getSubExpr();
1437-
TraverseStmt(expr);
1438-
ASR::expr_t* var = ASRUtils::EXPR(tmp.get());
14391474
ASR::expr_t* incbyone = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(
14401475
al, Lloc(x), var, ASR::binopType::Add,
14411476
ASRUtils::EXPR(ASR::make_IntegerConstant_t(
@@ -1445,8 +1480,12 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
14451480
is_stmt_created = true;
14461481
break;
14471482
}
1483+
case clang::UnaryOperatorKind::UO_Minus: {
1484+
CreateUnaryMinus(var, Lloc(x));
1485+
break;
1486+
}
14481487
default: {
1449-
throw std::runtime_error("Only postfix increment is supported so far");
1488+
throw std::runtime_error("Only postfix increment and minus are supported so far.");
14501489
}
14511490
}
14521491
return true;

src/libasr/codegen/llvm_array_utils.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ namespace LCompilers {
602602
int n_args, bool check_for_bounds, bool is_unbounded_pointer_to_data) {
603603
llvm::Value* prod = llvm::ConstantInt::get(context, llvm::APInt(32, 1));
604604
llvm::Value* idx = llvm::ConstantInt::get(context, llvm::APInt(32, 0));
605-
for( int r = 0, r1 = 0; r < n_args; r++ ) {
605+
for( int r = n_args - 1, r1 = 2*n_args - 2; r >= 0; r-- ) {
606606
llvm::Value* curr_llvm_idx = m_args[r];
607607
llvm::Value* lval = llvm_diminfo[r1];
608608
curr_llvm_idx = builder->CreateSub(curr_llvm_idx, lval);
@@ -611,10 +611,10 @@ namespace LCompilers {
611611
}
612612
idx = builder->CreateAdd(idx, builder->CreateMul(prod, curr_llvm_idx));
613613
if (is_unbounded_pointer_to_data) {
614-
r1 += 1;
614+
r1 -= 1;
615615
} else {
616616
llvm::Value* dim_size = llvm_diminfo[r1 + 1];
617-
r1 += 2;
617+
r1 -= 2;
618618
prod = builder->CreateMul(prod, dim_size);
619619
}
620620
}

0 commit comments

Comments
 (0)