Mercurial > projects > ldc
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 |