comparison gen/statements.c @ 33:bc641b23a714 trunk

[svn r37] * Initial support for foreach on static arrays. Not 100% complete
author lindquist
date Thu, 04 Oct 2007 22:38:53 +0200
parents a86fe7496b58
children 4648206ca213
comparison
equal deleted inserted replaced
32:a86fe7496b58 33:bc641b23a714
657 else 657 else
658 { 658 {
659 assert(0); 659 assert(0);
660 } 660 }
661 661
662 if (op == TOKforeach) 662 if (op == TOKforeach) {
663 {
664 new llvm::StoreInst(llvm::ConstantInt::get(keytype,0,false), keyvar, p->scopebb()); 663 new llvm::StoreInst(llvm::ConstantInt::get(keytype,0,false), keyvar, p->scopebb());
665 } 664 }
666 else if (op == TOKforeach_reverse) 665 else if (op == TOKforeach_reverse) {
667 {
668 llvm::Value* v = llvm::BinaryOperator::createSub(numiters, llvm::ConstantInt::get(keytype,1,false),"tmp",p->scopebb()); 666 llvm::Value* v = llvm::BinaryOperator::createSub(numiters, llvm::ConstantInt::get(keytype,1,false),"tmp",p->scopebb());
669 new llvm::StoreInst(v, keyvar, p->scopebb()); 667 new llvm::StoreInst(v, keyvar, p->scopebb());
670 } 668 }
671 else
672 assert(0);
673 669
674 delete arr; 670 delete arr;
675 671
676 llvm::BasicBlock* oldend = gIR->scopeend(); 672 llvm::BasicBlock* oldend = gIR->scopeend();
673 llvm::BasicBlock* nexbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend);
677 llvm::BasicBlock* begbb = new llvm::BasicBlock("foreachbegin", p->topfunc(), oldend); 674 llvm::BasicBlock* begbb = new llvm::BasicBlock("foreachbegin", p->topfunc(), oldend);
678 llvm::BasicBlock* nexbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend);
679 llvm::BasicBlock* endbb = new llvm::BasicBlock("foreachend", p->topfunc(), oldend); 675 llvm::BasicBlock* endbb = new llvm::BasicBlock("foreachend", p->topfunc(), oldend);
680 676
681 new llvm::BranchInst(begbb, p->scopebb()); 677 new llvm::BranchInst(begbb, p->scopebb());
678
679 // next
680 p->scope() = IRScope(nexbb,begbb);
681 llvm::Value* done = 0;
682 llvm::Value* load = new llvm::LoadInst(keyvar, "tmp", p->scopebb());
683 if (op == TOKforeach) {
684 load = llvm::BinaryOperator::createAdd(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb());
685 new llvm::StoreInst(load, keyvar, p->scopebb());
686 done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, numiters, "tmp", p->scopebb());
687 }
688 else if (op == TOKforeach_reverse) {
689 done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, load, llvm::ConstantInt::get(keytype, 0, false), "tmp", p->scopebb());
690 load = llvm::BinaryOperator::createSub(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb());
691 new llvm::StoreInst(load, keyvar, p->scopebb());
692 }
693 new llvm::BranchInst(begbb, endbb, done, p->scopebb());
682 694
683 // begin 695 // begin
684 p->scope() = IRScope(begbb,nexbb); 696 p->scope() = IRScope(begbb,nexbb);
685 697
686 value->llvmValue = LLVM_DtoGEP(val,llvm::ConstantInt::get(keytype,0,false),keyvar,"tmp",p->scopebb()); 698 // get value for this iteration
699 value->llvmValue = LLVM_DtoGEP(val,llvm::ConstantInt::get(keytype,0,false),new llvm::LoadInst(keyvar,"tmp",p->scopebb()),"tmp",p->scopebb());
687 700
688 // body 701 // body
702 p->scope() = IRScope(p->scopebb(),endbb);
703 p->loopbbs.push_back(IRScope(nexbb,endbb));
689 body->toIR(p); 704 body->toIR(p);
690 705 p->loopbbs.pop_back();
691 // next 706
692 p->scope() = IRScope(nexbb,endbb); 707 if (!p->scope().returned)
693 new llvm::BranchInst(endbb, p->scopebb()); 708 new llvm::BranchInst(nexbb, p->scopebb());
694 709
695 // end 710 // end
696 if (!p->scope().returned)
697 new llvm::BranchInst(endbb, p->scopebb());
698 p->scope() = IRScope(endbb,oldend); 711 p->scope() = IRScope(endbb,oldend);
699 } 712 }
700 713
701 ////////////////////////////////////////////////////////////////////////////// 714 //////////////////////////////////////////////////////////////////////////////
702 715