Skip to content

Commit 40bafe2

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 341dd6a commit 40bafe2

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
@@ -2635,6 +2635,23 @@ For example:
26352635
This attribute indicates that outlining passes should not modify the
26362636
function.
26372637

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

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"
@@ -4001,6 +4002,63 @@ Instruction *InstCombinerImpl::visitCallBrInst(CallBrInst &CBI) {
40014002
return visitCallBase(CBI);
40024003
}
40034004

4005+
static Value *optimizeModularFormat(CallInst *CI, IRBuilderBase &B) {
4006+
if (!CI->hasFnAttr("modular-format"))
4007+
return nullptr;
4008+
4009+
SmallVector<StringRef> Args(
4010+
llvm::split(CI->getFnAttr("modular-format").getValueAsString(), ','));
4011+
// TODO: Examine the format argument in Args[0].
4012+
// TODO: Error handling
4013+
unsigned FirstArgIdx;
4014+
if (!llvm::to_integer(Args[1], FirstArgIdx))
4015+
return nullptr;
4016+
if (FirstArgIdx == 0)
4017+
return nullptr;
4018+
--FirstArgIdx;
4019+
StringRef FnName = Args[2];
4020+
StringRef ImplName = Args[3];
4021+
DenseSet<StringRef> Aspects(llvm::from_range,
4022+
ArrayRef<StringRef>(Args).drop_front(4));
4023+
Module *M = CI->getModule();
4024+
Function *Callee = CI->getCalledFunction();
4025+
FunctionCallee ModularFn =
4026+
M->getOrInsertFunction(FnName, Callee->getFunctionType(),
4027+
Callee->getAttributes().removeFnAttribute(
4028+
M->getContext(), "modular-format"));
4029+
CallInst *New = cast<CallInst>(CI->clone());
4030+
New->setCalledFunction(ModularFn);
4031+
New->removeFnAttr("modular-format");
4032+
B.Insert(New);
4033+
4034+
const auto ReferenceAspect = [&](StringRef Aspect) {
4035+
SmallString<20> Name = ImplName;
4036+
Name += '_';
4037+
Name += Aspect;
4038+
Constant *Sym =
4039+
M->getOrInsertGlobal(Name, Type::getInt8Ty(M->getContext()));
4040+
Function *RelocNoneFn =
4041+
Intrinsic::getOrInsertDeclaration(M, Intrinsic::reloc_none);
4042+
B.CreateCall(RelocNoneFn, {Sym});
4043+
};
4044+
4045+
if (Aspects.contains("float")) {
4046+
Aspects.erase("float");
4047+
if (llvm::any_of(
4048+
llvm::make_range(std::next(CI->arg_begin(), FirstArgIdx),
4049+
CI->arg_end()),
4050+
[](Value *V) { return V->getType()->isFloatingPointTy(); }))
4051+
ReferenceAspect("float");
4052+
}
4053+
4054+
SmallVector<StringRef> UnknownAspects(Aspects.begin(), Aspects.end());
4055+
llvm::sort(UnknownAspects);
4056+
for (StringRef Request : UnknownAspects)
4057+
ReferenceAspect(Request);
4058+
4059+
return New;
4060+
}
4061+
40044062
Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
40054063
if (!CI->getCalledFunction()) return nullptr;
40064064

@@ -4022,6 +4080,10 @@ Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
40224080
++NumSimplified;
40234081
return CI->use_empty() ? CI : replaceInstUsesWith(*CI, With);
40244082
}
4083+
if (Value *With = optimizeModularFormat(CI, Builder)) {
4084+
++NumSimplified;
4085+
return CI->use_empty() ? CI : replaceInstUsesWith(*CI, With);
4086+
}
40254087

40264088
return nullptr;
40274089
}

0 commit comments

Comments
 (0)