[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