Skip to content

Commit

Permalink
Full optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
yukoba committed Apr 9, 2020
1 parent 288cc6c commit acbfeeb
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 15 deletions.
1 change: 1 addition & 0 deletions llvm/cppbuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,4 @@ case $PLATFORM in
esac

cd ../..
cp ../../src/cpp/*.h include/
22 changes: 9 additions & 13 deletions llvm/samples/polly/MatMulBenchmark.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
*
* If you set usePollyParallel, you may have to modify the file name of LLVMLoadLibraryPermanently().
*
* Warning: Because it does not optimize for AVX, etc, this code is slower than this:
* clang -O3 -march=native -mllvm -polly -mllvm -polly-vectorizer=stripmine
*
* Note: Instead of JNA, to obtain maximum performance, FunctionPointer should be used as shown here:
* https://github.com/bytedeco/javacpp/blob/master/src/test/java/org/bytedeco/javacpp/PointerTest.java
*
Expand Down Expand Up @@ -237,15 +234,14 @@ static LLVMModuleRef build() {
}

static void optimize(LLVMModuleRef module) {
LLVMPassManagerBuilderRef pmb = LLVMPassManagerBuilderCreate();
LLVMPassManagerBuilderSetOptLevel(pmb, 3);
LLVMPassManagerRef pass = LLVMCreatePassManager();
LLVMPassManagerBuilderPopulateModulePassManager(pmb, pass);

LLVMRunPassManager(pass, module);

LLVMDisposePassManager(pass);
LLVMPassManagerBuilderDispose(pmb);
BytePointer error = new BytePointer((Pointer) null);
try {
if (JavaCPPLLVMOptimizeModule(module, 3, 0, error) != 0) {
throw new RuntimeException(error.getString());
}
} finally {
LLVMDisposeMessage(error);
}
}

static void verify(LLVMModuleRef module, boolean dumpModule) {
Expand All @@ -265,7 +261,7 @@ static void verify(LLVMModuleRef module, boolean dumpModule) {
static void jitCompile(LLVMExecutionEngineRef engine, LLVMModuleRef module) {
BytePointer error = new BytePointer((Pointer) null);
try {
if (LLVMCreateJITCompilerForModule(engine, module, 3, error) != 0) {
if (JavaCPPLLVMCreateOptimizedJITCompilerForModule(engine, module, 3, error) != 0) {
throw new RuntimeException(error.getString());
}
} finally {
Expand Down
151 changes: 151 additions & 0 deletions llvm/src/cpp/JavaCPPLLVMHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Copyright (C) 2020 Yu Kobayashi
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
* the Free Software Foundation (subject to the "Classpath" exception),
* either version 2, or any later version (collectively, the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.gnu.org/licenses/
* http://www.gnu.org/software/classpath/license.html
*
* or as provided in the LICENSE.txt file that accompanied this code.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef JAVACPP_LLVM_HELPER_H
#define JAVACPP_LLVM_HELPER_H

#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Pass.h"
#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm-c/Types.h"

using namespace llvm;

#ifdef __cplusplus
extern "C" {
#endif

static void JavaCPPLLVMAddOptimizationPasses(
legacy::PassManagerBase &passes,
legacy::FunctionPassManager &fnPasses,
TargetMachine *machine,
unsigned optLevel,
unsigned sizeLevel
) {
PassManagerBuilder builder;
builder.OptLevel = optLevel;
builder.SizeLevel = sizeLevel;
builder.Inliner = createFunctionInliningPass(optLevel, sizeLevel, false);
builder.LoopVectorize = optLevel > 1 && sizeLevel < 2;
builder.SLPVectorize = optLevel > 1 && sizeLevel < 2;
machine->adjustPassManager(builder);

builder.populateFunctionPassManager(fnPasses);
builder.populateModulePassManager(passes);
}

static void JavaCPPLLVMAddStandardLinkPasses(legacy::PassManagerBase &passes, unsigned optLevel, unsigned sizeLevel) {
PassManagerBuilder builder;
builder.VerifyInput = true;
builder.Inliner = createFunctionInliningPass(optLevel, sizeLevel, false);
builder.populateLTOPassManager(passes);
}

LLVMBool JavaCPPLLVMOptimizeModule(
LLVMModuleRef moduleRef,
unsigned optLevel,
unsigned sizeLevel,
char** outError
) {
// This function is based on main() of llvm/tools/opt/opt.cpp
Module *module = unwrap(moduleRef);

std::string error;
std::string cpuStr = sys::getHostCPUName();

EngineBuilder engineBuilder;
TargetMachine *machine = engineBuilder
.setEngineKind(EngineKind::JIT)
.setMCPU(cpuStr)
.setErrorStr(&error)
.setOptLevel(static_cast<CodeGenOpt::Level>(optLevel))
.selectTarget();
if (machine == nullptr) {
*outError = strdup(error.c_str());
return 1;
}

module->setTargetTriple(machine->getTargetTriple().str());
module->setDataLayout(machine->createDataLayout());

legacy::PassManager passes;
passes.add(new TargetLibraryInfoWrapperPass(machine->getTargetTriple()));
passes.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis()));

legacy::FunctionPassManager fnPasses(module);
fnPasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis()));

JavaCPPLLVMAddOptimizationPasses(passes, fnPasses, machine, optLevel, sizeLevel);
JavaCPPLLVMAddStandardLinkPasses(passes, optLevel, sizeLevel);

fnPasses.doInitialization();
for (Function &func : *module) {
fnPasses.run(func);
}
fnPasses.doFinalization();

passes.add(createVerifierPass());
passes.run(*module);

return 0;
}

LLVMBool JavaCPPLLVMCreateOptimizedJITCompilerForModule(
LLVMExecutionEngineRef *outJIT,
LLVMModuleRef moduleRef,
unsigned optLevel,
char **outError
) {
std::string error;
std::string cpuStr = sys::getHostCPUName();

EngineBuilder engineBuilder(std::unique_ptr<Module>(unwrap(moduleRef)));
ExecutionEngine *ee = engineBuilder
.setEngineKind(EngineKind::JIT)
.setMCPU(cpuStr)
.setErrorStr(&error)
.setOptLevel(static_cast<CodeGenOpt::Level>(optLevel))
.create();
if (ee == nullptr) {
*outError = strdup(error.c_str());
return 1;
}
ee->finalizeObject();
*outJIT = wrap(ee);
return 0;
}

#ifdef __cplusplus
}
#endif

#endif
5 changes: 3 additions & 2 deletions llvm/src/main/java/org/bytedeco/llvm/presets/LLVM.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"<llvm-c/Comdat.h>", "<llvm-c/DebugInfo.h>", "<llvm-c/Error.h>", "<llvm-c/ErrorHandling.h>", "<llvm-c/OrcBindings.h>", "<llvm-c/Remarks.h>",
"<llvm-c/Transforms/AggressiveInstCombine.h>", "<llvm-c/Transforms/Coroutines.h>", "<llvm-c/Transforms/InstCombine.h>",
"<llvm-c/Transforms/IPO.h>", "<llvm-c/Transforms/PassManagerBuilder.h>", "<llvm-c/Transforms/Scalar.h>", "<llvm-c/Transforms/Utils.h>", "<llvm-c/Transforms/Vectorize.h>",
"<polly/LinkAllPasses.h>"},
"<polly/LinkAllPasses.h>", "<JavaCPPLLVMHelper.h>"},
compiler = "cpp14", link = {"LLVM-10", "LTO@.10", "LLVMPolly"}),
@Platform(value = {"macosx", "windows"}, link = {"LLVM", "LTO", "Polly", "PollyISL", "PollyPPCG"})})
public class LLVM implements InfoMapper {
Expand Down Expand Up @@ -136,6 +136,7 @@ public void map(InfoMap infoMap) {
.put(new Info("defined(_MSC_VER) && !defined(inline)").define(false))
.put(new Info("GPU_CODEGEN").define(false))
.put(new Info("LLVMDumpType", "LLVMConstGEP2", "LLVMConstInBoundsGEP2", "LLVMCreateOprofileJITEventListener",
"llvm_optimize_modules", "llvm_destroy_optimizer", "llvm_read_object_file", "llvm_create_optimizer", "LLVMRemarkVersion").skip());
"llvm_optimize_modules", "llvm_destroy_optimizer", "llvm_read_object_file", "llvm_create_optimizer", "LLVMRemarkVersion",
"JavaCPPLLVMAddOptimizationPasses", "JavaCPPLLVMAddStandardLinkPasses").skip());
}
}

0 comments on commit acbfeeb

Please sign in to comment.