@@ -880,10 +880,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
880
880
complex_type_8_ptr = llvm::StructType::create (context, els_8_ptr, " complex_8_ptr" );
881
881
character_type = llvm::Type::getInt8PtrTy (context);
882
882
883
- llvm::Type* size_arg = (llvm::Type*)llvm::StructType::create (context, std::vector<llvm::Type*>({
884
- arr_descr->get_dimension_descriptor_type (true ),
885
- getIntType (4 )}), " size_arg" );
886
- fname2arg_type[" size" ] = std::make_pair (size_arg, size_arg->getPointerTo ());
887
883
llvm::Type* bound_arg = static_cast <llvm::Type*>(arr_descr->get_dimension_descriptor_type (true ));
888
884
fname2arg_type[" lbound" ] = std::make_pair (bound_arg, bound_arg->getPointerTo ());
889
885
fname2arg_type[" ubound" ] = std::make_pair (bound_arg, bound_arg->getPointerTo ());
@@ -2356,50 +2352,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
2356
2352
} else if ( x.m_abi == ASR::abiType::Intrinsic &&
2357
2353
x.m_deftype == ASR::deftypeType::Interface ) {
2358
2354
std::string m_name = x.m_name ;
2359
- if ( m_name == " size" ) {
2360
-
2361
- define_function_entry (x);
2362
-
2363
- // Defines the size intrinsic's body at LLVM level.
2364
- ASR::Variable_t *arg = EXPR2VAR (x.m_args [0 ]);
2365
- uint32_t h = get_hash ((ASR::asr_t *)arg);
2366
- llvm::Value* llvm_arg = llvm_symtab[h];
2367
- ASR::Variable_t *ret = EXPR2VAR (x.m_return_var );
2368
- h = get_hash ((ASR::asr_t *)ret);
2369
- llvm::Value* llvm_ret_ptr = llvm_symtab[h];
2370
- llvm::Value* dim_des_val = CreateLoad (llvm_utils->create_gep (llvm_arg, 0 ));
2371
- llvm::Value* rank = CreateLoad (llvm_utils->create_gep (llvm_arg, 1 ));
2372
- builder->CreateStore (llvm::ConstantInt::get (context, llvm::APInt (32 , 1 )), llvm_ret_ptr);
2373
-
2374
- llvm::BasicBlock *loophead = llvm::BasicBlock::Create (context, " loop.head" );
2375
- llvm::BasicBlock *loopbody = llvm::BasicBlock::Create (context, " loop.body" );
2376
- llvm::BasicBlock *loopend = llvm::BasicBlock::Create (context, " loop.end" );
2377
- this ->current_loophead = loophead;
2378
- this ->current_loopend = loopend;
2379
-
2380
- llvm::Value* r = builder->CreateAlloca (getIntType (4 ), nullptr );
2381
- builder->CreateStore (llvm::ConstantInt::get (context, llvm::APInt (32 , 0 )), r);
2382
- // head
2383
- start_new_block (loophead);
2384
- llvm::Value *cond = builder->CreateICmpSLT (CreateLoad (r), rank);
2385
- builder->CreateCondBr (cond, loopbody, loopend);
2386
-
2387
- // body
2388
- start_new_block (loopbody);
2389
- llvm::Value* r_val = CreateLoad (r);
2390
- llvm::Value* ret_val = CreateLoad (llvm_ret_ptr);
2391
- llvm::Value* dim_size = arr_descr->get_dimension_size (dim_des_val, r_val);
2392
- ret_val = builder->CreateMul (ret_val, dim_size);
2393
- builder->CreateStore (ret_val, llvm_ret_ptr);
2394
- r_val = builder->CreateAdd (r_val, llvm::ConstantInt::get (context, llvm::APInt (32 , 1 )));
2395
- builder->CreateStore (r_val, r);
2396
- builder->CreateBr (loophead);
2397
-
2398
- // end
2399
- start_new_block (loopend);
2400
-
2401
- define_function_exit (x);
2402
- } else if ( m_name == " lbound" || m_name == " ubound" ) {
2355
+ if ( m_name == " lbound" || m_name == " ubound" ) {
2403
2356
define_function_entry (x);
2404
2357
2405
2358
// Defines the size intrinsic's body at LLVM level.
@@ -2532,6 +2485,15 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
2532
2485
}
2533
2486
}
2534
2487
2488
+ void visit_AssociateBlockCall (const ASR::AssociateBlockCall_t& x) {
2489
+ LFORTRAN_ASSERT (ASR::is_a<ASR::AssociateBlock_t>(*x.m_m ));
2490
+ ASR::AssociateBlock_t* associate_block = ASR::down_cast<ASR::AssociateBlock_t>(x.m_m );
2491
+ declare_vars (*associate_block);
2492
+ for (size_t i = 0 ; i < associate_block->n_body ; i++) {
2493
+ this ->visit_stmt (*(associate_block->m_body [i]));
2494
+ }
2495
+ }
2496
+
2535
2497
inline void visit_expr_wrapper (const ASR::expr_t * x, bool load_ref=false ) {
2536
2498
this ->visit_expr (*x);
2537
2499
if ( x->type == ASR::exprType::ArrayRef ||
@@ -3844,31 +3806,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
3844
3806
x_abi = sub->m_abi ;
3845
3807
}
3846
3808
if ( x_abi == ASR::abiType::Intrinsic ) {
3847
- if ( name == " size" ) {
3848
- /*
3849
- When size intrinsic is called on a fortran array then the above
3850
- code extracts the dimension descriptor array and its rank from the
3851
- overall array descriptor. It wraps them into a struct (specifically, arg_struct of type, size_arg here)
3852
- and passes to LLVM size. So, if you do, size(a) (a is a fortran array), then at LLVM level,
3853
- @size(%size_arg* %x) is used as call where size_arg
3854
- is described above.
3855
- */
3856
- ASR::Variable_t *arg = EXPR2VAR (x.m_args [0 ].m_value );
3857
- uint32_t h = get_hash ((ASR::asr_t *)arg);
3858
- tmp = llvm_symtab[h];
3859
- llvm::Value* arg_struct = builder->CreateAlloca (fname2arg_type[" size" ].first , nullptr );
3860
- llvm::Value* first_ele_ptr = arr_descr->get_pointer_to_dimension_descriptor_array (tmp);
3861
- llvm::Value* first_arg_ptr = llvm_utils->create_gep (arg_struct, 0 );
3862
- builder->CreateStore (first_ele_ptr, first_arg_ptr);
3863
- llvm::Value* rank_ptr = llvm_utils->create_gep (arg_struct, 1 );
3864
- builder->CreateStore (arr_descr->get_rank (tmp), rank_ptr);
3865
- tmp = arg_struct;
3866
- args.push_back (tmp);
3867
- llvm::Value* dim = builder->CreateAlloca (getIntType (4 ));
3868
- args.push_back (dim);
3869
- llvm::Value* kind = builder->CreateAlloca (getIntType (4 ));
3870
- args.push_back (kind);
3871
- } else if ( name == " lbound" || name == " ubound" ) {
3809
+ if ( name == " lbound" || name == " ubound" ) {
3872
3810
ASR::Variable_t *arg = EXPR2VAR (x.m_args [0 ].m_value );
3873
3811
uint32_t h = get_hash ((ASR::asr_t *)arg);
3874
3812
tmp = llvm_symtab[h];
@@ -4374,6 +4312,55 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
4374
4312
pop_nested_stack (s);
4375
4313
}
4376
4314
4315
+ void visit_ArraySize (const ASR::ArraySize_t& x) {
4316
+ if ( x.m_value ) {
4317
+ visit_expr_wrapper (x.m_value , true );
4318
+ return ;
4319
+ }
4320
+ visit_expr_wrapper (x.m_v );
4321
+ llvm::Value* llvm_arg = tmp;
4322
+ llvm::Value* dim_des_val = arr_descr->get_pointer_to_dimension_descriptor_array (llvm_arg);
4323
+ if ( x.m_dim ) {
4324
+ visit_expr_wrapper (x.m_dim , true );
4325
+ int kind = ASRUtils::extract_kind_from_ttype_t (ASRUtils::expr_type (x.m_dim ));
4326
+ tmp = builder->CreateSub (tmp, llvm::ConstantInt::get (context, llvm::APInt (kind * 8 , 1 )));
4327
+ tmp = arr_descr->get_dimension_size (dim_des_val, tmp);
4328
+ return ;
4329
+ }
4330
+ llvm::Value* rank = arr_descr->get_rank (llvm_arg);
4331
+ llvm::Value* llvm_size = builder->CreateAlloca (getIntType (ASRUtils::extract_kind_from_ttype_t (x.m_type )), nullptr );
4332
+ builder->CreateStore (llvm::ConstantInt::get (context, llvm::APInt (32 , 1 )), llvm_size);
4333
+
4334
+ llvm::BasicBlock *loophead = llvm::BasicBlock::Create (context, " loop.head" );
4335
+ llvm::BasicBlock *loopbody = llvm::BasicBlock::Create (context, " loop.body" );
4336
+ llvm::BasicBlock *loopend = llvm::BasicBlock::Create (context, " loop.end" );
4337
+ this ->current_loophead = loophead;
4338
+ this ->current_loopend = loopend;
4339
+
4340
+ llvm::Value* r = builder->CreateAlloca (getIntType (4 ), nullptr );
4341
+ builder->CreateStore (llvm::ConstantInt::get (context, llvm::APInt (32 , 0 )), r);
4342
+ // head
4343
+ start_new_block (loophead);
4344
+ llvm::Value *cond = builder->CreateICmpSLT (CreateLoad (r), rank);
4345
+ builder->CreateCondBr (cond, loopbody, loopend);
4346
+
4347
+ // body
4348
+ start_new_block (loopbody);
4349
+ llvm::Value* r_val = CreateLoad (r);
4350
+ llvm::Value* ret_val = CreateLoad (llvm_size);
4351
+ llvm::Value* dim_size = arr_descr->get_dimension_size (dim_des_val, r_val);
4352
+ ret_val = builder->CreateMul (ret_val, dim_size);
4353
+ builder->CreateStore (ret_val, llvm_size);
4354
+ r_val = builder->CreateAdd (r_val, llvm::ConstantInt::get (context, llvm::APInt (32 , 1 )));
4355
+ builder->CreateStore (r_val, r);
4356
+ builder->CreateBr (loophead);
4357
+
4358
+ // end
4359
+ start_new_block (loopend);
4360
+
4361
+ tmp = CreateLoad (llvm_size);
4362
+ }
4363
+
4377
4364
};
4378
4365
4379
4366
0 commit comments