Skip to content

Commit 7c7e4db

Browse files
committed
3rd attempt to make Bsucc an array
1 parent 2990bc7 commit 7c7e4db

13 files changed

Lines changed: 136 additions & 47 deletions

File tree

compiler/src/dmd/backend/barray.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ struct Barray(T)
190190
*/
191191
bool equals(ref const Barray rhs)
192192
{
193-
if (array.length != rhs.length)
194-
return false;
193+
if (array.length != rhs.length)
194+
return false;
195195
foreach (i, ref t; array)
196196
{
197197
if (t != rhs.array[i])

compiler/src/dmd/backend/blockopt.d

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,16 @@ void block_pred(ref BlockOpt bo)
207207
for (block* b = bo.startblock; b; b = b.Bnext) // for each block
208208
b.Bpred.reset();
209209

210+
convertBsuccToBsucca(bo.startblock);
210211
for (block* b = bo.startblock; b; b = b.Bnext) // for each block
211212
{
212213
//printf("b = %p, BC = BC.%s\n", b, bc_str(b.bc));
213-
foreach (bp; ListRange(b.Bsucc))
214+
foreach (bp; b.Bsucca[])
215+
//foreach (bp; ListRange(b.Bsucc))
214216
{ /* for each successor to b */
215217
//printf("\tbs = %p\n",list_block(bp));
216-
list_block(bp).Bpred.push(b); // original inserts at the beginning, don't think it matters
218+
bp.Bpred.push(b); // original inserts at the beginning, don't think it matters
219+
//list_block(bp).Bpred.push(b); // original inserts at the beginning, don't think it matters
217220
}
218221
}
219222
assert(bo.startblock.Bpred.length == 0); /* startblock has no preds */
@@ -237,9 +240,11 @@ void block_clearvisit(ref BlockOpt bo)
237240
void block_visit(block* b)
238241
{
239242
b.Bflags |= BFL.visited;
240-
foreach (l; ListRange(b.Bsucc))
243+
convertOneBsuccToBsucca(b);
244+
foreach (bs; b.Bsucca[])
245+
//foreach (l; ListRange(b.Bsucc))
241246
{
242-
block* bs = list_block(l);
247+
//block* bs = list_block(l);
243248
assert(bs);
244249
if ((bs.Bflags & BFL.visited) == 0) // if not visited
245250
block_visit(bs);
@@ -306,7 +311,9 @@ void block_free(ref BlockOpt bo, block* b)
306311
assert(b);
307312
if (b.Belem)
308313
el_free(b.Belem);
314+
b.Bsucca.dtor();
309315
list_free(&b.Bsucc,FPNULL);
316+
b.Bsucca.dtor();
310317
b.Bpred.dtor();
311318
if (OPTIMIZER)
312319
block_optimizer_free(b);
@@ -416,6 +423,7 @@ void blockopt(ref GlobalOptimizer go, ref BlockOpt bo)
416423
{
417424
//printf("changes = %d, count = %d, dfo.length = %d\n",go.changes,count,dfo.length);
418425
go.changes = 0;
426+
convertBsuccToBsucca(bo.startblock);
419427
bropt(go, bo); // branch optimization
420428
brrear(bo); // branch rearrangement
421429
blident(go, bo); // combine identical blocks
@@ -481,6 +489,7 @@ void blockopt(ref GlobalOptimizer go, ref BlockOpt bo)
481489
bo.startblock.Belem = el_combine(e, bo.startblock.Belem);
482490
}
483491

492+
convertBsuccToBsucca(bo.startblock);
484493
bropt(go, bo); /* branch optimization */
485494
brrear(bo); /* branch rearrangement */
486495
comsubs(go, bo); /* eliminate common subexpressions */
@@ -646,10 +655,12 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo)
646655
{
647656
b.bc = BC.exit;
648657
// Exit block has no successors, so remove them
649-
foreach (bp; ListRange(b.Bsucc))
658+
foreach (bp; b.Bsucca[])
659+
//foreach (bp; ListRange(b.Bsucc))
650660
{
651-
list_block(bp).Bpred.subtract(b);
661+
bp.Bpred.subtract(b);
652662
}
663+
b.Bsucca.reset();
653664
list_free(&b.Bsucc, FPNULL);
654665
debug if (debugc) printf("CHANGE: noreturn becomes BC.exit\n");
655666
go.changes++;
@@ -670,6 +681,7 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo)
670681
(*pn).Ety = tym;
671682
for (n = b.Belem; n.Eoper == OPcomma; n = n.E2)
672683
n.Ety = tym;
684+
b.Bsucca.reverse();
673685
b.Bsucc = list_reverse(b.Bsucc);
674686
debug if (debugc) printf("CHANGE: if (!e)\n");
675687
go.changes++;
@@ -681,14 +693,17 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo)
681693
{
682694
// select first succ
683695
db = b.nthSucc(1);
696+
assert(db == b.Bsucca[1]);
684697
goto L1;
685698
}
686699
else if (iffalse(n))
687700
{
688701
// select second succ
689702
db = b.nthSucc(0);
703+
assert(db == b.Bsucca[0]);
690704

691705
L1:
706+
b.Bsucca.subtract(db);
692707
list_subtract(&(b.Bsucc),db);
693708
db.Bpred.subtract(b);
694709
b.bc = BC.goto_;
@@ -704,6 +719,7 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo)
704719
{
705720
b.bc = BC.goto_;
706721
db = b.nthSucc(0);
722+
b.Bsucca.subtract(db);
707723
list_subtract(&(b.Bsucc),db);
708724
db.Bpred.subtract(b);
709725
debug if (debugc) printf("CHANGE: if (e) goto L1; else goto L1;\n");
@@ -728,6 +744,7 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo)
728744
}
729745
}
730746
block* db = b.nthSucc(i);
747+
assert(db == b.Bsucca[i]);
731748

