// 只支持 X86
static cl::opt<bool> SimplifyRODataLoads("simplify-rodata-loads",cl::desc("通过用相应节中找到的常数替换内存操作数,简化来自只读节的加载"),cl::cat(BoltOptCategory));
测试用例:
./build4/bin/llvm-lit bolt/test/X86/rodata-simpl-loads.test -a
# bolt/test/X86/Inputs/rodata_simpl_loads.s
效果(立即数代替了地址(少了寻址过程)
):
bool SimplifyRODataLoads::simplifyRODataLoads(BinaryFunction &BF) {// 对所以可能加载内存的操作Desc.mayLoad()// 如果是 PC 相关的指令if (MIB->hasPCRelOperand(Inst)) {// 获取内存操作数的偏移MCOperand *DispOpI = MIB->getMemOperandDisp(Inst);// 通过内存操作数获取目标符号与偏移std::tie(DisplSymbol, DisplOffset) = MIB->getTargetSymbolInfo(DispOpI->getExpr());// 通过偏移符号获取 BinaryDataBinaryData *BD = BC.getBinaryDataByName(DisplSymbol->getName());// 起始地址加偏移获取目的地址TargetAddress = BD->getAddress() + DisplOffset;}// 不然直接通过接口获取else if (!MIB->evaluateMemOperandTarget(Inst, TargetAddress))// 根据目标地址获取Sec, 只处理只读节BC.getSectionForAddress(TargetAddress);// 如果目标地址需要重定位或需要动态重定位(链接时数据可能会更改) -- 无法处理// 计算节省的动态加载的次数NumDynamicLocalLoadsFound += BB->getExecutionCount();// 最后的替换动作 -- 只支持x86MIB->replaceMemOperandWithImm(Inst, ConstantData, Offset)
}
遗留问题:
- arm 能否实现相同场景的优化
- 是否可以放到链接时做