I have a small test program that uses llvm to calculate values from some equation. The setup is as follows: I created a bc file containing functions for adding, multiplying, division, subtraction and square double numbers. Now I have installed linear equations with different parameters, combining the functions of addition and multiplication. Then I transform the functions using the optimizers from the kaleidoscope example. This works well - the resulting function takes x as a parameter and only performs 2 floating point calculations (multiply and add). Code to configure these features:
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));
Now I want the following: when I generate a function with a coefficient of 1, it must optimize the multiplication and with the term 0 it should optimize the addition. With a coefficient of 0, it should simply return the term. Is there a pass that already does this? I just assume that llvm does not do this due to the reasons mentioned here: Why doesn't LLVM pass in floating point instruction optimizations?
Thanks for the help Tobias
Addition - I tried adding instcombine via createInstructionCombiningPass() , but the optimized code still looks the same:
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 }
Now I tried adding a nested pass using createFuntionInliningPass() - but this causes an assertion error
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();
and get the following error: Assertion failed: !PMS.empty() && "Unable to handle Call Graph Pass"
This error is caused by the fact that inlining is not a function, but a module optimization and should be used in passing module optimization. The setup for this now looks like this:
PassManagerBuilder pmb; pmb.OptLevel=3; PassManager mpm; pmb.populateModulePassManager(mpm); mpm.add(createFunctionInliningPass());
but even performing the second optimization of a function passes through all functions containing instcombine bandwidth, it does not perform the trick
FunctionPassManager instcombiner(module); instcombiner.add(createInstructionCombiningPass()); instcombiner.doInitialization(); for (auto i=module->begin(); i!=module->end(); ++i) { instcombiner.run(*i); }