From 12115a6b11770c7b6a38ad7b152165b143b59c31 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Fri, 29 May 2026 18:15:23 -0700 Subject: [PATCH] refactor Bsucc to be an array rather than a list --- compiler/src/dmd/backend/barray.d | 4 +- compiler/src/dmd/backend/blockopt.d | 238 +++++++++++++------------- compiler/src/dmd/backend/cc.d | 16 +- compiler/src/dmd/backend/cgcs.d | 4 +- compiler/src/dmd/backend/debugprint.d | 17 +- compiler/src/dmd/backend/dout.d | 4 +- compiler/src/dmd/backend/dwarfeh.d | 4 +- compiler/src/dmd/backend/eh.d | 6 +- compiler/src/dmd/backend/gflow.d | 10 +- compiler/src/dmd/backend/gloop.d | 94 ++++------ compiler/src/dmd/backend/gother.d | 9 +- compiler/src/dmd/backend/inliner.d | 2 +- compiler/src/dmd/backend/x86/cgcod.d | 6 +- compiler/src/dmd/backend/x86/cgreg.d | 6 +- compiler/src/dmd/backend/x86/cod3.d | 74 ++++---- compiler/src/dmd/backend/x86/cod5.d | 4 +- compiler/src/dmd/glue/package.d | 2 +- compiler/src/dmd/glue/s2ir.d | 136 +++++++-------- 18 files changed, 294 insertions(+), 342 deletions(-) diff --git a/compiler/src/dmd/backend/barray.d b/compiler/src/dmd/backend/barray.d index aeb3e99a991a..df0c1a4e07b7 100644 --- a/compiler/src/dmd/backend/barray.d +++ b/compiler/src/dmd/backend/barray.d @@ -190,8 +190,8 @@ struct Barray(T) */ bool equals(ref const Barray rhs) { - if (array.length != rhs.length) - return false; + if (array.length != rhs.length) + return false; foreach (i, ref t; array) { if (t != rhs.array[i]) diff --git a/compiler/src/dmd/backend/blockopt.d b/compiler/src/dmd/backend/blockopt.d index 3bc503131ecd..6cbb64d9fce6 100644 --- a/compiler/src/dmd/backend/blockopt.d +++ b/compiler/src/dmd/backend/blockopt.d @@ -141,7 +141,7 @@ block* block_goto(ref BlockOpt bo, BlockState* bx, BC bc, block* bn) b = bx.curblock; block_next(bo, bx,bc,bn); - b.appendSucc(bx.curblock); + b.Bsucc.push(bx.curblock); return bx.curblock; } @@ -168,7 +168,7 @@ void block_goto(block* bgoto,block* bnew) BC bc; assert(bgoto); - curblock.appendSucc(bgoto); + curblock.Bsucc.push(bgoto); if (curblock.Bcode) // If there is already code in the block // then this is an ASM block bc = BC.asm_; @@ -210,10 +210,10 @@ void block_pred(ref BlockOpt bo) for (block* b = bo.startblock; b; b = b.Bnext) // for each block { //printf("b = %p, BC = BC.%s\n", b, bc_str(b.bc)); - foreach (bp; ListRange(b.Bsucc)) + foreach (bp; b.Bsucc[]) { /* for each successor to b */ //printf("\tbs = %p\n",list_block(bp)); - list_block(bp).Bpred.push(b); // original inserts at the beginning, don't think it matters + bp.Bpred.push(b); // original inserts at the beginning, don't think it matters } } assert(bo.startblock.Bpred.length == 0); /* startblock has no preds */ @@ -237,9 +237,8 @@ void block_clearvisit(ref BlockOpt bo) void block_visit(block* b) { b.Bflags |= BFL.visited; - foreach (l; ListRange(b.Bsucc)) + foreach (bs; b.Bsucc[]) { - block* bs = list_block(l); assert(bs); if ((bs.Bflags & BFL.visited) == 0) // if not visited block_visit(bs); @@ -306,7 +305,7 @@ void block_free(ref BlockOpt bo, block* b) assert(b); if (b.Belem) el_free(b.Belem); - list_free(&b.Bsucc,FPNULL); + b.Bsucc.dtor(); b.Bpred.dtor(); if (OPTIMIZER) block_optimizer_free(b); @@ -406,7 +405,7 @@ void blockopt(ref GlobalOptimizer go, ref BlockOpt bo) { if (OPTIMIZER) { - blassertsplit(go, bo); // only need this once +//xyzzy blassertsplit(go, bo); // only need this once int iterationLimit = 200; if (iterationLimit < bo.dfo.length) @@ -416,15 +415,16 @@ void blockopt(ref GlobalOptimizer go, ref BlockOpt bo) { //printf("changes = %d, count = %d, dfo.length = %d\n",go.changes,count,dfo.length); go.changes = 0; - bropt(go, bo); // branch optimization - brrear(bo); // branch rearrangement - blident(go, bo); // combine identical blocks - blreturn(go, bo); // split out return blocks - bltailmerge(go, bo); // do tail merging - brtailrecursion(go, bo); // do tail recursion - brcombine(go, bo); // convert graph to expressions - blexit(go, bo); - brmin(go, bo); // minimize branching +//xyzzy bropt(go, bo); // branch optimization +// brrear(bo); // branch rearrangement +// blident(go, bo); // combine identical blocks +// blreturn(go, bo); // split out return blocks + +// bltailmerge(go, bo); // do tail merging +// brtailrecursion(go, bo); // do tail recursion +// brcombine(go, bo); // convert graph to expressions +// blexit(go, bo); +// brmin(go, bo); // minimize branching // Switched to one block per Statement, do not undo it enum merge = false; @@ -481,8 +481,8 @@ void blockopt(ref GlobalOptimizer go, ref BlockOpt bo) bo.startblock.Belem = el_combine(e, bo.startblock.Belem); } - bropt(go, bo); /* branch optimization */ - brrear(bo); /* branch rearrangement */ +//xyzzy bropt(go, bo); /* branch optimization */ +// brrear(bo); /* branch rearrangement */ comsubs(go, bo); /* eliminate common subexpressions */ debug if (debugb) @@ -499,6 +499,7 @@ void blockopt(ref GlobalOptimizer go, ref BlockOpt bo) */ @trusted +private void brcombine(ref GlobalOptimizer go, ref BlockOpt bo) { debug if (debugc) printf("brcombine()\n"); @@ -519,8 +520,8 @@ void brcombine(ref GlobalOptimizer go, ref BlockOpt bo) const bc = b.bc; if (bc == BC.iftrue) { - block* b2 = b.nthSucc(0); - block* b3 = b.nthSucc(1); + block* b2 = b.Bsucc[0]; + block* b3 = b.Bsucc[1]; if (b2.Bpred.length > 1) // if more than one predecessor continue; @@ -533,7 +534,7 @@ void brcombine(ref GlobalOptimizer go, ref BlockOpt bo) const bc2 = b2.bc; if (bc2 == BC.goto_ && - b3 == b2.nthSucc(0)) + b3 == b2.Bsucc[0]) { b.bc = BC.goto_; if (b2.Belem) @@ -542,7 +543,7 @@ void brcombine(ref GlobalOptimizer go, ref BlockOpt bo) b.Belem = el_bin(op,TYint,b.Belem,b2.Belem); b2.Belem = null; } - list_subtract(&(b.Bsucc),b2); + b.Bsucc.subtract(b2); b2.Bpred.subtract(b); debug if (debugc) printf("brcombine(): if !e1 then e2 => e1 || e2\n"); anychanges++; @@ -562,7 +563,7 @@ void brcombine(ref GlobalOptimizer go, ref BlockOpt bo) b.Belem.ET = b2.Belem.ET; b2.Belem = null; b3.Belem = null; - list_free(&b.Bsucc,FPNULL); + b.Bsucc.reset(); b2.Bpred.subtract(b); b3.Bpred.subtract(b); debug if (debugc) printf("brcombine(): if e1 return e2 else return e3 => ret e1?e2:e3\n"); @@ -570,9 +571,9 @@ void brcombine(ref GlobalOptimizer go, ref BlockOpt bo) } else if (bc2 == BC.goto_ && b3.bc == BC.goto_ && - b2.nthSucc(0) == b3.nthSucc(0)) + b2.Bsucc[0] is b3.Bsucc[0]) { - block* bsucc = b2.nthSucc(0); + block* bsucc = b2.Bsucc[0]; if (b2.Belem) { elem* e; @@ -600,15 +601,15 @@ void brcombine(ref GlobalOptimizer go, ref BlockOpt bo) } b.bc = BC.goto_; b3.Belem = null; - list_free(&b.Bsucc,FPNULL); + b.Bsucc.reset(); - b.appendSucc(bsucc); + b.Bsucc.push(bsucc); bsucc.Bpred.push(b); b2.Bpred.dtor(); - list_free(&(b2.Bsucc),FPNULL); + b2.Bsucc.dtor(); b2.Bpred.dtor(); - list_free(&(b3.Bsucc),FPNULL); + b3.Bsucc.dtor(); b2.bc = BC.ret; b3.bc = BC.ret; bsucc.Bpred.subtract(b2); @@ -646,11 +647,11 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo) { b.bc = BC.exit; // Exit block has no successors, so remove them - foreach (bp; ListRange(b.Bsucc)) + foreach (bp; b.Bsucc[]) { - list_block(bp).Bpred.subtract(b); + bp.Bpred.subtract(b); } - list_free(&b.Bsucc, FPNULL); + b.Bsucc.reset(); debug if (debugc) printf("CHANGE: noreturn becomes BC.exit\n"); go.changes++; continue; @@ -663,14 +664,12 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo) /* IF OPnot (e) GOTO ... */ if (n.Eoper == OPnot) { - tym_t tym; - - tym = n.E1.Ety; + const tym = n.E1.Ety; *pn = el_selecte1(n); (*pn).Ety = tym; for (n = b.Belem; n.Eoper == OPcomma; n = n.E2) n.Ety = tym; - b.Bsucc = list_reverse(b.Bsucc); + b.Bsucc.reverse(); debug if (debugc) printf("CHANGE: if (!e)\n"); go.changes++; } @@ -680,16 +679,16 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo) if (iftrue(n)) /* if elem is true */ { // select first succ - db = b.nthSucc(1); + db = b.Bsucc[1]; goto L1; } else if (iffalse(n)) { // select second succ - db = b.nthSucc(0); + db = b.Bsucc[0]; L1: - list_subtract(&(b.Bsucc),db); + b.Bsucc.subtract(db); db.Bpred.subtract(b); b.bc = BC.goto_; /* delete elem if it has no side effects */ @@ -699,12 +698,12 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo) } /* Look for both destinations being the same */ - else if (b.nthSucc(0) == - b.nthSucc(1)) + else if (b.Bsucc[0] == + b.Bsucc[1]) { b.bc = BC.goto_; - db = b.nthSucc(0); - list_subtract(&(b.Bsucc),db); + db = b.Bsucc[0]; + b.Bsucc.subtract(db); db.Bpred.subtract(b); debug if (debugc) printf("CHANGE: if (e) goto L1; else goto L1;\n"); go.changes++; @@ -727,21 +726,21 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo) break; } } - block* db = b.nthSucc(i); + block* db = b.Bsucc[1]; /* delete predecessors of successors (!) */ - foreach (bl; ListRange(b.Bsucc)) + foreach (bl; b.Bsucc[]) { if (i--) // but not the db successor { - bool bx = list_block(bl).Bpred.subtract(b); + bool bx = bl.Bpred.subtract(b); assert(bx); } } /* dump old successor list and create a new one */ - list_free(&b.Bsucc,FPNULL); - b.appendSucc(db); + b.Bsucc.reset(); + b.Bsucc.push(db); b.bc = BC.goto_; b.Belem = doptelem(b.Belem, Goal.none | Goal.again); debug if (debugc) printf("CHANGE: switch (const)\n"); @@ -760,11 +759,12 @@ private void brrear(ref BlockOpt bo) debug if (debugc) printf("brrear()\n"); for (block* b = bo.startblock; b; b = b.Bnext) // for each block { - foreach (bl; ListRange(b.Bsucc)) + foreach (i, bl; b.Bsucc[]) + //foreach (ref bl; b.Bsucc[]) { /* For each transfer of control block pointer */ int iter = 0; - block* bt = list_block(bl); + block* bt = bl; /* If it is a transfer to a block that consists */ /* of nothing but an unconditional transfer, */ @@ -776,7 +776,7 @@ private void brrear(ref BlockOpt bo) static if (NTEXCEPTIONS) enum additionalAnd = "b.Btry == bt.Btry && - bt.Btry == bt.nthSucc(0).Btry"; + bt.Btry == bt.Bsucc[0].Btry"; else enum additionalAnd = "true"; @@ -785,14 +785,15 @@ private void brrear(ref BlockOpt bo) (OPTIMIZER || !(bt.Bsrcpos.Slinnum && config.addlinenumbers)) && ++iter < 10) { - bl.ptr = list_ptr(bt.Bsucc); + // skip over bt + b.Bsucc[i] = bl = bt.Bsucc[0]; if (bt.Bsrcpos.Slinnum && !b.Bsrcpos.Slinnum) b.Bsrcpos = bt.Bsrcpos; b.Bflags |= bt.Bflags; - list_block(bl).Bpred.push(b); + bl.Bpred.push(b); bt.Bpred.subtract(b); debug if (debugc) printf("goto.goto\n"); - bt = list_block(bl); + bt = bl; } // Bsucc after the first are the targets of @@ -814,14 +815,14 @@ private void brrear(ref BlockOpt bo) if (b.bc == BC.iftrue || b.bc == BC.iffalse) { - block* bif = b.nthSucc(0); - block* belse = b.nthSucc(1); + block* bif = b.Bsucc[0]; + block* belse = b.Bsucc[1]; if (bif == b.Bnext) { b.bc ^= BC.iffalse ^ BC.iftrue; /* toggle */ - b.setNthSucc(0, belse); - b.setNthSucc(1, bif); + b.Bsucc[0] = belse; + b.Bsucc[1] = bif; b.Bflags |= bif.Bflags & BFL.visited; debug if (debugc) printf("if (e) L1 else L2\n"); } @@ -838,6 +839,7 @@ private void brrear(ref BlockOpt bo) * dfo = array to fill in in DFO * startblock = list of blocks */ +public void compdfo(ref BlockOpt bo, ref Barray!(block*) dfo, block* startblock) { debug if (debugc) printf("compdfo()\n"); @@ -853,9 +855,8 @@ void compdfo(ref BlockOpt bo, ref Barray!(block*) dfo, block* startblock) assert(b); b.Bflags |= BFL.visited; // executed at least once - foreach (bl; ListRange(b.Bsucc)) // for each successor + foreach (bs; b.Bsucc[]) // for each successor { - block* bs = list_block(bl); assert(bs); if ((bs.Bflags & BFL.visited) == 0) // if not visited walkDFO(bs); @@ -914,11 +915,14 @@ private void elimblks(ref GlobalOptimizer go, ref BlockOpt bo) /* for each marked successor S to b */ /* remove b from S.Bpred. */ /* Presumably all predecessors to b are unmarked also. */ - foreach (s; ListRange(b.Bsucc)) + foreach (s; b.Bsucc[]) { - assert(list_block(s)); - if (list_block(s).Bflags & BFL.visited) /* if it is marked */ - list_block(s).Bpred.subtract(b); + assert(s); + if (s.Bflags & BFL.visited) /* if it is marked */ + { + bool result = s.Bpred.subtract(b); + assert(result); + } } if (b.Balign && b.Bnext && b.Balign > b.Bnext.Balign) b.Bnext.Balign = b.Balign; @@ -965,7 +969,7 @@ private int mergeblks(ref BlockOpt bo) foreach (b; bo.dfo[]) { if (b.bc == BC.goto_) - { block* bL2 = list_block(b.Bsucc); + { block* bL2 = b.Bsucc[0]; if (b == bL2) { @@ -996,14 +1000,14 @@ private int mergeblks(ref BlockOpt bo) b.Bpred.reset(); /* Remove bL2 from successors of b */ - list_free(&b.Bsucc,FPNULL); + b.Bsucc.reset(); /* fix up successor list of predecessors */ foreach (bl; bL2.Bpred[]) { - foreach (bs; ListRange(bl.Bsucc)) - if (list_block(bs) == b) - bs.ptr = cast(void*)bL2; + foreach (i, bs; bl.Bsucc[]) + if (bs == b) + bl.Bsucc[i] = bL2; } merge++; @@ -1066,9 +1070,9 @@ private void blident(ref GlobalOptimizer go, ref BlockOpt bo) else enum additionalAnd = true; if (b.bc == bn.bc && - //(!OPTIMIZER || !(go.mfoptim & MFtime) || !b.Bsucc) && - (!OPTIMIZER || !(b.Bflags & BFL.nomerg) || !b.Bsucc) && - list_equal(b.Bsucc,bn.Bsucc) && + //(!OPTIMIZER || !(go.mfoptim & MFtime) || !b.Bsucc.length) && + (!OPTIMIZER || !(b.Bflags & BFL.nomerg) || !b.Bsucc.length) && + b.Bsucc.equals(bn.Bsucc) && additionalAnd && el_match(b.Belem,bn.Belem) ) @@ -1137,9 +1141,9 @@ private void blident(ref GlobalOptimizer go, ref BlockOpt bo) /* b instead of bn */ foreach (bp; bn.Bpred[]) { - foreach (bls; ListRange(bp.Bsucc)) - if (list_block(bls) == bn) - { bls.ptr = cast(void*)b; + foreach (i, bls; bp.Bsucc[]) + if (bls == bn) + { bp.Bsucc[i] = b; b.Bpred.push(bp); } } @@ -1221,7 +1225,7 @@ private void blreturn(ref GlobalOptimizer go, ref BlockOpt bo) } b.bc = BC.goto_; b.Bnext = bn; - list_append(&b.Bsucc,bn); + b.Bsucc.push(bn); bn.Bpred.push(b); b = bn; @@ -1339,7 +1343,7 @@ private void bltailmerge(ref GlobalOptimizer go, ref BlockOpt bo) { elem* en; if (b.bc == bn.bc && - list_equal(b.Bsucc,bn.Bsucc) && + b.Bsucc.equals(bn.Bsucc) && bn.Blist && el_match(e,(en = list_elem(bn.Blist))) && mixin(additionalAnd) @@ -1389,18 +1393,17 @@ private void bltailmerge(ref GlobalOptimizer go, ref BlockOpt bo) bn.Bnext = bnew; /* The successor list to bnew is the same as b's was */ - bnew.Bsucc = b.Bsucc; - b.Bsucc = null; - list_free(&bn.Bsucc,FPNULL); + bnew.Bsucc.move(b.Bsucc); + bn.Bsucc.reset(); /* Update the predecessor list of the successor list of bnew, from b to bnew, and removing bn */ - foreach (bl; ListRange(bnew.Bsucc)) + foreach (bl; bnew.Bsucc[]) { - list_block(bl).Bpred.subtract(b); - list_block(bl).Bpred.subtract(bn); - list_block(bl).Bpred.push(bnew); + bl.Bpred.subtract(b); + bl.Bpred.subtract(bn); + bl.Bpred.push(bnew); } /* The predecessors to bnew are b and bn */ @@ -1410,8 +1413,8 @@ private void bltailmerge(ref GlobalOptimizer go, ref BlockOpt bo) /* The successors to b and bn are bnew */ b.bc = BC.goto_; bn.bc = BC.goto_; - list_append(&b.Bsucc,bnew); - list_append(&bn.Bsucc,bnew); + b.Bsucc.push(bnew); + bn.Bsucc.push(bnew); go.changes++; @@ -1476,19 +1479,17 @@ private void brmin(ref GlobalOptimizer go, ref BlockOpt bo) if (!isExceptionHandler(b.Bnext)) { // Skip the block if one of the successors is already at Bnext. - foreach (bl; ListRange(b.Bsucc)) + foreach (bl; b.Bsucc[]) { - if (list_block(bl) == b.Bnext) + if (bl == b.Bnext) continue Lbb; } } // Look for a successor of b for which everyone must jmp to. Lsucc: - foreach (bl; ListRange(b.Bsucc)) + foreach (bs; b.Bsucc[]) { - block* bs = list_block(bl); - // BC.exit should have been optimized by blexit(). // Also ignore exception handlers. if (bs.bc == BC.exit || isExceptionHandler(bs)) @@ -1547,7 +1548,7 @@ private void brmin(ref GlobalOptimizer go, ref BlockOpt bo) moveDistance++; if (bss.Btry == bnext.Btry && - (!bss.Bnext || list_nitems(bss.Bsucc) == 0)) + (!bss.Bnext || bss.Bsucc.length == 0)) { // A very crude cost model. // Assume each basic block occupies 20 bytes. L1i cache @@ -1595,7 +1596,7 @@ private void block_check() { for (block* b = startblock; b; b = b.Bnext) { - int nsucc = list_nitems(b.Bsucc); + int nsucc = b.Bsucc.length; int npred = b.Bpred.length; switch (b.bc) { @@ -1608,10 +1609,8 @@ private void block_check() break; } - foreach (bl; ListRange(b.Bsucc)) + foreach (bs; b.Bsucc[]) { - block* bs = list_block(bl); - foreach (bls; bs.Bpred[]) { assert(bls); @@ -1664,7 +1663,7 @@ private void brtailrecursion(ref GlobalOptimizer go, ref BlockOpt bo) if (*pe && (b.bc == BC.ret || b.bc == BC.retexp || - (b.bc == BC.goto_ && (bn = list_block(b.Bsucc)).Belem == null && + (b.bc == BC.goto_ && (bn = b.Bsucc[0]).Belem == null && bn.bc == BC.ret) ) ) @@ -1707,17 +1706,17 @@ private void brtailrecursion(ref GlobalOptimizer go, ref BlockOpt bo) if (b.bc == BC.goto_) { - list_subtract(&b.Bsucc, bn); + b.Bsucc.subtract(bn); bn.Bpred.subtract(b); - list_append(&b1.Bsucc, bn); + b1.Bsucc.push(bn); bn.Bpred.subtract(b1); - list_append(&b2.Bsucc, bn); + b2.Bsucc.push(bn); bn.Bpred.subtract(b2); } - list_append(&b.Bsucc, b1); + b.Bsucc.push(b1); b1.Bpred.push(b); - list_append(&b.Bsucc, b2); + b.Bsucc.push(b2); b2.Bpred.push(b); b1.bc = b.bc; @@ -1753,11 +1752,11 @@ private void brtailrecursion(ref GlobalOptimizer go, ref BlockOpt bo) if (b.bc == BC.goto_) { - list_subtract(&b.Bsucc,bn); + b.Bsucc.subtract(bn); bn.Bpred.subtract(b); } b.bc = BC.goto_; - list_append(&b.Bsucc,bo.startblock); + b.Bsucc.push(bo.startblock); bo.startblock.Bpred.push(b); // Create a new startblock, bs, because startblock cannot @@ -1765,7 +1764,7 @@ private void brtailrecursion(ref GlobalOptimizer go, ref BlockOpt bo) block* bs = block_calloc(bo); bs.bc = BC.goto_; bs.Bnext = bo.startblock; - list_append(&bs.Bsucc,bo.startblock); + bs.Bsucc.push(bo.startblock); bo.startblock.Bpred.push(bs); bo.startblock = bs; @@ -1785,7 +1784,7 @@ private elem* assignparams(elem** pe,int* psi,elem** pe2) { elem* e = *pe; - if (e.Eoper == OPparam) + if (e.Eoper == OPparam) { elem* ea = null; elem* eb = null; @@ -1841,7 +1840,7 @@ private void emptyloops(ref GlobalOptimizer go, ref BlockOpt bo) for (block* b = bo.startblock; b; b = b.Bnext) { if (b.bc == BC.iftrue && - list_block(b.Bsucc) == b && + b.Bsucc[0] == b && b.Bpred.length == 2) { // Find predecessor to b @@ -1882,7 +1881,7 @@ private void emptyloops(ref GlobalOptimizer go, ref BlockOpt bo) erel.Ety = erel.E1.Ety; erel.E1 = el_selecte1(erel.E1); b.bc = BC.goto_; - list_subtract(&b.Bsucc,b); + b.Bsucc.subtract(b); b.Bpred.subtract(b); debug if (debugc) @@ -2088,14 +2087,14 @@ private void blassertsplit(ref GlobalOptimizer go, ref BlockOpt bo) b.Belem = bl_delist2(earray[0 .. i + 1]); - /* Transfer successors of b to b2. - * Fix up predecessors of successors to b2 to point to b2 instead of b + /* Transfer successors of b to b2 + */ + b2.Bsucc.move(b.Bsucc); + + /* Fix up predecessors of successors to b2 to point to b2 instead of b */ - b2.Bsucc = b.Bsucc; - b.Bsucc = null; - foreach (b2sl; ListRange(b2.Bsucc)) + foreach (b2s; b2.Bsucc[]) { - block* b2s = list_block(b2sl); foreach (ref b2spl; b2s.Bpred[]) { if (b2spl == b) @@ -2105,9 +2104,9 @@ private void blassertsplit(ref GlobalOptimizer go, ref BlockOpt bo) b.bc = BC.iftrue; assert(b.Belem); - list_append(&b.Bsucc, b2); + b.Bsucc.push(b2); b2.Bpred.push(b); - list_append(&b.Bsucc, bexit); + b.Bsucc.push(bexit); bexit.Bpred.push(b); b = b2; @@ -2159,12 +2158,11 @@ private void blexit(ref GlobalOptimizer go, ref BlockOpt bo) b.bc = BC.exit; - foreach (bsl; ListRange(b.Bsucc)) + foreach (bs; b.Bsucc[]) { - block* bs = list_block(bsl); bs.Bpred.subtract(b); } - list_free(&b.Bsucc, FPNULL); + b.Bsucc.reset(); if (b != bo.startblock && b.Bnext) bexits.push(b); diff --git a/compiler/src/dmd/backend/cc.d b/compiler/src/dmd/backend/cc.d index 0d7f08fcf4b2..a606b36fc07e 100644 --- a/compiler/src/dmd/backend/cc.d +++ b/compiler/src/dmd/backend/cc.d @@ -203,8 +203,7 @@ nothrow: } block* Bnext; // pointer to next block in list - list_t Bsucc; // linked list of pointers to successors - // of this block + Barray!(block*) Bsucc; // linked list of pointers to successors of this block Barray!(block*) Bpred; // and the predecessor array int Bindex; // into created object stack int Bendindex; // index at end of block @@ -318,18 +317,9 @@ nothrow: } @trusted - void appendSucc(block* b) { list_append(&this.Bsucc, b); } + void prependSucc(block* b) { this.Bsucc.insert(b, 0); } - @trusted - void prependSucc(block* b) { list_prepend(&this.Bsucc, b); } - - int numSucc() { return list_nitems(this.Bsucc); } - - @trusted - block* nthSucc(int n) { return cast(block*)list_ptr(list_nth(Bsucc, n)); } - - @trusted - void setNthSucc(int n, block* b) { list_nth(Bsucc, n).ptr = b; } + int numSucc() { return cast(int)this.Bsucc.length; } } @trusted diff --git a/compiler/src/dmd/backend/cgcs.d b/compiler/src/dmd/backend/cgcs.d index a0f1fa8f2210..c397b3c5b4c8 100644 --- a/compiler/src/dmd/backend/cgcs.d +++ b/compiler/src/dmd/backend/cgcs.d @@ -99,8 +99,8 @@ void comsubs2(block* startblock, ref CGCS cgcs, ref GlobalOptimizer go, ref Bloc auto blc = bl; while (bln && bln.Bpred.length == 1 && ((blc.bc == BC.iftrue && - blc.nthSucc(1) == bln) || - (blc.bc == BC.goto_ && blc.nthSucc(0) == bln) + blc.Bsucc[1] == bln) || + (blc.bc == BC.goto_ && blc.Bsucc[0] == bln) ) && bln.bc != BC.asm_ // no CSE's extending across ASM blocks ) diff --git a/compiler/src/dmd/backend/debugprint.d b/compiler/src/dmd/backend/debugprint.d index 200a7938361e..60af42c6dd71 100644 --- a/compiler/src/dmd/backend/debugprint.d +++ b/compiler/src/dmd/backend/debugprint.d @@ -392,7 +392,7 @@ void WRblock(block* b) printf(" catchvar = %p",b.catchvar); printf("\n"); printf("\tBpred: "); WRblockarray(b.Bpred[]); - printf("\tBsucc: "); WRblocklist(b.Bsucc); + printf("\tBsucc: "); WRblockarray(b.Bsucc[]); if (b.Belem) { if (debugf) /* if full output */ @@ -444,12 +444,11 @@ void WRblock(block* b) { case BC.switch_: printf("\tncases = %d\n", cast(int)b.Bswitch.length); - list_t bl = b.Bsucc; - printf("\tdefault: B%d\n",list_block(bl) ? list_block(bl).Bnumber : 0); - foreach (val; b.Bswitch) + auto ba = b.Bsucc[]; + printf("\tdefault: B%d\n",ba.length ? ba[0].Bnumber : 0); + foreach (i, val; b.Bswitch) { - bl = list_next(bl); - printf("\tcase %lld: B%d\n", cast(long)val, list_block(bl).Bnumber); + printf("\tcase %lld: B%d\n", cast(long)val, ba[1 + i].Bnumber); } break; @@ -465,11 +464,11 @@ void WRblock(block* b) case BC._lpad: case BC._ret: case BC._except: - if (list_t bl = b.Bsucc) + if (b.Bsucc.length) { printf("\tBsucc:"); - for ( ; bl; bl = list_next(bl)) - printf(" B%d",list_block(bl).Bnumber); + foreach (bl; b.Bsucc[]) + printf(" B%d", bl.Bnumber); printf("\n"); } break; diff --git a/compiler/src/dmd/backend/dout.d b/compiler/src/dmd/backend/dout.d index 1b91dc7e72e7..786af474a094 100644 --- a/compiler/src/dmd/backend/dout.d +++ b/compiler/src/dmd/backend/dout.d @@ -1002,14 +1002,14 @@ void writefunc2(Symbol* sfunc, ref GlobalOptimizer go, ref BlockOpt bo) { outelem(b.Belem, addressOfParam); if (b.Belem.Eoper == OPhalt) { b.bc = BC.exit; - list_free(&b.Bsucc,FPNULL); + b.Bsucc.dtor(); } } if (b.bc == BC.asm_) anyasm = true; if (sfunc.Sflags & SFLexit && (b.bc == BC.ret || b.bc == BC.retexp)) { b.bc = BC.exit; - list_free(&b.Bsucc,FPNULL); + b.Bsucc.dtor(); } assert(b != b.Bnext); } diff --git a/compiler/src/dmd/backend/dwarfeh.d b/compiler/src/dmd/backend/dwarfeh.d index e9e5fec4fd2c..823d6e27bb35 100644 --- a/compiler/src/dmd/backend/dwarfeh.d +++ b/compiler/src/dmd/backend/dwarfeh.d @@ -119,7 +119,7 @@ static if (0) DwEhTableEntry* d = deh.push(); d.start = cast(uint)b.Boffset; - block* bf = b.nthSucc(1); + block* bf = b.Bsucc[1]; if (bf.bc == BC.jcatch) { d.lpad = cast(uint)bf.Boffset; @@ -138,7 +138,7 @@ static if (0) d.action = offset + 1; } else - d.lpad = cast(uint)bf.nthSucc(0).Boffset; + d.lpad = cast(uint)bf.Bsucc[0].Boffset; d.prev = index; index = i; bprev = b.Btry; diff --git a/compiler/src/dmd/backend/eh.d b/compiler/src/dmd/backend/eh.d index 64f5c649ceab..48c7b446230a 100644 --- a/compiler/src/dmd/backend/eh.d +++ b/compiler/src/dmd/backend/eh.d @@ -216,10 +216,10 @@ void except_fillInEHTable(Symbol* s) { assert(nsucc == 2); dtb.dword(0); // no catch offset - block* bhandler = b.nthSucc(1); + block* bhandler = b.Bsucc[1]; assert(bhandler.bc == BC._finally); // To successor of BC._finally block - bhandler = bhandler.nthSucc(0); + bhandler = bhandler.Bsucc[0]; // finally handler address if (config.ehmethod == EHmethod.EH_DM) { @@ -341,7 +341,7 @@ void except_fillInEHTable(Symbol* s) for (int j = 1; j < nsucc; ++j) { - block* bcatch = b.nthSucc(j); + block* bcatch = b.Bsucc[j]; dtb.xoff(bcatch.Bcatchtype,0,TYnptr); diff --git a/compiler/src/dmd/backend/gflow.d b/compiler/src/dmd/backend/gflow.d index c031b4f55c3b..dbccbb98e765 100644 --- a/compiler/src/dmd/backend/gflow.d +++ b/compiler/src/dmd/backend/gflow.d @@ -570,7 +570,7 @@ private void flowaecp(ref GlobalOptimizer go, ref BlockOpt bo) bool first = true; foreach (bp; b.Bpred[]) { - if (bp.bc == BC.iftrue && bp.nthSucc(0) != b) + if (bp.bc == BC.iftrue && bp.Bsucc[0] != b) { if (first) vec_copy(b.Bin,bp.Bout2); @@ -1353,9 +1353,9 @@ void flowlv(ref BlockOpt bo) { /* Bout = union of Bins of all successors to B. */ bool first = true; - foreach (bl; ListRange(b.Bsucc)) + foreach (bl; b.Bsucc[]) { - const inlv = list_block(bl).Binlv; + const inlv = bl.Binlv; if (first) vec_copy(b.Boutlv, inlv); else @@ -1702,9 +1702,9 @@ void flowvbe(ref GlobalOptimizer go, ref BlockOpt bo) /* Bout = & of Bin of all successors */ bool first = true; - foreach (bl; ListRange(b.Bsucc)) + foreach (bl; b.Bsucc[]) { - const vin = list_block(bl).Bin; + const vin = bl.Bin; if (first) vec_copy(b.Bout, vin); else diff --git a/compiler/src/dmd/backend/gloop.d b/compiler/src/dmd/backend/gloop.d index b4882c684012..4be580d88b0d 100644 --- a/compiler/src/dmd/backend/gloop.d +++ b/compiler/src/dmd/backend/gloop.d @@ -221,8 +221,8 @@ bool blockinit(ref BlockOpt bo) L1: foreach (blp; b.Bpred[]) { - foreach (bls; ListRange(blp.Bsucc)) - if (list_block(bls) == b) + foreach (bls; blp.Bsucc[]) + if (bls == b) continue L1; assert(0); } @@ -340,9 +340,8 @@ private void findloops(ref BlockOpt bo, block*[] dfo, ref Loops loops) // loops are found first) { assert(b); - foreach (bl; ListRange(b.Bsucc)) + foreach (s; b.Bsucc[]) { - block* s = list_block(bl); // each successor s to b assert(s); if (dom(bo, s, b)) // if s dominates b buildloop(bo, loops, s, b); // we found a loop @@ -455,8 +454,8 @@ L1: vec_setbit(i,l.Lexit); /* ret blocks are exit blocks */ else { - foreach (bl; ListRange(bo.dfo[i].Bsucc)) - if (!vec_testbit(list_block(bl).Bdfoidx,l.Lloop)) + foreach (bl; bo.dfo[i].Bsucc[]) + if (!vec_testbit(bl.Bdfoidx,l.Lloop)) { vec_setbit(i,l.Lexit); break; @@ -480,7 +479,7 @@ L1: } else { - if (list_next(b.Bsucc)) // if more than 1 successor + if (b.Bsucc.length > 1) // if more than 1 successor break; // b can't be a preheader l.Lpreheader = b; } @@ -596,7 +595,6 @@ private bool looprotate(ref GlobalOptimizer go, ref BlockOpt bo, ref Loop l) // pred(head1) = pred(head) outside loop // pred(head2) = pred(head) inside loop -static if (1) for (size_t i = 0; i < head.Bpred.length; ) { if (vec_testbit(head.Bpred[i].Bdfoidx, l.Lloop)) // if head predecessor [i] is in the loop @@ -607,10 +605,10 @@ static if (1) head.Bpred.subtracti(i); // Any successors to predecessors to head blocks get redirected to head2 - foreach (bl; ListRange(bs.Bsucc)) - if (list_block(bl) == head) + foreach (j, bl; bs.Bsucc[]) + if (bl == head) { - bl.ptr = cast(void*)head2; + bs.Bsucc[i] = head2; goto L2; } assert(0); @@ -619,39 +617,10 @@ static if (1) else ++i; // next predecessor in head } // for each pred(head) -else -{ - list_t* pbln; - auto pbl2 = &(head2.Bpred); - for (list_t* pbl = &(head.Bpred); *pbl; pbl = pbln) - { - if (vec_testbit(list_block(*pbl).Bdfoidx, l.Lloop)) - { // if this predecessor is inside the loop - - *pbl2 = *pbl; - *pbl = list_next(*pbl); - pbln = pbl; // don't skip this next one - (*pbl2).next = null; - auto bsucc = list_block(*pbl2).Bsucc; - pbl2 = &((*pbl2).next); - foreach (bl; ListRange(bsucc)) - if (list_block(bl) == head) - { - bl.ptr = cast(void*)head2; - goto L2; - } - assert(0); - L2: - } - else - pbln = &((*pbl).next); // next predecessor in list - } // for each pred(head) -} // succ(head2) = succ(head) - foreach (bl; ListRange(head.Bsucc)) + foreach (b; head.Bsucc[]) { - block* b = list_block(bl); - list_append(&(head2.Bsucc),b); + head2.Bsucc.push(b); b.Bpred.push(head2); } if (debugc) printf("1Rotated loop %p\n", &l); @@ -709,6 +678,9 @@ private __gshared @trusted void loopopt(ref GlobalOptimizer go, ref BlockOpt bo) +{ +return; // xyzzy +static if (0) { __gshared Loops startloop_cache; @@ -777,8 +749,8 @@ restart: l.Lpreheader = p; p.bc = BC.goto_; - assert(p.Bsucc == null); - list_append(&(p.Bsucc),h); /* only successor is h */ + assert(p.Bsucc.length == 0); + p.Bsucc.push(h); /* only successor is h */ p.Btry = h.Btry; if (debugc) printf("Adding preheader %p to loop %p\n",p,&l); @@ -795,9 +767,9 @@ restart: i = 0; // start over /* Fix up successors of predecessors */ - foreach (bls; ListRange(b.Bsucc)) - if (list_block(bls) == h) - bls.ptr = cast(void*)p; + foreach (ref bls; b.Bsucc[]) + if (bls == h) + bls = p; } else ++i; @@ -954,6 +926,7 @@ restart: freeloop(startloop); startloop_cache = startloop; } +} /***************************** * If elem is loop invariant, mark it. @@ -1576,14 +1549,10 @@ Lnextlis: if (!(pdomexit & 1)) // if not case 1 { - uint i; - for (i = 0; (i = cast(uint) vec_index(i, l.Lexit)) < bo.dfo.length; ++i) // for each exit block + for (uint i = 0; (i = cast(uint) vec_index(i, l.Lexit)) < bo.dfo.length; ++i) // for each exit block { - foreach (bl; ListRange(bo.dfo[i].Bsucc)) + foreach (s; bo.dfo[i].Bsucc[]) { - block* s; // successor to exit block - - s = list_block(bl); if (!vec_testbit(s.Bdfoidx,l.Lloop) && (!symbol_isintab(v) || vec_testbit(v.Ssymnum,s.Binlv))) // if v is live on exit @@ -3041,11 +3010,9 @@ private void elimbasivs(ref GlobalOptimizer go, ref BlockOpt bo, ref Loop l) for (uint i = 0; (i = cast(uint) vec_index(i, l.Lexit)) < bo.dfo.length; ++i) // for each exit block { elem* ne; - block* b; - foreach (bl; ListRange(bo.dfo[i].Bsucc)) + foreach (j, b; bo.dfo[i].Bsucc[]) { /* for each successor */ - b = list_block(bl); if (vec_testbit(b.Bdfoidx,l.Lloop)) continue; /* inside loop */ if (!vec_testbit(X.Ssymnum,b.Binlv)) @@ -3086,9 +3053,10 @@ private void elimbasivs(ref GlobalOptimizer go, ref BlockOpt bo, ref Loop l) bn.bc = BC.goto_; bn.Bnext = bo.dfo[i].Bnext; bo.dfo[i].Bnext = bn; - list_append(&(bn.Bsucc),b); + bn.Bsucc.push(b); bn.Bpred.push(bo.dfo[i]); - bl.ptr = cast(void*)bn; + b = bn; + bo.dfo[i].Bsucc[j] = bn; foreach (ref bl2; b.Bpred[]) if (bl2 == bo.dfo[i]) { @@ -3098,6 +3066,7 @@ private void elimbasivs(ref GlobalOptimizer go, ref BlockOpt bo, ref Loop l) assert(0); L2: b = bn; + bo.dfo[i].Bsucc[j] = bn; addblk = true; } @@ -3119,9 +3088,8 @@ private void elimbasivs(ref GlobalOptimizer go, ref BlockOpt bo, ref Loop l) /* Eliminate the basic IV if it is not live on any successor */ for (uint i = 0; (i = cast(uint) vec_index(i, l.Lexit)) < bo.dfo.length; ++i) // for each exit block { - foreach (bl; ListRange(bo.dfo[i].Bsucc)) + foreach (b; bo.dfo[i].Bsucc[]) { /* for each successor */ - block* b = list_block(bl); if (vec_testbit(b.Bdfoidx,l.Lloop)) continue; /* inside loop */ if (vec_testbit(X.Ssymnum,b.Binlv)) @@ -3181,12 +3149,10 @@ private void elimopeqs(ref GlobalOptimizer go, ref BlockOpt bo, ref Loop l) { } else if (refcount == 0) // if no uses of IV in loop { // Eliminate the basic IV if it is not live on any successor - uint i; - for (i = 0; (i = cast(uint) vec_index(i, l.Lexit)) < bo.dfo.length; ++i) // for each exit block + for (uint i = 0; (i = cast(uint) vec_index(i, l.Lexit)) < bo.dfo.length; ++i) // for each exit block { - foreach (bl; ListRange(bo.dfo[i].Bsucc)) + foreach (b; bo.dfo[i].Bsucc[]) { // for each successor - block* b = list_block(bl); if (vec_testbit(b.Bdfoidx,l.Lloop)) continue; // inside loop if (vec_testbit(X.Ssymnum,b.Binlv)) diff --git a/compiler/src/dmd/backend/gother.d b/compiler/src/dmd/backend/gother.d index 593e4108066e..83367b5ae1be 100644 --- a/compiler/src/dmd/backend/gother.d +++ b/compiler/src/dmd/backend/gother.d @@ -898,7 +898,7 @@ private void intranges(ref GlobalOptimizer go, ref Elemdatas rellist, ref Elemda // Eliminate loop if it is empty if (relatop == OPlt && rb.bc == BC.iftrue && - list_block(rb.Bsucc) == rb && + rb.Bsucc[0] == rb && rb.Belem.Eoper == OPcomma && rb.Belem.E1 == rdinc && rb.Belem.E2 == rel.pelem @@ -907,8 +907,8 @@ private void intranges(ref GlobalOptimizer go, ref Elemdatas rellist, ref Elemda rel.pelem.Eoper = OPeq; rel.pelem.Ety = rel.pelem.E1.Ety; rb.bc = BC.goto_; - list_subtract(&rb.Bsucc,rb); - list_subtract(&rb.Bpred,rb); + rb.Bsucc.subtract(rb); + rb.Bpred.subtract(rb); debug if (debugc) @@ -1066,9 +1066,8 @@ private int loopcheck(block* start,block* inc,block* rel) { if (!(start.Bflags & BFL.visited)) { start.Bflags |= BFL.visited; /* guarantee eventual termination */ - foreach (list; ListRange(start.Bsucc)) + foreach (b; start.Bsucc[]) { - block* b = cast(block*) list_ptr(list); if (b != rel && (b == inc || loopcheck(b,inc,rel))) return true; } diff --git a/compiler/src/dmd/backend/inliner.d b/compiler/src/dmd/backend/inliner.d index 9bf090530a52..7e4689d82377 100644 --- a/compiler/src/dmd/backend/inliner.d +++ b/compiler/src/dmd/backend/inliner.d @@ -112,7 +112,7 @@ bool canInlineFunction(Symbol* sfunc) switch (b.bc) { case BC.goto_: - if (b.Bnext != b.nthSucc(0)) + if (b.Bnext != b.Bsucc[0]) return no(__LINE__); b = b.Bnext; continue; diff --git a/compiler/src/dmd/backend/x86/cgcod.d b/compiler/src/dmd/backend/x86/cgcod.d index a0b832758a2b..6382bf47884c 100644 --- a/compiler/src/dmd/backend/x86/cgcod.d +++ b/compiler/src/dmd/backend/x86/cgcod.d @@ -88,7 +88,7 @@ void codgen(Symbol* sfunc) /*********************** * Same as codgen(), but adding in CGstate argument * Params: - * cg = code generator state + * cg = code generator state * sfunc = function to generate code for */ private @trusted @@ -2131,7 +2131,7 @@ bool cssave(elem* e, regm_t regm, bool opsflag) /*if (e.Ecount && e.Ecount == e.Ecomsub)*/ if (e.Ecount && e.Ecomsub) { - CGstate* cg = &cgstate; + CGstate* cg = &cgstate; if (!opsflag && cg.pass != BackendPass.final_ && (I32 || I64)) return false; @@ -2579,7 +2579,7 @@ private void loadcse(ref CodeBuilder cdb,elem* e,reg_t reg,regm_t regm) //printf("CSE[%d] = %p, regm = %s\n", i, cse.e, regm_str(cse.regm)); if (cse.regm & regm) { - CGstate* cg = &cgstate; + CGstate* cg = &cgstate; cg.reflocal = true; cse.flags |= CSEload; /* it was loaded */ cg.regcon.cse.value[reg] = e; diff --git a/compiler/src/dmd/backend/x86/cgreg.d b/compiler/src/dmd/backend/x86/cgreg.d index e3644d01f7c9..24a7299e2a5a 100644 --- a/compiler/src/dmd/backend/x86/cgreg.d +++ b/compiler/src/dmd/backend/x86/cgreg.d @@ -607,15 +607,15 @@ void cgreg_spillreg_epilog(block* b,Symbol* s,ref CodeBuilder cdbstore, ref Code const bi = b.Bdfoidx; //printf("cgreg_spillreg_epilog(block %d, s = '%s')\n",bi,s.Sident.ptr); //assert(b.bc == BC.goto_); - if (!cgreg_gotoepilog(b.nthSucc(0), s)) + if (!cgreg_gotoepilog(b.Bsucc[0], s)) return; const live = vec_testbit(bi,s.Slvreg) != 0; // Look at successors to see if we need to load in/out of register - foreach (bl; ListRange(b.Bsucc)) + foreach (bl; b.Bsucc[]) { - const bpi = list_block(bl).Bdfoidx; + const bpi = bl.Bdfoidx; if (!vec_testbit(bpi,s.Srange)) continue; if (vec_testbit(bpi,s.Slvreg)) diff --git a/compiler/src/dmd/backend/x86/cod3.d b/compiler/src/dmd/backend/x86/cod3.d index 51da0e2a8446..eb4587296f54 100644 --- a/compiler/src/dmd/backend/x86/cod3.d +++ b/compiler/src/dmd/backend/x86/cod3.d @@ -1060,8 +1060,8 @@ void outblkexitcode(ref CGstate cg, ref CodeBuilder cdb, block* bl, ref int anys case BC.iftrue: { bool jcond = true; - block* bs1 = bl.nthSucc(0); - block* bs2 = bl.nthSucc(1); + block* bs1 = bl.Bsucc[0]; + block* bs2 = bl.Bsucc[1]; if (bs1 == bl.Bnext) { // Swap bs1 and bs2 block* btmp; @@ -1117,7 +1117,7 @@ void outblkexitcode(ref CGstate cg, ref CodeBuilder cdb, block* bl, ref int anys } goto case_goto; case BC.goto_: - nextb = bl.nthSucc(0); + nextb = bl.Bsucc[0]; if ((MARS || funcsym_p.Sfunc.Fflags3 & Fnteh) && ehmethod(funcsym_p) != EHmethod.EH_DWARF && @@ -1132,7 +1132,7 @@ void outblkexitcode(ref CGstate cg, ref CodeBuilder cdb, block* bl, ref int anys if (toindex + 1 == fromindex) { // Simply call __finally if (bl.Btry && - bl.Btry.nthSucc(1).bc == BC.jcatch) + bl.Btry.Bsucc[1].bc == BC.jcatch) { goto L5; // it's a try-catch, not a try-finally } @@ -1155,7 +1155,7 @@ void outblkexitcode(ref CGstate cg, ref CodeBuilder cdb, block* bl, ref int anys { block* bf; //printf("\tbt.Bscope_index = %d, bt.Blast_index = %d\n", bt.Bscope_index, bt.Blast_index); - bf = bt.nthSucc(1); + bf = bt.Bsucc[1]; // Only look at try-finally blocks if (bf.bc == BC.jcatch) continue; @@ -1165,11 +1165,11 @@ void outblkexitcode(ref CGstate cg, ref CodeBuilder cdb, block* bl, ref int anys //printf("\tbf = B%d, nextb = B%d\n", bf.Bdfoidx, nextb.Bdfoidx); if (nextb.bc == BC.goto_ && !nextb.Belem && - bf == nextb.nthSucc(0)) + bf == nextb.Bsucc[0]) continue; // call __finally - cdb.append(callFinallyBlock(cg, bf.nthSucc(0), retregsx)); + cdb.append(callFinallyBlock(cg, bf.Bsucc[0], retregsx)); } } } @@ -1197,7 +1197,7 @@ void outblkexitcode(ref CGstate cg, ref CodeBuilder cdb, block* bl, ref int anys cdb.append(cdbstore); cdb.append(cdbload); } - nextb = bl.nthSucc(0); + nextb = bl.Bsucc[0]; goto L5; } @@ -1231,8 +1231,8 @@ void outblkexitcode(ref CGstate cg, ref CodeBuilder cdb, block* bl, ref int anys regm_t retregsx = 0; gencodelem(cdb,bl.Belem,retregsx,true); - // JMP bl.nthSucc(1) - nextb = bl.nthSucc(1); + // JMP bl.Bsucc[1] + nextb = bl.Bsucc[1]; goto L5; } @@ -1248,10 +1248,10 @@ void outblkexitcode(ref CGstate cg, ref CodeBuilder cdb, block* bl, ref int anys assert(!e); // Generate CALL to finalizer code - cdb.append(callFinallyBlock(cg, bl.nthSucc(0), 0)); + cdb.append(callFinallyBlock(cg, bl.Bsucc[0], 0)); - // JMP bl.nthSucc(1) - nextb = bl.nthSucc(1); + // JMP bl.Bsucc[1] + nextb = bl.Bsucc[1]; goto L5; } @@ -1266,8 +1266,8 @@ void outblkexitcode(ref CGstate cg, ref CodeBuilder cdb, block* bl, ref int anys regm_t retregsx = 0; gencodelem(cdb,bl.Belem,retregsx,true); - // JMP bl.nthSucc(0) - nextb = bl.nthSucc(0); + // JMP bl.Bsucc[0] + nextb = bl.Bsucc[0]; goto L5; } @@ -1291,7 +1291,7 @@ static if (NTEXCEPTIONS) cg.usednteh |= NTEH_except; nteh_setsp(cg, cdb,0x8B); getregsNoSave(cg.allregs); - nextb = bl.nthSucc(0); + nextb = bl.Bsucc[0]; goto L5; } case BC._filter: @@ -1529,7 +1529,7 @@ static if (NTEXCEPTIONS) block* bt = bl; while ((bt = bt.Btry) != null) { - block* bf = bt.nthSucc(1); + block* bf = bt.Bsucc[1]; // Only look at try-finally blocks if (bf.bc == BC.jcatch) { @@ -1547,7 +1547,7 @@ static if (NTEXCEPTIONS) nteh_gensindex(cdb,-1); gensaverestore(cg,retregs,cdbs,cdbr); cdb.append(cdbs); - cdb.genc(0xE8,0,FL.unde,0,FL.block,cast(targ_size_t)bf.nthSucc(0)); + cdb.genc(0xE8,0,FL.unde,0,FL.block,cast(targ_size_t)bf.Bsucc[0]); cg.regcon.immed.mval = 0; cdb.append(cdbr); } @@ -1560,7 +1560,7 @@ static if (NTEXCEPTIONS) else { // call __finally - cdb.append(callFinallyBlock(cg, bf.nthSucc(0), retregs)); + cdb.append(callFinallyBlock(cg, bf.Bsucc[0], retregs)); } } } @@ -1582,7 +1582,7 @@ static if (NTEXCEPTIONS) getregs(cdbx, iasm_regs(bl)); // mark destroyed registers code* c = cdbx.finish(); if (bl.Bsucc) - { nextb = bl.nthSucc(0); + { nextb = bl.Bsucc[0]; if (!bl.Bnext) { cdb.append(bl.Bcode); @@ -1593,7 +1593,7 @@ static if (NTEXCEPTIONS) bl.Bnext && !(bl.Bnext.bc == BC.goto_ && !bl.Bnext.Belem && - nextb == bl.Bnext.nthSucc(0))) + nextb == bl.Bnext.Bsucc[0])) { // See if already have JMP at end of block code* cl = code_last(bl.Bcode); @@ -2067,8 +2067,7 @@ void doswitch(ref CGstate cg, ref CodeBuilder cdb, block* b) reg = findreg(retregs); // reg that result is in reg2 = NOREG; } - list_t bl = b.Bsucc; - block* bdefault = b.nthSucc(0); + block* bdefault = b.Bsucc[0]; if (dword && mswsame) { cdb.genc2(0x81,modregrm(3,7,reg2),msw); // CMP reg2,MSW @@ -2085,11 +2084,12 @@ void doswitch(ref CGstate cg, ref CodeBuilder cdb, block* b) auto sb = SmallBuffer!(CaseVal)(ncases, tmp[]); CaseVal[] casevals = sb[]; + size_t i = 1; foreach (n, val; b.Bswitch) { casevals[n].val = val; - bl = list_next(bl); - casevals[n].target = list_block(bl); + casevals[n].target = b.Bsucc[i]; + ++i; // See if we need a scratch register if (!cg.AArch64 && sreg == NOREG && I64 && sz == 8 && val != cast(int)val) @@ -2149,19 +2149,19 @@ void doswitch(ref CGstate cg, ref CodeBuilder cdb, block* b) cdb.genc2(0x81,modregrm(3,5,reg),cast(targ_size_t)vmin); // SUB reg,vmin if (dword) { cdb.genc2(0x81,modregrm(3,3,reg2),cast(targ_size_t)MSREG(vmin)); // SBB reg2,vmin - genjmp(cdb,JNE,FL.block,b.nthSucc(0)); // JNE default + genjmp(cdb,JNE,FL.block,b.Bsucc[0]); // JNE default } } else if (dword) { gentstreg(cdb,reg2); // TEST reg2,reg2 - genjmp(cdb,JNE,FL.block,b.nthSucc(0)); // JNE default + genjmp(cdb,JNE,FL.block,b.Bsucc[0]); // JNE default } if (vmax - vmin != REGMASK) // if there is a maximum { // CMP reg,vmax-vmin cdb.genc2(0x81,modregrm(3,7,reg),cast(targ_size_t)(vmax-vmin)); if (I64 && sz == 8) code_orrex(cdb.last(), REX_W); - genjmp(cdb,JA,FL.block,b.nthSucc(0)); // JA default + genjmp(cdb,JA,FL.block,b.Bsucc[0]); // JA default } if (I64) { @@ -2216,14 +2216,14 @@ static if (JMPJMPTABLE) ... */ CodeBuilder ctable; ctable.ctor(); - block* bdef = b.nthSucc(0); + block* bdef = b.Bsucc[0]; targ_llong u; for (u = vmin; ; u++) { block* targ = bdef; foreach (n, val; b.Bswitch) { if (val == u) - { targ = b.nthSucc(n + 1); + { targ = b.Bsucc[n + 1]; break; } } @@ -2329,7 +2329,7 @@ else if (dword && mswsame) { /* CMP DX,MSW */ cdb.genc2(0x81,modregrm(3,7,DX),msw); - genjmp(cdb,JNE,FL.block,b.nthSucc(0)); // JNE default + genjmp(cdb,JNE,FL.block,b.Bsucc[0]); // JNE default } getregs(cdb,mCX|mDI); @@ -2403,7 +2403,7 @@ else cdb.gen1(0xF2); // REPNE cdb.gen1(0xAF); // SCASW } - genjmp(cdb,JNE,FL.block,b.nthSucc(0)); // JNE default + genjmp(cdb,JNE,FL.block,b.Bsucc[0]); // JNE default const int mod = (disp > 127) ? 2 : 1; // 1 or 2 byte displacement if (csseg) cdb.gen1(SEGCS); // table is in code segment @@ -2468,14 +2468,14 @@ void outjmptab(block* b) assert(*poffset == b.Btableoffset); // should match precomputed value Symbol* gotsym = null; - targ_size_t def = b.nthSucc(0).Boffset; // default address + targ_size_t def = b.Bsucc[0].Boffset; // default address for (targ_llong u = vmin; ; u++) { targ_size_t targ = def; // default foreach (n; 0 .. ncases) { if (b.Bswitch[n] == u) { - targ = b.nthSucc(cast(int)(n + 1)).Boffset; + targ = b.Bsucc[n + 1].Boffset; break; } } @@ -2564,11 +2564,11 @@ void outswitab(block* b) assert(*poffset == offset); } - list_t bl = b.Bsucc; + size_t i = 1; foreach (n; 0 .. ncases) // send out address table { - bl = list_next(bl); - objmod.reftocodeseg(seg,*poffset,list_block(bl).Boffset); + objmod.reftocodeseg(seg,*poffset,b.Bsucc[i].Boffset); + ++i; *poffset += tysize(TYnptr); } assert(*poffset == offset + ncases * tysize(TYnptr)); diff --git a/compiler/src/dmd/backend/x86/cod5.d b/compiler/src/dmd/backend/x86/cod5.d index eeaba0e5f901..a2fa1fdce273 100644 --- a/compiler/src/dmd/backend/x86/cod5.d +++ b/compiler/src/dmd/backend/x86/cod5.d @@ -182,8 +182,8 @@ private void pe_add(block* b) return; b.Bflags |= BFL.outsideprolog; - foreach (bl; ListRange(b.Bsucc)) - pe_add(list_block(bl)); + foreach (bl; b.Bsucc[]) + pe_add(bl); } /********************************************** diff --git a/compiler/src/dmd/glue/package.d b/compiler/src/dmd/glue/package.d index b53eed25f03b..a4f161e059c5 100644 --- a/compiler/src/dmd/glue/package.d +++ b/compiler/src/dmd/glue/package.d @@ -1055,7 +1055,7 @@ void FuncDeclaration_toObjFile(FuncDeclaration fd, bool multiobj) block_appendexp(startBlk, exec); //payload startBlk.bc = BC.goto_; auto next = block_calloc(bo); - startBlk.appendSucc(next); + startBlk.Bsucc.push(next); startBlk.Bnext = next; next.bc = BC.ret; //Emit in binary diff --git a/compiler/src/dmd/glue/s2ir.d b/compiler/src/dmd/glue/s2ir.d index 048d0840ab39..f8fddbfdbf4c 100644 --- a/compiler/src/dmd/glue/s2ir.d +++ b/compiler/src/dmd/glue/s2ir.d @@ -160,23 +160,23 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block* bcond = blx.curblock; block_next(blx, BC.iftrue, null); - bcond.appendSucc(blx.curblock); + bcond.Bsucc.push(blx.curblock); if (s.ifbody) { if (!s.isIfCtfeBlock()) // __ctfe is always false at runtime Statement_toIR(s.ifbody, irs, &mystate); } - blx.curblock.appendSucc(bexit); + blx.curblock.Bsucc.push(bexit); if (s.elsebody) { block_next(blx, BC.goto_, null); - bcond.appendSucc(blx.curblock); + bcond.Bsucc.push(blx.curblock); Statement_toIR(s.elsebody, irs, &mystate); - blx.curblock.appendSucc(bexit); + blx.curblock.Bsucc.push(bexit); } else - bcond.appendSucc(bexit); + bcond.Bsucc.push(bexit); block_next(blx, BC.goto_, bexit); @@ -213,14 +213,14 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block* bpre = blx.curblock; block_next(blx, BC.goto_, null); - bpre.appendSucc(blx.curblock); + bpre.Bsucc.push(blx.curblock); - mystate.contBlock.appendSucc(blx.curblock); - mystate.contBlock.appendSucc(mystate.breakBlock); + mystate.contBlock.Bsucc.push(blx.curblock); + mystate.contBlock.Bsucc.push(mystate.breakBlock); if (s._body) Statement_toIR(s._body, irs, &mystate); - blx.curblock.appendSucc(mystate.contBlock); + blx.curblock.Bsucc.push(mystate.contBlock); block_next(blx, BC.goto_, mystate.contBlock); incUsage(irs, s.condition.loc); @@ -246,28 +246,28 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block* bpre = blx.curblock; block_next(blx,BC.goto_,null); block* bcond = blx.curblock; - bpre.appendSucc(bcond); - mystate.contBlock.appendSucc(bcond); + bpre.Bsucc.push(bcond); + mystate.contBlock.Bsucc.push(bcond); if (s.condition) { incUsage(irs, s.condition.loc); block_appendexp(bcond, toElemDtor(s.condition, irs)); block_next(blx,BC.iftrue,null); - bcond.appendSucc(blx.curblock); - bcond.appendSucc(mystate.breakBlock); + bcond.Bsucc.push(blx.curblock); + bcond.Bsucc.push(mystate.breakBlock); } else { /* No conditional, it's a straight goto */ block_next(blx,BC.goto_,null); - bcond.appendSucc(blx.curblock); + bcond.Bsucc.push(blx.curblock); } if (s._body) Statement_toIR(s._body, irs, &mystate); /* End of the body goes to the continue block */ - blx.curblock.appendSucc(mystate.contBlock); + blx.curblock.Bsucc.push(mystate.contBlock); block_setLoc(blx.curblock, s.endloc); block_next(blx, BC.goto_, mystate.contBlock); @@ -304,7 +304,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) /* Nothing more than a 'goto' to the current break destination */ - b.appendSucc(bbreak); + b.Bsucc.push(bbreak); block_setLoc(b, s.loc); block_next(blx, BC.goto_, null); } @@ -332,7 +332,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) /* Nothing more than a 'goto' to the current continue destination */ - b.appendSucc(bcont); + b.Bsucc.push(bcont); block_setLoc(b, s.loc); block_next(blx, BC.goto_, null); } @@ -351,7 +351,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block* bdest = cast(block*)s.label.statement.extra; block* b = blx.curblock; incUsage(irs, s.loc); - b.appendSucc(bdest); + b.Bsucc.push(bdest); block_setLoc(b, s.loc); block_next(blx,BC.goto_,null); @@ -370,7 +370,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) bdest.Btry = blx.tryblock; block_next(blx, BC.goto_, bdest); - bc.appendSucc(blx.curblock); + bc.Bsucc.push(blx.curblock); if (s.statement) Statement_toIR(s.statement, irs, &mystate); } @@ -430,15 +430,15 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block_appendexp(b, e); block* cb = cast(block*)cs.extra; block_next(blx, BC.iftrue, null); - b.appendSucc(cb); - b.appendSucc(blx.curblock); + b.Bsucc.push(cb); + b.Bsucc.push(blx.curblock); } /* The final 'else' clause goes to the default */ block* b = blx.curblock; block_next(blx, BC.goto_, null); - b.appendSucc(mystate.defaultBlock); + b.Bsucc.push(mystate.defaultBlock); Statement_toIR(s._body, irs, &mystate); @@ -461,7 +461,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) /* First successor is the default block */ - mystate.switchBlock.appendSucc(mystate.defaultBlock); + mystate.switchBlock.Bsucc.push(mystate.defaultBlock); if (numcases) { @@ -494,8 +494,8 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block_next(blx, BC.goto_, cb); block* bsw = stmtstate.getSwitchBlock(); if (bsw.bc == BC.switch_) - bsw.appendSucc(cb); // second entry in pair - bcase.appendSucc(cb); + bsw.Bsucc.push(cb); // second entry in pair + bcase.Bsucc.push(cb); if (!isAssertFalse(s.statement)) incUsage(irs, s.loc); if (s.statement) @@ -508,7 +508,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block* bcase = blx.curblock; block* bdefault = stmtstate.getDefaultBlock(); block_next(blx,BC.goto_,bdefault); - bcase.appendSucc(blx.curblock); + bcase.Bsucc.push(blx.curblock); if (!isAssertFalse(s.statement)) incUsage(irs, s.loc); if (s.statement) @@ -525,7 +525,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) // The rest is equivalent to GotoStatement - b.appendSucc(bdest); + b.Bsucc.push(bdest); incUsage(irs, s.loc); block_next(blx,BC.goto_,null); } @@ -538,7 +538,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) // The rest is equivalent to GotoStatement - b.appendSucc(bdest); + b.Bsucc.push(bdest); incUsage(irs, s.loc); block_next(blx,BC.goto_,null); } @@ -574,7 +574,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) (finallyBlock = stmtstate.getFinallyBlock()) != null) { assert(finallyBlock.bc == BC._finally); - blx.curblock.appendSucc(finallyBlock); + blx.curblock.Bsucc.push(finallyBlock); } block_setLoc(blx.curblock, s.loc); @@ -705,7 +705,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) // goto the next block block* b = blx.curblock; block_next(blx, BC.goto_, null); - b.appendSucc(blx.curblock); + b.Bsucc.push(blx.curblock); } /************************************** @@ -752,7 +752,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block_next(blx, BC.goto_, null); block* bdo = blx.curblock; - bpre.appendSucc(bdo); + bpre.Bsucc.push(bdo); block* bdox; @@ -766,13 +766,13 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) bdox = blx.curblock; block_next(blx, BC.goto_, mystate.contBlock); - bdox.appendSucc(mystate.contBlock); + bdox.Bsucc.push(mystate.contBlock); } } bdox = blx.curblock; block_next(blx, BC.goto_, mystate.breakBlock); - bdox.appendSucc(mystate.breakBlock); + bdox.Bsucc.push(mystate.breakBlock); } @@ -894,7 +894,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) // create new break block that follows all the catches block* breakblock2 = block_calloc(blx); - blx.curblock.appendSucc(breakblock2); + blx.curblock.Bsucc.push(breakblock2); block_next(blx,BC.goto_,null); assert(s.catches); @@ -956,7 +956,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) } block* bcatch = blx.curblock; - tryblock.appendSucc(bcatch); + tryblock.Bsucc.push(bcatch); block_goto(blx, BC.jcatch, null); block* defaultblock = block_calloc(blx); @@ -971,7 +971,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) long* pu = cast(long*) Mem.check(.malloc(long.sizeof * numcases)); bswitch.Bswitch = pu[0 .. numcases]; } - bswitch.appendSucc(defaultblock); + bswitch.Bsucc.push(defaultblock); block_next(blx, BC.switch_, null); foreach (i, cs; *s.catches) @@ -1022,7 +1022,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) bswitch.Bswitch[i] = f.typesTable.length; // index starts at 1 L1: block* bcase = blx.curblock; - bswitch.appendSucc(bcase); + bswitch.Bsucc.push(bcase); if (cs.handler !is null) { @@ -1059,7 +1059,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) else Statement_toIR(cs.handler, irs, &catchState); } - blx.curblock.appendSucc(breakblock2); + blx.curblock.Bsucc.push(breakblock2); if (i + 1 == numcases) { block_next(blx, BC.goto_, defaultblock); @@ -1090,7 +1090,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block* bcatch = blx.curblock; if (cs.type) bcatch.Bcatchtype = toSymbol(cs.type.toBasetype()); - tryblock.appendSucc(bcatch); + tryblock.Bsucc.push(bcatch); block_goto(blx, BC.jcatch, null); if (cs.type && irs.target.os == Target.OS.Windows && irs.target.isX86_64) // Win64 @@ -1128,7 +1128,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) } Statement_toIR(cs.handler, irs, &catchState); } - blx.curblock.appendSucc(breakblock2); + blx.curblock.Bsucc.push(breakblock2); block_next(blx, BC.goto_, null); } } @@ -1176,7 +1176,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block* finallyblock = block_calloc(blx); - tryblock.appendSucc(finallyblock); + tryblock.Bsucc.push(finallyblock); finallyblock.bc = BC._finally; bodyirs.finallyBlock = finallyblock; @@ -1204,13 +1204,13 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) * BC._ret * breakblock */ - blx.curblock.appendSucc(breakblock); + blx.curblock.Bsucc.push(breakblock); block_next(blx,BC.goto_,finallyblock); block* landingPad = block_goto(blx,BC._finally,null); block_goto(blx,BC._lpad,null); // lpad is [0] - finallyblock.appendSucc(blx.curblock); // start of finalybody is [1] - finallyblock.appendSucc(breakblock); // breakblock is [2] + finallyblock.Bsucc.push(blx.curblock); // start of finalybody is [1] + finallyblock.Bsucc.push(breakblock); // breakblock is [2] /* Declare flag variable */ @@ -1268,7 +1268,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) if (s.bodyFallsThru) { // BC.goto_ [breakblock] - blx.curblock.appendSucc(breakblock); + blx.curblock.Bsucc.push(breakblock); block_next(blx,BC.goto_,finallyblock); } else @@ -1293,8 +1293,8 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) block* landingPad = block_goto(blx,BC._finally,null); block_goto(blx,BC._lpad,null); // lpad is [0] - finallyblock.appendSucc(blx.curblock); // start of finalybody is [1] - finallyblock.appendSucc(breakblock); // breakblock is [2] + finallyblock.Bsucc.push(blx.curblock); // start of finalybody is [1] + finallyblock.Bsucc.push(breakblock); // breakblock is [2] /* Declare flag variable */ @@ -1337,9 +1337,9 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) /* Append the last successor to finallyblock, which is the first block past the BC._ret block. */ - finallyblock.appendSucc(blx.curblock); + finallyblock.Bsucc.push(blx.curblock); - retblock.appendSucc(blx.curblock); + retblock.Bsucc.push(blx.curblock); /* The BC.finally..bc._ret blocks form a function that gets called from stack unwinding. * The successors to BC._ret blocks are both the next outer BC.finally and the destination @@ -1351,14 +1351,14 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) if (b.bc == BC.goto_ && b.numSucc() == 1) { - block* bdest = b.nthSucc(0); + block* bdest = b.Bsucc[0]; if (btry && bdest.Btry != btry) { //printf("test1 b %p b.Btry %p bdest %p bdest.Btry %p\n", b, btry, bdest, bdest.Btry); - block* bfinally = btry.nthSucc(1); + block* bfinally = btry.Bsucc[1]; if (bfinally == finallyblock) { - b.appendSucc(finallyblock); + b.Bsucc.push(finallyblock); } } } @@ -1366,20 +1366,20 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) // If the goto exits a try block, then the finally block is also a successor if (b.bc == BC.goto_ && b.numSucc() == 2) // if goto exited a tryblock { - block* bdest = b.nthSucc(0); + block* bdest = b.Bsucc[0]; // If the last finally block executed by the goto if (bdest.Btry == tryblock.Btry) { // The finally block will exit and return to the destination block - retblock.appendSucc(bdest); + retblock.Bsucc.push(bdest); } } if (b.bc == BC._ret && b.Btry == tryblock) { // b is nested inside this TryFinally, and so this finally will be called next - b.appendSucc(finallyblock); + b.Bsucc.push(finallyblock); } } } @@ -1400,7 +1400,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) bpre = blx.curblock; block_next(blx,BC.goto_,null); basm = blx.curblock; - bpre.appendSucc(basm); + bpre.Bsucc.push(basm); basm.Bcode = cast(code*)s.asmcode; basm.Balign = cast(ubyte)s.asmalign; @@ -1415,7 +1415,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) // FL.block and FL.blockoff have LabelDsymbol's - convert to blocks LabelDsymbol label = cast(LabelDsymbol)c.IEV1.Vlsym; block* b = cast(block*)label.statement.extra; - basm.appendSucc(b); + basm.Bsucc.push(b); c.IEV1.Vblock = b; break; } @@ -1441,7 +1441,7 @@ void Statement_toIR(Statement s, ref IRState irs, StmtState* stmtstate) { LabelDsymbol label = cast(LabelDsymbol)c.IEV2.Vlsym; block* b = cast(block*)label.statement.extra; - basm.appendSucc(b); + basm.Bsucc.push(b); c.IEV2.Vblock = b; break; } @@ -1535,7 +1535,7 @@ void insertFinallyBlockCalls(block* startblock) bcret.bc = BC.ret; } b.bc = BC.goto_; - b.appendSucc(bcret); + b.Bsucc.push(bcret); goto case_goto; case BC.retexp: @@ -1560,7 +1560,7 @@ void insertFinallyBlockCalls(block* startblock) bcretexp.Belem.ET = t; } b.bc = BC.goto_; - b.appendSucc(bcretexp); + b.Bsucc.push(bcretexp); b.Belem = elAssign(el_var(stmp), e, null, e.ET); goto case_goto; } @@ -1593,14 +1593,14 @@ void insertFinallyBlockCalls(block* startblock) *x BC._ret * breakblock */ - block* breakblock = b.nthSucc(0); + block* breakblock = b.Bsucc[0]; block* lasttry = breakblock.Btry; block* blast = b; ++flagvalue; for (block* bt = b.Btry; bt != lasttry; bt = bt.Btry) { assert(bt.bc == BC._try); - block* bf = bt.nthSucc(1); + block* bf = bt.Bsucc[1]; if (bf.bc == BC.jcatch) continue; // skip try-catch assert(bf.bc == BC._finally); @@ -1615,7 +1615,7 @@ void insertFinallyBlockCalls(block* startblock) b.Belem = el_combine(b.Belem, e); assert(blast.bc == BC.goto_ || blast.bc == BC.iftrue); - blast.setNthSucc(0, bf); + blast.Bsucc[0] = bf; // Create new block, bnew, which will replace retblock block* bnew = block_calloc(bo); @@ -1626,8 +1626,8 @@ void insertFinallyBlockCalls(block* startblock) e = el_bin(OPeqeq, TYbool, el_var(sflag), el_long(TYint, flagvalue)); retblock.Belem = el_combine(retblock.Belem, e); retblock.bc = BC.iftrue; - retblock.appendSucc(breakblock); - retblock.appendSucc(bnew); + retblock.Bsucc.push(breakblock); + retblock.Bsucc.push(bnew); bnew.Bnext = retblock.Bnext; retblock.Bnext = bnew; @@ -1692,13 +1692,13 @@ void insertFinallyBlockGotos(block* startblock) { case BC._try: b.bc = BC.goto_; - list_subtract(&b.Bsucc, b.nthSucc(1)); + b.Bsucc.subtract(b.Bsucc[1]); break; case BC._finally: b.bc = BC.goto_; - list_subtract(&b.Bsucc, b.nthSucc(2)); - list_subtract(&b.Bsucc, b.nthSucc(0)); + b.Bsucc.subtract(b.Bsucc[2]); + b.Bsucc.subtract(b.Bsucc[0]); break; case BC._lpad: