Skip to content

AddingSpaceTeam/slang_ir

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 

Repository files navigation

slang_ir

Main goal of slang_ir is to provide access to the internal intermediate representation of slang. This will help creating custom shader languages compilers with leveraging the backends available in slang, automatic differentiation (great for ml) and slang's optimization capabilities.

API design of this library is heavily inspired by libgccjit.

Library targets to mid-level instructions (not high-level that slang specific like Result type), but with exceptions for automatic differentiation support.

Locations

// source code location
type slang_ir_location

you can always pass NULL to any API entrypoint accepting one.

slang_ir_location_create(slang_ir_builder* builder, const char* filename, int line, int column)

Types

type slang_ir_type
type slang_ir_vector_type
type slang_ir_array_type
type slang_ir_matrix_type

Basic types

// get base type
slang_ir_type *slang_ir_type_get(slang_ir_builder* builder, enum slang_ir_types type_)

enum
slang_ir_types
{
  SLANG_IR_TYPE_VOID,
  SLANG_IR_TYPE_BOOL,
  SLANG_IR_TYPE_INT8,
  SLANG_IR_TYPE_INT16,
  SLANG_IR_TYPE_INT,
  SLANG_IR_TYPE_INT64,
  SLANG_IR_TYPE_UINT8,
  SLANG_IR_TYPE_UINT16,
  SLANG_IR_TYPE_UINT,
  SLANG_IR_TYPE_UINT64,
  SLANG_IR_TYPE_HALF,
  SLANG_IR_TYPE_FLOAT,
  SLANG_IR_TYPE_DOUBLE,
};

// get int type with specified size
slang_ir_type *slang_ir_type_get_int(slang_ir_builder* b, int num_bytes, int is_signed)

Vector types

Vec = {
					struct_name = "VectorType",
					operands = { { "elementType", "IRType" }, { "elementCount" } },
					hoistable = true,
      },
// get vec type
slang_ir_vector_type *slang_ir_type_get_vector(slang_ir_type *type, size_t num_elements)

size_t slang_ir_vector_type_get_num_elements (slang_ir_vector_type *vector_type);

gcc_jit_type *slang_ir_vector_type_get_element_type (slang_ir_vector_type *vector_type);

// sizeof
size_t slang_ir_type_get_size(slang_ir_type *type)

Array types

ArrayTypeBase = {
    hoistable = true,
    {
        Array = {
            struct_name = "ArrayType",
            operands = {
                { "elementType", "IRType" },
                { "elementCount" },
                { "stride", optional = true },
            },
        },
    },
    {
        UnsizedArray = {
            struct_name = "UnsizedArrayType",
            operands = { { "elementType", "IRType" }, { "stride", optional = true } },
        },
    },
},
slang_ir_array_type *slang_ir_type_get_array(slang_ir_type *type, int64_t num_elements, int stride);
slang_ir_array_type *slang_ir_type_get_unsized_array(slang_ir_type *type, int stride);

Matrix types

Mat = {
					struct_name = "MatrixType",
					operands = { { "elementType", "IRType" }, { "rowCount" }, { "columnCount" }, { "layout" } },
					hoistable = true,
      },
enum
slang_ir_matrix_layouts
{
  SLANG_IR_MATRIX_LAYOUT_UNKNOWN     = 0,
  SLANG_IR_MATRIX_LAYOUT_ROW_MAJOR   = 1,
  SLANG_IR_MATRIX_LAYOUT_COLUMN_MAJOR = 2,
};

slang_ir_matrix_type slang_ir_type_get_matrix(slang_ir_type *type, int64_t num_rows, int64_t num_cols, enum slang_ir_matrix_layouts layout)

Functions

Unlike libgccjit, we need to create function type and then function, it better map to modern programming languages. First param is return type / return param

slang_ir_function_param_create(slang_ir_builder* builder, slang_ir_location* loc, lang_ir_type* type, const char* name)

slang_ir_type_get_func(int num_params, gcc_jit_param **params)

slang_ir_function slang_ir_function_create(slang_ir_builder* builder, slang_ir_type* function_type, const char *name)

slang_ir_rvalue *slang_ir_function_call(slang_ir_builder* builder, slang_ir_location* loc, slang_ir_function* func, int num_args, slang_ir_rvalue **args)
slang_ir_lvalue *slang_ir_function_discard(slang_ir_rvalue *fn_expr) // need for lvalue function call, if rvalue is not function: NULL

