如何使llvm优化以下浮点方程

Tob*_*ner 6 c++ llvm

我有一个小测试程序,它使用llvm来计算某些方程式的值.设置如下:我创建了一个包含添加,乘法,除法,减法和平方双数的函数的bc文件.现在我通过组合加法和乘法函数来设置具有不同参数的线性方程.然后我使用万花筒示例中的优化器转换函数.这很好用 - 结果函数将x作为参数,只进行2次浮点计算(乘法和加法).设置这些功能的代码是:

Function* createLinearFunction(const std::string& name, double factor, double summand, Module* module)
{
    LLVMContext& context = getGlobalContext();

    Function* func = cast<Function>(module->getOrInsertFunction(name.c_str(),Type::getDoubleTy(context),Type::getDoubleTy(context),(Type *)0)); 
    //add basic block
    BasicBlock* bb1 = BasicBlock::Create(context,"EntryBlock",func);
    IRBuilder<> builder(bb1);
    Argument* x0 = func->arg_begin();
    x0->setName("x0");
    Value* x1 = ConstantFP::get(context,APFloat(factor));
    Value* x2 = ConstantFP::get(context,APFloat(summand));
    std::vector<Value*> args1;
    args1.push_back(x0);
    args1.push_back(x1);
    Value* x3 = builder.CreateCall(mul_d_dd,args1,"");
    std::vector<Value*> args2;
    args2.push_back(x2);
    args2.push_back(x3);
    Value* x4 = builder.CreateCall(add_d_dd,args2,"");
    builder.CreateRet(x4);
    return func;
}
Run Code Online (Sandbox Code Playgroud)

我现在想要的是以下内容 - 当我生成一个因子1的函数时,它应该优化乘法,并且使用summand 0它应该优化加法.使用因子0,它应该只返回summand.有通行证已经做到了吗?我只是假设llvm没有这样做,因为这里提到的原因:为什么LLVM不通过优化浮点指令?

谢谢你的帮助Tobias


添加 - 我尝试添加instcombine via createInstructionCombiningPass(),但优化的代码看起来仍然相同:

define double @Linear0xPlus0(double %x0) {
EntryBlock:
  %0 = call double @mul_d_dd(double %x0, double 0.000000e+00)
  %1 = call double @add_d_dd(double 0.000000e+00, double %0)
  ret double %1
}
Run Code Online (Sandbox Code Playgroud)

我现在尝试使用createFuntionInliningPass()- 添加内联传递- 但这会导致断言错误

    FunctionPassManager fpm(module);
    fpm.add(new DataLayout(module->getDataLayout()));
    fpm.add(createFunctionInliningPass());
    fpm.add(createBasicAliasAnalysisPass());
    fpm.add(createInstructionCombiningPass());
    fpm.add(createReassociatePass());
    fpm.add(createGVNPass());
    fpm.add(createCFGSimplificationPass());
    fpm.add(createInstructionCombiningPass());
    fpm.doInitialization();
Run Code Online (Sandbox Code Playgroud)

并得到以下错误: Assertion failed: !PMS.empty() && "Unable to handle Call Graph Pass"

此错误是由于内联不是函数,而是模块优化并且必须在模块优化过程中使用的事实引起的.现在的设置如下所示:

PassManagerBuilder pmb;
pmb.OptLevel=3;
PassManager mpm;
pmb.populateModulePassManager(mpm);
mpm.add(createFunctionInliningPass());
Run Code Online (Sandbox Code Playgroud)

但即使运行第二个函数优化传递包含instcombine传递的所有函数也不起作用

FunctionPassManager instcombiner(module);
instcombiner.add(createInstructionCombiningPass());
instcombiner.doInitialization();
for (auto i=module->begin(); i!=module->end(); ++i)
{
    instcombiner.run(*i);
}
Run Code Online (Sandbox Code Playgroud)

Oak*_*Oak 3

instcombine过程应该执行这些类型的优化,即使对于浮点运算也是如此。

尝试它的一个简单方法是运行opt -instcombine位码文件并检查输出。

  • @TobiasLangner,除非我误解了你,否则这些函数肯定不是内联的 - 你会看到对它们的调用,而不是它们的内容 - `fmul`,`fadd` 等。 (2认同)