diff options
author | Florian Hahn <florian.hahn@arm.com> | 2017-11-13 10:35:52 +0000 |
---|---|---|
committer | Florian Hahn <florian.hahn@arm.com> | 2017-11-13 10:35:52 +0000 |
commit | 0e9dec672daa73640cc7f832da9a0dad3c448414 (patch) | |
tree | e93f90807012efe9c8d7b2d4e54c0fb6c592c902 /llvm/lib/Transforms/IPO/PartialInlining.cpp | |
parent | 070a7ff1adbba5be10e33d0f1462ccc92ed59585 (diff) | |
download | bcm5719-llvm-0e9dec672daa73640cc7f832da9a0dad3c448414.tar.gz bcm5719-llvm-0e9dec672daa73640cc7f832da9a0dad3c448414.zip |
[PartialInliner] Inline vararg functions that forward varargs.
Summary:
This patch extends the partial inliner to support inlining parts of
vararg functions, if the vararg handling is done in the outlined part.
It adds a `ForwardVarArgsTo` argument to InlineFunction. If it is
non-null, all varargs passed to the inlined function will be added to
all calls to `ForwardVarArgsTo`.
The partial inliner takes care to only pass `ForwardVarArgsTo` if the
varargs handing is done in the outlined function. It checks that vastart
is not part of the function to be inlined.
`test/Transforms/CodeExtractor/PartialInlineNoInline.ll` (already part
of the repo) checks we do not do partial inlining if vastart is used in
a basic block that will be inlined.
Reviewers: davide, davidxl, grosser
Reviewed By: davide, davidxl, grosser
Subscribers: gyiu, grosser, eraman, llvm-commits
Differential Revision: https://reviews.llvm.org/D39607
llvm-svn: 318028
Diffstat (limited to 'llvm/lib/Transforms/IPO/PartialInlining.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/PartialInlining.cpp | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/IPO/PartialInlining.cpp b/llvm/lib/Transforms/IPO/PartialInlining.cpp index c47d8b78df3..c00e13c4ae2 100644 --- a/llvm/lib/Transforms/IPO/PartialInlining.cpp +++ b/llvm/lib/Transforms/IPO/PartialInlining.cpp @@ -149,7 +149,12 @@ struct PartialInlinerImpl { // the return block. void NormalizeReturnBlock(); - // Do function outlining: + // Do function outlining. + // NOTE: For vararg functions that do the vararg handling in the outlined + // function, we temporarily generate IR that does not properly + // forward varargs to the outlined function. Calling InlineFunction + // will update calls to the outlined functions to properly forward + // the varargs. Function *doFunctionOutlining(); Function *OrigFunc = nullptr; @@ -813,7 +818,8 @@ Function *PartialInlinerImpl::FunctionCloner::doFunctionOutlining() { // Extract the body of the if. OutlinedFunc = CodeExtractor(ToExtract, &DT, /*AggregateArgs*/ false, - ClonedFuncBFI.get(), &BPI) + ClonedFuncBFI.get(), &BPI, + /* AllowVarargs */ true) .extractCodeRegion(); if (OutlinedFunc) { @@ -938,7 +944,7 @@ bool PartialInlinerImpl::tryPartialInline(FunctionCloner &Cloner) { << ore::NV("Caller", CS.getCaller()); InlineFunctionInfo IFI(nullptr, GetAssumptionCache, PSI); - if (!InlineFunction(CS, IFI)) + if (!InlineFunction(CS, IFI, nullptr, true, Cloner.OutlinedFunc)) continue; ORE.emit(OR); |