Skip to content

[SIL] NFC: Simplify SILVTable and save 8 bytes per SILVTable #32238

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
Jun 10, 2020

Conversation

davezarzycki
Copy link
Contributor

@davezarzycki davezarzycki commented Jun 8, 2020

EDITED

We are not using the primary benefits of an intrusive list, namely the ability to insert or remove from the middle of the list, so let's switch to a plain vector. This also avoids linked-list pointer chasing.

OLD TEXT

I noticed that vtables were being tracked redundantly by SILModule and nothing seems to be using the intrusive list aspect of SILVTable, so I tried just converging everything onto the DenseMap. This almost works, but then the destructor for SILModule blows up when it finds a function with a non-zero reference count. This surprised me.

Am I missing something obvious?

Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

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

This makes the compiler non-deterministic.
For example, when iterating over the vtables for serialization.

The general rule is: never iterate over a map/set of pointers, except it can be 100% proven that the iteration order does not effect any compilation result.

@davezarzycki
Copy link
Contributor Author

davezarzycki commented Jun 8, 2020

Ya, I just figured out why the ref count was non-zero and now the test suite is blowing up as you predicted. Nevertheless, sort() can solve this, no? Or is important that vtables be emitted in source order?

@eeckstein
Copy link
Contributor

It doesn't necessarily be in source order. But it needs to be deterministic.
'sort' cannot solve this.

@davezarzycki
Copy link
Contributor Author

So why do we have -emit-sorted-sil then?

@eeckstein
Copy link
Contributor

-emit-sorted-sil is to get some more consistent output in textual SIL, but it's not to fix non-determinism in the compiler.

What would be the sort predicate for vtables?

Beside that, providing an iteration API for something which is a non-deterministic map under the hood, is extremely dangerous. It's very easy to misuse this API and introduce non-determinism.

@davezarzycki
Copy link
Contributor Author

Fair enough. I'm observing your point now in the test suite. In any case, we can still save memory and avoid pointer chasing if we don't use an intrusive list, so I'll simplify this patch.

@davezarzycki davezarzycki changed the title WIP: Shrink SILVTable [SIL] NFC: Simplify SILVTable and save 8 bytes per SILVTable Jun 8, 2020
@davezarzycki davezarzycki marked this pull request as ready for review June 8, 2020 14:47
@davezarzycki
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Jun 8, 2020

Build failed
Swift Test Linux Platform
Git Sha - ca8fcbc90d464f6d6c95ccbe7be907cee33d5c87

@davezarzycki davezarzycki dismissed eeckstein’s stale review June 8, 2020 14:49

Addressed feedback

@davezarzycki davezarzycki requested a review from eeckstein June 8, 2020 14:49
@swift-ci
Copy link
Contributor

swift-ci commented Jun 8, 2020

Build failed
Swift Test OS X Platform
Git Sha - ca8fcbc90d464f6d6c95ccbe7be907cee33d5c87

vtable_iterator vtable_begin() { return getVTableList().begin(); }
vtable_iterator vtable_end() { return getVTableList().end(); }
vtable_const_iterator vtable_begin() const { return getVTableList().begin(); }
vtable_const_iterator vtable_end() const { return getVTableList().end(); }
iterator_range<vtable_iterator> getVTables() {
Copy link
Contributor

@eeckstein eeckstein Jun 8, 2020

Choose a reason for hiding this comment

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

I don't think we still need both of getVTableList() and getVTables().
I would keep

  VTableListType getVTables() { return llvm::ArrayRef<SILVTable*>(vtables); }

@@ -178,7 +178,7 @@ class SILModule {
llvm::DenseMap<const ClassDecl *, SILVTable *> VTableMap;

/// The list of SILVTables in the module.
VTableListType vtables;
std::vector<SILVTable*> vtables;
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we could use an llvm::MapVector here, so that we get both stable order and efficient lookup?

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 just looked at the llvm::MapVector implementation. It's less time and space efficient than what this pull request is proposing (in short: "map of keys to indices into a vector of key/value pairs"). It's also less convenient because the std::vector is key/value pairs when all we need/want is an array of values.

Copy link
Contributor

Choose a reason for hiding this comment

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

Alright, sounds good.

@davezarzycki
Copy link
Contributor Author

@eeckstein – I've made the getVTableList() -> getVTables() change you requested.

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Jun 9, 2020

Build failed
Swift Test Linux Platform
Git Sha - 7cecb61081c27dcd0f1ee8be54a6296afd0a3727

@swift-ci
Copy link
Contributor

swift-ci commented Jun 9, 2020

Build failed
Swift Test OS X Platform
Git Sha - 7cecb61081c27dcd0f1ee8be54a6296afd0a3727

Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

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

lgtm!

@davezarzycki
Copy link
Contributor Author

Thanks. I'm going to hold out on merging this while I make a last ditch effort to get the build czars to fix last nights erroneous merge "correctly".

@davezarzycki
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 0da8e88c0c0beea3f06ba49d4d89c78b947352cc

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 0da8e88c0c0beea3f06ba49d4d89c78b947352cc

We were not using the primary benefits of an intrusive list, namely the
ability to insert or remove from the middle of the list, so let's switch
to a plain vector. This also avoids linked-list pointer chasing.
@davezarzycki
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 0da8e88c0c0beea3f06ba49d4d89c78b947352cc

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 0da8e88c0c0beea3f06ba49d4d89c78b947352cc

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