This is an archive of the discontinued LLVM Phabricator instance.

[LTO] Make processing of combined module more consistent
ClosedPublic

Authored by vitalybuka on Dec 14 2017, 5:38 PM.

Details

Summary
  1. Use stream 0 only for combined module. Previously if combined module was not processes ThinLTO used the stream for own output. However small changes in input, could trigger combined module and shuffle outputs making life of llvm::LTO client harder.
  1. Always process combined module and write output to stream 0. Processing empty combined module is cheap and allows llvm::LTO users to avoid implementing processing which is already done in llvm::LTO.

Diff Detail

Repository
rL LLVM

Event Timeline

vitalybuka created this revision.Dec 14 2017, 5:38 PM
vitalybuka added a subscriber: llvm-commits.

Peter, please take a look at general approach.
I will add a test.

pcc added a comment.Dec 14 2017, 5:56 PM

I think this patch can be simplified with my suggestions below. Let me know if it works.

llvm/include/llvm/LTO/LTO.h
283–284 ↗(On Diff #127056)

Change these to:

Module CombinedModule;
IRMover Mover;

and have them be initialized by the RegularLTOState constructor in the same way as LTO::linkRegularLTO is doing right now.

295 ↗(On Diff #127056)

Remove this field.

llvm/lib/LTO/LTO.cpp
472 ↗(On Diff #127056)

Make this code use RegularLTO.CombinedModule.{g,s}etTargetTriple() instead.

662–667 ↗(On Diff #127056)

Remove this code.

744 ↗(On Diff #127056)

I don't think you need to add 1 here. With my suggestions, module 0 will be the empty module.

768 ↗(On Diff #127056)

Remove this line.

771–782 ↗(On Diff #127056)

Remove all of this.

pcc added inline comments.Dec 14 2017, 6:00 PM
llvm/lib/LTO/LTO.cpp
1187–1188 ↗(On Diff #127058)

Replace with RegularLTO.ParallelCodeGenParallelismLevel.

The commit message does not make much sense to me in the context of this C++ API: there is a non-negligible layer between the build and the build system rules and the LTO implementation, i.e. the linker.
Implementing a contract that makes it convenient for your build system in the implementation of the LTO "engine" behind this API looks like leaking abstractions to me.

Addressed review comments

vitalybuka marked 7 inline comments as done.Dec 15 2017, 1:09 PM

The commit message does not make much sense to me in the context of this C++ API: there is a non-negligible layer between the build and the build system rules and the LTO implementation, i.e. the linker.
Implementing a contract that makes it convenient for your build system in the implementation of the LTO "engine" behind this API looks like leaking abstractions to me.

Updated commit message.

llvm/include/llvm/LTO/LTO.h
283–284 ↗(On Diff #127056)

abandoned

295 ↗(On Diff #127056)

are you askin to merge RegularLTOState and ThinLTOState?

vitalybuka retitled this revision from [LTO] Write LTO output for empty RegularLTO.ModsWithSummaries to [LTO] Make processing of combined module more consistent.Dec 15 2017, 1:09 PM
vitalybuka edited the summary of this revision. (Show Details)
vitalybuka edited the summary of this revision. (Show Details)
vitalybuka edited the summary of this revision. (Show Details)
vitalybuka marked an inline comment as done.

Remove unchanged file

pcc added a comment.Dec 15 2017, 1:13 PM

Please add a test that shows that we create an empty object file with the correct target triple.

llvm/include/llvm/LTO/LTO.h
295 ↗(On Diff #127056)

No, I was talking about EmptyModuleTargetTriple which you have removed.

vitalybuka planned changes to this revision.Dec 15 2017, 1:16 PM
vitalybuka marked 3 inline comments as done.

Adding promised but forgotten test

However small changes in input, could trigger combined module and shuffle outputs making life of llvm::LTO harder.

Sorry but this is still loaded in assumption about the client, which seems dubious in general to me.

However small changes in input, could trigger combined module and shuffle outputs making life of llvm::LTO harder.

Sorry but this is still loaded in assumption about the client, which seems dubious in general to me.

At this point I am trying to solve problem is the gold plugin, however I'd expect this could be helpful for other clients as well.
Anyway why benefit of particular client without regressing behavior for the rest is a problem? Especially considering that the patch simplify implementation.

vitalybuka edited the summary of this revision. (Show Details)Dec 15 2017, 1:45 PM

updated comment

pcc accepted this revision.Dec 15 2017, 5:39 PM

LGTM

llvm/test/ThinLTO/X86/empty-module.ll
6 ↗(On Diff #127221)

This could be | count 0. Same for the other test that you added.

This revision is now accepted and ready to land.Dec 15 2017, 5:39 PM
vitalybuka marked an inline comment as done.

use count 0

pcc added inline comments.Dec 15 2017, 5:56 PM
llvm/test/ThinLTO/X86/empty-module.ll
9 ↗(On Diff #127224)

Remove this line.

Remove unneeded line

vitalybuka marked an inline comment as done.Dec 15 2017, 5:58 PM
vitalybuka marked an inline comment as done.
This revision was automatically updated to reflect the committed changes.

However small changes in input, could trigger combined module and shuffle outputs making life of llvm::LTO harder.

Sorry but this is still loaded in assumption about the client, which seems dubious in general to me.

At this point I am trying to solve problem is the gold plugin, however I'd expect this could be helpful for other clients as well.
Anyway why benefit of particular client without regressing behavior for the rest is a problem? Especially considering that the patch simplify implementation.

That a problem because it is a terrible way in general to design complex system: this is a sign of over-coupling components and leaking abstractions through implicit API contract.

However small changes in input, could trigger combined module and shuffle outputs making life of llvm::LTO harder.

Sorry but this is still loaded in assumption about the client, which seems dubious in general to me.

At this point I am trying to solve problem is the gold plugin, however I'd expect this could be helpful for other clients as well.
Anyway why benefit of particular client without regressing behavior for the rest is a problem? Especially considering that the patch simplify implementation.

That a problem because it is a terrible way in general to design complex system: this is a sign of over-coupling components and leaking abstractions through implicit API contract.

I agree that implicit contract about streams order is not nice here, and we should consider to make it explicit.

I agree that implicit contract about streams order is not nice here, and we should consider to make it explicit.

That makes the system more rigid, and leave less room for improvements/innovation/etc.

For instance the C API LTO bindings intentionally specifies that the client needs to be prepared to receive a different number of objects than the number of modules it supplied. This allows ThinLTO to evolve toward different granularity of partitioning for instance.
Making the LTO API a 1-1 in term of matching the output files to the inputs modules would make this uneasy. Constraining the API a this level is really not great: if you feel that you need 1-1 matching for some client, it seems to me that it should be achieved by adding an intermediate layer that would take care of it instead of injecting it there.