Skip to content

Commit bb3b826

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 0ca07a8 commit bb3b826

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
@@ -2742,6 +2742,23 @@ For example:
27422742
This attribute indicates that outlining passes should not modify the
27432743
function.
27442744

2745+
``"modular_format"="<string_idx>,<first_idx_to_check>,<modular_impl_fn>,<impl_name>,<aspects...>"``
2746+
This attribute indicates that the implementation is modular on a particular
2747+
format string argument . When the argument for a given call is constant, the
2748+
compiler may redirect the call to a modular implementation function
2749+
instead.
2750+
2751+
The compiler also emits relocations to report various aspects of the format
2752+
string and arguments that were present. The compiler reports an aspect by
2753+
issing a relocation for the symbol `<impl_name>_<aspect>``. This arranges
2754+
for code and data needed to support the aspect of the implementation to be
2755+
brought into the link to satisfy weak references in the modular
2756+
implemenation function.
2757+
2758+
The following aspects are currently supported:
2759+
2760+
- ``float``: The call has a floating point argument
2761+
27452762
Call Site Attributes
27462763
----------------------
27472764

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"
@@ -4071,6 +4072,63 @@ Instruction *InstCombinerImpl::visitCallBrInst(CallBrInst &CBI) {
40714072
return visitCallBase(CBI);
40724073
}
40734074

4075+
static Value *optimizeModularFormat(CallInst *CI, IRBuilderBase &B) {
4076+
if (!CI->hasFnAttr("modular-format"))
4077+
return nullptr;
4078+
4079+
SmallVector<StringRef> Args(
4080+
llvm::split(CI->getFnAttr("modular-format").getValueAsString(), ','));
4081+
// TODO: Examine the format argument in Args[0].
4082+
// TODO: Error handling
4083+
unsigned FirstArgIdx;
4084+
if (!llvm::to_integer(Args[1], FirstArgIdx))
4085+
return nullptr;
4086+
if (FirstArgIdx == 0)
4087+
return nullptr;
4088+
--FirstArgIdx;
4089+
StringRef FnName = Args[2];
4090+
StringRef ImplName = Args[3];
4091+
DenseSet<StringRef> Aspects(llvm::from_range,
4092+
ArrayRef<StringRef>(Args).drop_front(4));
4093+
Module *M = CI->getModule();
4094+
Function *Callee = CI->getCalledFunction();
4095+
FunctionCallee ModularFn =
4096+
M->getOrInsertFunction(FnName, Callee->getFunctionType(),
4097+
Callee->getAttributes().removeFnAttribute(
4098+
M->getContext(), "modular-format"));
4099+
CallInst *New = cast<CallInst>(CI->clone());
4100+
New->setCalledFunction(ModularFn);
4101+
New->removeFnAttr("modular-format");
4102+
B.Insert(New);
4103+
4104+
const auto ReferenceAspect = [&](StringRef Aspect) {
4105+
SmallString<20> Name = ImplName;
4106+
Name += '_';
4107+
Name += Aspect;
4108+
Constant *Sym =
4109+
M->getOrInsertGlobal(Name, Type::getInt8Ty(M->getContext()));
4110+
Function *RelocNoneFn =
4111+
Intrinsic::getOrInsertDeclaration(M, Intrinsic::reloc_none);
4112+
B.CreateCall(RelocNoneFn, {Sym});
4113+
};
4114+
4115+
if (Aspects.contains("float")) {
4116+
Aspects.erase("float");
4117+
if (llvm::any_of(
4118+
llvm::make_range(std::next(CI->arg_begin(), FirstArgIdx),
4119+
CI->arg_end()),
4120+
[](Value *V) { return V->getType()->isFloatingPointTy(); }))
4121+
ReferenceAspect("float");
4122+
}
4123+
4124+
SmallVector<StringRef> UnknownAspects(Aspects.begin(), Aspects.end());
4125+
llvm::sort(UnknownAspects);
4126+
for (StringRef Request : UnknownAspects)
4127+
ReferenceAspect(Request);
4128+
4129+
return New;
4130+
}
4131+
40744132
Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
40754133
if (!CI->getCalledFunction()) return nullptr;
40764134

@@ -4092,6 +4150,10 @@ Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
40924150
++NumSimplified;
40934151
return CI->use_empty() ? CI : replaceInstUsesWith(*CI, With);
40944152
}
4153+
if (Value *With = optimizeModularFormat(CI, Builder)) {
4154+
++NumSimplified;
4155+
return CI->use_empty() ? CI : replaceInstUsesWith(*CI, With);
4156+
}
40954157

40964158
return nullptr;
40974159
}

0 commit comments

Comments
 (0)