Skip to content

Perform ExistentialSpecializer when SoleConformingType is known #20977

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
Jan 15, 2019

Conversation

rajbarik
Copy link
Contributor

@rajbarik rajbarik commented Dec 3, 2018

The criteria for ExistentialSpecializer is now based on an argument having "findInitExistential or SoleConformingType".

/// Perform specialization.
specializeExistentialArgsInAppliesWithinFunction(*F);
}
};
} // namespace

/// Find concrete type from Sole Conforming Type.
bool ExistentialSpecializer::findConcreteTypeFromSoleConformingType(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method checks if a SoleConformingType can be determined for the argument. Some parts of code (5-6 lines) overlap with what was done in SILCombiner, but there are lot of disparities to make it a new APi in Existential.h altogether.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@atrick You had a similar concern from SILCombiner, but the overlap is minor to warrant a new API?

@@ -158,6 +208,14 @@ findIfCalleeUsesArgInDestroyUse(SILValue Arg,
}
}

/// Helper function to ensure that the argument is not InOut or InOut_Aliasable
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added to filter out inout args, which otherwise would be fed to openExistentialRef as non-objects!

CanType ConcreteType;
if (!findConcreteType(Apply, Idx, ConcreteType)) {
if (!((F->getModule().isWholeModule() &&
Copy link
Contributor Author

Choose a reason for hiding this comment

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

First tries to check if there is a SoleConformingType, if not, then tries findConcreteTypeUsingInitExistential.

@@ -417,6 +417,8 @@ void ExistentialTransform::populateThunkBody() {
break;
}
case ExistentialRepresentation::Class: {
/// If the operand is not object type, we would need an explicit load.
assert(OrigOperand->getType().isObject());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Extra check for accidental non-object operand type being passed to OEI.

@rajbarik rajbarik force-pushed the raj-extend-existential2generic branch from 4974abc to 6b0d1a1 Compare December 3, 2018 22:31
// CHECK: return
// CHECK-LABEL: } // end sil function '$s30existential_transform_soletype4opt11bs5Int32VAA3SPP_p_tF'

// CHECK-LABEL: sil shared [noinline] @$s30existential_transform_soletype4opt21bs5Int32VAA3SPP_p_tFTf4e_n : $@convention(thin) <τ_0_0 where τ_0_0 : SPP> (@in_guaranteed τ_0_0) -> Int32 {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

opt1 does not get optimized since the caller foo is under @_optimize(none).

Copy link
Contributor

Choose a reason for hiding this comment

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

It's generally better to use .sil test cases for individual passes, but not an absolute requirement. The source is definitely helpful, but that can be included as a comment.

@rajbarik
Copy link
Contributor Author

rajbarik commented Dec 3, 2018

@slavapestov @atrick Can you review this small PR? This one extends ExistentialSpecializer to also perform the optimization when SoleConformingType can be found.

if (!findConcreteType(Apply, Idx, ConcreteType)) {
if (!((F->getModule().isWholeModule() &&
isNonInoutIndirectArgument(Arg, ArgConvention) &&
findConcreteTypeFromSoleConformingType(Arg, ConcreteType)) ||
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@atrick fyi

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.

Otherwise, LGTM.

(CD->getEffectiveAccess() == AccessLevel::Open ||
CHA->hasKnownDirectSubclasses(CD))) {
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be a standalone API because it has special logic to reason about possible conformances. That logic should only exist in one place in the compiler.

Copy link
Contributor Author

@rajbarik rajbarik Dec 14, 2018

Choose a reason for hiding this comment

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

Originally I had this in findSoleConformingType function of ProtocolConformanceAnalysis, however since this also required ClassHierarchyAnalysis, we had to split. I can put this in Existential.cpp in Utils. This would be a wrapper for findSoleConformingType.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm just trying to avoid duplicating logic that reasons about the type system in multiple places in the SILOptimizer. As an alternative, we could just have a CHA->mayHaveSubclasses query.

// CHECK: return
// CHECK-LABEL: } // end sil function '$s30existential_transform_soletype4opt11bs5Int32VAA3SPP_p_tF'

// CHECK-LABEL: sil shared [noinline] @$s30existential_transform_soletype4opt21bs5Int32VAA3SPP_p_tFTf4e_n : $@convention(thin) <τ_0_0 where τ_0_0 : SPP> (@in_guaranteed τ_0_0) -> Int32 {
Copy link
Contributor

Choose a reason for hiding this comment

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

It's generally better to use .sil test cases for individual passes, but not an absolute requirement. The source is definitely helpful, but that can be included as a comment.

@rajbarik
Copy link
Contributor Author

@atrick after you merge your changes #21316, we should clean this up and get this merged with cleaner interface.

@atrick
Copy link
Contributor

atrick commented Dec 22, 2018

@rajbarik I finished rebasing
#21316 but just missed the branch lockdown. Of course, you could check this branch out yourself from my repo if you want to cleanup this PR. I'll merge my PR without further changes on Jan 2.

@rajbarik rajbarik force-pushed the raj-extend-existential2generic branch from 6b0d1a1 to 1f4c6ca Compare January 5, 2019 01:36
@rajbarik
Copy link
Contributor Author

rajbarik commented Jan 5, 2019

@atrick please check. I extracted out the common code between SILCombiner and ExistentialSpecializer to ProtocolConformanceAnalysis. Have a look.

@rajbarik
Copy link
Contributor Author

rajbarik commented Jan 7, 2019

@atrick, fyi, this needs your approval. thanks.

@atrick
Copy link
Contributor

atrick commented Jan 7, 2019

@rajbarik it looks like I already approved this, but I think you need to add a commit message.

@slavapestov
Copy link
Contributor

@swift-ci Please test

@slavapestov
Copy link
Contributor

@swift-ci Please test source compatibility

@slavapestov
Copy link
Contributor

@swift-ci Please benchmark

@swift-ci
Copy link
Contributor

swift-ci commented Jan 7, 2019

Build failed
Swift Test OS X Platform
Git Sha - 6b0d1a109d22a2bcb614c10d91d9db2fed646cbf

@swift-ci
Copy link
Contributor

swift-ci commented Jan 7, 2019

Build failed
Swift Test Linux Platform
Git Sha - 6b0d1a109d22a2bcb614c10d91d9db2fed646cbf

@swift-ci
Copy link
Contributor

swift-ci commented Jan 7, 2019

Build comment file:

No performance and code size changes


@rajbarik rajbarik force-pushed the raj-extend-existential2generic branch from 1f4c6ca to 0070730 Compare January 7, 2019 22:48
@atrick
Copy link
Contributor

atrick commented Jan 7, 2019

@swift-ci test.

@swift-ci
Copy link
Contributor

swift-ci commented Jan 7, 2019

Build failed
Swift Test Linux Platform
Git Sha - 1f4c6cac47ab5bf3a54402d80eb1bdbdbbebcacb

@swift-ci
Copy link
Contributor

swift-ci commented Jan 7, 2019

Build failed
Swift Test OS X Platform
Git Sha - 1f4c6cac47ab5bf3a54402d80eb1bdbdbbebcacb

@slavapestov
Copy link
Contributor

@rajbarik Are you able to build and test Swift on Linux?

18:39:35 The following tests FAILED:
18:39:35 	  1 - TestFoundation (SEGFAULT)

@rajbarik
Copy link
Contributor Author

rajbarik commented Jan 8, 2019

@slavapestov I do not have a Linux Box. Other means?

@rajbarik
Copy link
Contributor Author

rajbarik commented Jan 8, 2019

Update: Found a linux box and installed Swift on it. It built fine. When I run tests, I get a lot of precompiled header errors, nothing like Foundation SEGFAULT.
@atrick any clue how to go about handling the Linux error that Slava is pointing out?

@rajbarik
Copy link
Contributor Author

@atrick //cc @airspeedswift @eeckstein could you please look at this one when you get time? I am unable to reproduce this on a linux box at my end. I am in the process of writing a benchmark for #19820 -- this one needs to be committed before I commit the benchmark.

@atrick
Copy link
Contributor

atrick commented Jan 14, 2019

@swift-ci test linux platform.

@atrick
Copy link
Contributor

atrick commented Jan 14, 2019

I don't think I'll have time to debug this week. Let's get the results again. Maybe it's unrelated to this PR.

@atrick atrick merged commit bc884d4 into swiftlang:master Jan 15, 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.

4 participants