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 <[email protected]>
---
 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 © 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
[email protected]
http://lists.freedesktop.org/mailman/listinfo/beignet

Reply via email to