Skip to content

Commit

Permalink
Nullify in ASR, LLVM
Browse files Browse the repository at this point in the history
  • Loading branch information
dpoerio committed Jan 4, 2022
1 parent 06a5975 commit 15005fe
Show file tree
Hide file tree
Showing 18 changed files with 202 additions and 0 deletions.
1 change: 1 addition & 0 deletions grammar/ASR.asdl
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ stmt
| SubroutineCall(symbol name, symbol? original_name, expr* args, expr? dt)
| Where(expr test, stmt* body, stmt* orelse)
| WhileLoop(expr test, stmt* body)
| Nullify(symbol* vars)


expr
Expand Down
12 changes: 12 additions & 0 deletions integration_tests/nullify_01.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
program nullify_01
implicit none

integer, pointer :: p1, p2
integer, target :: t1

p1=>t1
p2=>t1
p1 = 1
nullify(p1, p2)

end program nullify_01
16 changes: 16 additions & 0 deletions integration_tests/nullify_02.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
program nullify_02
implicit none

real, pointer :: p1
real, target :: t1
integer, pointer :: p2
integer, target :: t2

p1=>t1
p1 = 1
p2=>t2
p2 = 2.
nullify(p1, p2)


end program nullify_02
33 changes: 33 additions & 0 deletions src/lfortran/semantics/ast_body_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,39 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
tmp = ASR::make_ErrorStop_t(al, x.base.base.loc, code);
}

void visit_Nullify(const AST::Nullify_t &x) {
Vec<ASR::symbol_t*> arg_vec;
arg_vec.reserve(al, x.n_args);
for( size_t i = 0; i < x.n_args; i++ ) {
this->visit_expr(*(x.m_args[i]));
ASR::expr_t* tmp_expr = LFortran::ASRUtils::EXPR(tmp);
if( tmp_expr->type != ASR::exprType::Var ) {
throw SemanticError("Only a pointer variable symbol "
"can be nullified.",
tmp_expr->base.loc);
} else {
const ASR::Var_t* tmp_var = ASR::down_cast<ASR::Var_t>(tmp_expr);
ASR::symbol_t* tmp_sym = tmp_var->m_v;
if( LFortran::ASRUtils::symbol_get_past_external(tmp_sym)->type
!= ASR::symbolType::Variable ) {
throw SemanticError("Only a pointer variable symbol "
"can be nullified.",
tmp_expr->base.loc);
} else {
ASR::Variable_t* tmp_v = ASR::down_cast<ASR::Variable_t>(tmp_sym);
if (ASR::is_a<ASR::Pointer_t>(*tmp_v->m_type)) {
arg_vec.push_back(al, tmp_sym);
} else {
throw SemanticError("Only a pointer variable symbol "
"can be nullified.",
tmp_expr->base.loc);
}
}
}
}
tmp = ASR::make_Nullify_t(al, x.base.base.loc, arg_vec.p, arg_vec.size());
}

};

Result<ASR::TranslationUnit_t*> body_visitor(Allocator &al,
Expand Down
11 changes: 11 additions & 0 deletions src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,17 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
}
}

void visit_Nullify(const ASR::Nullify_t& x) {
for( size_t i = 0; i < x.n_vars; i++ ) {
std::uint32_t h = get_hash((ASR::asr_t*)x.m_vars[i]);
llvm::Value *target = llvm_symtab[h];
llvm::Type* tp = target->getType()->getContainedType(0);
llvm::Value* np = builder->CreateIntToPtr(
llvm::ConstantInt::get(context, llvm::APInt(32, 0)), tp);
builder->CreateStore(np, target);
}
}

