[Beignet] [PATCH 1/2] Move the llvm optimize pass from clang to backend.
Yang, Rong R
rong.r.yang at intel.com
Mon Dec 30 23:04:05 PST 2013
There is bugs in FunctionArgumentLowerer::buildConstantPush, and this patch will trigger it. I have sent a new patch to fix. Thanks.
-----Original Message-----
From: Zhigang Gong [mailto:zhigang.gong at linux.intel.com]
Sent: Tuesday, December 31, 2013 11:20 AM
To: Yang, Rong R
Cc: beignet at lists.freedesktop.org
Subject: Re: [Beignet] [PATCH 1/2] Move the llvm optimize pass from clang to backend.
This patch causes one regression when run all the utest:
compiler_function_argument3:
compiler_function_argument3() [FAILED]
Error: dst[0].h == 7.0f
at file /home/gongzg/git/fdo/beignet/utests/compiler_function_argument3.cpp, function compiler_function_argument3, line 40
If run this single test case, it passes. Could you check it again? Thanks.
On Thu, Dec 26, 2013 at 09:55:54AM +0800, Yang Rong wrote:
> Call llvm opt pass in llvmToGen. Remove SROA pass and call GVN pass
> with NoLoads is true to avoid large integer. Also handle the opt level
> in function llvmToGen, 0 equal to clang -O1, and 1 equal to clang -O2.
>
> Signed-off-by: Yang Rong <rong.r.yang at intel.com>
> ---
> backend/src/backend/gen_program.cpp | 5 +-
> backend/src/backend/program.cpp | 23 ++++----
> backend/src/backend/program.h | 3 +-
> backend/src/backend/program.hpp | 2 +-
> backend/src/llvm/llvm_to_gen.cpp | 102 ++++++++++++++++++++++++++++++++++--
> backend/src/llvm/llvm_to_gen.hpp | 5 +-
> src/cl_program.c | 2 +-
> 7 files changed, 119 insertions(+), 23 deletions(-)
>
> diff --git a/backend/src/backend/gen_program.cpp
> b/backend/src/backend/gen_program.cpp
> index e0a6f91..22f4aa1 100644
> --- a/backend/src/backend/gen_program.cpp
> +++ b/backend/src/backend/gen_program.cpp
> @@ -151,13 +151,14 @@ namespace gbe {
> static gbe_program genProgramNewFromLLVM(const char *fileName,
> size_t stringSize,
> char *err,
> - size_t *errSize)
> + size_t *errSize,
> + int optLevel)
> {
> using namespace gbe;
> GenProgram *program = GBE_NEW_NO_ARG(GenProgram);
> std::string error;
> // Try to compile the program
> - if (program->buildFromLLVMFile(fileName, error) == false) {
> + if (program->buildFromLLVMFile(fileName, error, optLevel) ==
> + false) {
> if (err != NULL && errSize != NULL && stringSize > 0u) {
> const size_t msgSize = std::min(error.size(), stringSize-1u);
> std::memcpy(err, error.c_str(), msgSize); diff --git
> a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
> index 46ec04f..3ab1bc2 100644
> --- a/backend/src/backend/program.cpp
> +++ b/backend/src/backend/program.cpp
> @@ -102,9 +102,9 @@ namespace gbe {
>
> BVAR(OCL_OUTPUT_GEN_IR, false);
>
> - bool Program::buildFromLLVMFile(const char *fileName, std::string
> &error) {
> + bool Program::buildFromLLVMFile(const char *fileName, std::string
> + &error, int optLevel) {
> ir::Unit unit;
> - if (llvmToGen(unit, fileName) == false) {
> + if (llvmToGen(unit, fileName, optLevel) == false) {
> error = std::string(fileName) + " not found";
> return false;
> }
> @@ -469,7 +469,6 @@ namespace gbe {
> size_t stringSize, char *err, size_t *errSize) {
> // Arguments to pass to the clang frontend
> vector<const char *> args;
> - bool bOpt = true;
> bool bFastMath = false;
>
> vector<std::string> useless; //hold substrings to avoid c_str
> free @@ -480,7 +479,8 @@ namespace gbe {
> -cl-no-signed-zeros, -cl-fp32-correctly-rounded-divide-sqrt
> all support options, refer to clang/include/clang/Driver/Options.inc
> */
> - const std::string unsupportedOptions("-cl-denorms-are-zero, -cl-strict-aliasing,"
> + //Handle -cl-opt-disable in llvmToGen, skip here
> + const std::string unsupportedOptions("-cl-denorms-are-zero, -cl-strict-aliasing, -cl-opt-disable,"
> "-cl-no-signed-zeros, -cl-fp32-correctly-rounded-divide-sqrt");
> while (end != std::string::npos) {
> end = options.find(' ', start); @@ -488,7 +488,6 @@ namespace
> gbe {
> start = end + 1;
> if(str.size() == 0)
> continue;
> - if(str == "-cl-opt-disable") bOpt = false;
> if(str == "-cl-fast-relaxed-math") bFastMath = true;
> if(unsupportedOptions.find(str) != std::string::npos)
> continue;
> @@ -504,12 +503,7 @@ namespace gbe {
> // FIXME we haven't implement those builtin functions,
> // so disable it currently.
> args.push_back("-fno-builtin");
> - // FIXME as we don't support function call currently, we may encounter
> - // build problem with -O0 as we rely on always inline all functions option.
> - if(bOpt)
> - args.push_back("-O2");
> - else
> - args.push_back("-O1");
> + args.push_back("-disable-llvm-optzns");
> if(bFastMath)
> args.push_back("-D __FAST_RELAXED_MATH__=1"); #if
> LLVM_VERSION_MINOR <= 2 @@ -659,6 +653,7 @@ namespace gbe {
> const std::string llName = std::string(tmpnam_r(llStr)) + ".ll"; /* unsafe! */
> std::string pchHeaderName;
> std::string clOpt;
> + int optLevel = 1;
>
> FILE *clFile = fopen(clName.c_str(), "w");
> FATAL_IF(clFile == NULL, "Failed to open temporary file"); @@
> -728,6 +723,10 @@ namespace gbe {
> }
> }
>
> + p = strstr(const_cast<char *>(options), "-cl-opt-disable");
> + if (p)
> + optLevel = 0;
> +
> clOpt += options;
> }
>
> @@ -766,7 +765,7 @@ namespace gbe {
> clangErrSize = *errSize;
> }
> p = gbe_program_new_from_llvm(llName.c_str(), stringSize,
> - err, errSize);
> + err, errSize, optLevel);
> if (err != NULL)
> *errSize += clangErrSize;
> gbe_mutex.unlock();
> diff --git a/backend/src/backend/program.h
> b/backend/src/backend/program.h index e574764..d00ea51 100644
> --- a/backend/src/backend/program.h
> +++ b/backend/src/backend/program.h
> @@ -130,7 +130,8 @@ extern gbe_program_serialize_to_binary_cb
> *gbe_program_serialize_to_binary; typedef gbe_program (gbe_program_new_from_llvm_cb)(const char *fileName,
> size_t string_size,
> char *err,
> - size_t *err_size);
> + size_t *err_size,
> + int optLevel);
> extern gbe_program_new_from_llvm_cb *gbe_program_new_from_llvm;
>
> /*! Get the size of global constants */ diff --git
> a/backend/src/backend/program.hpp b/backend/src/backend/program.hpp
> index 0f88742..e6fc411 100644
> --- a/backend/src/backend/program.hpp
> +++ b/backend/src/backend/program.hpp
> @@ -231,7 +231,7 @@ namespace gbe {
> /*! Build a program from a ir::Unit */
> bool buildFromUnit(const ir::Unit &unit, std::string &error);
> /*! Buils a program from a LLVM source code */
> - bool buildFromLLVMFile(const char *fileName, std::string &error);
> + bool buildFromLLVMFile(const char *fileName, std::string &error,
> + int optLevel);
> /*! Buils a program from a OCL string */
> bool buildFromSource(const char *source, std::string &error);
> /*! Get size of the global constant arrays */ diff --git
> a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp
> index e11e449..a9f70d9 100644
> --- a/backend/src/llvm/llvm_to_gen.cpp
> +++ b/backend/src/llvm/llvm_to_gen.cpp
> @@ -1,4 +1,4 @@
> -/*
> +/*
> * Copyright (c) 2012 Intel Corporation
> *
> * This library is free software; you can redistribute it and/or @@
> -26,12 +26,19 @@ #if LLVM_VERSION_MINOR <= 2 #include
> "llvm/LLVMContext.h"
> #include "llvm/Module.h"
> +#include "llvm/DataLayout.h"
> #else
> #include "llvm/IR/LLVMContext.h"
> #include "llvm/IR/Module.h"
> +#include "llvm/IR/DataLayout.h"
> #endif /* LLVM_VERSION_MINOR <= 2 */ #include "llvm/PassManager.h"
> #include "llvm/Pass.h"
> +#include "llvm/Analysis/Verifier.h"
> +#include "llvm/Analysis/Passes.h"
> +#include "llvm/Transforms/IPO.h"
> +#include "llvm/Target/TargetLibraryInfo.h"
> +#include "llvm/ADT/Triple.h"
> #if LLVM_VERSION_MINOR <= 2
> #include "llvm/Support/IRReader.h"
> #else
> @@ -56,11 +63,92 @@ namespace gbe
> {
> BVAR(OCL_OUTPUT_LLVM, false);
> BVAR(OCL_OUTPUT_LLVM_BEFORE_EXTRA_PASS, false);
> + using namespace llvm;
>
> - bool llvmToGen(ir::Unit &unit, const char *fileName)
> + void runFuntionPass(Module &mod, TargetLibraryInfo *libraryInfo)
> {
> - using namespace llvm;
> + FunctionPassManager FPM(&mod);
> + FPM.add(new DataLayout(&mod));
> + FPM.add(createVerifierPass());
> + FPM.add(new TargetLibraryInfo(*libraryInfo));
> + FPM.add(createTypeBasedAliasAnalysisPass());
> + FPM.add(createBasicAliasAnalysisPass());
> + FPM.add(createCFGSimplificationPass());
> + FPM.add(createSROAPass());
> + FPM.add(createEarlyCSEPass());
> + FPM.add(createLowerExpectIntrinsicPass());
>
> + FPM.doInitialization();
> + for (Module::iterator I = mod.begin(),
> + E = mod.end(); I != E; ++I)
> + if (!I->isDeclaration())
> + FPM.run(*I);
> + FPM.doFinalization();
> + }
> +
> + void runModulePass(Module &mod, TargetLibraryInfo *libraryInfo, int
> + optLevel) {
> + llvm::PassManager MPM;
> +
> + MPM.add(new DataLayout(&mod));
> + MPM.add(new TargetLibraryInfo(*libraryInfo));
> + MPM.add(createTypeBasedAliasAnalysisPass());
> + MPM.add(createBasicAliasAnalysisPass());
> + MPM.add(createGlobalOptimizerPass()); // Optimize out global vars
> +
> + MPM.add(createIPSCCPPass()); // IP SCCP
> + MPM.add(createDeadArgEliminationPass()); // Dead argument
> + elimination
> +
> + MPM.add(createInstructionCombiningPass());// Clean up after IPCP & DAE
> + MPM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE
> + MPM.add(createPruneEHPass()); // Remove dead EH info
> + MPM.add(createFunctionInliningPass(200000));
> + MPM.add(createFunctionAttrsPass()); // Set readonly/readnone attrs
> +
> + //MPM.add(createScalarReplAggregatesPass(64, true, -1, -1, 64))
> + //MPM.add(createSROAPass(/*RequiresDomTree*/ false));
> + MPM.add(createEarlyCSEPass()); // Catch trivial redundancies
> + MPM.add(createJumpThreadingPass()); // Thread jumps.
> + MPM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals
> + MPM.add(createCFGSimplificationPass()); // Merge & remove BBs
> + MPM.add(createInstructionCombiningPass()); // Combine silly
> + seq's
> +
> + MPM.add(createTailCallEliminationPass()); // Eliminate tail calls
> + MPM.add(createCFGSimplificationPass()); // Merge & remove BBs
> + MPM.add(createReassociatePass()); // Reassociate expressions
> + MPM.add(createLoopRotatePass()); // Rotate Loop
> + MPM.add(createLICMPass()); // Hoist loop invariants
> + MPM.add(createLoopUnswitchPass(true));
> + MPM.add(createInstructionCombiningPass());
> + MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars
> + MPM.add(createLoopIdiomPass()); // Recognize idioms like memset.
> + MPM.add(createLoopDeletionPass()); // Delete dead loops
> + MPM.add(createLoopUnrollPass()); // Unroll small loops
> + if(optLevel > 0)
> + MPM.add(createGVNPass(true)); // Remove redundancies
> + MPM.add(createMemCpyOptPass()); // Remove memcpy / form memset
> + MPM.add(createSCCPPass()); // Constant prop with SCCP
> +
> + // Run instcombine after redundancy elimination to exploit opportunities
> + // opened up by them.
> + MPM.add(createInstructionCombiningPass());
> + MPM.add(createJumpThreadingPass()); // Thread jumps
> + MPM.add(createCorrelatedValuePropagationPass());
> + MPM.add(createDeadStoreEliminationPass()); // Delete dead stores
> + MPM.add(createAggressiveDCEPass()); // Delete dead instructions
> + MPM.add(createCFGSimplificationPass()); // Merge & remove BBs
> + MPM.add(createInstructionCombiningPass()); // Clean up after everything.
> + MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes
> + if(optLevel > 0) {
> + MPM.add(createGlobalDCEPass()); // Remove dead fns and globals.
> + MPM.add(createConstantMergePass()); // Merge dup global constants
> + }
> +
> + MPM.run(mod);
> + }
> +
> + bool llvmToGen(ir::Unit &unit, const char *fileName, int optLevel)
> + {
> // Get the global LLVM context
> llvm::LLVMContext& c = llvm::getGlobalContext();
> std::string errInfo;
> @@ -75,6 +163,13 @@ namespace gbe
> if (M.get() == 0) return false;
> Module &mod = *M.get();
>
> + Triple TargetTriple(mod.getTargetTriple());
> + TargetLibraryInfo *libraryInfo = new TargetLibraryInfo(TargetTriple);
> + libraryInfo->disableAllFunctions();
> +
> + runFuntionPass(mod, libraryInfo);
> + runModulePass(mod, libraryInfo, optLevel);
> +
> llvm::PassManager passes;
>
> // Print the code before further optimizations @@ -98,4 +193,3 @@
> namespace gbe
> return true;
> }
> } /* namespace gbe */
> -
> diff --git a/backend/src/llvm/llvm_to_gen.hpp
> b/backend/src/llvm/llvm_to_gen.hpp
> index 4006667..50ea267 100644
> --- a/backend/src/llvm/llvm_to_gen.hpp
> +++ b/backend/src/llvm/llvm_to_gen.hpp
> @@ -30,8 +30,9 @@ namespace gbe {
> class Unit;
> } /* namespace ir */
>
> - /*! Convert the LLVM IR code to a GEN IR code */
> - bool llvmToGen(ir::Unit &unit, const char *fileName);
> + /*! Convert the LLVM IR code to a GEN IR code,
> + optLevel 0 equal to clang -O1 and 1 equal to clang -O2*/
> + bool llvmToGen(ir::Unit &unit, const char *fileName, int optLevel);
>
> } /* namespace gbe */
>
> diff --git a/src/cl_program.c b/src/cl_program.c index
> d6d68c0..10eecee 100644
> --- a/src/cl_program.c
> +++ b/src/cl_program.c
> @@ -225,7 +225,7 @@ cl_program_create_from_llvm(cl_context ctx,
> INVALID_VALUE_IF (file_name == NULL);
>
> program = cl_program_new(ctx);
> - program->opaque = gbe_program_new_from_llvm(file_name,
> program->build_log_max_sz, program->build_log,
> &program->build_log_sz);
> + program->opaque = gbe_program_new_from_llvm(file_name,
> + program->build_log_max_sz, program->build_log,
> + &program->build_log_sz, 1);
> if (UNLIKELY(program->opaque == NULL)) {
> err = CL_INVALID_PROGRAM;
> goto error;
> --
> 1.8.1.2
>
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet
More information about the Beignet
mailing list