@@ -279,6 +279,59 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
279
279
builder->SetInsertPoint (bb);
280
280
}
281
281
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
+
282
335
inline bool verify_dimensions_t (ASR::dimension_t * m_dims, int n_dims) {
283
336
if ( n_dims <= 0 ) {
284
337
return false ;
@@ -1116,17 +1169,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
1116
1169
fetch_var (v);
1117
1170
if ( x.class_type == ASR::stmtType::ImplicitDeallocate ) {
1118
1171
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
+ }, [](){});
1130
1175
} else {
1131
1176
call_lfortran_free (free_fn);
1132
1177
}
@@ -3811,73 +3856,42 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
3811
3856
3812
3857
void visit_If (const ASR::If_t &x) {
3813
3858
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
+ });
3832
3868
}
3833
3869
3834
3870
void visit_IfExp (const ASR::IfExp_t &x) {
3835
3871
// IfExp(expr test, expr body, expr orelse, ttype type, expr? value)
3836
3872
this ->visit_expr_wrapper (x.m_test , true );
3837
3873
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
+ });
3852
3883
tmp = builder->CreateSelect (cond, then_val, else_val);
3853
3884
}
3854
3885
3855
3886
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
+ });
3881
3895
}
3882
3896
3883
3897
void visit_Exit (const ASR::Exit_t & /* x */ ) {
@@ -4447,19 +4461,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
4447
4461
4448
4462
void visit_Assert (const ASR::Assert_t &x) {
4449
4463
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, []() {}, [=]() {
4463
4465
if (x.m_msg ) {
4464
4466
char * s = ASR::down_cast<ASR::StringConstant_t>(x.m_msg )->m_s ;
4465
4467
llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr (" AssertionError: %s\n " );
@@ -4473,9 +4475,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
4473
4475
llvm::Value *exit_code = llvm::ConstantInt::get (context,
4474
4476
llvm::APInt (32 , exit_code_int));
4475
4477
exit (context, *module , *builder, exit_code);
4476
- }
4477
-
4478
- start_new_block (mergeBB);
4478
+ });
4479
4479
}
4480
4480
4481
4481
void visit_ComplexConstructor (const ASR::ComplexConstructor_t &x) {
0 commit comments