Skip to content

Conversation

@shajrawi
Copy link

@shajrawi shajrawi commented Sep 4, 2018

radar rdar://problem/42841839

@shajrawi shajrawi requested a review from atrick September 4, 2018 17:20
@shajrawi
Copy link
Author

shajrawi commented Sep 4, 2018

@atrick Can you please review?

@shajrawi
Copy link
Author

shajrawi commented Sep 4, 2018

@swift-ci Please test

Copy link
Contributor

Choose a reason for hiding this comment

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

Is "scop" a typo or a term I don't know?

Copy link
Author

Choose a reason for hiding this comment

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

Whoops! typo :) should be scope of course - thanks!

@shajrawi
Copy link
Author

shajrawi commented Sep 4, 2018

@swift-ci Please test

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.

Your mayRelease changes look good.

Two somewhat separate areas for improvement in the existing code:

  1. Use MapVector::remove_if instead of erase. Then remove all extra while (changed) loops, which are quadratic and complicate the code. They are in visitSetForConflicts, detectApplyConflicts, and visitBeginAccess. Also, remove the temporary map and extra loop in mergeAccessStruct.

  2. Remove the temporary map and extra loop in recordConflict.

Copy link
Contributor

Choose a reason for hiding this comment

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

s/Scop/Scope/

Copy link
Contributor

Choose a reason for hiding this comment

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

It took me a while to convince myself this is correct. You've added an assumption at this point in the code that all possibly releasing instructions are included in MayWrites. We should add a corresponding comment where we actually compute MayWrites (in analyzeCurrentLoop). Also, note that even though we are only concerned with class or global access, we need to consider local deinitializers because they can refer to globals.

Joe Shajrawi added 2 commits September 4, 2018 13:23
1) use vectors instead of MapVector for in/out of scope local maps 2) record nested conflict without creating a temporary copy
@shajrawi
Copy link
Author

shajrawi commented Sep 4, 2018

@swift-ci Please test

@swiftlang swiftlang deleted a comment from swift-ci Sep 4, 2018
@shajrawi
Copy link
Author

shajrawi commented Sep 5, 2018

I changed the code per our offline discussion - we no longer use MapVector - added the changes as a separate commit in this PR

@shajrawi shajrawi merged commit a9df586 into swiftlang:master Sep 5, 2018
@shajrawi shajrawi deleted the mayrelease branch September 5, 2018 00:41
/// Reachability results are stored here because very few accesses are
/// typically in-progress at a particular program point,
/// particularly at block boundaries.
using DenseAccessMap = llvm::SmallMapVector<unsigned, BeginAccessInst *, 4>;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would make more sense to call this DenseAccessSet (the vector part is an implementation detail of the Set).

Copy link
Author

Choose a reason for hiding this comment

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

fixed in new PR

auto index = it->first;
info.outOfScopeConflictFreeAccesses.conflictFreeAccesses.erase(index);
auto *otherBegin = *it;
auto rmIt = std::find(
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this now using find instead of conflictFreeAccesses.erase(otherBegin)?

Copy link
Author

Choose a reason for hiding this comment

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

You can't use erase on a non-iterator type. it is a reverse iterator.

accessStruct.conflictFreeAccesses.erase(index);
}
auto pred = [&](BeginAccessInst *it) {
auto rhsIt = std::find(RHSAccessStruct.conflictFreeAccesses.begin(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Checking Set membership is done with count.

Copy link
Author

Choose a reason for hiding this comment

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

Fixed - forgot to change that

info.inScopeConflictFreeAccesses.conflictFreeAccesses.insert(
std::make_pair(index, beginAccess));
assert(
std::find(info.inScopeConflictFreeAccesses.conflictFreeAccesses.begin(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Set membership is done with count.

Copy link
Author

Choose a reason for hiding this comment

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

Fixed - forgot to change that

auto &ai = result.getAccessInfo(*it);
ai.setSeenNestedConflict();
}
accessStruct.conflictFreeAccesses.erase(it);
Copy link
Contributor

Choose a reason for hiding this comment

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

This still invalidates the iterator.

Copy link
Author

Choose a reason for hiding this comment

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

Hmm yes: it might invalidate the iterator in recordConflict's caller. not it in this function of course. I reverted to the old behavior in the caller

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.

This doesn't look correct.

@shajrawi
Copy link
Author

shajrawi commented Sep 5, 2018

Fixed #19140

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

Labels

None yet

3 participants