Skip to content

Commit 2be5e48

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

13 files changed

Lines changed: 125 additions & 44 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: 42 additions & 11 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
/*************************

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
}

compiler/src/dmd/backend/x86/cgcod.d

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void codgen(Symbol* sfunc)
8888
/***********************
8989
* Same as codgen(), but adding in CGstate argument
9090
* Params:
91-
* cg = code generator state
91+
* cg = code generator state
9292
* sfunc = function to generate code for
9393
*/
9494
private @trusted
@@ -98,6 +98,10 @@ void codgenx(ref CGstate cg, Symbol* sfunc)
9898
assert(sfunc == funcsym_p);
9999
assert(cseg == funcsym_p.Sseg);
100100

101+
// Convert Bsucc to Bsucca
102+
convertBsuccToBsucca(bo.startblock);
103+
verifyBsuccMatchesBsucca(bo.startblock);
104+
101105
cgreg_init();
102106
CSE.initialize();
103107

@@ -2131,7 +2135,7 @@ bool cssave(elem* e, regm_t regm, bool opsflag)
21312135
/*if (e.Ecount && e.Ecount == e.Ecomsub)*/
21322136
if (e.Ecount && e.Ecomsub)
21332137
{
2134-
CGstate* cg = &cgstate;
2138+
CGstate* cg = &cgstate;
21352139
if (!opsflag && cg.pass != BackendPass.final_ && (I32 || I64))
21362140
return false;
21372141

@@ -2579,7 +2583,7 @@ private void loadcse(ref CodeBuilder cdb,elem* e,reg_t reg,regm_t regm)
25792583
//printf("CSE[%d] = %p, regm = %s\n", i, cse.e, regm_str(cse.regm));
25802584
if (cse.regm & regm)
25812585
{
2582-
CGstate* cg = &cgstate;
2586+
CGstate* cg = &cgstate;
25832587
cg.reflocal = true;
25842588
cse.flags |= CSEload; /* it was loaded */
25852589
cg.regcon.cse.value[reg] = e;

compiler/src/dmd/backend/x86/cgreg.d

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -607,15 +607,15 @@ void cgreg_spillreg_epilog(block* b,Symbol* s,ref CodeBuilder cdbstore, ref Code
607607
const bi = b.Bdfoidx;
608608
//printf("cgreg_spillreg_epilog(block %d, s = '%s')\n",bi,s.Sident.ptr);
609609
//assert(b.bc == BC.goto_);
610-
if (!cgreg_gotoepilog(b.nthSucc(0), s))
610+
if (!cgreg_gotoepilog(b.Bsucca[0], s))
611611
return;
612612

613613
const live = vec_testbit(bi,s.Slvreg) != 0;
614614

615615
// Look at successors to see if we need to load in/out of register
616-
foreach (bl; ListRange(b.Bsucc))
616+
foreach (bs; b.Bsucca[])
617617
{
618-
const bpi = list_block(bl).Bdfoidx;
618+
const bpi = bs.Bdfoidx;
619619
if (!vec_testbit(bpi,s.Srange))
620620
continue;
621621
if (vec_testbit(bpi,s.Slvreg))

0 commit comments

Comments
 (0)