This is an archive of the discontinued LLVM Phabricator instance.

[FuncSpec] Improve the accuracy of the cost model.
ClosedPublic

Authored by labrinea on May 12 2023, 10:43 AM.

Details

Summary

Instead of blindly traversing the use-def chain of constant arguments, compute known constants along the way. Stop as soon as a user cannot be replaced by a constant. Keep it light-weight by handling some basic instruction types.

Stats from the llvm testsuite (CTMark):
-O3 pipeline

Nspecs beforeClamAV : 5SPASS : 2Bullet : 1
Nspecs afterClamAV : 5consumer-typeset : 1Bullet : 1
InstrCount delta (geomean) : -0.029%

LTO pipeline

Nspecs beforesqlite3 : 1consumer-typeset : 1
Nspecs afterSPASS : 3consumer-typeset : 1
InstrCount delta (geomean) : -0.015%

Diff Detail

Event Timeline

labrinea created this revision.May 12 2023, 10:43 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 12 2023, 10:43 AM
labrinea requested review of this revision.May 12 2023, 10:43 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 12 2023, 10:43 AM

Can we find some method to test this? If a lit test is not good enough, maybe we can try to look at unit tests?

Can we find some method to test this? If a lit test is not good enough, maybe we can try to look at unit tests?

Sounds like a good idea. I'll write some.

labrinea updated this revision to Diff 523084.May 17 2023, 9:39 AM

I've added unittests but the results make more sense with D150649.

ChuanqiXu added inline comments.May 18 2023, 12:51 AM
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
790–791

Is this change necessary? Or what is the intention? It looks not good to me at the first sight.

794

We prefer code style with shorter ident.

794

Maybe we can make it look prettier by using InstVisitor for such code patterns.

798–800

We don't like else-after-return pattern.

810–836

Oh, good idea. But I only understand what you're trying to do after reading the codes. A comment here will be helpful.

826

Constant expression is going to be deprecated: https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179. Let's not add more constant expression.

832–834

Such code pattern looks a little bit dirty. Let's try to wrap it into a function.

841–843

This looks similar with estimateSwitchInst. Can we try to merge them?

845

Ditto.

876
labrinea added inline comments.
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
790–791

Quoting a comment I left on the parent revision (D150375) in response to @mingmingl :

The Specialization cost estimation is wrong and I am planning to fix that in later patches. Metrics.NumInsts already contains TargetTransformInfo::TCK_CodeSize.

See https://github.com/llvm/llvm-project/blob/main/llvm/lib/Analysis/CodeMetrics.cpp#L180

794

Can you give an example?

794

will do

810–836

will do

826

What alternative do we have?

841–843

I can factor out common code to a static function perhaps.

ChuanqiXu added inline comments.May 18 2023, 7:23 PM
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
790–791

Oh, sorry for disturbing.

794

There are multiple examples: InstructionAllowed and CallAnalyzer and so on. Maybe you would feel the code become longer after we adopt that. But I think it will be easier to read and understand. This is a suggestion and not a requirement.

826

I don't know if we have an off-the-shelf solution for this. But I'm sure that the resulting 'C' here shouldn't be ConstantExpr. If there is not an off-the-shelf solution, maybe we can add one for it. Or we can leave the case for later patches.

labrinea added inline comments.May 19 2023, 1:13 AM
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
794

Ah, you meant the instruction visitor like the one used by the SCCPSolver. I was experimenting with this idea yesterday. One problem I see is that the visit methods take only one argument (the visited instruction) so we would have to cache the extra parameters inside the visitor class. I'll investigate more.

826

I think we can use the data-layout agnostic constant folding.

labrinea updated this revision to Diff 524350.May 22 2023, 9:23 AM
labrinea edited the summary of this revision. (Show Details)

Added an InstructionVisitor for the bonus calculation.

labrinea marked 13 inline comments as done.May 22 2023, 9:25 AM
labrinea added inline comments.May 22 2023, 9:33 AM
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
148–150

This is a bit ugly but I couldn't think of a better way. As I explained before the visit functions only take one parameter, the instruction.

labrinea added inline comments.May 23 2023, 6:46 AM
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
148–150

Perhaps I could replace these two with ConstMap::iterator since we are inserting the {Use, C} pair on every visit.

labrinea updated this revision to Diff 524690.May 23 2023, 7:00 AM

Cached the Map Iterator in the InstructionVisitor instead of the {Key, Value} pair.

labrinea added inline comments.May 23 2023, 8:51 AM
llvm/unittests/Transforms/IPO/FunctionSpecializationTest.cpp
2

I've spotted a problem. This unittest is relying on target specific costs, so it will fail on some targets. I need to either make it x86 specific or change the expected values based on some logic.

labrinea updated this revision to Diff 524884.May 23 2023, 2:27 PM

Made the unittest more generic so that it succeeds on any target.

ChuanqiXu accepted this revision.May 23 2023, 8:22 PM

LGTM with nit comments. Thanks.

llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
100–103

Let's add a comment for this since its semantics are not clear from the signature.

210
234–236

Could we refactor it into this? Then we can remove AllOperandsAreConst.

This revision is now accepted and ready to land.May 23 2023, 8:22 PM
labrinea added inline comments.May 24 2023, 3:00 AM
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
100–103

Will do.

210

I don't understand. The worklist is populated by a chain of basic blocks. If 32 is too much perharps we could leave it to default? Surely 1 is too conservative and expanding the small vector at runtime seems expensive.

234–236

Oh yes, I had the old impementation (pre InstructionVisitor) in mind at the time of writing this.

This revision was landed with ongoing or failed builds.May 24 2023, 3:54 AM
This revision was automatically updated to reflect the committed changes.

@labrinea This change hits a crash when trying to build lld with thinLTO (i.e. stage2 lld) and with assertions enabled. I verified that the revision before this change works. I get the following assertion failure

opt: <workspace>/llvm-project/llvm/include/llvm/Support/Casting.h:578: decltype(auto) llvm::cast(From *) [To = llvm::ConstantInt, From = llvm::Constant]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

I reduced the issue and this can be reproed by building opt on this revision and then running

$ opt reduced.ll -o /dev/null -O3

where reduced.ll is https://reviews.llvm.org/P8311

Could you please take a look and advise the path forward?

cc: @smeenai

@labrinea This change hits a crash when trying to build lld with thinLTO (i.e. stage2 lld) and with assertions enabled. I verified that the revision before this change works. I get the following assertion failure

opt: <workspace>/llvm-project/llvm/include/llvm/Support/Casting.h:578: decltype(auto) llvm::cast(From *) [To = llvm::ConstantInt, From = llvm::Constant]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

I reduced the issue and this can be reproed by building opt on this revision and then running

$ opt reduced.ll -o /dev/null -O3

where reduced.ll is https://reviews.llvm.org/P8311

Could you please take a look and advise the path forward?

cc: @smeenai

I put up D154159 that should address the crashing issue.