Skip to content

Commit 9960922

Browse files
Smit-createczgdp1807
authored andcommitted
Refactor and use create_if_else
1 parent 9e5da4c commit 9960922

File tree

3 files changed

+55
-99
lines changed

3 files changed

+55
-99
lines changed

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -281,34 +281,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
281281
builder->SetInsertPoint(bb);
282282
}
283283

284-
// Note: `create_if_else` and `create_loop` are optional APIs
285-
// that do not have to be used. Many times, for more complicated
286-
// things, it might be more readable to just use the LLVM API
287-
// without any extra layer on top. In some other cases, it might
288-
// be more readable to use this abstraction.
289-
// The `if_block` and `else_block` must generate one or more blocks. In
290-
// addition, the `if_block` must not be terminated, we terminate it
291-
// ourselves. The `else_block` can be either terminated or not.
292-
template <typename IF, typename ELSE>
293-
void create_if_else(llvm::Value * cond, IF if_block, ELSE else_block) {
294-
llvm::Function *fn = builder->GetInsertBlock()->getParent();
295-
296-
llvm::BasicBlock *thenBB = llvm::BasicBlock::Create(context, "then", fn);
297-
llvm::BasicBlock *elseBB = llvm::BasicBlock::Create(context, "else");
298-
llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create(context, "ifcont");
299-
300-
builder->CreateCondBr(cond, thenBB, elseBB);
301-
builder->SetInsertPoint(thenBB); {
302-
if_block();
303-
}
304-
builder->CreateBr(mergeBB);
305-
306-
start_new_block(elseBB); {
307-
else_block();
308-
}
309-
start_new_block(mergeBB);
310-
}
311-
312284
template <typename Cond, typename Body>
313285
void create_loop(char *name, Cond condition, Body loop_body) {
314286
dict_api_lp->set_iterators();
@@ -1487,7 +1459,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
14871459
}
14881460
}
14891461
llvm::Value *cond = arr_descr->get_is_allocated_flag(tmp);
1490-
create_if_else(cond, [=]() {
1462+
llvm_utils->create_if_else(cond, [=]() {
14911463
call_lfortran_free(free_fn);
14921464
}, [](){});
14931465
}
@@ -5151,7 +5123,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
51515123

51525124
void visit_If(const ASR::If_t &x) {
51535125
this->visit_expr_wrapper(x.m_test, true);
5154-
create_if_else(tmp, [=]() {
5126+
llvm_utils->create_if_else(tmp, [=]() {
51555127
for (size_t i=0; i<x.n_body; i++) {
51565128
this->visit_stmt(*x.m_body[i]);
51575129
}
@@ -5168,7 +5140,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
51685140
llvm::Value *cond = tmp;
51695141
llvm::Value *then_val = nullptr;
51705142
llvm::Value *else_val = nullptr;
5171-
create_if_else(cond, [=, &then_val]() {
5143+
llvm_utils->create_if_else(cond, [=, &then_val]() {
51725144
this->visit_expr_wrapper(x.m_body, true);
51735145
then_val = tmp;
51745146
}, [=, &else_val]() {
@@ -5324,7 +5296,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
53245296
}
53255297
switch (x.m_op) {
53265298
case ASR::logicalbinopType::And: {
5327-
create_if_else(cond, [&, result, left_val]() {
5299+
llvm_utils->create_if_else(cond, [&, result, left_val]() {
53285300
LLVM::CreateStore(*builder, left_val, result);
53295301
}, [&, result, right_val]() {
53305302
LLVM::CreateStore(*builder, right_val, result);
@@ -5333,7 +5305,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
53335305
break;
53345306
};
53355307
case ASR::logicalbinopType::Or: {
5336-
create_if_else(cond, [&, result, right_val]() {
5308+
llvm_utils->create_if_else(cond, [&, result, right_val]() {
53375309
LLVM::CreateStore(*builder, right_val, result);
53385310

53395311
}, [&, result, left_val]() {
@@ -5865,7 +5837,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
58655837
void visit_Assert(const ASR::Assert_t &x) {
58665838
if (compiler_options.emit_debug_info) debug_emit_loc(x);
58675839
this->visit_expr_wrapper(x.m_test, true);
5868-
create_if_else(tmp, []() {}, [=]() {
5840+
llvm_utils->create_if_else(tmp, []() {}, [=]() {
58695841
if (compiler_options.emit_debug_info) {
58705842
llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr(infile);
58715843
llvm::Value *fmt_ptr1 = llvm::ConstantInt::get(context, llvm::APInt(

src/libasr/codegen/llvm_utils.cpp

Lines changed: 20 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,26 +1548,16 @@ namespace LCompilers {
15481548
void LLVMDict::_check_key_present_or_default(llvm::Module& module, llvm::Value *key, llvm::Value *key_list,
15491549
ASR::ttype_t* key_asr_type, llvm::Value *value_list, llvm::Value *pos,
15501550
llvm::Value *def_value, llvm::Value* &result) {
1551-
llvm::Function *fn_single_match = builder->GetInsertBlock()->getParent();
1552-
llvm::BasicBlock *thenBB_single_match = llvm::BasicBlock::Create(context, "then", fn_single_match);
1553-
llvm::BasicBlock *elseBB_single_match = llvm::BasicBlock::Create(context, "else");
1554-
llvm::BasicBlock *mergeBB_single_match = llvm::BasicBlock::Create(context, "ifcont");
15551551
llvm::Value* is_key_matching = llvm_utils->is_equal_by_value(key,
15561552
llvm_utils->list_api->read_item(key_list, pos, false, module,
15571553
LLVM::is_llvm_struct(key_asr_type)), module, key_asr_type);
1558-
builder->CreateCondBr(is_key_matching, thenBB_single_match, elseBB_single_match);
1559-
builder->SetInsertPoint(thenBB_single_match);
1560-
{
1554+
llvm_utils->create_if_else(is_key_matching, [&]() {
15611555
llvm::Value* item = llvm_utils->list_api->read_item(value_list, pos,
15621556
false, module, false);
15631557
LLVM::CreateStore(*builder, item, result);
1564-
}
1565-
builder->CreateBr(mergeBB_single_match);
1566-
llvm_utils->start_new_block(elseBB_single_match);
1567-
{
1558+
}, [=]() {
15681559
LLVM::CreateStore(*builder, LLVM::CreateLoad(*builder, def_value), result);
1569-
}
1570-
llvm_utils->start_new_block(mergeBB_single_match);
1560+
});
15711561
}
15721562

15731563
llvm::Value* LLVMDict::resolve_collision_for_read_with_default(
@@ -1621,19 +1611,13 @@ namespace LCompilers {
16211611
// In the above case we will end up returning value for a key
16221612
// which is not present in the dict. Instead we should return an error
16231613
// which is done in the below code.
1624-
llvm::Function *fn_single_match = builder->GetInsertBlock()->getParent();
1625-
llvm::BasicBlock *thenBB_single_match = llvm::BasicBlock::Create(context, "then", fn_single_match);
1626-
llvm::BasicBlock *elseBB_single_match = llvm::BasicBlock::Create(context, "else");
1627-
llvm::BasicBlock *mergeBB_single_match = llvm::BasicBlock::Create(context, "ifcont");
16281614
llvm::Value* is_key_matching = llvm_utils->is_equal_by_value(key,
16291615
llvm_utils->list_api->read_item(key_list, key_hash, false, module,
16301616
LLVM::is_llvm_struct(key_asr_type)), module, key_asr_type);
1631-
builder->CreateCondBr(is_key_matching, thenBB_single_match, elseBB_single_match);
1632-
builder->SetInsertPoint(thenBB_single_match);
1633-
LLVM::CreateStore(*builder, key_hash, pos_ptr);
1634-
builder->CreateBr(mergeBB_single_match);
1635-
llvm_utils->start_new_block(elseBB_single_match);
1636-
{
1617+
1618+
llvm_utils->create_if_else(is_key_matching, [=]() {
1619+
LLVM::CreateStore(*builder, key_hash, pos_ptr);
1620+
}, [&]() {
16371621
std::string message = "The dict does not contain the specified key";
16381622
llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr("KeyError: %s\n");
16391623
llvm::Value *fmt_ptr2 = builder->CreateGlobalStringPtr(message);
@@ -1642,8 +1626,7 @@ namespace LCompilers {
16421626
llvm::Value *exit_code = llvm::ConstantInt::get(context,
16431627
llvm::APInt(32, exit_code_int));
16441628
exit(context, module, *builder, exit_code);
1645-
}
1646-
llvm_utils->start_new_block(mergeBB_single_match);
1629+
});
16471630
}
16481631
builder->CreateBr(mergeBB);
16491632
llvm_utils->start_new_block(elseBB);
@@ -1687,22 +1670,14 @@ namespace LCompilers {
16871670
builder->CreateCondBr(is_prob_not_neeeded, thenBB, elseBB);
16881671
builder->SetInsertPoint(thenBB);
16891672
{
1690-
llvm::Function *fn_single_match = builder->GetInsertBlock()->getParent();
1691-
llvm::BasicBlock *thenBB_single_match = llvm::BasicBlock::Create(context, "then", fn_single_match);
1692-
llvm::BasicBlock *elseBB_single_match = llvm::BasicBlock::Create(context, "else");
1693-
llvm::BasicBlock *mergeBB_single_match = llvm::BasicBlock::Create(context, "ifcont");
16941673
llvm::Value* is_key_matching = llvm_utils->is_equal_by_value(key,
16951674
llvm_utils->list_api->read_item(key_list, key_hash, false, module,
16961675
LLVM::is_llvm_struct(key_asr_type)), module, key_asr_type);
1697-
builder->CreateCondBr(is_key_matching, thenBB_single_match, elseBB_single_match);
1698-
builder->SetInsertPoint(thenBB_single_match);
1699-
LLVM::CreateStore(*builder, key_hash, pos_ptr);
1700-
builder->CreateBr(mergeBB_single_match);
1701-
llvm_utils->start_new_block(elseBB_single_match);
1702-
{
1676+
llvm_utils->create_if_else(is_key_matching, [=]() {
1677+
LLVM::CreateStore(*builder, key_hash, pos_ptr);
1678+
}, [=]() {
17031679
LLVM::CreateStore(*builder, LLVM::CreateLoad(*builder, def_value), result);
1704-
}
1705-
llvm_utils->start_new_block(mergeBB_single_match);
1680+
});
17061681
}
17071682
builder->CreateBr(mergeBB);
17081683
llvm_utils->start_new_block(elseBB);
@@ -1740,10 +1715,6 @@ namespace LCompilers {
17401715
} else {
17411716
tmp_value_ptr_local = builder->CreateBitCast(tmp_value_ptr, value_type->getPointerTo());
17421717
}
1743-
llvm::Function *fn_single_match = builder->GetInsertBlock()->getParent();
1744-
llvm::BasicBlock *thenBB_single_match = llvm::BasicBlock::Create(context, "then", fn_single_match);
1745-
llvm::BasicBlock *elseBB_single_match = llvm::BasicBlock::Create(context, "else");
1746-
llvm::BasicBlock *mergeBB_single_match = llvm::BasicBlock::Create(context, "ifcont");
17471718
llvm::Value* key_mask_value = LLVM::CreateLoad(*builder,
17481719
llvm_utils->create_ptr_gep(key_mask, key_hash));
17491720
llvm::Value* does_kv_exists = builder->CreateICmpEQ(key_mask_value,
@@ -1752,18 +1723,13 @@ namespace LCompilers {
17521723
builder->CreateICmpNE(LLVM::CreateLoad(*builder, chain_itr),
17531724
llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(context)))
17541725
);
1755-
builder->CreateCondBr(does_kv_exists, thenBB_single_match, elseBB_single_match);
1756-
builder->SetInsertPoint(thenBB_single_match);
1757-
{
1726+
1727+
llvm_utils->create_if_else(does_kv_exists, [=]() {
17581728
llvm::Value* kv_struct_i8 = LLVM::CreateLoad(*builder, chain_itr);
17591729
llvm::Value* kv_struct = builder->CreateBitCast(kv_struct_i8, kv_struct_type->getPointerTo());
17601730
llvm::Value* value = LLVM::CreateLoad(*builder, llvm_utils->create_gep(kv_struct, 1));
17611731
LLVM::CreateStore(*builder, value, tmp_value_ptr_local);
1762-
1763-
}
1764-
builder->CreateBr(mergeBB_single_match);
1765-
llvm_utils->start_new_block(elseBB_single_match);
1766-
{
1732+
}, [&]() {
17671733
std::string message = "The dict does not contain the specified key";
17681734
llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr("KeyError: %s\n");
17691735
llvm::Value *fmt_ptr2 = builder->CreateGlobalStringPtr(message);
@@ -1772,8 +1738,7 @@ namespace LCompilers {
17721738
llvm::Value *exit_code = llvm::ConstantInt::get(context,
17731739
llvm::APInt(32, exit_code_int));
17741740
exit(context, module, *builder, exit_code);
1775-
}
1776-
llvm_utils->start_new_block(mergeBB_single_match);
1741+
});
17771742
return tmp_value_ptr;
17781743
}
17791744

@@ -1800,10 +1765,6 @@ namespace LCompilers {
18001765
} else {
18011766
tmp_value_ptr_local = builder->CreateBitCast(tmp_value_ptr, value_type->getPointerTo());
18021767
}
1803-
llvm::Function *fn_single_match = builder->GetInsertBlock()->getParent();
1804-
llvm::BasicBlock *thenBB_single_match = llvm::BasicBlock::Create(context, "then", fn_single_match);
1805-
llvm::BasicBlock *elseBB_single_match = llvm::BasicBlock::Create(context, "else");
1806-
llvm::BasicBlock *mergeBB_single_match = llvm::BasicBlock::Create(context, "ifcont");
18071768
llvm::Value* key_mask_value = LLVM::CreateLoad(*builder,
18081769
llvm_utils->create_ptr_gep(key_mask, key_hash));
18091770
llvm::Value* does_kv_exists = builder->CreateICmpEQ(key_mask_value,
@@ -1812,21 +1773,15 @@ namespace LCompilers {
18121773
builder->CreateICmpNE(LLVM::CreateLoad(*builder, chain_itr),
18131774
llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(context)))
18141775
);
1815-
builder->CreateCondBr(does_kv_exists, thenBB_single_match, elseBB_single_match);
1816-
builder->SetInsertPoint(thenBB_single_match);
1817-
{
1776+
1777+
llvm_utils->create_if_else(does_kv_exists, [=]() {
18181778
llvm::Value* kv_struct_i8 = LLVM::CreateLoad(*builder, chain_itr);
18191779
llvm::Value* kv_struct = builder->CreateBitCast(kv_struct_i8, kv_struct_type->getPointerTo());
18201780
llvm::Value* value = LLVM::CreateLoad(*builder, llvm_utils->create_gep(kv_struct, 1));
18211781
LLVM::CreateStore(*builder, value, tmp_value_ptr_local);
1822-
1823-
}
1824-
builder->CreateBr(mergeBB_single_match);
1825-
llvm_utils->start_new_block(elseBB_single_match);
1826-
{
1782+
}, [&]() {
18271783
LLVM::CreateStore(*builder, LLVM::CreateLoad(*builder, def_value), tmp_value_ptr_local);
1828-
}
1829-
llvm_utils->start_new_block(mergeBB_single_match);
1784+
});
18301785
return tmp_value_ptr;
18311786
}
18321787

src/libasr/codegen/llvm_utils.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,35 @@ namespace LCompilers {
150150
ASR::ttype_t* asr_type, llvm::Module* module,
151151
std::map<std::string, std::map<std::string, int>>& name2memidx);
152152

153+
154+
// Note: `llvm_utils->create_if_else` and `create_loop` are optional APIs
155+
// that do not have to be used. Many times, for more complicated
156+
// things, it might be more readable to just use the LLVM API
157+
// without any extra layer on top. In some other cases, it might
158+
// be more readable to use this abstraction.
159+
// The `if_block` and `else_block` must generate one or more blocks. In
160+
// addition, the `if_block` must not be terminated, we terminate it
161+
// ourselves. The `else_block` can be either terminated or not.
162+
template <typename IF, typename ELSE>
163+
void create_if_else(llvm::Value * cond, IF if_block, ELSE else_block) {
164+
llvm::Function *fn = builder->GetInsertBlock()->getParent();
165+
166+
llvm::BasicBlock *thenBB = llvm::BasicBlock::Create(context, "then", fn);
167+
llvm::BasicBlock *elseBB = llvm::BasicBlock::Create(context, "else");
168+
llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create(context, "ifcont");
169+
170+
builder->CreateCondBr(cond, thenBB, elseBB);
171+
builder->SetInsertPoint(thenBB); {
172+
if_block();
173+
}
174+
builder->CreateBr(mergeBB);
175+
176+
start_new_block(elseBB); {
177+
else_block();
178+
}
179+
start_new_block(mergeBB);
180+
}
181+
153182
}; // LLVMUtils
154183

155184
class LLVMList {

0 commit comments

Comments
 (0)