Skip to content

Dependency Scanning Library #34786

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 35 commits into from
Jan 8, 2021
Merged

Conversation

artemcm
Copy link
Contributor

@artemcm artemcm commented Nov 17, 2020

This PR introduces a dependency scanning tool/library that is meant to be used by libSwiftDriver, replacing its current calls to swift-frontend -scan-dependencies.

This library is designed to be used for dependency scanning across multiple, different modules, with a common ModuleDependencyCache, in order to re-use computed information about already-scanned modules.

This PR:

  • Adds a C++ interface for a tool that answers dependency-scanning queries (DependencyScanningTool).
  • Adds a unittest harness to invoke the DependencyScanningTool library.
  • Factors ModuleDependenciesCache out of a CompilerInstance into callers of scanDependencies. It is now the responsibility of the scanDependencies code to instantiate (and share) the cache. e.g. FrontendTool instantiates a new cache per -scan-dependencies invocation, and the DependencyScanningTool keeps one shared cache across its lifetime. (Effectively un-doing [Dependency Scanner] Share ModuleDependenciesCache as a part of the CompilerInstance #34646)
  • Deprecates and removes -scan-clang-dependencies. Since it was introduced, its use-case has been entirely subsumed by batch scanning.
  • Adds a C API layer for dependency scanning tool, scanning actions, and scan results. (include/swift-c/DependencyScan)
  • Refactors dependency scanner to return an in-memory format as its result output. Specifically, code in ScanDependencies.cpp is split into two functional groups:
    • Scan execution code that performs the mechanics of the scan and produces an in-memory result
    • Dependency scanner entry-points used when the scanning action is invoked as a swift-frontend execution mode
    • Adds the aforementioned in-memory dependency scanning result in DependencyScan.h, modelled after the InterModuleDependencyGraph representation in swift-driver

Resolves rdar://71209248
Resolves rdar://71209311

@artemcm artemcm requested a review from nkcsgexi November 17, 2020 20:06
@artemcm artemcm force-pushed the DependencyScanLibrary branch 2 times, most recently from f1dd0aa to 9f5fab0 Compare November 20, 2020 22:44
@artemcm
Copy link
Contributor Author

artemcm commented Nov 20, 2020

@swift-ci please smoke test

@artemcm
Copy link
Contributor Author

artemcm commented Nov 20, 2020

@nkcsgexi, curious to hear your thoughts on the refactor in ScanDependencies.h and ScanDependencies.cpp.

@nkcsgexi
Copy link
Contributor

They look good to me for now. Can we first define the C header defining those APIs libSwiftDriver need for scanning and refactor the C++ implementation accordingly?

@artemcm
Copy link
Contributor Author

artemcm commented Nov 20, 2020

They look good to me for now. Can we first define the C header defining those APIs libSwiftDriver need for scanning and refactor the C++ implementation accordingly?

I like this idea, yeah, I'll do that.

@artemcm artemcm force-pushed the DependencyScanLibrary branch 4 times, most recently from 6294902 to fb9ba46 Compare December 2, 2020 18:50
@artemcm
Copy link
Contributor Author

artemcm commented Dec 2, 2020

@akyrtzi @benlangmuir,
I would be grateful to get your comments on the C API, among other things, mostly contained in:
include/swift-c/DependencyScan

@artemcm
Copy link
Contributor Author

artemcm commented Dec 2, 2020

Likewise, @nkcsgexi.

@akyrtzi
Copy link
Contributor

akyrtzi commented Dec 5, 2020

Some additional things for your consideration:

  • Adding an exports list file would be general goodness. It is what will give you a linker error if an exported function is not implemented (e.g. when some type or function changes and the function implementation doesn't match the declaration) and can help to strip the library of unused code and make it smaller.
  • ds as prefix is too short. Consider that you are essentially adding symbols to the global namespace of a client's process (any client, not necessarily something we control), and the prefix is the "defense" against unintentional conflicts with other libraries. I'd suggest to use a more discriminating prefix, like swiftds_ or swiftscan_
  • Consider using _Nonnull and _Nullable to make the APIs more ergonomic for Swift
  • I'd recommend to base your testing on top of the C API. It will be a bit less convenient than testing using the C++ APIs but you will have piece of mind that you are really testing what the client is actually using.

*/
typedef struct {
const void *data;
unsigned private_flags;
} ds_string_t;
} swiftscan_string_t;
Copy link
Contributor

Choose a reason for hiding this comment

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

@akyrtzi do you know why CXString has this representation? I was surprised it's not just a pointer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only use of the flags seems to be to distinguishing who manages this pointer, whether it was malloc'd locally or points to unmanaged memory.

Copy link
Contributor

Choose a reason for hiding this comment

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

I personally dislike CXString, I'd suggest to either use something like indexstore_string_ref_t and be clear what is the lifetime of the returned string (e.g. "same lifetime as the object the string came from") or malloc and return a char * and require the caller to free() it.

Copy link
Contributor

Choose a reason for hiding this comment

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

be clear what is the lifetime of the returned string (e.g. "same lifetime as the object the string came from")

Note that on the Swift code you are mainly just going to copy it into a Swift string as soon as you call it, so the lifetime aspect it won't make things complicated (it will even simplify things since you won't have to call dispose on it).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed the string implementation to one that resembles index store_string_ref_t and its lifetime is now tied to the object the string comes from. Clients need not worry about freeing string memory, it will be freed automatically when the owning object is disposed of.

swiftscan_clang_detail_get_module_map_path(swiftscan_module_details_t details);

SWIFTSCAN_PUBLIC swiftscan_string_t
swiftscan_clang_detail_get_context_hash(swiftscan_module_details_t details);
Copy link
Contributor

Choose a reason for hiding this comment

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

These accessors that return swiftscan_string_t or swiftscan_string_set_t * are not clear about ownership. I see you have swiftscan_string_dispose and swiftscan_string_set_dispose methods, but the implementation looks like they are returned unowned. If not every API is consistent about whether the caller needs to dispose of the result, I recommend putting it in the doc comment for the accessors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Resolved by tying the lifetime of the string to the object it is associated with. swiftscan_string_dispose and swiftscan_string_set_dispose are no longer part of the public API.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In general, I propose we adopt Foundation-style ownership signals here

@CodaFi, thank you taking a look at this PR and proposing this convention.
The API now consistently follows this naming scheme, providing a create and dispose functions for all objects that the library's clients may take ownership of.

@artemcm artemcm requested a review from xymus December 8, 2020 18:38
@artemcm
Copy link
Contributor Author

artemcm commented Dec 9, 2020

  • Adding an exports list file would be general goodness. It is what will give you a linker error if an exported function is not implemented (e.g. when some type or function changes and the function implementation doesn't match the declaration) and can help to strip the library of unused code and make it smaller.

Already caught an error by doing this, thank you @akyrtzi!

@@ -0,0 +1,51 @@
swiftscan_dependency_result_get_main_module_name
Copy link
Contributor

Choose a reason for hiding this comment

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

You may have some entertaining conflicts with this.

//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_C_DEPENDENCY_SCAN_H
Copy link
Contributor

Choose a reason for hiding this comment

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

"llvm/Support/CBindingWrapping.h" provides some utilities that might help things here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks!

…side string construction

(Using string length provided by the type)
…h up-to-date search paths on successive scanner invocations

To ensure they do not get stuck with stale search paths when scanning successive targets.
…creation to populate LLVM's target data store.
@artemcm artemcm force-pushed the DependencyScanLibrary branch from 189da80 to cc400bf Compare January 7, 2021 17:08
@artemcm
Copy link
Contributor Author

artemcm commented Jan 7, 2021

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Jan 7, 2021

Build failed
Swift Test Linux Platform
Git Sha - cc400bf

@artemcm
Copy link
Contributor Author

artemcm commented Jan 7, 2021

@swift-ci please test Linux platform

@artemcm
Copy link
Contributor Author

artemcm commented Jan 7, 2021

@swift-ci please test

@artemcm artemcm force-pushed the DependencyScanLibrary branch from f542987 to e991ce2 Compare January 7, 2021 22:40
@artemcm
Copy link
Contributor Author

artemcm commented Jan 7, 2021

@swift-ci please test Windows platform

@artemcm artemcm force-pushed the DependencyScanLibrary branch from e991ce2 to 4f8c0e4 Compare January 7, 2021 23:45
@artemcm
Copy link
Contributor Author

artemcm commented Jan 7, 2021

@swift-ci please test Windows platform

@artemcm artemcm force-pushed the DependencyScanLibrary branch from 4f8c0e4 to 4eae21c Compare January 8, 2021 00:53
@artemcm
Copy link
Contributor Author

artemcm commented Jan 8, 2021

@swift-ci please test Windows platform

@swift-ci
Copy link
Contributor

swift-ci commented Jan 8, 2021

Build failed
Swift Test OS X Platform
Git Sha - f5429870d84d5be6dd03a076bbf07aa8ae02208b

@artemcm
Copy link
Contributor Author

artemcm commented Jan 8, 2021

@swift-ci please test Linux platform

@artemcm
Copy link
Contributor Author

artemcm commented Jan 8, 2021

@swift-ci please test macOS platform

@swift-ci
Copy link
Contributor

swift-ci commented Jan 8, 2021

Build failed
Swift Test OS X Platform
Git Sha - 4eae21c

@artemcm
Copy link
Contributor Author

artemcm commented Jan 8, 2021

@swift-ci please test macOS platform

@swift-ci
Copy link
Contributor

swift-ci commented Jan 8, 2021

Build failed
Swift Test OS X Platform
Git Sha - 4eae21c

@artemcm
Copy link
Contributor Author

artemcm commented Jan 8, 2021

@swift-ci please test macOS platform

@artemcm artemcm merged commit 7e6536d into swiftlang:main Jan 8, 2021
@nkcsgexi
Copy link
Contributor

nkcsgexi commented Jan 9, 2021

🎉

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.

6 participants