Function annotations

Entry point

enum
slang_ir_entry_point_annotations
{
  SLANG_IR_ENTRY_POINT_ANNOTATION_STAGE_VERTEX   = 0,
  SLANG_IR_ENTRY_POINT_ANNOTATION_STAGE_FRAGMENT = 1,
  SLANG_IR_ENTRY_POINT_ANNOTATION_STAGE_COMPUTE  = 2,
  // will be place for tesselation stage etc.
}

void slang_ir_func_add_entry_point_annotation(slang_ir_builder* builder, slang_ir_function* func, enum slang_ir_entry_point_annotations annotation)

Numthreads

void slang_ir_func_add_numthreads_annotation(slang_ir_builder* builder, slang_ir_function* func, int x, int y, int z)

Auto differentiation

API currently support annotations only for normal differentiation, without custom differentiation support in user code. For it, these 3 annotations is enough

enum
slang_ir_differentiation_annotations
{
  SLANG_IR_DIFFERENTIATION_ANNOTATION_ZERO = 0,
  SLANG_IR_DIFFERENTIATION_ANNOTATION_TYPE = 1,
  SLANG_IR_DIFFERENTIATION_ANNOTATION_ADD  = 2,
}

slang_ir_function slang_ir_differentiate(slang_ir_builder* builder, slang_ir_function* func)
void slang_ir_add_differentiation_annotation(slang_ir_builder* builder, slang_ir_function* func, enum slang_ir_differentiation_annotations annotation)

Expressions

type slang_ir_rvalue

Unary Operations

enum
slang_ir_unary_op
{
  SLANG_IR_UNARY_OP_ARITH_NEGATE,   // -x
  SLANG_IR_UNARY_OP_BITWISE_NEGATE, // ~x
  SLANG_IR_UNARY_OP_LOGICAL_NEGATE, // !x
}

slang_ir_rvalue *gcc_jit_context_create_unary_op(slang_ir_builder* builder, slang_ir_location *loc, enum slang_ir_unary_op op, slang_ir_type *result_type, slang_ir_rvalue *x)

Binary Operations

enum
slang_ir_binary_op
{
  SLANG_IR_BINARY_OP_ARITH_ADD,   // x + y
  SLANG_IR_BINARY_OP_ARITH_SUB,   // x - y
  SLANG_IR_BINARY_OP_ARITH_MUL,   // x * y
  SLANG_IR_BINARY_OP_ARITH_DIV,   // x / y
  SLANG_IR_BINARY_OP_ARITH_MOD,   // x % y
  SLANG_IR_BINARY_OP_BITWISE_AND, // x & y
  SLANG_IR_BINARY_OP_BITWISE_XOR, // x ^ y
  SLANG_IR_BINARY_OP_BITWISE_OR,  // x | y
  SLANG_IR_BINARY_OP_LOGICAL_AND, // x && y
  SLANG_IR_BINARY_OP_LOGICAL_OR,  // x || y
  SLANG_IR_BINARY_OP_SHL,         // x << y
  SLANG_IR_BINARY_OP_SHR,         // x >> y
}

slang_ir_rvalue *gcc_jit_context_create_binary_op(slang_ir_builder* builder, slang_ir_location *loc, enum slang_ir_binary_op op, slang_ir_type *result_type, slang_ir_rvalue *a, slang_ir_rvalue *b)

Comparisons

enum
slang_ir_comparison
{
  SLANG_IR_COMPARISON_EQ, // x == y
  SLANG_IR_COMPARISON_NE, // x != y
  SLANG_IR_COMPARISON_LT, // x < y
  SLANG_IR_COMPARISON_LE, // x <= y
  SLANG_IR_COMPARISON_GT, // x > y
  SLANG_IR_COMPARISON_GE, // x >= y
}

slang_ir_rvalue *gcc_jit_context_create_comparison(slang_ir_builder* builder, slang_ir_location *loc, enum slang_ir_comparison op, slang_ir_rvalue *a, slang_ir_rvalue *b)

Control flow

TODO

Builder

char *slang_ir_builder_emit_spirv(slang_ir_builder* builder, slang_ir_function* entry_point)

About

C bindings to slang IR

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors