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+
39183976Instruction *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