相关疑难解决方法(0)

为什么GCC不优化a*a*a*a*a*a到(a*a*a)*(a*a*a)?

我正在对科学应用进行一些数值优化.我注意到的一件事是GCC会pow(a,2)通过编译来优化调用a*a,但调用pow(a,6)没有优化,实际上会调用库函数pow,这会大大降低性能.(相比之下,英特尔C++编译器,可执行文件icc,将消除库调用pow(a,6).)

我很好奇的是,当我更换pow(a,6)a*a*a*a*a*a使用GCC 4.5.1和选项" -O3 -lm -funroll-loops -msse4",它采用5分mulsd的说明:

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
Run Code Online (Sandbox Code Playgroud)

如果我写(a*a*a)*(a*a*a),它会产生

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm13, %xmm13
Run Code Online (Sandbox Code Playgroud)

这将乘法指令的数量减少到3. icc具有类似的行为.

为什么编译器不能识别这种优化技巧?

floating-point assembly gcc compiler-optimization fast-math

2083
推荐指数
12
解决办法
20万
查看次数

如何使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 …
Run Code Online (Sandbox Code Playgroud)

c++ llvm

6
推荐指数
1
解决办法
523
查看次数