Skip to content

Commit d7e4f8f

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 b76a6c3 commit d7e4f8f

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

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

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)