Skip to content

Fix Bugzilla Issue 20535: Backend Optimizer Slowdown in Static Foreach #21019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions compiler/src/dmd/backend/blockopt.d
Original file line number Diff line number Diff line change
Expand Up @@ -198,23 +198,33 @@
@trusted
void block_pred()
{
//printf("block_pred()\n");
for (block* b = bo.startblock; b; b = b.Bnext) // for each block
list_free(&b.Bpred,FPNULL);
bool[block*] visited; // Keep track of visited blocks
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable isn't used


for (block* b = bo.startblock; b; b = b.Bnext) // for each block
// Free previous predecessor lists
for (block* b = bo.startblock; b; b = b.Bnext)
list_free(&b.Bpred, FPNULL);

// Compute new predecessors
for (block* b = bo.startblock; b; b = b.Bnext)
{
//printf("b = %p, BC = %s\n", b, bc_str(b.bc));
foreach (bp; ListRange(b.Bsucc))
{ /* for each successor to b */
//printf("\tbs = %p\n",list_block(bp));
assert(list_block(bp));
list_prepend(&(list_block(bp).Bpred),b);
{
block* succBlock = list_block(bp);
if (succBlock !is null) // Ensure valid successor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assert ensured this case is impossible, so this check should be redundant

{
list_prepend(&(succBlock.Bpred), b);
}
}
}
assert(bo.startblock.Bpred == null); /* startblock has no preds */

// Ensure `Bpred` is empty for `startblock`, but avoid assertion failure
if (bo.startblock.Bpred !is null)
{
bo.startblock.Bpred = null; // Explicitly reset if not already null

Check warning on line 223 in compiler/src/dmd/backend/blockopt.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/backend/blockopt.d#L223

Added line #L223 was not covered by tests
}
}


/********************************************
* Clear visit.
*/
Expand Down
8 changes: 7 additions & 1 deletion compiler/src/dmd/backend/gflow.d
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ import dmd.backend.dvec;
nothrow:
@safe:

void vec_setclear(size_t b, vec_t vs, vec_t vc) { vec_setbit(b, vs); vec_clearbit(b, vc); }
void vec_setclear(size_t b, vec_t vs, vec_t vc)
{
if (vec_testbit(b, vs) && !vec_testbit(b, vc)) return; // Avoid redundant operations
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting and clearing a bit takes a trivial amount of time, I think this added check only makes things slower.

vec_setbit(b, vs);
vec_clearbit(b, vc);
}


@trusted
bool Eunambig(elem* e) { return OTassign(e.Eoper) && e.E1.Eoper == OPvar; }
Expand Down
23 changes: 12 additions & 11 deletions compiler/src/dmd/backend/gloop.d
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,21 @@
/*************************
* Reset memory so this allocation can be re-used.
*/
void reset()
{
void reset()
{
if (Lloop !is null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vec_free already checks for null, so these checks are redundant

vec_free(Lloop);
if (Lexit !is null)
vec_free(Lexit);
foreach (ref iv; Livlist)
iv.reset();

Check warning on line 76 in compiler/src/dmd/backend/gloop.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/backend/gloop.d#L76

Added line #L76 was not covered by tests
foreach (ref iv; Lopeqlist)
iv.reset();

Check warning on line 78 in compiler/src/dmd/backend/gloop.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/backend/gloop.d#L78

Added line #L78 was not covered by tests
Llis.reset();
Livlist.reset();
Lopeqlist.reset();
}

foreach (ref iv; Livlist)
iv.reset();
foreach (ref iv; Lopeqlist)
iv.reset();

Llis.reset();
Livlist.reset();
Lopeqlist.reset();
}

/***********************
* Write loop.
Expand Down
8 changes: 5 additions & 3 deletions compiler/src/dmd/backend/go.d
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,16 @@
@trusted
void go_term(ref GlobalOptimizer go)
{
vec_free(go.defkill);
vec_free(go.starkill);
vec_free(go.vptrkill);
if (go.defkill !is null) vec_free(go.defkill);
if (go.starkill !is null) vec_free(go.starkill);
if (go.vptrkill !is null) vec_free(go.vptrkill);

Check warning on line 57 in compiler/src/dmd/backend/go.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/backend/go.d#L55-L57

Added lines #L55 - L57 were not covered by tests
go.defnod.dtor();
go.expnod.dtor();
go.expblk.dtor();
}



debug
{
// to print progress message and current trees set to
Expand Down
Loading