This is an archive of the discontinued LLVM Phabricator instance.

Rewrite InputGraph's Group
Needs ReviewPublic

Authored by ruiu on Nov 19 2014, 11:08 PM.

Details

Summary

The aim of this patch is to reduce the excessive abstraction from
the InputGraph. We found that even a simple thing, such as sorting
input files (Mach-O) or adding a new file to the input file list
(PE/COFF), is nearly impossible with the InputGraph abstraction,
because it hides too much information behind it. As a result,
we invented complex interactions between components (e.g.
notifyProgress() mechanism) and tricky code to work around that
limitation. There were many occasions that we needed to write
awkward code.

This patch is the first step to make it cleaner. As the first step,
this removes Group class from the InputGraph. The grouping feature,
is now directly handled by the Resolver. notifyProgress is removed
since we no longer need it. I could have cleaned it up even more,
but in order to keep the patch minimum, I focused on Group.

SimpleFileNode class, a container of File objects (confusing!), is
now limited to have only one File. We shold have done this earlier.
We used to allow putting multiple File objects to FileNode.
Although SimpleFileNode usually has only one file, the Driver class
actually used that capability. I modified the Driver class a bit,
so that one FileNode is created for each input File.

We should now probably remove SimpleFileNode and directly store
File objects to the InputGraph in some way, because a container
that can contain only one object is useless. This is a TODO.

Mach-O input files are now sorted before they are passe to the
Resolver. DarwinInputGraph class is no longer needed, so removed.

PECOFF still has hacky code to add a new file to the input file list.
This will be cleaned up in another patch.

Diff Detail

Event Timeline

ruiu updated this revision to Diff 16417.Nov 19 2014, 11:08 PM
ruiu retitled this revision from to Rewrite InputGraph's Group.
ruiu updated this object.
ruiu edited the test plan for this revision. (Show Details)
emaste added a subscriber: emaste.Nov 20 2014, 8:21 AM
kledzik edited edge metadata.Nov 21 2014, 10:43 AM

The big problem I still see is that this does not fix the issue of multiple different file kinds in one InputElement.

Resolver::resolveUndefines() is still convoluted.

It would be nice if there was some way to flatten the InputElement vector into a File vector (preserving groups). And maybe a parallel set of index ranges into the File vector for where the groups are.

include/lld/Core/Resolver.h
117–119

A little weird to have this method in the middle of the data members

lib/Core/Resolver.cpp
82

undefAdded = undefAdded || handleFile(*member);

lib/ReaderWriter/MachO/MachOLinkingContext.cpp
934–937

Does isa<File> work? File is the base class for SharedLibraryFile and ArchiveLibraryFile, so I would think that isa<File> would return true for libraries? Maybe this is a case of how dynamic_cast<> and isa<> differ?

939–942

This really only works if there is one file in each input element. That is not the case for yaml input.

957

Is that expression right? Or is it only right because this is a stable_sort(). That is, if both a and b are the same type, the comparator always returns false, no matter the order of a and b.

ruiu updated this revision to Diff 16511.Nov 21 2014, 2:28 PM
ruiu edited edge metadata.

I made a change to FileNode so that a FileNode containing multiple Files in it is expanded to multiple FileNode before it's passed to the Resolver. It's not a complete fix (because FileNode is now supposed to contain strictly one file, which makes FileNode useless as a container), but it should mitigate the situation. I'll try to remove that indirection of the container in a followup patch.

I totally agree that it's nice to have a way to get a list of files in the InputGraph. This patch removes Group nesting from the Graph, so this is one step towards that.

include/lld/Core/Resolver.h
117–119

Done.

lib/Core/Resolver.cpp
82

Done.

lib/ReaderWriter/MachO/MachOLinkingContext.cpp
934–937

I initially didn't notice that, but isa<File>(file) always returned true. Thank you for pointing that out. Because of that, the lambda function passed to stable_sort returned inconsistent results, but it happened to work in my environment.

What really matters is whether a file is library or not. So I removed this function and use !isLibrary instead.

939–942

Now the YAML file containing multiple files are expanded to multiple InputElements by getReplacements.

957

The lambda function passed to stable_sort is supposed to return true only if the first argument is less (in the sense of < operator) than the second. It's totally okay that both a < b and b < a are satisfied. That means a is equivalent to b in sort order, and their original order is preserved.

atanasyan added inline comments.Nov 21 2014, 2:54 PM
include/lld/Core/LinkingContext.h
323

Maybe rename this method to something like beforeResolving() or preResolving()? A derived class can override this method for something different from sorting.

ruiu added inline comments.Nov 21 2014, 3:07 PM
include/lld/Core/LinkingContext.h
323

Currently only Mach-O uses this hook so it's named accordingly. I kind of prefer this naming over beforeResolving because it's clear what it is (currently) doing. We could change the name when we want to use it for other archs. If you want me to rename it, I can do that now, though.

atanasyan added inline comments.Nov 23 2014, 2:34 AM
include/lld/Core/LinkingContext.h
323

OK. Let's use the current name.

ruiu added a comment.Nov 24 2014, 8:15 PM

Pre-thanksgiving ping.

rafael added a subscriber: Unknown Object (MLST).Nov 28 2014, 11:00 AM

This still seems too complicated. But it is a step in the right direction, so LGTM.

atanasyan resigned from this revision.Feb 3 2016, 12:45 AM
atanasyan removed a reviewer: atanasyan.