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"
@@ -3951,6 +3952,63 @@ Instruction *InstCombinerImpl::visitCallBrInst(CallBrInst &CBI) {
39513952 return visitCallBase (CBI);
39523953}
39533954
3955+ static Value *optimizeModularFormat (CallInst *CI, IRBuilderBase &B) {
3956+ if (!CI->hasFnAttr (" modular-format" ))
3957+ return nullptr ;
3958+
3959+ SmallVector<StringRef> Args (
3960+ llvm::split (CI->getFnAttr (" modular-format" ).getValueAsString (), ' ,' ));
3961+ // TODO: Examine the format argument in Args[0].
3962+ // TODO: Error handling
3963+ unsigned FirstArgIdx;
3964+ if (!llvm::to_integer (Args[1 ], FirstArgIdx))
3965+ return nullptr ;
3966+ if (FirstArgIdx == 0 )
3967+ return nullptr ;
3968+ --FirstArgIdx;
3969+ StringRef FnName = Args[2 ];
3970+ StringRef ImplName = Args[3 ];
3971+ DenseSet<StringRef> Aspects (llvm::from_range,
3972+ ArrayRef<StringRef>(Args).drop_front (4 ));
3973+ Module *M = CI->getModule ();
3974+ Function *Callee = CI->getCalledFunction ();
3975+ FunctionCallee ModularFn =
3976+ M->getOrInsertFunction (FnName, Callee->getFunctionType (),
3977+ Callee->getAttributes ().removeFnAttribute (
3978+ M->getContext (), " modular-format" ));
3979+ CallInst *New = cast<CallInst>(CI->clone ());
3980+ New->setCalledFunction (ModularFn);
3981+ New->removeFnAttr (" modular-format" );
3982+ B.Insert (New);
3983+
3984+ const auto ReferenceAspect = [&](StringRef Aspect) {
3985+ SmallString<20 > Name = ImplName;
3986+ Name += ' _' ;
3987+ Name += Aspect;
3988+ Constant *Sym =
3989+ M->getOrInsertGlobal (Name, Type::getInt8Ty (M->getContext ()));
3990+ Function *RelocNoneFn =
3991+ Intrinsic::getOrInsertDeclaration (M, Intrinsic::reloc_none);
3992+ B.CreateCall (RelocNoneFn, {Sym});
3993+ };
3994+
3995+ if (Aspects.contains (" float" )) {
3996+ Aspects.erase (" float" );
3997+ if (llvm::any_of (
3998+ llvm::make_range (std::next (CI->arg_begin (), FirstArgIdx),
3999+ CI->arg_end ()),
4000+ [](Value *V) { return V->getType ()->isFloatingPointTy (); }))
4001+ ReferenceAspect (" float" );
4002+ }
4003+
4004+ SmallVector<StringRef> UnknownAspects (Aspects.begin (), Aspects.end ());
4005+ llvm::sort (UnknownAspects);
4006+ for (StringRef Request : UnknownAspects)
4007+ ReferenceAspect (Request);
4008+
4009+ return New;
4010+ }
4011+
39544012Instruction *InstCombinerImpl::tryOptimizeCall (CallInst *CI) {
39554013 if (!CI->getCalledFunction ()) return nullptr ;
39564014
@@ -3972,6 +4030,10 @@ Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
39724030 ++NumSimplified;
39734031 return CI->use_empty () ? CI : replaceInstUsesWith (*CI, With);
39744032 }
4033+ if (Value *With = optimizeModularFormat (CI, Builder)) {
4034+ ++NumSimplified;
4035+ return CI->use_empty () ? CI : replaceInstUsesWith (*CI, With);
4036+ }
39754037
39764038 return nullptr ;
39774039}
0 commit comments