Skip to content

[SIL Optimization][CFGOptUtils.h] Remove completeJointPostDominanceSet utility function #27876

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

Merged
merged 1 commit into from
Oct 29, 2019

Conversation

ravikandhadai
Copy link
Contributor

utility function to return a set of postdominating blocks in addition to a
completion and add a utility using it to return the set of postdominating
instruction frontier for a given set of users.

Copy link
Contributor

@atrick atrick left a comment

Choose a reason for hiding this comment

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

Looks good, but I have several suggestions on comments and naming, and one efficiency issue.

I'm not too picky about this API though because I want to subsume the whole thing with ValueLifetimeAnalysis ultimately.

/// | | | Use2 |
/// +-----+ +-------+
///
/// the completion set would be the empty block, and the postdominating blocsk
Copy link
Contributor

Choose a reason for hiding this comment

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

blocsk

llvm::SmallVectorImpl<SILBasicBlock *> &postDominators);

/// Given a list of instructions \p defs defining SILValues and a list of users
/// of the SILValues \p users, find the set of immediate post-dominators for
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a "jointly post-dominating set of instructions". The term "immediate post-dominator" implies a node in the post-dominance tree, which is not accurate for these instructions or their parent blocks.

/// of the SILValues \p users, find the set of immediate post-dominators for
/// \p users. These are a set of instructions that mark end points of \p users
/// as per the control-flow order i.e., no instruction in \p users can be
/// encountered once a post-dominating instruction is seen during an evaluation.
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, I would refer to these as "instructions in the joint post dominance set". Somewhere we should just define this as simply the union of the instructions which follow last uses and instructions at the head of "completion" blocks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

define this as simply the union of the instructions which follow last uses and instructions at the head of "completion" blocks.

Sure. But one minor complication here is users within loops. For users within loops, this function will not have an instruction following it (in the syntactic sense). Perhaps, I can add a note clarifying this as well. (This was a reason why I decided to use a definition based on actual evaluation for characterizing this set.)

Copy link
Contributor

@atrick atrick Oct 25, 2019

Choose a reason for hiding this comment

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

Well, if we just state that users in loop are never considered "last users", then this still holds doesn't it? postDomSet == (next(I) for I in lastUsers) U (headBB) for BB in completionBlocks)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that is right.

SmallPtrSetImpl<SILBasicBlock *> &userBlocks,
SmallPtrSetImpl<SILBasicBlock *> &defBlocks,
llvm::SmallVectorImpl<SILBasicBlock *> &completion,
llvm::SmallVectorImpl<SILBasicBlock *> &postDominators);
Copy link
Contributor

Choose a reason for hiding this comment

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

postDominators makes me think of the post-dominance tree, which actually has nothing to do with this. The blocks aren't post-dominators at all. There is only one "post dominance" relation which is the entire set of (joint)postDominanceBlocks.

I think we should say very explicitly that "\p postDominanceBlocks is the union of \p completion blocks and \p userBlocks which contain lastUses".

In fact, this would be a cleaner API if we removed the completion set and let the caller check membership in userBlocks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure. That makes sense. I will change postdominators to joint post-dominating set. Thanks for pointing that out.

In fact, this would be a cleaner API if we removed the completion set and let the caller check membership in userBlocks.

Yes. I will do that.

SmallPtrSetImpl<SILInstruction *> &defs,
SmallVectorImpl<SILInstruction *> &postDominators) {
// Step 1. Collect the basic blocks of the users and defs.
SmallPtrSet<SILBasicBlock *, 4> userBlocks;
Copy link
Contributor

Choose a reason for hiding this comment

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

4 is a pretty small # of users.

// Step 3. Compute all post-dominating instructions by looking into the
// post-dominating blocks.
SmallPtrSet<SILBasicBlock *, 8> completionSet(completions.begin(),
completions.end());
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you should copy completions. You should be able to check membership in userBlocks instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's right. Will fix this.

for (SILBasicBlock *bb : postDominatingBlocks) {
if (completionSet.count(bb)) {
// Here, the basic block bb was added to complete the postdominator set
// and does not have any users of defs. So, the first instruction of the
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't a completion block have a def?

Copy link
Contributor Author

@ravikandhadai ravikandhadai Oct 25, 2019

Choose a reason for hiding this comment

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

That is an interesting question. I will refer to the reflexive, transitive closure of predecessors of a set of blocks as pred*(blocks). Essentially, completions are successors of pred*(userBlocks) that are not in pred*(userBlocks) . If we consider a completion block c, c is a succ(pred*(userBlocks)) and c is not in pred*(userBlocks). But one thing we know by definition is defBlocks are a subset of pred*(userBlocks). This is an implicit precondition (or rather assumption) of this function. Therefore, c cannot be in defBlocks.

However, I think the precondition that defBlocks are a subset of pred*(userBlocks) is not really necessary here. And c can be a part of defBlocks in such cases. Do you think that would cause any problems?

Copy link
Contributor

Choose a reason for hiding this comment

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

Uh OH! If defBlocks is always in userBlocks then the original post-dom-set utility is making an unexpected assumption that uses never occur before defs in the same block. Given that we allow multiple defBlocks, that's not a safe assumption, it's reasonable for this utility to be called on a phi-web where uses occur before defs.

But you're right, this won't be a problem for your particular use case.

// Here, the terminator of the basic block is a user. Therefore, use the
// first instruction of the successor blocks as post-dominating
// instructions.
for (SILBasicBlock *succ : bb->getSuccessors()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please assert that succ is not in postDominators.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.

@ravikandhadai
Copy link
Contributor Author

@atrick Thanks for the very insightful and helpful comments. I will fix them.

@ravikandhadai
Copy link
Contributor Author

This utility is now fully subsumed by ValueLifetimeAnalysis: #27892 . Can we remove completeJointPostdominatorSet function as well? It is completely subsumed by ValueLifetimeAnalysis.cpp.

@atrick
Copy link
Contributor

atrick commented Oct 28, 2019

@ravikandhadai I guess you can close this PR now? And we don't need completeJointPostdominatorSet either.

…ceSet

utility which is completely subsumed by ValueLifetimeAnalysis.
@ravikandhadai
Copy link
Contributor Author

@atrick @gottesmm I have pushed an update that removes this utility completely, so that people don't accidentally reach out for this. ValueLifetimeAnalysis should be used instead

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please test

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please smoke test

@ravikandhadai ravikandhadai changed the title [SIL Optimization][CFGOptUtils.h] Update the completeJointPostDominanceSet [SIL Optimization][CFGOptUtils.h] Remove completeJointPostDominanceSet utility function Oct 28, 2019
@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 90e80800088824d2e31f3776506139298f4c4f9d

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 90e80800088824d2e31f3776506139298f4c4f9d

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please test linux platform

@ravikandhadai ravikandhadai merged commit bc48004 into swiftlang:master Oct 29, 2019
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