Skip to content

Commit

Permalink
[SPIR-V] Enable SPIR-V format emitter in clang.
Browse files Browse the repository at this point in the history
Signed-off-by: Vladimir Lazarev <vladimir.lazarev@intel.com>
  • Loading branch information
vladimirlaz committed Jan 22, 2019
1 parent fa1ff0a commit e802518
Show file tree
Hide file tree
Showing 382 changed files with 62,334 additions and 0 deletions.
3 changes: 3 additions & 0 deletions clang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,12 @@ include(AddClang)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(LLVM_SPIRV_INCLUDE_DIRS "${LLVM_MAIN_SRC_DIR}/../llvm-spirv/include")

include_directories(BEFORE
${CMAKE_CURRENT_BINARY_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/include
${LLVM_SPIRV_INCLUDE_DIRS}
)

if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/CodeGen/BackendUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace clang {
enum BackendAction {
Backend_EmitAssembly, ///< Emit native assembly files
Backend_EmitBC, ///< Emit LLVM bitcode files
Backend_EmitSPIRV, ///< Emit SPIR-V bitcode files
Backend_EmitLL, ///< Emit human-readable LLVM assembly
Backend_EmitNothing, ///< Don't emit anything (benchmarking mode)
Backend_EmitMCNull, ///< Run CodeGen, but don't emit anything
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/CodeGen/CodeGenAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ class EmitBCAction : public CodeGenAction {
EmitBCAction(llvm::LLVMContext *_VMContext = nullptr);
};

class EmitSPIRVAction : public CodeGenAction {
virtual void anchor();
public:
EmitSPIRVAction(llvm::LLVMContext *_VMContext = nullptr);
};

class EmitLLVMAction : public CodeGenAction {
virtual void anchor();
public:
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/CC1Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,8 @@ def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">,
HelpText<"Build ASTs then convert to LLVM, emit .bc file">;
def emit_llvm_only : Flag<["-"], "emit-llvm-only">,
HelpText<"Build ASTs and convert to LLVM, discarding output">;
def emit_spirv : Flag<["-"], "emit-spirv">,
HelpText<"Build ASTs then convert to LLVM then convert to SPIR-V, emit .spv file">;
def emit_codegen_only : Flag<["-"], "emit-codegen-only">,
HelpText<"Generate machine code, but discard output">;
def emit_obj : Flag<["-"], "emit-obj">,
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ enum ActionKind {
/// Emit a .bc file.
EmitBC,

/// Emit a .spv file.
EmitSPIRV,

/// Translate input source into HTML.
EmitHTML,

Expand Down
13 changes: 13 additions & 0 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/NameAnonGlobals.h"
#include "llvm/Transforms/Utils/SymbolRewriter.h"
#include "LLVMSPIRVLib.h"
#include <memory>
using namespace clang;
using namespace llvm;
Expand Down Expand Up @@ -777,6 +778,7 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,

bool UsesCodeGen = (Action != Backend_EmitNothing &&
Action != Backend_EmitBC &&
Action != Backend_EmitSPIRV &&
Action != Backend_EmitLL);
CreateTargetMachine(UsesCodeGen);

Expand Down Expand Up @@ -831,6 +833,13 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
}
break;


case Backend_EmitSPIRV:

PerModulePasses.add(createSPIRVWriterPass(*OS));

break;

case Backend_EmitLL:
PerModulePasses.add(
createPrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
Expand Down Expand Up @@ -1066,6 +1075,10 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
}
break;

case Backend_EmitSPIRV:
CodeGenPasses.add(createSPIRVWriterPass(*OS));
break;

case Backend_EmitLL:
MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
break;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ set(LLVM_LINK_COMPONENTS
Support
Target
TransformUtils
SPIRVLib
)

# In a standard Clang+LLVM build, we need to generate intrinsics before
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/CodeGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,8 @@ GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
return CI.createDefaultOutputFile(false, InFile, "ll");
case Backend_EmitBC:
return CI.createDefaultOutputFile(true, InFile, "bc");
case Backend_EmitSPIRV:
return CI.createDefaultOutputFile(true, InFile, "spv");
case Backend_EmitNothing:
return nullptr;
case Backend_EmitMCNull:
Expand Down Expand Up @@ -1058,6 +1060,10 @@ void EmitBCAction::anchor() { }
EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext)
: CodeGenAction(Backend_EmitBC, _VMContext) {}

void EmitSPIRVAction::anchor() { }
EmitSPIRVAction::EmitSPIRVAction(llvm::LLVMContext *_VMContext)
: CodeGenAction(Backend_EmitSPIRV, _VMContext) {}

void EmitLLVMAction::anchor() { }
EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext)
: CodeGenAction(Backend_EmitLL, _VMContext) {}
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ static unsigned getOptimizationLevel(ArgList &Args, InputKind IK,
if (IK.getLanguage() == InputKind::OpenCL && !Args.hasArg(OPT_cl_opt_disable))
DefaultOpt = llvm::CodeGenOpt::Default;

if (Args.hasArg(OPT_emit_spirv))
return 0; // LLVM-SPIRV translator expects not optimized IR

if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
if (A->getOption().matches(options::OPT_O0))
return llvm::CodeGenOpt::None;
Expand Down Expand Up @@ -1183,6 +1186,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
}
}

Opts.EmitOpenCLArgMetadata |= Args.hasArg(OPT_emit_spirv);

if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
StringRef Val = A->getValue();
if (Val == "ieee")
Expand Down Expand Up @@ -1606,6 +1611,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ProgramAction = frontend::EmitAssembly; break;
case OPT_emit_llvm_bc:
Opts.ProgramAction = frontend::EmitBC; break;
case OPT_emit_spirv:
Opts.ProgramAction = frontend::EmitSPIRV; break;
case OPT_emit_html:
Opts.ProgramAction = frontend::EmitHTML; break;
case OPT_emit_llvm:
Expand Down Expand Up @@ -3033,6 +3040,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
case frontend::ASTView:
case frontend::EmitAssembly:
case frontend::EmitBC:
case frontend::EmitSPIRV:
case frontend::EmitHTML:
case frontend::EmitLLVM:
case frontend::EmitLLVMOnly:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
case DumpTokens: return llvm::make_unique<DumpTokensAction>();
case EmitAssembly: return llvm::make_unique<EmitAssemblyAction>();
case EmitBC: return llvm::make_unique<EmitBCAction>();
case EmitSPIRV: return llvm::make_unique<EmitSPIRVAction>();
case EmitHTML: return llvm::make_unique<HTMLPrintAction>();
case EmitLLVM: return llvm::make_unique<EmitLLVMAction>();
case EmitLLVMOnly: return llvm::make_unique<EmitLLVMOnlyAction>();
Expand Down
16 changes: 16 additions & 0 deletions clang/test/CodeGenSPIRV/intel/is_valid_event.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Make sure that OpenCL builtins declared in opencl.h are translated
// to corresponding SPIR-V instructions, not a function calls.
// Builtins must be declared as overloadable, so Clang mangles their names,
// and LLVM-SPIRV translator can recognize them.

// RUN: %clang_cc1 %s -emit-spirv -triple spir-unknown-unknown -O0 -cl-std=CL2.0 -include opencl-c.h -o %t.spv
// RUN: llvm-spirv -to-text %t.spv -o - | FileCheck %s

// CHECK: CreateUserEvent
// CHECK: IsValidEvent
// CHECK-NOT: FunctionCall

bool test() {
clk_event_t e = create_user_event();
return is_valid_event(e);
}
39 changes: 39 additions & 0 deletions clang/test/CodeGenSPIRV/intel/private-array-initialization.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-LLVM
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-spirv -o %t.spv
// RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV

// CHECK-LLVM: @__const.test.arr = private unnamed_addr addrspace(2) constant [3 x i32] [i32 1, i32 2, i32 3], align 4

// CHECK-SPIRV-DAG: TypeInt [[i32:[0-9]+]] 32 0
// CHECK-SPIRV-DAG: TypeInt [[i8:[0-9]+]] 8 0
// CHECK-SPIRV-DAG: Constant [[i32]] [[one:[0-9]+]] 1
// CHECK-SPIRV-DAG: Constant [[i32]] [[two:[0-9]+]] 2
// CHECK-SPIRV-DAG: Constant [[i32]] [[three:[0-9]+]] 3
// CHECK-SPIRV-DAG: Constant [[i32]] [[twelve:[0-9]+]] 12
// CHECK-SPIRV-DAG: TypeArray [[i32x3:[0-9]+]] [[i32]] [[three]]
// CHECK-SPIRV-DAG: TypePointer [[i32x3_ptr:[0-9]+]] 7 [[i32x3]]
// CHECK-SPIRV-DAG: TypePointer [[const_i32x3_ptr:[0-9]+]] 0 [[i32x3]]
// CHECK-SPIRV-DAG: TypePointer [[i8_ptr:[0-9]+]] 7 [[i8]]
// CHECK-SPIRV-DAG: TypePointer [[const_i8_ptr:[0-9]+]] 0 [[i8]]
// CHECK-SPIRV: ConstantComposite [[i32x3]] [[test_arr_init:[0-9]+]] [[one]] [[two]] [[three]]
// CHECK-SPIRV: Variable [[const_i32x3_ptr]] [[test_arr:[0-9]+]] 0 [[test_arr_init]]
// CHECK-SPIRV: Variable [[const_i32x3_ptr]] [[test_arr2:[0-9]+]] 0 [[test_arr_init]]

void test() {
__private int arr[] = {1,2,3};
__private const int arr2[] = {1,2,3};
// CHECK-LLVM: %arr = alloca [3 x i32], align 4
// CHECK-LLVM: %[[arr_i8_ptr:[0-9]+]] = bitcast [3 x i32]* %arr to i8*
// CHECK-LLVM: call void @llvm.memcpy.p0i8.p2i8.i32(i8* align 4 %0, i8 addrspace(2)* align 4 bitcast ([3 x i32] addrspace(2)* @__const.test.arr to i8 addrspace(2)*), i32 12, i1 false)

// CHECK-SPIRV: Variable [[i32x3_ptr]] [[arr:[0-9]+]] 7
// CHECK-SPIRV: Variable [[i32x3_ptr]] [[arr2:[0-9]+]] 7

// CHECK-SPIRV: Bitcast [[i8_ptr]] [[arr_i8_ptr:[0-9]+]] [[arr]]
// CHECK-SPIRV: Bitcast [[const_i8_ptr]] [[test_arr_const_i8_ptr:[0-9]+]] [[test_arr]]
// CHECK-SPIRV: CopyMemorySized [[arr_i8_ptr]] [[test_arr_const_i8_ptr]] [[twelve]] 2 4

// CHECK-SPIRV: Bitcast [[i8_ptr]] [[arr2_i8_ptr:[0-9]+]] [[arr2]]
// CHECK-SPIRV: Bitcast [[const_i8_ptr]] [[test_arr2_const_i8_ptr:[0-9]+]] [[test_arr2]]
// CHECK-SPIRV: CopyMemorySized [[arr2_i8_ptr]] [[test_arr2_const_i8_ptr]] [[twelve]] 2 4
}
2 changes: 2 additions & 0 deletions llvm-spirv/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BasedOnStyle: LLVM

19 changes: 19 additions & 0 deletions llvm-spirv/.clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,readability-identifier-naming,-llvm-header-guard'
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.EnumCase
value: CamelCase
- key: readability-identifier-naming.FunctionCase
value: camelBack
- key: readability-identifier-naming.MemberCase
value: CamelCase
- key: readability-identifier-naming.ParameterCase
value: CamelCase
- key: readability-identifier-naming.UnionCase
value: CamelCase
- key: readability-identifier-naming.VariableCase
value: CamelCase
- key: llvm-namespace-comment.ShortNamespaceLines
value: '25'

66 changes: 66 additions & 0 deletions llvm-spirv/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#==============================================================================#
# This file specifies intentionally untracked files that git should ignore.
# See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html
#
# This file is intentionally different from the output of `git svn show-ignore`,
# as most of those are useless.
#==============================================================================#

#==============================================================================#
# File extensions to be ignored anywhere in the tree.
#==============================================================================#
# Temp files created by most text editors.
*~
# Merge files created by git.
*.orig
# Byte compiled python modules.
*.pyc
# vim swap files
.*.swp
.sw?
#OS X specific files.
.DS_store

#==============================================================================#
# Explicit files to ignore (only matches one).
#==============================================================================#
# Various tag programs
/tags
/TAGS
/GPATH
/GRTAGS
/GSYMS
/GTAGS
.gitusers
autom4te.cache
cscope.files
cscope.out
autoconf/aclocal.m4
autoconf/autom4te.cache
compile_commands.json

#==============================================================================#
# Directories to ignore (do not add trailing '/'s, they skip symlinks).
#==============================================================================#
# External projects that are tracked independently.
projects/*
!projects/CMakeLists.txt
!projects/Makefile
# Clang, which is tracked independently.
tools/clang
# LLDB, which is tracked independently.
tools/lldb
# lld, which is tracked independently.
tools/lld
# llgo, which is tracked independently.
tools/llgo
# Polly, which is tracked independently.
tools/polly
# Sphinx build tree, if building in-source dir.
docs/_build

#==============================================================================#
# Files created in tree by the Go bindings.
#==============================================================================#
bindings/go/llvm/llvm_config.go
bindings/go/llvm/workdir
Loading

0 comments on commit e802518

Please sign in to comment.