inline void call_lfortran_free(llvm::Function* fn) {
llvm::Value* arr = builder->CreateLoad(arr_descr->get_pointer_to_data(tmp));
llvm::AllocaInst *arg_arr = builder->CreateAlloca(character_type, nullptr);
Expand Down
13 changes: 13 additions & 0 deletions tests/reference/asr-nullify_01-09aa501.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "asr-nullify_01-09aa501",
"cmd": "lfortran --show-asr --no-color {infile} -o {outfile}",
"infile": "tests/../integration_tests/nullify_01.f90",
"infile_hash": "5869e698f080612903a66a6001fa03b7b3390371a5a9eef3ca48a545",
"outfile": null,
"outfile_hash": null,
"stdout": "asr-nullify_01-09aa501.stdout",
"stdout_hash": "4cf7b13ba6cf51c300539d58843aa752f0eb5185e9712690b11bc9d8",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
1 change: 1 addition & 0 deletions tests/reference/asr-nullify_01-09aa501.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(TranslationUnit (SymbolTable 1 {nullify_01: (Program (SymbolTable 2 {p1: (Variable 2 p1 Local () () Default (Pointer (Integer 4 [])) Source Public Required .false.), p2: (Variable 2 p2 Local () () Default (Pointer (Integer 4 [])) Source Public Required .false.), t1: (Variable 2 t1 Local () () Default (Integer 4 []) Source Public Required .false.)}) nullify_01 [] [(=> (Var 2 p1) (Var 2 t1)) (=> (Var 2 p2) (Var 2 t1)) (= (Var 2 p1) (ConstantInteger 1 (Integer 4 [])) ()) (Nullify [2 p1 2 p2])])}) [])
13 changes: 13 additions & 0 deletions tests/reference/asr-nullify_02-1f0bd3a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "asr-nullify_02-1f0bd3a",
"cmd": "lfortran --show-asr --no-color {infile} -o {outfile}",
"infile": "tests/../integration_tests/nullify_02.f90",
"infile_hash": "8603bbfc07290d14f0828e12a8b04c3521c007c844a4c901b4bb7483",
"outfile": null,
"outfile_hash": null,
"stdout": "asr-nullify_02-1f0bd3a.stdout",
"stdout_hash": "6d3127f42329e3029bd4d604dce4b3a9ad7515db5fff04b9673a05c5",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
1 change: 1 addition & 0 deletions tests/reference/asr-nullify_02-1f0bd3a.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(TranslationUnit (SymbolTable 1 {nullify_02: (Program (SymbolTable 2 {p1: (Variable 2 p1 Local () () Default (Pointer (Real 4 [])) Source Public Required .false.), p2: (Variable 2 p2 Local () () Default (Pointer (Integer 4 [])) Source Public Required .false.), t1: (Variable 2 t1 Local () () Default (Real 4 []) Source Public Required .false.), t2: (Variable 2 t2 Local () () Default (Integer 4 []) Source Public Required .false.)}) nullify_02 [] [(=> (Var 2 p1) (Var 2 t1)) (= (Var 2 p1) (ImplicitCast (ConstantInteger 1 (Integer 4 [])) IntegerToReal (Pointer (Real 4 [])) (ConstantReal 1.000000 (Real 4 []))) ()) (=> (Var 2 p2) (Var 2 t2)) (= (Var 2 p2) (ImplicitCast (ConstantReal 2.000000 (Real 4 [])) RealToInteger (Pointer (Integer 4 [])) (ConstantInteger 2 (Integer 4 []))) ()) (Nullify [2 p1 2 p2])])}) [])
13 changes: 13 additions & 0 deletions tests/reference/ast-nullify_01-24b8fbc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "ast-nullify_01-24b8fbc",
"cmd": "lfortran --show-ast --no-color {infile} -o {outfile}",
"infile": "tests/../integration_tests/nullify_01.f90",
"infile_hash": "5869e698f080612903a66a6001fa03b7b3390371a5a9eef3ca48a545",
"outfile": null,
"outfile_hash": null,
"stdout": "ast-nullify_01-24b8fbc.stdout",
"stdout_hash": "fef0d9bd9b7a0c9e990f66d6973b62f8c9e736885a21e5f3f1a28999",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
1 change: 1 addition & 0 deletions tests/reference/ast-nullify_01-24b8fbc.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(TranslationUnit [(Program nullify_01 () [] [(ImplicitNone [] (TriviaNode [] [(EndOfLine) (EndOfLine)]))] [(Declaration (AttrType TypeInteger [] () None) [(SimpleAttribute AttrPointer)] [(p1 [] [] () None ()) (p2 [] [] () None ())] ()) (Declaration (AttrType TypeInteger [] () None) [(SimpleAttribute AttrTarget)] [(t1 [] [] () None ())] (TriviaNode [] [(EndOfLine) (EndOfLine)]))] [(=> 0 p1 t1 ()) (=> 0 p2 t1 ()) (= 0 p1 1 ()) (Nullify 0 [p1 p2] [] (TriviaNode [] [(EndOfLine) (EndOfLine)]))] [])])
13 changes: 13 additions & 0 deletions tests/reference/ast-nullify_02-1c6befe.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "ast-nullify_02-1c6befe",
"cmd": "lfortran --show-ast --no-color {infile} -o {outfile}",
"infile": "tests/../integration_tests/nullify_02.f90",
"infile_hash": "8603bbfc07290d14f0828e12a8b04c3521c007c844a4c901b4bb7483",
"outfile": null,
"outfile_hash": null,
"stdout": "ast-nullify_02-1c6befe.stdout",
"stdout_hash": "15fe1c8febd35a74a234d8e519186802feb86ae388cf89cc6a10e982",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
1 change: 1 addition & 0 deletions tests/reference/ast-nullify_02-1c6befe.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(TranslationUnit [(Program nullify_02 () [] [(ImplicitNone [] (TriviaNode [] [(EndOfLine) (EndOfLine)]))] [(Declaration (AttrType TypeReal [] () None) [(SimpleAttribute AttrPointer)] [(p1 [] [] () None ())] ()) (Declaration (AttrType TypeReal [] () None) [(SimpleAttribute AttrTarget)] [(t1 [] [] () None ())] ()) (Declaration (AttrType TypeInteger [] () None) [(SimpleAttribute AttrPointer)] [(p2 [] [] () None ())] ()) (Declaration (AttrType TypeInteger [] () None) [(SimpleAttribute AttrTarget)] [(t2 [] [] () None ())] (TriviaNode [] [(EndOfLine) (EndOfLine)]))] [(=> 0 p1 t1 ()) (= 0 p1 1 ()) (=> 0 p2 t2 ()) (= 0 p2 (Real "2.") ()) (Nullify 0 [p1 p2] [] (TriviaNode [] [(EndOfLine) (EndOfLine) (EndOfLine)]))] [])])
13 changes: 13 additions & 0 deletions tests/reference/llvm-nullify_01-810c9d3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "llvm-nullify_01-810c9d3",
"cmd": "lfortran --no-color --show-llvm {infile} -o {outfile}",
"infile": "tests/../integration_tests/nullify_01.f90",
"infile_hash": "5869e698f080612903a66a6001fa03b7b3390371a5a9eef3ca48a545",
"outfile": null,
"outfile_hash": null,
"stdout": "llvm-nullify_01-810c9d3.stdout",
"stdout_hash": "7ff2dae193a77a7dcc5945817fd0be794570e0641e5fa252c92d9653",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
16 changes: 16 additions & 0 deletions tests/reference/llvm-nullify_01-810c9d3.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; ModuleID = 'LFortran'
source_filename = "LFortran"

define i32 @main() {
.entry:
%p1 = alloca i32*, align 8
%p2 = alloca i32*, align 8
%t1 = alloca i32, align 4
store i32* %t1, i32** %p1, align 8
store i32* %t1, i32** %p2, align 8
%0 = load i32*, i32** %p1, align 8
store i32 1, i32* %0, align 4
store i32* null, i32** %p1, align 8
store i32* null, i32** %p2, align 8
ret i32 0
}
13 changes: 13 additions & 0 deletions tests/reference/llvm-nullify_02-3c7ee61.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "llvm-nullify_02-3c7ee61",
"cmd": "lfortran --no-color --show-llvm {infile} -o {outfile}",
"infile": "tests/../integration_tests/nullify_02.f90",
"infile_hash": "8603bbfc07290d14f0828e12a8b04c3521c007c844a4c901b4bb7483",
"outfile": null,
"outfile_hash": null,
"stdout": "llvm-nullify_02-3c7ee61.stdout",
"stdout_hash": "258af1fc233e90af6360f3cb9cf6c388b862ef603ba273748f60bf44",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
19 changes: 19 additions & 0 deletions tests/reference/llvm-nullify_02-3c7ee61.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; ModuleID = 'LFortran'
source_filename = "LFortran"

define i32 @main() {
.entry:
%p1 = alloca float*, align 8
%p2 = alloca i32*, align 8
%t1 = alloca float, align 4
%t2 = alloca i32, align 4
store float* %t1, float** %p1, align 8
%0 = load float*, float** %p1, align 8
store float 1.000000e+00, float* %0, align 4
store i32* %t2, i32** %p2, align 8
%1 = load i32*, i32** %p2, align 8
store i32 2, i32* %1, align 4
store float* null, float** %p1, align 8
store i32* null, i32** %p2, align 8
ret i32 0
}
12 changes: 12 additions & 0 deletions tests/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1789,3 +1789,15 @@ ast_f90 = true
[[test]]
filename = "../integration_tests/forall_01.f90"
asr = true

[[test]]
filename = "../integration_tests/nullify_01.f90"
ast = true
asr = true
llvm = true

[[test]]
filename = "../integration_tests/nullify_02.f90"
ast = true
asr = true
llvm = true

0 comments on commit 15005fe

Please sign in to comment.