Skip to content

Commit f647c53

Browse files
committed
wip
1 parent 6ed36a1 commit f647c53

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/libasr/codegen/llvm_utils.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,24 @@ namespace LFortran {
8585
};
8686
return builder.CreateCall(fn, args);
8787
}
88+
89+
llvm::Value* lfortran_free(llvm::LLVMContext &context, llvm::Module &module,
90+
llvm::IRBuilder<> &builder, llvm::Value* ptr) {
91+
std::string func_name = "_lfortran_free";
92+
llvm::Function *fn = module.getFunction(func_name);
93+
if (!fn) {
94+
llvm::FunctionType *function_type = llvm::FunctionType::get(
95+
llvm::Type::getVoidTy(context), {
96+
llvm::Type::getInt8PtrTy(context)
97+
}, true);
98+
fn = llvm::Function::Create(function_type,
99+
llvm::Function::ExternalLinkage, func_name, module);
100+
}
101+
std::vector<llvm::Value*> args = {
102+
builder.CreateBitCast(ptr, llvm::Type::getInt8PtrTy(context)),
103+
};
104+
return builder.CreateCall(fn, args);
105+
}
88106
} // namespace LLVM
89107

90108
LLVMUtils::LLVMUtils(llvm::LLVMContext& context,
@@ -429,6 +447,9 @@ namespace LFortran {
429447
// integration_tests/test_list_07.py.
430448
if( LLVM::is_llvm_struct(element_type) ) {
431449
builder->CreateStore(copy_data, get_pointer_to_list_data(dest));
450+
// TODO: Should be created outside the user loop and not here.
451+
// LLVMList should treat them as data members and create them
452+
// only if they are NULL
432453
llvm::AllocaInst *pos_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context),
433454
nullptr);
434455
LLVM::CreateStore(*builder, llvm::ConstantInt::get(llvm::Type::getInt32Ty(context),
@@ -708,6 +729,9 @@ namespace LFortran {
708729
new_key_mask = builder->CreateBitCast(new_key_mask, llvm::Type::getInt1PtrTy(context));
709730

710731
llvm::Value* current_capacity = LLVM::CreateLoad(*builder, get_pointer_to_capacity(dict));
732+
// TODO: Should be created outside the user loop and not here.
733+
// LLVMDict should treat them as data members and create them
734+
// only if they are NULL
711735
llvm::Value* idx_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr);
712736
LLVM::CreateStore(*builder, llvm::ConstantInt::get(llvm::Type::getInt32Ty(context),
713737
llvm::APInt(32, 0)), idx_ptr);
@@ -769,6 +793,9 @@ namespace LFortran {
769793
reset_iterators();
770794

771795
// TODO: Free key_list, value_list and key_mask
796+
llvm_utils->list_api->free_data(key_list, *module);
797+
llvm_utils->list_api->free_data(value_list, *module);
798+
LLVM::lfortran_free(context, *module, *builder, key_mask);
772799
LLVM::CreateStore(*builder, LLVM::CreateLoad(*builder, new_key_list), key_list);
773800
LLVM::CreateStore(*builder, LLVM::CreateLoad(*builder, new_value_list), value_list);
774801
LLVM::CreateStore(*builder, new_key_mask, get_pointer_to_keymask(dict));
@@ -925,10 +952,16 @@ namespace LFortran {
925952
* list[pos] = item;
926953
*/
927954

955+
// TODO: Should be created outside the user loop and not here.
956+
// LLVMList should treat them as data members and create them
957+
// only if they are NULL
928958
llvm::AllocaInst *tmp_ptr = builder->CreateAlloca(el_type, nullptr);
929959
LLVM::CreateStore(*builder, read_item(list, pos, false), tmp_ptr);
930960
llvm::Value* tmp = nullptr;
931961

962+
// TODO: Should be created outside the user loop and not here.
963+
// LLVMList should treat them as data members and create them
964+
// only if they are NULL
932965
llvm::AllocaInst *pos_ptr = builder->CreateAlloca(
933966
llvm::Type::getInt32Ty(context), nullptr);
934967
LLVM::CreateStore(*builder, pos, pos_ptr);
@@ -975,6 +1008,9 @@ namespace LFortran {
9751008
llvm::Type* pos_type = llvm::Type::getInt32Ty(context);
9761009
llvm::Value* current_end_point = LLVM::CreateLoad(*builder,
9771010
get_pointer_to_current_end_point(list));
1011+
// TODO: Should be created outside the user loop and not here.
1012+
// LLVMList should treat them as data members and create them
1013+
// only if they are NULL
9781014
llvm::AllocaInst *i = builder->CreateAlloca(pos_type, nullptr);
9791015
LLVM::CreateStore(*builder, llvm::ConstantInt::get(
9801016
context, llvm::APInt(32, 0)), i);
@@ -1059,6 +1095,9 @@ namespace LFortran {
10591095
llvm::Type* pos_type = llvm::Type::getInt32Ty(context);
10601096
llvm::Value* current_end_point = LLVM::CreateLoad(*builder,
10611097
get_pointer_to_current_end_point(list));
1098+
// TODO: Should be created outside the user loop and not here.
1099+
// LLVMList should treat them as data members and create them
1100+
// only if they are NULL
10621101
llvm::AllocaInst *item_pos = builder->CreateAlloca(pos_type, nullptr);
10631102
llvm::Value* tmp = LLVMList::find_item_position(list, item, item_type, module);
10641103
LLVM::CreateStore(*builder, tmp, item_pos);
@@ -1114,6 +1153,11 @@ namespace LFortran {
11141153
LLVM::CreateStore(*builder, zero, end_point_ptr);
11151154
}
11161155

1156+
void LLVMList::free_data(llvm::Value* list, llvm::Module& module) {
1157+
llvm::Value* data = LLVM::CreateLoad(*builder, get_pointer_to_list_data(list));
1158+
LLVM::lfortran_free(context, module, *builder, data);
1159+
}
1160+
11171161

11181162
LLVMTuple::LLVMTuple(llvm::LLVMContext& context_,
11191163
LLVMUtils* llvm_utils_,

src/libasr/codegen/llvm_utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ namespace LFortran {
5151
llvm::IRBuilder<> &builder, llvm::Value* ptr, llvm::Value* arg_size);
5252
llvm::Value* lfortran_calloc(llvm::LLVMContext &context, llvm::Module &module,
5353
llvm::IRBuilder<> &builder, llvm::Value* count, llvm::Value* type_size);
54+
llvm::Value* lfortran_free(llvm::LLVMContext &context, llvm::Module &module,
55+
llvm::IRBuilder<> &builder, llvm::Value* ptr);
5456
static inline bool is_llvm_struct(ASR::ttype_t* asr_type) {
5557
return ASR::is_a<ASR::Tuple_t>(*asr_type) ||
5658
ASR::is_a<ASR::List_t>(*asr_type) ||
@@ -176,6 +178,8 @@ namespace LFortran {
176178
llvm::Value* find_item_position(llvm::Value* list,
177179
llvm::Value* item, ASR::ttype_t* item_type,
178180
llvm::Module& module);
181+
182+
void free_data(llvm::Value* list, llvm::Module& module);
179183
};
180184

181185
class LLVMTuple {

0 commit comments

Comments
 (0)