Skip to content

Commit 813226e

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 b8e772f commit 813226e

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
@@ -2620,6 +2620,23 @@ For example:
26202620
This attribute indicates that outlining passes should not modify the
26212621
function.
26222622

2623+
``"modular_format"="<string_idx>,<first_idx_to_check>,<modular_impl_fn>,<impl_name>,<aspects...>"``
2624+
This attribute indicates that the implementation is modular on a particular
2625+
format string argument . When the argument for a given call is constant, the
2626+
compiler may redirect the call to a modular implementation function
2627+
instead.
2628+
2629+
The compiler also emits relocations to report various aspects of the format
2630+
string and arguments that were present. The compiler reports an aspect by
2631+
issing a relocation for the symbol `<impl_name>_<aspect>``. This arranges
2632+
for code and data needed to support the aspect of the implementation to be
2633+
brought into the link to satisfy weak references in the modular
2634+
implemenation function.
2635+
2636+
The following aspects are currently supported:
2637+
2638+
- ``float``: The call has a floating point argument
2639+
26232640
Call Site Attributes
26242641
----------------------
26252642

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"
@@ -3915,6 +3916,63 @@ Instruction *InstCombinerImpl::visitCallBrInst(CallBrInst &CBI) {
39153916
return visitCallBase(CBI);
39163917
}
39173918

3919+
static Value *optimizeModularFormat(CallInst *CI, IRBuilderBase &B) {
3920+
if (!CI->hasFnAttr("modular-format"))
3921+
return nullptr;
3922+
3923+
SmallVector<StringRef> Args(
3924+
llvm::split(CI->getFnAttr("modular-format").getValueAsString(), ','));
3925+
// TODO: Examine the format argument in Args[0].
3926+
// TODO: Error handling
3927+
unsigned FirstArgIdx;
3928+
if (!llvm::to_integer(Args[1], FirstArgIdx))
3929+
return nullptr;
3930+
if (FirstArgIdx == 0)
3931+
return nullptr;
3932+
--FirstArgIdx;
3933+
StringRef FnName = Args[2];
3934+
StringRef ImplName = Args[3];
3935+
DenseSet<StringRef> Aspects(llvm::from_range,
3936+
ArrayRef<StringRef>(Args).drop_front(4));
3937+
Module *M = CI->getModule();
3938+
Function *Callee = CI->getCalledFunction();
3939+
FunctionCallee ModularFn =
3940+
M->getOrInsertFunction(FnName, Callee->getFunctionType(),
3941+
Callee->getAttributes().removeFnAttribute(
3942+
M->getContext(), "modular-format"));
3943+
CallInst *New = cast<CallInst>(CI->clone());
3944+
New->setCalledFunction(ModularFn);
3945+
New->removeFnAttr("modular-format");
3946+
B.Insert(New);
3947+
3948+
const auto ReferenceAspect = [&](StringRef Aspect) {
3949+
SmallString<20> Name = ImplName;
3950+
Name += '_';
3951+
Name += Aspect;
3952+
Constant *Sym =
3953+
M->getOrInsertGlobal(Name, Type::getInt8Ty(M->getContext()));
3954+
Function *RelocNoneFn =
3955+
Intrinsic::getOrInsertDeclaration(M, Intrinsic::reloc_none);
3956+
B.CreateCall(RelocNoneFn, {Sym});
3957+
};
3958+
3959+
if (Aspects.contains("float")) {
3960+
Aspects.erase("float");
3961+
if (llvm::any_of(
3962+
llvm::make_range(std::next(CI->arg_begin(), FirstArgIdx),
3963+
CI->arg_end()),
3964+
[](Value *V) { return V->getType()->isFloatingPointTy(); }))
3965+
ReferenceAspect("float");
3966+
}
3967+
3968+
SmallVector<StringRef> UnknownAspects(Aspects.begin(), Aspects.end());
3969+
llvm::sort(UnknownAspects);
3970+
for (StringRef Request : UnknownAspects)
3971+
ReferenceAspect(Request);
3972+
3973+
return New;
3974+
}
3975+
39183976
Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
39193977
if (!CI->getCalledFunction()) return nullptr;
39203978

@@ -3936,6 +3994,10 @@ Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
39363994
++NumSimplified;
39373995
return CI->use_empty() ? CI : replaceInstUsesWith(*CI, With);
39383996
}
3997+
if (Value *With = optimizeModularFormat(CI, Builder)) {
3998+
++NumSimplified;
3999+
return CI->use_empty() ? CI : replaceInstUsesWith(*CI, With);
4000+
}
39394001

39404002
return nullptr;
39414003
}

0 commit comments

Comments
 (0)