LLVM DAG中常量在Lowering阶段变更,如何阻止该变更?
阻止LLVM Lowering阶段DAG常量变更的方法
1. 精准禁用DAG Combine相关优化
如果常量变更是在DAG Combine阶段发生的:
- 全局禁用(不推荐,影响性能):编译时添加命令行选项
disable-dag-combiner - 精细控制:修改LLVM源码
DAGCombiner.cpp,找到处理AND指令或常量折叠的逻辑,添加条件跳过对i8类型-32的处理。例如:// 在DAG组合逻辑中添加判断 if (Op.getOpcode() == ISD::AND) { SDValue ConstOp = Op.getOperand(1); if (ConstOp.isConstant() && ConstOp.getValueType() == MVT::i8 && cast<ConstantSDNode>(ConstOp)->getSExtValue() == -32) { return SDValue(); // 跳过当前组合逻辑 } }
2. 调整LegalizeDAG阶段的常量合法性规则
若变更发生在Legalize阶段,通常是目标架构对有符号常量的处理规则导致:
- 在目标架构的
XXXLegalizerInfo.cpp文件中,修改getLegality或常量合法化逻辑,标记i8类型的-32为合法常量,避免被转换为无符号形式。例如:// 在目标LegalizerInfo初始化中添加 getActions().setLegal({MVT::i8, /* 对应常量-32的规则 */});
3. 在IR层强制保留常量形式
通过IR编码方式避免常量被自动转换:
- 将常量定义为全局常量,而非直接使用字面量:
全局常量在Lowering阶段更难被自动修改。@neg32_i8 = constant i8 -32 ... %bf.clear = and i8 %bf.load, @neg32_i8
4. 自定义目标Lowering逻辑
针对目标架构的TargetLowering.cpp,重写LowerOperation方法,拦截AND指令并保留目标常量:
SDValue XXXTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { case ISD::AND: { SDValue Op1 = Op.getOperand(1); if (Op1.isConstant() && Op1.getValueType() == MVT::i8 && cast<ConstantSDNode>(Op1)->getSExtValue() == -32) { return Op; // 直接返回原指令,不做修改 } // 其他正常Lower逻辑 break; } // 其他指令处理 } return TargetLowering::LowerOperation(Op, DAG); }
提示:先通过
-view-dag-combine1-dags和-view-legalize-dags确认变更发生的具体阶段,再针对性处理。
内容的提问来源于stack exchange,提问作者xiaoroubao
相关产品推荐
相关产品推荐

