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