Skip to content

Commit 28473bd

Browse files
Merge pull request #1110 from Thirumalai-Shaktivel/if_api
2 parents 6de9758 + 5a75f6f commit 28473bd

File tree

1 file changed

+84
-84
lines changed

1 file changed

+84
-84
lines changed

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 84 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,59 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
279279
builder->SetInsertPoint(bb);
280280
}
281281

282+
// Note: `create_if_else` and `create_loop` are optional APIs
283+
// that do not have to be used. Many times, for more complicated
284+
// things, it might be more readable to just use the LLVM API
285+
// without any extra layer on top. In some other cases, it might
286+
// be more readable to use this abstraction.
287+
template <typename IF, typename ELSE>
288+
void create_if_else(llvm::Value * cond, IF if_block, ELSE else_block) {
289+
llvm::Function *fn = builder->GetInsertBlock()->getParent();
290+
291+
llvm::BasicBlock *thenBB = llvm::BasicBlock::Create(context, "then", fn);
292+
llvm::BasicBlock *elseBB = llvm::BasicBlock::Create(context, "else");
293+
llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create(context, "ifcont");
294+
295+
builder->CreateCondBr(cond, thenBB, elseBB);
296+
builder->SetInsertPoint(thenBB); {
297+
if_block();
298+
}
299+
builder->CreateBr(mergeBB);
300+
301+
start_new_block(elseBB); {
302+
else_block();
303+
}
304+
start_new_block(mergeBB);
305+
}
306+
307+
template <typename Cond, typename Body>
308+
void create_loop(Cond condition, Body loop_body) {
309+
dict_api_lp->set_iterators();
310+
dict_api_sc->set_iterators();
311+
llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head");
312+
llvm::BasicBlock *loopbody = llvm::BasicBlock::Create(context, "loop.body");
313+
llvm::BasicBlock *loopend = llvm::BasicBlock::Create(context, "loop.end");
314+
this->current_loophead = loophead;
315+
this->current_loopend = loopend;
316+
317+
// head
318+
start_new_block(loophead); {
319+
llvm::Value* cond = condition();
320+
builder->CreateCondBr(cond, loopbody, loopend);
321+
}
322+
323+
// body
324+
start_new_block(loopbody); {
325+
loop_body();
326+
builder->CreateBr(loophead);
327+
}
328+
329+
// end
330+
start_new_block(loopend);
331+
dict_api_lp->reset_iterators();
332+
dict_api_sc->reset_iterators();
333+
}
334+
282335
inline bool verify_dimensions_t(ASR::dimension_t* m_dims, int n_dims) {
283336
if( n_dims <= 0 ) {
284337
return false;
@@ -1116,17 +1169,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
11161169
fetch_var(v);
11171170
if( x.class_type == ASR::stmtType::ImplicitDeallocate ) {
11181171
llvm::Value *cond = arr_descr->get_is_allocated_flag(tmp);
1119-
llvm::Function *fn = builder->GetInsertBlock()->getParent();
1120-
llvm::BasicBlock *thenBB = llvm::BasicBlock::Create(context, "then", fn);
1121-
llvm::BasicBlock *elseBB = llvm::BasicBlock::Create(context, "else");
1122-
llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create(context, "ifcont");
1123-
builder->CreateCondBr(cond, thenBB, elseBB);
1124-
builder->SetInsertPoint(thenBB);
1125-
//print_util(cond, "%d");
1126-
call_lfortran_free(free_fn);
1127-
builder->CreateBr(mergeBB);
1128-
start_new_block(elseBB);
1129-
start_new_block(mergeBB);
1172+
create_if_else(cond, [=]() {
1173+
call_lfortran_free(free_fn);
1174+
}, [](){});
11301175
} else {
11311176
call_lfortran_free(free_fn);
11321177
}
@@ -3811,73 +3856,42 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
38113856

38123857
void visit_If(const ASR::If_t &x) {
38133858
this->visit_expr_wrapper(x.m_test, true);
3814-
llvm::Value *cond=tmp;
3815-
llvm::Function *fn = builder->GetInsertBlock()->getParent();
3816-
llvm::BasicBlock *thenBB = llvm::BasicBlock::Create(context, "then", fn);
3817-
llvm::BasicBlock *elseBB = llvm::BasicBlock::Create(context, "else");
3818-
llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create(context, "ifcont");
3819-
builder->CreateCondBr(cond, thenBB, elseBB);
3820-
builder->SetInsertPoint(thenBB);
3821-
for (size_t i=0; i<x.n_body; i++) {
3822-
this->visit_stmt(*x.m_body[i]);
3823-
}
3824-
builder->CreateBr(mergeBB);
3825-
3826-
start_new_block(elseBB);
3827-
for (size_t i=0; i<x.n_orelse; i++) {
3828-
this->visit_stmt(*x.m_orelse[i]);
3829-
}
3830-
3831-
start_new_block(mergeBB);
3859+
create_if_else(tmp, [=]() {
3860+
for (size_t i=0; i<x.n_body; i++) {
3861+
this->visit_stmt(*x.m_body[i]);
3862+
}
3863+
}, [=]() {
3864+
for (size_t i=0; i<x.n_orelse; i++) {
3865+
this->visit_stmt(*x.m_orelse[i]);
3866+
}
3867+
});
38323868
}
38333869

38343870
void visit_IfExp(const ASR::IfExp_t &x) {
38353871
// IfExp(expr test, expr body, expr orelse, ttype type, expr? value)
38363872
this->visit_expr_wrapper(x.m_test, true);
38373873
llvm::Value *cond = tmp;
3838-
llvm::Function *fn = builder->GetInsertBlock()->getParent();
3839-
llvm::BasicBlock *thenBB = llvm::BasicBlock::Create(context, "then", fn);
3840-
llvm::BasicBlock *elseBB = llvm::BasicBlock::Create(context, "else");
3841-
llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create(context, "ifcont");
3842-
builder->CreateCondBr(cond, thenBB, elseBB);
3843-
builder->SetInsertPoint(thenBB);
3844-
this->visit_expr_wrapper(x.m_body, true);
3845-
llvm::Value *then_val = tmp;
3846-
builder->CreateBr(mergeBB);
3847-
start_new_block(elseBB);
3848-
this->visit_expr_wrapper(x.m_orelse, true);
3849-
llvm::Value *else_val = tmp;
3850-
builder->CreateBr(mergeBB);
3851-
start_new_block(mergeBB);
3874+
llvm::Value *then_val = nullptr;
3875+
llvm::Value *else_val = nullptr;
3876+
create_if_else(cond, [=, &then_val]() {
3877+
this->visit_expr_wrapper(x.m_body, true);
3878+
then_val = tmp;
3879+
}, [=, &else_val]() {
3880+
this->visit_expr_wrapper(x.m_orelse, true);
3881+
else_val = tmp;
3882+
});
38523883
tmp = builder->CreateSelect(cond, then_val, else_val);
38533884
}
38543885

38553886
void visit_WhileLoop(const ASR::WhileLoop_t &x) {
3856-
dict_api_lp->set_iterators();
3857-
dict_api_sc->set_iterators();
3858-
llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head");
3859-
llvm::BasicBlock *loopbody = llvm::BasicBlock::Create(context, "loop.body");
3860-
llvm::BasicBlock *loopend = llvm::BasicBlock::Create(context, "loop.end");
3861-
this->current_loophead = loophead;
3862-
this->current_loopend = loopend;
3863-
3864-
// head
3865-
start_new_block(loophead);
3866-
this->visit_expr_wrapper(x.m_test, true);
3867-
llvm::Value *cond = tmp;
3868-
builder->CreateCondBr(cond, loopbody, loopend);
3869-
3870-
// body
3871-
start_new_block(loopbody);
3872-
for (size_t i=0; i<x.n_body; i++) {
3873-
this->visit_stmt(*x.m_body[i]);
3874-
}
3875-
builder->CreateBr(loophead);
3876-
3877-
// end
3878-
start_new_block(loopend);
3879-
dict_api_lp->reset_iterators();
3880-
dict_api_sc->reset_iterators();
3887+
create_loop([=]() {
3888+
this->visit_expr_wrapper(x.m_test, true);
3889+
return tmp;
3890+
}, [=]() {
3891+
for (size_t i=0; i<x.n_body; i++) {
3892+
this->visit_stmt(*x.m_body[i]);
3893+
}
3894+
});
38813895
}
38823896

38833897
void visit_Exit(const ASR::Exit_t & /* x */) {
@@ -4447,19 +4461,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
44474461

44484462
void visit_Assert(const ASR::Assert_t &x) {
44494463
this->visit_expr_wrapper(x.m_test, true);
4450-
llvm::Value *cond = tmp;
4451-
llvm::Function *fn = builder->GetInsertBlock()->getParent();
4452-
llvm::BasicBlock *thenBB = llvm::BasicBlock::Create(context, "then", fn);
4453-
llvm::BasicBlock *elseBB = llvm::BasicBlock::Create(context, "else");
4454-
llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create(context, "ifcont");
4455-
builder->CreateCondBr(cond, thenBB, elseBB);
4456-
builder->SetInsertPoint(thenBB);
4457-
4458-
builder->CreateBr(mergeBB);
4459-
4460-
start_new_block(elseBB);
4461-
4462-
{
4464+
create_if_else(tmp, []() {}, [=]() {
44634465
if (x.m_msg) {
44644466
char* s = ASR::down_cast<ASR::StringConstant_t>(x.m_msg)->m_s;
44654467
llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr("AssertionError: %s\n");
@@ -4473,9 +4475,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
44734475
llvm::Value *exit_code = llvm::ConstantInt::get(context,
44744476
llvm::APInt(32, exit_code_int));
44754477
exit(context, *module, *builder, exit_code);
4476-
}
4477-
4478-
start_new_block(mergeBB);
4478+
});
44794479
}
44804480

44814481
void visit_ComplexConstructor(const ASR::ComplexConstructor_t &x) {

0 commit comments

Comments
 (0)