19
19
#include " llvm/ADT/SmallBitVector.h"
20
20
#include " llvm/ADT/SmallVector.h"
21
21
#include " llvm/ADT/Statistic.h"
22
+ #include " llvm/ADT/StringExtras.h"
22
23
#include " llvm/Analysis/AliasAnalysis.h"
23
24
#include " llvm/Analysis/AssumeBundleQueries.h"
24
25
#include " llvm/Analysis/AssumptionCache.h"
@@ -3915,6 +3916,63 @@ Instruction *InstCombinerImpl::visitCallBrInst(CallBrInst &CBI) {
3915
3916
return visitCallBase (CBI);
3916
3917
}
3917
3918
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
+
3918
3976
Instruction *InstCombinerImpl::tryOptimizeCall (CallInst *CI) {
3919
3977
if (!CI->getCalledFunction ()) return nullptr ;
3920
3978
@@ -3936,6 +3994,10 @@ Instruction *InstCombinerImpl::tryOptimizeCall(CallInst *CI) {
3936
3994
++NumSimplified;
3937
3995
return CI->use_empty () ? CI : replaceInstUsesWith (*CI, With);
3938
3996
}
3997
+ if (Value *With = optimizeModularFormat (CI, Builder)) {
3998
+ ++NumSimplified;
3999
+ return CI->use_empty () ? CI : replaceInstUsesWith (*CI, With);
4000
+ }
3939
4001
3940
4002
return nullptr ;
3941
4003
}
0 commit comments