055、CSE(公共子表达式消除)在MLIR中的实现
055、CSE(公共子表达式消除)在MLIR中的实现从一次诡异的性能回退说起去年调一个AI推理引擎,模型跑在自研NPU上,性能死活上不去。同事把IR dump出来给我看,我一眼就发现了一个“经典”问题:同一个add操作,在循环里被重复计算了三次。更离谱的是,其中两次的输入完全一样,只是中间隔了几个无关的relu。当时我就想,MLIR的CSE(Common Subexpression Elimination)不是默认开启的吗?怎么没起作用?后来追进去看,发现是pass pipeline顺序的问题——CSE跑得太早,后续的某些pattern匹配又把表达式给“拆”开了。这个坑让我意识到,CSE在MLIR里远不是“把相同操作合并”那么简单。今天我们就从MLIR的视角,把CSE的里里外外扒一遍。MLIR的CSE和LLVM的CSE有什么不同?如果你写过LLVM pass,会知道LLVM的CSE是基于SSA形式的,通过DominatorTree和ValueTracking来判定两个表达式是否等价。MLIR的CSE思路类似,但有几个关键差异:MLIR的操作是“带方言”的——两个arith.addi长得一样,但一个在linalgregion里,一个在scfregion里,能不能合并?MLIR的CSE会考