Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Dibyendu Majumdar committed Jul 5, 2015
1 parent fcb22d1 commit b65e5d2
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 121 deletions.
12 changes: 7 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The project was kicked off in January 2015.

JIT Implementation
++++++++++++++++++
Right now (June 2015) I am working on the ``libgccjit`` based JIT implementation.
Right now (July 2015) I am working on the ``libgccjit`` based JIT implementation.

The LLVM JIT compiler is mostly functional. The Lua and Ravi bytecodes currently implemented in LLVM are described in `JIT Status <http://the-ravi-programming-language.readthedocs.org/en/latest/ravi-jit-status.html>`_ page.

Expand All @@ -33,7 +33,7 @@ For performance benchmarks please visit the `Ravi Performance Benchmarks <http:/

Optional Static Typing
++++++++++++++++++++++
Ravi allows you to annotate local variables with static types. The supported types and the resulting behaviour are as follows:
Ravi allows you to annotate ``local`` variables with static types. The supported types and the resulting behaviour are as follows:

``integer``
denotes an integral value of 64-bits.
Expand All @@ -44,12 +44,14 @@ Ravi allows you to annotate local variables with static types. The supported typ
``number[]``
denotes an array of numbers

Declaring the types of variables has following advantages.
Declaring the types of ``local`` variables has following advantages.

* Variables declared with above types are automatically initialized to 0
.. attention:: Currently function parameters cannot be decorated with types; this will be added in future.

* Local variables declared with above types are automatically initialized to 0
* Arithmetic operations trigger type specific bytecodes which leads to more efficient JIT compilation
* Specialised operators to get/set from arrays are implemented which makes array access more efficient in JIT mode as the access can be inlined
* Values assigned to typed variables are checked statically unless the values are results from a function call in which case the there is an attempt to convert values at runtime
* Values assigned to typed variables are checked statically unless the values are results from a function call in which case the there is an attempt to convert values at runtime (i.e. value is cast to the expected type - this can be exploited to work around the limitation that function parameter types cannot be specified)
* The standard table operations on arrays are checked to ensure that the type is not subverted
* Even if a typed variable is captured in a closure its type must be respected

Expand Down
11 changes: 8 additions & 3 deletions include/ravi_llvmcodegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -685,17 +685,23 @@ class RaviCodeGenerator {
// emit code to store lua_Number value into register
void emit_store_reg_n(RaviFunctionDef *def, llvm::Value *value,
llvm::Value *dest_ptr);
void emit_store_reg_n_withtype(RaviFunctionDef *def, llvm::Value *value,
llvm::Value *dest_ptr);

// emit code to store lua_Integer value into register
void emit_store_reg_i(RaviFunctionDef *def, llvm::Value *value,
llvm::Value *dest_ptr);
void emit_store_reg_i_withtype(RaviFunctionDef *def, llvm::Value *value,
llvm::Value *dest_ptr);

// emit code to store bool value into register
void emit_store_reg_b(RaviFunctionDef *def, llvm::Value *value,
llvm::Value *dest_ptr);
void emit_store_reg_b_withtype(RaviFunctionDef *def, llvm::Value *value,
llvm::Value *dest_ptr);

// emit code to set the type in the register
void emit_store_type(RaviFunctionDef *def, llvm::Value *value, int type);
void emit_store_type_(RaviFunctionDef *def, llvm::Value *value, int type);

// emit code to load the type from a register
llvm::Instruction *emit_load_type(RaviFunctionDef *def, llvm::Value *value);
Expand All @@ -712,8 +718,7 @@ class RaviCodeGenerator {
void emit_assign(RaviFunctionDef *def, llvm::Value *ra, llvm::Value *rb);

// Get &upvals[offset] from LClosure
llvm::Value *emit_gep_upvals(RaviFunctionDef *def, llvm::Value *cl_ptr,
int offset);
llvm::Value *emit_gep_upvals(RaviFunctionDef *def, int offset);

// Load the &upvals[offset] -> result is UpVal*
llvm::Instruction *emit_load_pupval(RaviFunctionDef *def,
Expand Down
12 changes: 7 additions & 5 deletions readthedocs/ravi-overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The project was kicked off in January 2015.

JIT Implementation
++++++++++++++++++
Right now (June 2015) I am working on the ``libgccjit`` based JIT implementation.
Right now (July 2015) I am working on the ``libgccjit`` based JIT implementation.

The LLVM JIT compiler is mostly functional. The Lua and Ravi bytecodes currently implemented in LLVM are described in `JIT Status <http://the-ravi-programming-language.readthedocs.org/en/latest/ravi-jit-status.html>`_ page.

