1、在社区commit 2813acb7d1将m_Undef同时能识别undefs and poisons后,CSE 中SimplifyICmpInst就能对这些Undef比较的指令进行简化
注意:要求所有向量元素均是undefs 或者 poisons,详见上述patch中的
undef_match
// icmp X, X -> true/false
// icmp X, undef -> true/false because undef could be X.
if (LHS == RHS || Q.isUndefValue(RHS))
return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
2、
PRE 包括CSE和LICM, 基于GVN分析进行优化
.PRE is considered to be a powerful transformation because it subsumes a (full redundancy elimination) transformation like common subexpression elimination (CSE) and loop invariant code motion (LICM) [5].参考
https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.96.4443&rep=rep1&type=pdf
3、PRE和向量化存在冲突,因为Pre创建了反向跨迭代依赖阻止了向量化 (
向量化中循环结点不允许存在IV之外的PHI结点
) 参考
[loop vectorize] failure to vectorize after GVN load-pre · Issue #38583 · llvm/llvm-project · GitHub
4、在 commit bcdcf984cc 中切换默认的GVN方法,
Use ‘-passes=newgvn’ instead of ‘-basic-aa -newgvn’
5、不变量外提需要考虑寄存器压力,因此一些mov类指令会被认为增加寄存器压力而不外提,详见MachineLICM.cpp:IsProfitableToHoist. 但事实上,
寄存器压力评估是不准确的
,比如的寄存器压力实际并不大
[optimization] use vector register to init const float value · Issue #53651 · llvm/llvm-project · GitHub
6、gvn-hoist需要阻止不同类型的loads (same source pointer)进行合并,参考D122521
7、 MachineSinking::isProfitableToSinkTo 中决定指令是否需要sink?
106268 – [suboptimal] Remove unnecessary loops releated to fortran compare to ifort
8、
在LICM中,会根据MSSA、AAResult分析相关指令的alias信息,进而实现循环中store指令的外提, 参考
collectPromotionCandidates
循环不变量外提需要依靠MemorySSA的分析结果,而MemorySSA分析也需要借助AliasAnalysis的结果
。
buildMemorySSA( ) -> 生成默认MemoryUse(value) -> optimizeUsesInBlock( ) (更新MemoryUse(value)的value值)-> … -> instructionClobbersQuery( ) (调用AliasAnalysis获取信息查询指令的Clobber)
MemoryUse
(XX)
对应的MemoryDef
(XX)
是初始默认的Def
9、增强不变量属性invariant的分析,commit 8d0383eb(非必须), 但并不意味着会外提?
需要确保外提后没有寄存器压力的问题
commit 645bdd4b69
SU(6): t62: nxv2f64,ch = LD1RD_IMM<Mem:(dereferenceable
invariant
load (s64)
注意:能外提的指令,显然是要求没有
副作用hasUnmodeledSideEffects()
,在isSafeToMove中判断(注:
默认属性仅对signle pattern tablegen起效
,参考D139637)