Skip to content

Serialize SIL witness-tables and v-tables if package cmo is enabled. #72606

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
Apr 9, 2024

Conversation

elsh
Copy link
Contributor

@elsh elsh commented Mar 27, 2024

Serialize SIL witness-tables and v-tables and their entries if package cmo is
enabled. If two modules are in the same package and package cmo is enabled,
v-table or witness-table calls should not be generated at the use site in the
client module. Modified conformance serialization check to allow serializing
witness thunks.

Also reordered SIL functions bottom-up so the most nested referenced functions
can be serialized first. Allowed serializing a function if it's a shared definition
(e.g. function print). Added a check for resilient modes and loadable types.

Added tests for SIL tables and resilient mode on/off.

rdar://124632670

@elsh elsh requested review from aschwaighofer and eeckstein March 27, 2024 01:30
@elsh
Copy link
Contributor Author

elsh commented Mar 27, 2024

@swift-ci smoke test

@elsh elsh requested a review from slavapestov March 27, 2024 01:30
@elsh elsh force-pushed the elsh/pkg-serialize-tables branch 3 times, most recently from 1a445b9 to f523041 Compare April 2, 2024 12:02
@elsh
Copy link
Contributor Author

elsh commented Apr 2, 2024

@swift-ci smoke test

@elsh elsh force-pushed the elsh/pkg-serialize-tables branch from f523041 to 8c8bff4 Compare April 3, 2024 08:30
@elsh
Copy link
Contributor Author

elsh commented Apr 3, 2024

@swift-ci smoke test

@elsh elsh force-pushed the elsh/pkg-serialize-tables branch from 8c8bff4 to 32fda75 Compare April 3, 2024 08:57
@elsh
Copy link
Contributor Author

elsh commented Apr 3, 2024

@swift-ci smoke test

auto accessLevelToCheck =
optInPackage ? AccessLevel::Package : AccessLevel::Public;

if (conformance->getProtocol()->getEffectiveAccess() < accessLevelToCheck)
Copy link
Contributor Author

@elsh elsh Apr 3, 2024

Choose a reason for hiding this comment

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

Without this, witness thunks for conformance with package linkage don't get proper linkages in SILGenConformance::addMethodImplementation(..); they are defaulted to private otherwise and an attempt to serialize during package-cmo would lead to an assert fail.

@elsh elsh force-pushed the elsh/pkg-serialize-tables branch from 32fda75 to 12571f5 Compare April 5, 2024 00:58
@elsh elsh requested review from hborla and xedin as code owners April 5, 2024 00:58
@elsh elsh force-pushed the elsh/pkg-serialize-tables branch 2 times, most recently from acd9a4f to bb70268 Compare April 5, 2024 01:14
@elsh
Copy link
Contributor Author

elsh commented Apr 5, 2024

@swift-ci smoke test

@aschwaighofer
Copy link
Contributor

Unrelated to your PR. But I noticed something in the following code:

bool CrossModuleOptimization::canSerializeFunction(                             
                               SILFunction *function,                           
                               FunctionFlags &canSerializeFlags,                
                               int maxDepth) {                                  
  auto iter = canSerializeFlags.find(function);                                 
  // Avoid infinite recursion in case it's a cycle in the call graph.           
  if (iter != canSerializeFlags.end())                                          
    return iter->second;                                                        
                                                                                
  // Temporarily set the flag to false (to avoid infinite recursion) until we set
  // it to true at the end of this function.                                    
  canSerializeFlags[function] = false;                                          
                                                                                
  if (everything) {                                                             
   canSerializeFlags[function] = true;                                          
   return true;                                                                 
  }                                                                             
                                                                                
  if (DeclContext *funcCtxt = function->getDeclContext()) {                     
    if (!canUseFromInline(funcCtxt))                                            
      return false;                                                             
  }                                                                             
                                                                                
  if (function->isSerialized())                                                 
    return true;  

The first time we call the canSerializeFunction function me might end up in the if (function->isSerialized()) branch. But the second time we call canSerializeFunction on the same function we will end up in the cached value which returns false because of the earlier:

  // Temporarily set the flag to false (to avoid infinite recursion) until we set
  // it to true at the end of this function.                                    
  canSerializeFlags[function] = false;   

This seems to be an oversight/ unnecessary pessimistic. I think we should change the code to:

  if (function->isSerialized()) {
    canSerializeFlags[function] = true;                                               
    return true; 
  }

…e cmo is

enabled. If two modules are in the same package and package cmo is enabled,
v-table or witness-table calls should not be generated at the use site in the
client module. Modified conformance serialization check to allow serializing
witness thunks.

Also reordered SIL functions bottom-up so the most nested referenced functions
can be serialized first. Allowed serializing a function if a shared definition
(e.g. function `print`). Added a check for resilient mode wrt struct instructions.

Added tests for SIL tables and resilient mode on/off.

rdar://124632670
@elsh elsh force-pushed the elsh/pkg-serialize-tables branch from bb70268 to c44b22a Compare April 8, 2024 20:38
@elsh
Copy link
Contributor Author

elsh commented Apr 8, 2024

@swift-ci smoke test

Copy link
Contributor

@aschwaighofer aschwaighofer left a comment

Choose a reason for hiding this comment

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

LGTM

@elsh elsh merged commit 3bb25de into main Apr 9, 2024
@elsh elsh deleted the elsh/pkg-serialize-tables branch April 9, 2024 17:06
@elsh elsh requested a review from nkcsgexi April 9, 2024 20:18
@elsh elsh mentioned this pull request May 29, 2024
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.

2 participants