Skip to content

Conversation

@niaow
Copy link
Member

@niaow niaow commented Nov 22, 2019

No description provided.

@niaow niaow requested a review from aykevl November 22, 2019 18:17
@deadprogram
Copy link
Member

Any action happening on this PR?

@niaow
Copy link
Member Author

niaow commented Dec 5, 2019

It needs some major changes and I do not have time to implement them right now.

@deadprogram
Copy link
Member

Understood. Can just let it hang out until ready to land, then.

@niaow
Copy link
Member Author

niaow commented Dec 21, 2019

Alright, I updated the strategy to use a BFS to scan backwards. A defer will be stack-allocated unless there exists a path from the defer's block to itself. The only situation in which this would be slow that I can think of is something along the lines of:

// Thousands of basic blocks.

defer something()
defer something()
// thousands of defers

If a defer is in the entry block then the loop should only run once.

@niaow niaow requested a review from aykevl December 21, 2019 00:01
Copy link
Member

@aykevl aykevl left a comment

Choose a reason for hiding this comment

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

The algorithm looks sound, although it looks quadratic on crafted inputs. So except for a minor nit, this looks good to me.

Meanwhile I've been thinking about this problem, and I think there is a way to do this in linear or polynomial time (if the result is cached per function). The algorithm (in pseudocode) to calculate all blocks that are in a loop:

blocks := fn.DomPreorder()
inLoop := make([]bool, len(blocks))
for block in blocks:
    if block has predecessor that has not yet been seen:
        mark inLoop from block to predecessor
        optimization: continue from the predecessor (which comes later)

The idea is to walk from the first to the last block in DomPreorder, and if a block has a predecessor that has not been seen yet there must be a loop and all blocks from the checked block up to (and including) that predecessor are marked as in a loop.
The checked block may also be in a loop (directly jumping back to itself) so should not be marked as seen until the predecessors are checked.

This assumes of course that blocks in DomPreorder are ordered as is common in structural programming, I'm not sure whether this is always the case.

@niaow niaow added this to the v0.12 milestone Dec 28, 2019
@aykevl
Copy link
Member

aykevl commented Dec 30, 2019

Kicking the Windows build again...

@aykevl aykevl merged commit eee1b99 into tinygo-org:dev Dec 30, 2019
@aykevl
Copy link
Member

aykevl commented Dec 30, 2019

Great! Thank you for working on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants