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"
@@ -4091,6 +4092,63 @@ Instruction *InstCombinerImpl::visitCallBrInst(CallBrInst &CBI) {
40914092 return visitCallBase (CBI);
40924093}
40934094
4095+ static Value *optimizeModularFormat (CallInst *CI, IRBuilderBase &B) {
4096+ if (!CI->hasFnAttr (" modular-format" ))
4097+ return nullptr ;
4098+
4099+ SmallVector<StringRef> Args (
4100+ llvm::split (CI->getFnAttr (" modular-format" ).getValueAsString (), ' ,' ));
4101+ // TODO: Examine the format argument in Args[0].
4102+ // TODO: Error handling
4103+ unsigned FirstArgIdx;
4104+ if (!llvm::to_integer (Args[1 ], FirstArgIdx))
4105+ return nullptr ;
4106+ if (FirstArgIdx == 0 )
4107+ return nullptr ;
4108+ --FirstArgIdx;
4109+ StringRef FnName = Args[2 ];
4110+ StringRef ImplName = Args[3 ];
4111+ DenseSet<StringRef> Aspects (llvm::from_range,
4112+ ArrayRef<StringRef>(Args).drop_front (4 ));
4113+ Module *M = CI->getModule ();
4114+ Function *Callee = CI->getCalledFunction ();
4115+ FunctionCallee ModularFn =
4116+ M->getOrInsertFunction (FnName, Callee->getFunctionType (),
4117+ Callee->getAttributes ().removeFnAttribute (
4118+ M->getContext (), " modular-format" ));
4119+ CallInst *New = cast<CallInst>(CI->clone ());
4120+ New->setCalledFunction (ModularFn);
4121+ New->removeFnAttr (" modular-format" );
4122+ B.Insert (New);
4123+
4124+ const auto ReferenceAspect = [&](StringRef Aspect) {
4125+ SmallString<20 > Name = ImplName;
4126+ Name += ' _' ;
4127+ Name += Aspect;
4128+ Constant *Sym =
4129+ M->getOrInsertGlobal (Name, Type::getInt8Ty (M->getContext ()));
4130+ Function *RelocNoneFn =
4131+ Intrinsic::getOrInsertDeclaration (M, Intrinsic::reloc_none);
4132+ B.CreateCall (RelocNoneFn, {Sym});
4133+ };
4134+
4135+ if (Aspects.contains (" float" )) {
4136+ Aspects.erase (" float" );
4137+ if (llvm::any_of (
4138+ llvm::make_range (std::next (CI->arg_begin (), FirstArgIdx),
4139+ CI->arg_end ()),
4140+ [](Value *V) { return V->getType ()->isFloatingPointTy (); }))
4141+ ReferenceAspect (" float" );
4142+ }
4143+
4144+ SmallVector<StringRef> UnknownAspects (Aspects.begin (), Aspects.end ());
4145+ llvm::sort (UnknownAspects);
4146+ for (StringRef Request : UnknownAspects)
4147+ ReferenceAspect (Request);
4148+
4149+ return New;
4150+ }
4151+
40944152Instruction *InstCombinerImpl::tryOptimizeCall (CallInst *CI) {
40954153 if (!CI->getCalledFunction ()) return nullptr ;
40964154
@@ -4112,6 +4170,10 @@ Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
41124170 ++NumSimplified;
41134171 return CI->use_empty () ? CI : replaceInstUsesWith (*CI, With);
41144172 }
4173+ if (Value *With = optimizeModularFormat (CI, Builder)) {
4174+ ++NumSimplified;
4175+ return CI->use_empty () ? CI : replaceInstUsesWith (*CI, With);
4176+ }
41154177
41164178 return nullptr ;
41174179}
0 commit comments