732749
/* delete predecessors of successors (!) */
733750
foreach (bl; ListRange(b.Bsucc))
@@ -741,13 +758,16 @@ private void bropt(ref GlobalOptimizer go, ref BlockOpt bo)
741758

742759
/* dump old successor list and create a new one */
743760
list_free(&b.Bsucc,FPNULL);
761+
b.Bsucca.reset();
744762
b.appendSucc(db);
763+
b.Bsucca.push(db);
745764
b.bc = BC.goto_;
746765
b.Belem = doptelem(b.Belem, Goal.none | Goal.again);
747766
debug if (debugc) printf("CHANGE: switch (const)\n");
748767
go.changes++;
749768
}
750769
}
770+
verifyBsuccMatchesBsucca(bo.startblock);
751771
}
752772

753773
/*********************************
@@ -760,11 +780,13 @@ private void brrear(ref BlockOpt bo)
760780
debug if (debugc) printf("brrear()\n");
761781
for (block* b = bo.startblock; b; b = b.Bnext) // for each block
762782
{
763-
foreach (bl; ListRange(b.Bsucc))
783+
foreach (i, bl; b.Bsucca[])
784+
//foreach (bl; ListRange(b.Bsucc))
764785
{ /* For each transfer of control block pointer */
765786
int iter = 0;
766787

767-
block* bt = list_block(bl);
788+
block* bt = bl;
789+
//block* bt = list_block(bl);
768790

769791
/* If it is a transfer to a block that consists */
770792
/* of nothing but an unconditional transfer, */
@@ -785,14 +807,17 @@ private void brrear(ref BlockOpt bo)
785807
(OPTIMIZER || !(bt.Bsrcpos.Slinnum && config.addlinenumbers)) &&
786808
++iter < 10)
787809
{
788-
bl.ptr = list_ptr(bt.Bsucc);
810+
b.Bsucca[i] = bt.Bsucca[0];
811+
//bl.ptr = list_ptr(bt.Bsucc);
789812
if (bt.Bsrcpos.Slinnum && !b.Bsrcpos.Slinnum)
790813
b.Bsrcpos = bt.Bsrcpos;
791814
b.Bflags |= bt.Bflags;
792-
list_block(bl).Bpred.push(b);
815+
b.Bsucca[i].Bpred.push(b);
816+
//list_block(bl).Bpred.push(b);
793817
bt.Bpred.subtract(b);
794818
debug if (debugc) printf("goto.goto\n");
795-
bt = list_block(bl);
819+
bt = b.Bsucca[i];
820+
//bt = list_block(bl);
796821
}
797822

798823
// Bsucc after the first are the targets of
@@ -803,6 +828,11 @@ private void brrear(ref BlockOpt bo)
803828
break;
804829
}
805830

