comparison gen/statements.cpp @ 774:9688da40cd4d

Fixed problem with continue/break in unrolled loop statements.
author tomas@myhost
date Wed, 19 Nov 2008 14:40:24 +0100
parents f04dde6e882c
children 4adf0f742896
comparison
equal deleted inserted replaced
773:5696a7167b21 774:9688da40cd4d
887 void UnrolledLoopStatement::toIR(IRState* p) 887 void UnrolledLoopStatement::toIR(IRState* p)
888 { 888 {
889 Logger::println("UnrolledLoopStatement::toIR(): %s", loc.toChars()); 889 Logger::println("UnrolledLoopStatement::toIR(): %s", loc.toChars());
890 LOG_SCOPE; 890 LOG_SCOPE;
891 891
892 if (global.params.symdebug) 892 // if no statements, there's nothing to do
893 DtoDwarfStopPoint(loc.linnum); 893 if (!statements || !statements->dim)
894 return;
895
896 if (global.params.symdebug)
897 DtoDwarfStopPoint(loc.linnum);
898
899 // DMD doesn't fold stuff like continue/break, and since this isn't really a loop
900 // we have to keep track of each statement and jump to next the next/end on continue/break
894 901
895 llvm::BasicBlock* oldend = gIR->scopeend(); 902 llvm::BasicBlock* oldend = gIR->scopeend();
903
904 // create a block for each statement
905 size_t nstmt = statements->dim;
906 LLSmallVector<llvm::BasicBlock*, 4> blocks(nstmt, NULL);
907
908 for (size_t i=0; i<nstmt; i++)
909 {
910 blocks[i] = llvm::BasicBlock::Create("unrolledstmt", p->topfunc(), oldend);
911 }
912
913 // create end block
896 llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend); 914 llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend);
897 915
898 p->scope() = IRScope(p->scopebb(),endbb); 916 // enter first stmt
899 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb)); 917 if (!p->scopereturned())
900 918 p->ir->CreateBr(blocks[0]);
901 for (int i=0; i<statements->dim; ++i) 919
902 { 920 // do statements
903 Statement* s = (Statement*)statements->data[i]; 921 Statement** stmts = (Statement**)statements->data;
922
923 for (int i=0; i<nstmt; i++)
924 {
925 Statement* s = stmts[i];
926
927 // get blocks
928 llvm::BasicBlock* thisbb = blocks[i];
929 llvm::BasicBlock* nextbb = (i+1 == nstmt) ? endbb : blocks[i+1];
930
931 // update scope
932 p->scope() = IRScope(thisbb,nextbb);
933
934 // push loop scope
935 // continue goes to next statement, break goes to end
936 p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,nextbb,endbb));
937
938 // do statement
904 s->toIR(p); 939 s->toIR(p);
905 } 940
906 941 // pop loop scope
907 p->loopbbs.pop_back(); 942 p->loopbbs.pop_back();
908 943
909 llvm::BranchInst::Create(endbb, p->scopebb()); 944 // next stmt
945 if (!p->scopereturned())
946 p->ir->CreateBr(nextbb);
947 }
948
949 // finish scope
950 if (!p->scopereturned())
951 p->ir->CreateBr(endbb);
910 p->scope() = IRScope(endbb,oldend); 952 p->scope() = IRScope(endbb,oldend);
911 } 953 }
912 954
913 ////////////////////////////////////////////////////////////////////////////// 955 //////////////////////////////////////////////////////////////////////////////
914 956