Expand All @@ -33,7 +33,7 @@ For performance benchmarks please visit the `Ravi Performance Benchmarks <http:/

Optional Static Typing
++++++++++++++++++++++
Ravi allows you to annotate local variables with static types. The supported types and the resulting behaviour are as follows:
Ravi allows you to annotate ``local`` variables with static types. The supported types and the resulting behaviour are as follows:

``integer``
denotes an integral value of 64-bits.
Expand All @@ -44,12 +44,14 @@ Ravi allows you to annotate local variables with static types. The supported typ
``number[]``
denotes an array of numbers

Declaring the types of variables has following advantages.
Declaring the types of ``local`` variables has following advantages.

* Variables declared with above types are automatically initialized to 0
.. attention:: Currently function parameters cannot be decorated with types; this will be added in future.

* Local variables declared with above types are automatically initialized to 0
* Arithmetic operations trigger type specific bytecodes which leads to more efficient JIT compilation
* Specialised operators to get/set from arrays are implemented which makes array access more efficient in JIT mode as the access can be inlined
* Values assigned to typed variables are checked statically unless the values are results from a function call in which case the there is an attempt to convert values at runtime
* Values assigned to typed variables are checked statically unless the values are results from a function call in which case the there is an attempt to convert values at runtime (i.e. value is cast to the expected type - this can be exploited to work around the limitation that function parameter types cannot be specified)
* The standard table operations on arrays are checked to ensure that the type is not subverted
* Even if a typed variable is captured in a closure its type must be respected

Expand Down
72 changes: 24 additions & 48 deletions src/ravi_llvmarith1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ void RaviCodeGenerator::emit_UNMF(RaviFunctionDef *def, int A, int B) {
llvm::Value *rb = emit_gep_register_or_constant(def, B);
llvm::Instruction *lhs = emit_load_reg_n(def, rb);
llvm::Value *result = def->builder->CreateFNeg(lhs);
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := -R(B), integer
Expand All @@ -46,8 +45,7 @@ void RaviCodeGenerator::emit_UNMI(RaviFunctionDef *def, int A, int B) {
llvm::Value *rb = emit_gep_register_or_constant(def, B);
llvm::Instruction *lhs = emit_load_reg_i(def, rb);
llvm::Value *result = def->builder->CreateNeg(lhs, "", false, true);
emit_store_reg_i(def, result, ra);
emit_store_type(def, ra, LUA_TNUMINT);
emit_store_reg_i_withtype(def, result, ra);
}

// R(A) := RK(B) + C, result is floating
Expand All @@ -60,8 +58,7 @@ void RaviCodeGenerator::emit_ADDFN(RaviFunctionDef *def, int A, int B, int C) {
lhs,
def->builder->CreateSIToFP(llvm::ConstantInt::get(def->types->C_intT, C),
def->types->lua_NumberT));
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) + RK(C), all floating
Expand All @@ -73,8 +70,7 @@ void RaviCodeGenerator::emit_ADDFF(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *lhs = emit_load_reg_n(def, rb);
llvm::Instruction *rhs = emit_load_reg_n(def, rc);
llvm::Value *result = def->builder->CreateFAdd(lhs, rhs);
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) + RK(C), float+int
Expand All @@ -87,8 +83,7 @@ void RaviCodeGenerator::emit_ADDFI(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *rhs = emit_load_reg_i(def, rc);
llvm::Value *result = def->builder->CreateFAdd(
lhs, def->builder->CreateSIToFP(rhs, def->types->lua_NumberT));
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) + RK(C), int+int
Expand All @@ -101,8 +96,7 @@ void RaviCodeGenerator::emit_ADDII(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *lhs = emit_load_reg_i(def, rb);
llvm::Instruction *rhs = emit_load_reg_i(def, rc);
llvm::Value *result = def->builder->CreateAdd(lhs, rhs, "", false, true);
emit_store_reg_i(def, result, ra);
emit_store_type(def, ra, LUA_TNUMINT);
emit_store_reg_i_withtype(def, result, ra);
}

// R(A) := RK(B) + C, int+c
Expand All @@ -114,8 +108,7 @@ void RaviCodeGenerator::emit_ADDIN(RaviFunctionDef *def, int A, int B, int C) {
llvm::Value *result = def->builder->CreateAdd(
lhs, llvm::ConstantInt::get(def->types->lua_IntegerT, C), "", false,
true);
emit_store_reg_i(def, result, ra);
emit_store_type(def, ra, LUA_TNUMINT);
emit_store_reg_i_withtype(def, result, ra);
}

// R(A) := RK(B) - RK(C), float-float
Expand All @@ -127,8 +120,7 @@ void RaviCodeGenerator::emit_SUBFF(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *lhs = emit_load_reg_n(def, rb);
llvm::Instruction *rhs = emit_load_reg_n(def, rc);
llvm::Value *result = def->builder->CreateFSub(lhs, rhs);
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) - RK(C), float-int
Expand All @@ -141,8 +133,7 @@ void RaviCodeGenerator::emit_SUBFI(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *rhs = emit_load_reg_i(def, rc);
llvm::Value *result = def->builder->CreateFSub(
lhs, def->builder->CreateSIToFP(rhs, def->types->lua_NumberT));
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) - RK(C), int-float
Expand All @@ -155,8 +146,7 @@ void RaviCodeGenerator::emit_SUBIF(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *rhs = emit_load_reg_n(def, rc);
llvm::Value *result = def->builder->CreateFSub(
def->builder->CreateSIToFP(lhs, def->types->lua_NumberT), rhs);
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) - RK(C), int-int
Expand All @@ -168,8 +158,7 @@ void RaviCodeGenerator::emit_SUBII(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *lhs = emit_load_reg_i(def, rb);
llvm::Instruction *rhs = emit_load_reg_i(def, rc);
llvm::Value *result = def->builder->CreateSub(lhs, rhs, "", false, true);
emit_store_reg_i(def, result, ra);
emit_store_type(def, ra, LUA_TNUMINT);
emit_store_reg_i_withtype(def, result, ra);
}

// R(A) := RK(B) - C, float - c
Expand All @@ -182,8 +171,7 @@ void RaviCodeGenerator::emit_SUBFN(RaviFunctionDef *def, int A, int B, int C) {
lhs,
def->builder->CreateSIToFP(llvm::ConstantInt::get(def->types->C_intT, C),
def->types->lua_NumberT));
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := B - RK(C), b - float
Expand All @@ -196,8 +184,7 @@ void RaviCodeGenerator::emit_SUBNF(RaviFunctionDef *def, int A, int B, int C) {
def->builder->CreateSIToFP(llvm::ConstantInt::get(def->types->C_intT, B),
def->types->lua_NumberT),
rhs);
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := B - RK(C), b - int
Expand All @@ -209,8 +196,7 @@ void RaviCodeGenerator::emit_SUBIN(RaviFunctionDef *def, int A, int B, int C) {
llvm::Value *result = def->builder->CreateSub(
lhs, llvm::ConstantInt::get(def->types->lua_IntegerT, C), "", false,
true);
emit_store_reg_i(def, result, ra);
emit_store_type(def, ra, LUA_TNUMINT);
emit_store_reg_i_withtype(def, result, ra);
}

// R(A) := RK(B) - C, int - c
Expand All @@ -222,8 +208,7 @@ void RaviCodeGenerator::emit_SUBNI(RaviFunctionDef *def, int A, int B, int C) {
llvm::Value *result = def->builder->CreateSub(
llvm::ConstantInt::get(def->types->lua_IntegerT, C), rhs, "", false,
true);
emit_store_reg_i(def, result, ra);
emit_store_type(def, ra, LUA_TNUMINT);
emit_store_reg_i_withtype(def, result, ra);
}

// R(A) := RK(B) * C, float*c
Expand All @@ -236,8 +221,7 @@ void RaviCodeGenerator::emit_MULFN(RaviFunctionDef *def, int A, int B, int C) {
lhs,
def->builder->CreateSIToFP(llvm::ConstantInt::get(def->types->C_intT, C),
def->types->lua_NumberT));
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) * RK(C), float*float
Expand All @@ -249,8 +233,7 @@ void RaviCodeGenerator::emit_MULFF(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *lhs = emit_load_reg_n(def, rb);
llvm::Instruction *rhs = emit_load_reg_n(def, rc);
llvm::Value *result = def->builder->CreateFMul(lhs, rhs);
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) * RK(C), float*int
Expand All @@ -263,8 +246,7 @@ void RaviCodeGenerator::emit_MULFI(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *rhs = emit_load_reg_i(def, rc);
llvm::Value *result = def->builder->CreateFMul(
lhs, def->builder->CreateSIToFP(rhs, def->types->lua_NumberT));
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) * RK(C), int*int
Expand All @@ -277,8 +259,7 @@ void RaviCodeGenerator::emit_MULII(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *lhs = emit_load_reg_i(def, rb);
llvm::Instruction *rhs = emit_load_reg_i(def, rc);
llvm::Value *result = def->builder->CreateMul(lhs, rhs, "", false, true);
emit_store_reg_i(def, result, ra);
emit_store_type(def, ra, LUA_TNUMINT);
emit_store_reg_i_withtype(def, result, ra);
}

// R(A) := RK(B) * C, int*c
Expand All @@ -290,8 +271,7 @@ void RaviCodeGenerator::emit_MULIN(RaviFunctionDef *def, int A, int B, int C) {
llvm::Value *result = def->builder->CreateMul(
lhs, llvm::ConstantInt::get(def->types->lua_IntegerT, C), "", false,
true);
emit_store_reg_i(def, result, ra);
emit_store_type(def, ra, LUA_TNUMINT);
emit_store_reg_i_withtype(def, result, ra);
}

// R(A) := RK(B) / RK(C), float/float
Expand All @@ -303,8 +283,7 @@ void RaviCodeGenerator::emit_DIVFF(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *lhs = emit_load_reg_n(def, rb);
llvm::Instruction *rhs = emit_load_reg_n(def, rc);
llvm::Value *result = def->builder->CreateFDiv(lhs, rhs);
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) / RK(C), float/int
Expand All @@ -317,8 +296,7 @@ void RaviCodeGenerator::emit_DIVFI(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *rhs = emit_load_reg_i(def, rc);
llvm::Value *result = def->builder->CreateFDiv(
lhs, def->builder->CreateSIToFP(rhs, def->types->lua_NumberT));
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) / RK(C), int/float
Expand All @@ -331,8 +309,7 @@ void RaviCodeGenerator::emit_DIVIF(RaviFunctionDef *def, int A, int B, int C) {
llvm::Instruction *rhs = emit_load_reg_n(def, rc);
llvm::Value *result = def->builder->CreateFDiv(
def->builder->CreateSIToFP(lhs, def->types->lua_NumberT), rhs);
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}

// R(A) := RK(B) / RK(C), int/int but result is float
Expand All @@ -346,7 +323,6 @@ void RaviCodeGenerator::emit_DIVII(RaviFunctionDef *def, int A, int B, int C) {
llvm::Value *result = def->builder->CreateFDiv(
def->builder->CreateSIToFP(lhs, def->types->lua_NumberT),
def->builder->CreateSIToFP(rhs, def->types->lua_NumberT));
emit_store_reg_n(def, result, ra);
emit_store_type(def, ra, LUA_TNUMFLT);
emit_store_reg_n_withtype(def, result, ra);
}
}

0 comments on commit b65e5d2

Please sign in to comment.