831+
// Rebuild linked list
832+
list_free(&b.Bsucc,FPNULL);
833+
foreach (bl; b.Bsucca[])
834+
list_append(&b.Bsucc,bl);
835+
806836
static if(0)
807837
{
808838
/* Replace cases of */
@@ -828,6 +858,7 @@ private void brrear(ref BlockOpt bo)
828858
}
829859
}
830860
} /* for */
861+
verifyBsuccMatchesBsucca(bo.startblock);
831862
}
832863

833864
/*************************
@@ -840,6 +871,7 @@ private void brrear(ref BlockOpt bo)
840871
*/
841872
void compdfo(ref BlockOpt bo, ref Barray!(block*) dfo, block* startblock)
842873
{
874+
convertBsuccToBsucca(bo.startblock);
843875
debug if (debugc) printf("compdfo()\n");
844876
debug assert(OPTIMIZER);
845877
block_clearvisit(bo);
@@ -853,9 +885,8 @@ void compdfo(ref BlockOpt bo, ref Barray!(block*) dfo, block* startblock)
853885
assert(b);
854886
b.Bflags |= BFL.visited; // executed at least once
855887

856-
foreach (bl; ListRange(b.Bsucc)) // for each successor
888+
foreach (bs; b.Bsucca[]) // for each successor
857889
{
858-
block* bs = list_block(bl);
859890
assert(bs);
860891
if ((bs.Bflags & BFL.visited) == 0) // if not visited
861892
walkDFO(bs);
@@ -902,6 +933,7 @@ void compdfo(ref BlockOpt bo, ref Barray!(block*) dfo, block* startblock)
902933
@trusted
903934
private void elimblks(ref GlobalOptimizer go, ref BlockOpt bo)
904935
{
936+
convertBsuccToBsucca(bo.startblock);
905937
debug if (debugc) printf("elimblks()\n");
906938
block* bf = null;
907939
block* b;
@@ -914,7 +946,13 @@ private void elimblks(ref GlobalOptimizer go, ref BlockOpt bo)
914946
/* for each marked successor S to b */
915947
/* remove b from S.Bpred. */
916948
/* Presumably all predecessors to b are unmarked also. */
917-
foreach (s; ListRange(b.Bsucc))
949+
foreach (s; b.Bsucca[])
950+
{
951+
assert(s);
952+
if (s.Bflags & BFL.visited) /* if it is marked */
953+
s.Bpred.subtract(b);
954+
}
955+
static if (0) foreach (s; ListRange(b.Bsucc))
918956
{
919957
assert(list_block(s));
920958
if (list_block(s).Bflags & BFL.visited) /* if it is marked */
@@ -941,6 +979,7 @@ private void elimblks(ref GlobalOptimizer go, ref BlockOpt bo)
941979
}
942980

943981
debug if (debugc) printf("elimblks done\n");
982+
verifyBsuccMatchesBsucca(bo.startblock);
944983
}
945984

946985
/**********************************

compiler/src/dmd/backend/cc.d

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ nothrow:
205205
block* Bnext; // pointer to next block in list
206206
list_t Bsucc; // linked list of pointers to successors
207207
// of this block
208+
Barray!(block*) Bsucca; // and the successor array copy of Bsucc
208209
Barray!(block*) Bpred; // and the predecessor array
209210
int Bindex; // into created object stack
210211
int Bendindex; // index at end of block
@@ -335,6 +336,44 @@ nothrow:
335336
@trusted
336337
inout(block)* list_block(inout list_t lst) { return cast(inout(block)*)list_ptr(lst); }
337338

339+
// Convert Bsucc to Bsucca
340+
void convertBsuccToBsucca(block *b)
341+
{
342+
for (; b; b = b.Bnext)
343+
{
344+
convertOneBsuccToBsucca(b);
345+
}
346+
}
347+
348+
void convertOneBsuccToBsucca(block *b)
349+
{
350+
int n = list_nitems(b.Bsucc);
351+
b.Bsucca.setLength(n);
352+
int i;
353+
foreach (bp; ListRange(b.Bsucc))
354+
{
355+
b.Bsucca[i] = list_block(bp);
356+
++i;
357+
}
358+
assert(i == b.Bsucca.length);
359+
}
360+
361+
// Verify Bsucc has same contents as Bsucca
362+
void verifyBsuccMatchesBsucca(block *b)
363+
{
364+
for (; b; b = b.Bnext)
365+
{
366+
int n = list_nitems(b.Bsucc);
367+
assert(n == b.Bsucca.length);
368+
int i;
369+
foreach (bp; ListRange(b.Bsucc))
370+
{
371+
assert(b.Bsucca[i] == list_block(bp));
372+
++i;
373+
}
374+
}
375+
}
376+
338377
/** Basic block control flow operators. **/
339378

340379
enum BC : ubyte

compiler/src/dmd/backend/gflow.d

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,7 @@ void flowlv(ref BlockOpt bo)
13391339
foreach (b; bo.dfo[])
13401340
{
13411341
vec_copy(b.Binlv, b.Bgen); // Binlv = Bgen
1342+
convertOneBsuccToBsucca(b);
13421343
}
13431344

13441345
vec_t tmp = vec_calloc(globsym.length);
@@ -1353,9 +1354,10 @@ void flowlv(ref BlockOpt bo)
13531354
{
13541355
/* Bout = union of Bins of all successors to B. */
13551356
bool first = true;
1356-
foreach (bl; ListRange(b.Bsucc))
1357+
foreach (bl; b.Bsucca[])
1358+
//foreach (bl; ListRange(b.Bsucc))
13571359
{
1358-
const inlv = list_block(bl).Binlv;
1360+
const inlv = bl.Binlv;
13591361
if (first)
13601362
vec_copy(b.Boutlv, inlv);
13611363
else
@@ -1656,6 +1658,7 @@ private void accumlv(vec_t GEN, vec_t KILL, const(elem)* n, const vec_t ambigsym
16561658
@trusted
16571659
void flowvbe(ref GlobalOptimizer go, ref BlockOpt bo)
16581660
{
1661+
if (&go) assert(0);
16591662
go.flowxx = VBE;
16601663
aecpgenkill(go, bo); // compute Bgen and Bkill for VBEs
16611664
if (go.exptop <= 1) /* if no candidates for VBEs */
@@ -1702,9 +1705,10 @@ void flowvbe(ref GlobalOptimizer go, ref BlockOpt bo)
17021705

17031706
/* Bout = & of Bin of all successors */
17041707
bool first = true;
1705-
foreach (bl; ListRange(b.Bsucc))
1708+
foreach (bl; b.Bsucca[])
1709+
//foreach (bl; ListRange(b.Bsucc))
17061710
{
1707-
const vin = list_block(bl).Bin;
1711+
const vin = bl.Bin;
17081712
if (first)
17091713
vec_copy(b.Bout, vin);
17101714
else

compiler/src/dmd/backend/gloop.d

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,15 +214,18 @@ bool blockinit(ref BlockOpt bo)
214214
{
215215
bool hasasm = false;
216216

217+
convertBsuccToBsucca(bo.startblock);
217218
assert(bo.dfo);
218219
foreach (b; BlockRange(bo.startblock))
219220
{
220-
debug /* check integrity of Bpred and Bsucc */
221+
//debug /* check integrity of Bpred and Bsucc */
221222
L1:
222223
foreach (blp; b.Bpred[])
223224
{
224-
foreach (bls; ListRange(blp.Bsucc))
225-
if (list_block(bls) == b)
225+
foreach (bls; blp.Bsucca[])
226+
if (bls == b)
227+
//foreach (bls; ListRange(blp.Bsucc))
228+
//if (list_block(bls) == b)
226229
continue L1;
227230
assert(0);
228231
}

compiler/src/dmd/backend/gother.d

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,9 +1066,10 @@ private int loopcheck(block* start,block* inc,block* rel)
10661066
{
10671067
if (!(start.Bflags & BFL.visited))
10681068
{ start.Bflags |= BFL.visited; /* guarantee eventual termination */
1069-
foreach (list; ListRange(start.Bsucc))
1069+
1070+
convertOneBsuccToBsucca(start);
1071+
foreach (b; start.Bsucca[])
10701072
{
1071-
block* b = cast(block*) list_ptr(list);
10721073
if (b != rel && (b == inc || loopcheck(b,inc,rel)))
10731074
return true;
10741075
}

0 commit comments

Comments
 (0)