Changeset 774:9688da40cd4d
- Timestamp:
- 11/19/08 08:40:24
(2 months ago)
- Author:
- tomas@myhost
- branch:
- default
- Message:
Fixed problem with continue/break in unrolled loop statements.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r758 |
r774 |
|
| 890 | 890 | LOG_SCOPE; |
|---|
| 891 | 891 | |
|---|
| 892 | | if (global.params.symdebug) |
|---|
| 893 | | DtoDwarfStopPoint(loc.linnum); |
|---|
| | 892 | // if no statements, there's nothing to do |
|---|
| | 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 | 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 | 914 | llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend); |
|---|
| 897 | 915 | |
|---|
| 898 | | p->scope() = IRScope(p->scopebb(),endbb); |
|---|
| 899 | | p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb)); |
|---|
| 900 | | |
|---|
| 901 | | for (int i=0; i<statements->dim; ++i) |
|---|
| 902 | | { |
|---|
| 903 | | Statement* s = (Statement*)statements->data[i]; |
|---|
| | 916 | // enter first stmt |
|---|
| | 917 | if (!p->scopereturned()) |
|---|
| | 918 | p->ir->CreateBr(blocks[0]); |
|---|
| | 919 | |
|---|
| | 920 | // do statements |
|---|
| | 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 | 939 | s->toIR(p); |
|---|
| 905 | | } |
|---|
| 906 | | |
|---|
| 907 | | p->loopbbs.pop_back(); |
|---|
| 908 | | |
|---|
| 909 | | llvm::BranchInst::Create(endbb, p->scopebb()); |
|---|
| | 940 | |
|---|
| | 941 | // pop loop scope |
|---|
| | 942 | p->loopbbs.pop_back(); |
|---|
| | 943 | |
|---|
| | 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 | 952 | p->scope() = IRScope(endbb,oldend); |
|---|
| 911 | 953 | } |
|---|