@@ -2629,6 +2629,74 @@ namespace LCompilers {
26292629 shift_end_point_by_one (list);
26302630 }
26312631
2632+ void LLVMList::reverse (llvm::Value* list, ASR::ttype_t * list_type, llvm::Module& module ) {
2633+
2634+ /* Equivalent in C++:
2635+ *
2636+ * int i = 0;
2637+ * int j = end_point - 1;
2638+ *
2639+ * tmp;
2640+ *
2641+ * while(j > i) {
2642+ * tmp = list[i];
2643+ * list[i] = list[j];
2644+ * list[j] = tmp;
2645+ * i = i + 1;
2646+ * j = j - 1;
2647+ * }
2648+ */
2649+
2650+ llvm::Value* end_point = LLVM::CreateLoad (*builder,
2651+ get_pointer_to_current_end_point (list));
2652+
2653+ llvm::Type* pos_type = llvm::Type::getInt32Ty (context);
2654+ llvm::AllocaInst *i = builder->CreateAlloca (pos_type, nullptr );
2655+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (
2656+ context, llvm::APInt (32 , 0 )), i); // i = 0
2657+ llvm::AllocaInst *j = builder->CreateAlloca (pos_type, nullptr );
2658+ llvm::Value* tmp = nullptr ;
2659+ tmp = builder->CreateSub (end_point, llvm::ConstantInt::get (context, llvm::APInt (32 , 1 )));
2660+ LLVM::CreateStore (*builder, tmp, j); // j = end_point - 1
2661+
2662+ llvm::BasicBlock *loophead = llvm::BasicBlock::Create (context, " loop.head" );
2663+ llvm::BasicBlock *loopbody = llvm::BasicBlock::Create (context, " loop.body" );
2664+ llvm::BasicBlock *loopend = llvm::BasicBlock::Create (context, " loop.end" );
2665+
2666+ // head
2667+ llvm_utils->start_new_block (loophead);
2668+ {
2669+ llvm::Value *cond = builder->CreateICmpSGT (LLVM::CreateLoad (*builder, j), LLVM::CreateLoad (*builder, i));
2670+ builder->CreateCondBr (cond, loopbody, loopend);
2671+ }
2672+
2673+ // body
2674+ llvm_utils->start_new_block (loopbody);
2675+ {
2676+ tmp = read_item (list, LLVM::CreateLoad (*builder, i),
2677+ false , module , LLVM::is_llvm_struct (list_type)); // tmp = list[i]
2678+ write_item (list, LLVM::CreateLoad (*builder, i),
2679+ read_item (list, LLVM::CreateLoad (*builder, j),
2680+ false , module , LLVM::is_llvm_struct (list_type)),
2681+ false , module ); // list[i] = list[j]
2682+ write_item (list, LLVM::CreateLoad (*builder, j),
2683+ tmp, false , module ); // list[j] = tmp
2684+
2685+ tmp = builder->CreateAdd (
2686+ LLVM::CreateLoad (*builder, i),
2687+ llvm::ConstantInt::get (context, llvm::APInt (32 , 1 )));
2688+ LLVM::CreateStore (*builder, tmp, i);
2689+ tmp = builder->CreateSub (
2690+ LLVM::CreateLoad (*builder, j),
2691+ llvm::ConstantInt::get (context, llvm::APInt (32 , 1 )));
2692+ LLVM::CreateStore (*builder, tmp, j);
2693+ }
2694+ builder->CreateBr (loophead);
2695+
2696+ // end
2697+ llvm_utils->start_new_block (loopend);
2698+ }
2699+
26322700 llvm::Value* LLVMList::find_item_position (llvm::Value* list,
26332701 llvm::Value* item, ASR::ttype_t * item_type, llvm::Module& module ) {
26342702 llvm::Type* pos_type = llvm::Type::getInt32Ty (context);
0 commit comments