Skip to content

Commit 8ff3f0b

Browse files
committed
[IR] "modular-format" attribute for functions using format strings
A new InstCombine transform uses this attribute to rewrite calls to a modular version of the implementation along with llvm.reloc.none relocations against aspects of the implementation needed by the call. This change only adds support for the 'float' aspect, but it also builds the structure needed for others. See issue #146159
1 parent 657f659 commit 8ff3f0b

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

llvm/docs/LangRef.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2633,6 +2633,23 @@ For example:
26332633
This attribute indicates that outlining passes should not modify the
26342634
function.
26352635

2636+
``"modular_format"="<string_idx>,<first_idx_to_check>,<modular_impl_fn>,<impl_name>,<aspects...>"``
2637+
This attribute indicates that the implementation is modular on a particular
2638+
format string argument . When the argument for a given call is constant, the
2639+
compiler may redirect the call to a modular implementation function
2640+
instead.
2641+
2642+
The compiler also emits relocations to report various aspects of the format
2643+
string and arguments that were present. The compiler reports an aspect by
2644+
issing a relocation for the symbol `<impl_name>_<aspect>``. This arranges
2645+
for code and data needed to support the aspect of the implementation to be
2646+
brought into the link to satisfy weak references in the modular
2647+
implemenation function.
2648+
2649+
The following aspects are currently supported:
2650+
2651+
- ``float``: The call has a floating point argument
2652+
26362653
Call Site Attributes
26372654
----------------------
26382655

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/SmallBitVector.h"
2020
#include "llvm/ADT/SmallVector.h"
2121
#include "llvm/ADT/Statistic.h"
22+
#include "llvm/ADT/StringExtras.h"
2223
#include "llvm/Analysis/AliasAnalysis.h"
2324
#include "llvm/Analysis/AssumeBundleQueries.h"
2425
#include "llvm/Analysis/AssumptionCache.h"
@@ -3951,6 +3952,63 @@ Instruction *InstCombinerImpl::visitCallBrInst(CallBrInst &CBI) {
39513952
return visitCallBase(CBI);
39523953
}
39533954

3955+
static Value *optimizeModularFormat(CallInst *CI, IRBuilderBase &B) {
3956+
if (!CI->hasFnAttr("modular-format"))
3957+
return nullptr;
3958+
3959+
SmallVector<StringRef> Args(
3960+
llvm::split(CI->getFnAttr("modular-format").getValueAsString(), ','));
3961+
// TODO: Examine the format argument in Args[0].
3962+
// TODO: Error handling
3963+
unsigned FirstArgIdx;
3964+
if (!llvm::to_integer(Args[1], FirstArgIdx))
3965+
return nullptr;
3966+
if (FirstArgIdx == 0)
3967+
return nullptr;
3968+
--FirstArgIdx;
3969+
StringRef FnName = Args[2];
3970+
StringRef ImplName = Args[3];
3971+
DenseSet<StringRef> Aspects(llvm::from_range,
3972+
ArrayRef<StringRef>(Args).drop_front(4));
3973+
Module *M = CI->getModule();
3974+
Function *Callee = CI->getCalledFunction();
3975+
FunctionCallee ModularFn =
3976+
M->getOrInsertFunction(FnName, Callee->getFunctionType(),
3977+
Callee->getAttributes().removeFnAttribute(
3978+
M->getContext(), "modular-format"));
3979+
CallInst *New = cast<CallInst>(CI->clone());
3980+
New->setCalledFunction(ModularFn);
3981+
New->removeFnAttr("modular-format");
3982+
B.Insert(New);
3983+
3984+
const auto ReferenceAspect = [&](StringRef Aspect) {
3985+
SmallString<20> Name = ImplName;
3986+
Name += '_';
3987+
Name += Aspect;
3988+
Constant *Sym =
3989+
M->getOrInsertGlobal(Name, Type::getInt8Ty(M->getContext()));
3990+
Function *RelocNoneFn =
3991+
Intrinsic::getOrInsertDeclaration(M, Intrinsic::reloc_none);
3992+
B.CreateCall(RelocNoneFn, {Sym});
3993+
};
3994+
3995+
if (Aspects.contains("float")) {
3996+
Aspects.erase("float");
3997+
if (llvm::any_of(
3998+
llvm::make_range(std::next(CI->arg_begin(), FirstArgIdx),
3999+
CI->arg_end()),
4000+
[](Value *V) { return V->getType()->isFloatingPointTy(); }))
4001+
ReferenceAspect("float");
4002+
}
4003+
4004+
SmallVector<StringRef> UnknownAspects(Aspects.begin(), Aspects.end());
4005+
llvm::sort(UnknownAspects);
4006+
for (StringRef Request : UnknownAspects)
4007+
ReferenceAspect(Request);
4008+
4009+
return New;
4010+
}
4011+
39544012
Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
39554013
if (!CI->getCalledFunction()) return nullptr;
39564014

@@ -3972,6 +4030,10 @@ Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
39724030
++NumSimplified;
39734031
return CI->use_empty() ? CI : replaceInstUsesWith(*CI, With);
39744032
}
4033+
if (Value *With = optimizeModularFormat(CI, Builder)) {
4034+
++NumSimplified;
4035+
return CI->use_empty() ? CI : replaceInstUsesWith(*CI, With);
4036+
}
39754037

39764038
return nullptr;
39774039
}

0 commit comments

Comments
 (0)