Clover Git
OpenCL 1.1 software implementation

program.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, Denis Steckelmacher <steckdenis@yahoo.fr>
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *     * Redistributions of source code must retain the above copyright
00008  *       notice, this list of conditions and the following disclaimer.
00009  *     * Redistributions in binary form must reproduce the above copyright
00010  *       notice, this list of conditions and the following disclaimer in the
00011  *       documentation and/or other materials provided with the distribution.
00012  *     * Neither the name of the copyright holder nor the
00013  *       names of its contributors may be used to endorse or promote products
00014  *       derived from this software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
00020  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 
00033 #include "program.h"
00034 #include "device.h"
00035 #include "kernel.h"
00036 #include "builtins.h"
00037 
00038 #include "../program.h"
00039 
00040 #include <llvm/PassManager.h>
00041 #include <llvm/Analysis/Passes.h>
00042 #include <llvm/Analysis/Verifier.h>
00043 #include <llvm/Transforms/Scalar.h>
00044 #include <llvm/Transforms/IPO.h>
00045 #include <llvm/ExecutionEngine/ExecutionEngine.h>
00046 #include <llvm/ExecutionEngine/JIT.h>
00047 #include <llvm/ExecutionEngine/Interpreter.h>
00048 
00049 #include <string>
00050 #include <iostream>
00051 
00052 using namespace Coal;
00053 
00054 CPUProgram::CPUProgram(CPUDevice *device, Program *program)
00055 : DeviceProgram(), p_device(device), p_program(program), p_jit(0)
00056 {
00057 
00058 }
00059 
00060 CPUProgram::~CPUProgram()
00061 {
00062     if (p_jit)
00063     {
00064         // Dont delete the module
00065         p_jit->removeModule(p_module);
00066 
00067         delete p_jit;
00068     }
00069 }
00070 
00071 bool CPUProgram::linkStdLib() const
00072 {
00073     return true;
00074 }
00075 
00076 void CPUProgram::createOptimizationPasses(llvm::PassManager *manager, bool optimize)
00077 {
00078     if (optimize)
00079     {
00080         /*
00081          * Inspired by code from "The LLVM Compiler Infrastructure"
00082          */
00083         manager->add(llvm::createDeadArgEliminationPass());
00084         manager->add(llvm::createInstructionCombiningPass());
00085         manager->add(llvm::createFunctionInliningPass());
00086         manager->add(llvm::createPruneEHPass());   // Remove dead EH info.
00087         manager->add(llvm::createGlobalOptimizerPass());
00088         manager->add(llvm::createGlobalDCEPass()); // Remove dead functions.
00089         manager->add(llvm::createArgumentPromotionPass());
00090         manager->add(llvm::createInstructionCombiningPass());
00091         manager->add(llvm::createJumpThreadingPass());
00092         manager->add(llvm::createScalarReplAggregatesPass());
00093         manager->add(llvm::createFunctionAttrsPass()); // Add nocapture.
00094         manager->add(llvm::createGlobalsModRefPass()); // IP alias analysis.
00095         manager->add(llvm::createLICMPass());      // Hoist loop invariants.
00096         manager->add(llvm::createGVNPass());       // Remove redundancies.
00097         manager->add(llvm::createMemCpyOptPass()); // Remove dead memcpys.
00098         manager->add(llvm::createDeadStoreEliminationPass());
00099         manager->add(llvm::createInstructionCombiningPass());
00100         manager->add(llvm::createJumpThreadingPass());
00101         manager->add(llvm::createCFGSimplificationPass());
00102     }
00103 }
00104 
00105 bool CPUProgram::build(llvm::Module *module)
00106 {
00107     // Nothing to build
00108     p_module = module;
00109 
00110     return true;
00111 }
00112 
00113 bool CPUProgram::initJIT()
00114 {
00115     if (p_jit)
00116         return true;
00117 
00118     if (!p_module)
00119         return false;
00120 
00121     // Create the JIT
00122     std::string err;
00123     llvm::EngineBuilder builder(p_module);
00124 
00125     builder.setErrorStr(&err);
00126     builder.setAllocateGVsWithCode(false);
00127 
00128     p_jit = builder.create();
00129 
00130     if (!p_jit)
00131     {
00132         std::cout << "Unable to create a JIT: " << err << std::endl;
00133         return false;
00134     }
00135 
00136     p_jit->DisableSymbolSearching(true);    // Avoid an enormous security hole (a kernel calling system())
00137     p_jit->InstallLazyFunctionCreator(&getBuiltin);
00138 
00139     return true;
00140 }
00141 
00142 llvm::ExecutionEngine *CPUProgram::jit() const
00143 {
00144     return p_jit;
00145 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines