refactor/cleanup

pull/81/head
Dibyendu Majumdar 9 years ago
parent ab9771299a
commit 9125af5981

@ -89,12 +89,10 @@ Compatibility with Lua
----------------------
Ravi should be able to run all Lua 5.3 programs in interpreted mode. When JIT compilation is enabled some things may not work:
* You cannot yield from a compiled function
* The debugger doesn't work when JIT compilation is turned on as information it requires is not available
* You cannot yield from a compiled function, so if you use coroutines then it is better to use the interpreter, as compiled code does not support coroutines
* The debugger doesn't work when JIT compilation is turned on as information it requires is not available; the debugger also does not support Ravi's extended opcodes
* JIT compilation is work in progress and not all features are supported yet
Ravi also supports optional typing and enhanced types such as arrays (described later). Programs using these features cannot be run by standard Lua.
However all types in Ravi can be passed to Lua functions - there are some restrictions on arrays that are described in a later section.
* Ravi supports optional typing and enhanced types such as arrays (described later). Programs using these features cannot be run by standard Lua. However all types in Ravi can be passed to Lua functions - there are some restrictions on arrays that are described in a later section. Values crossing from Lua to Ravi may be subjected to typechecks.
Documentation
--------------

@ -550,8 +550,11 @@ public:
llvm::Value *emit_boolean_testfalse(RaviFunctionDef *def, llvm::Value *reg,
bool donot);
// L->top = ci->top
void emit_refresh_L_top(RaviFunctionDef *def);
// L->top = R(B)
void emit_set_L_top_toreg(RaviFunctionDef *def, llvm::Instruction *base_ptr, int B);
// Look for Lua bytecodes that are jump targets and allocate
// a BasicBlock for each such target in def->jump_targets.

@ -89,7 +89,7 @@ Compatibility with Lua
----------------------
Ravi should be able to run all Lua 5.3 programs in interpreted mode. When JIT compilation is enabled some things may not work:
* You cannot yield from a compiled function, so if you use coroutines then it is better to use the interpreter
* You cannot yield from a compiled function, so if you use coroutines then it is better to use the interpreter, as compiled code does not support coroutines
* The debugger doesn't work when JIT compilation is turned on as information it requires is not available; the debugger also does not support Ravi's extended opcodes
* JIT compilation is work in progress and not all features are supported yet
* Ravi supports optional typing and enhanced types such as arrays (described later). Programs using these features cannot be run by standard Lua. However all types in Ravi can be passed to Lua functions - there are some restrictions on arrays that are described in a later section. Values crossing from Lua to Ravi may be subjected to typechecks.

@ -24,6 +24,20 @@
namespace ravi {
// OP_JMP
void RaviCodeGenerator::emit_JMP(RaviFunctionDef *def, int j) {
assert(def->jmp_targets[j].jmp1);
if (def->builder->GetInsertBlock()->getTerminator()) {
llvm::BasicBlock *jmp_block =
llvm::BasicBlock::Create(def->jitState->context(), "jump", def->f);
def->builder->SetInsertPoint(jmp_block);
}
def->builder->CreateBr(def->jmp_targets[j].jmp1);
llvm::BasicBlock *block =
llvm::BasicBlock::Create(def->jitState->context(), "postjump", def->f);
def->builder->SetInsertPoint(block);
}
// Handle OP_CALL
void RaviCodeGenerator::emit_CALL(RaviFunctionDef *def, llvm::Value *L_ci,
llvm::Value *proto, int A, int B, int C) {
@ -48,16 +62,17 @@ void RaviCodeGenerator::emit_CALL(RaviFunctionDef *def, llvm::Value *L_ci,
// if (b != 0)
if (B != 0) {
emit_set_L_top_toreg(def, base_ptr, A + B);
// L->top = ra + b
// See similar construct in OP_RETURN
// Get pointer to register at ra + b
llvm::Value *ptr = emit_array_get(def, base_ptr, A + B);
//llvm::Value *ptr = emit_array_get(def, base_ptr, A + B);
// Get pointer to L->top
top = emit_gep(def, "L.top", def->L, 0, 4);
//top = emit_gep(def, "L.top", def->L, 0, 4);
// Assign to L->top
llvm::Instruction *ins = def->builder->CreateStore(ptr, top);
ins->setMetadata(llvm::LLVMContext::MD_tbaa,
def->types->tbaa_luaState_topT);
//llvm::Instruction *ins = def->builder->CreateStore(ptr, top);
//ins->setMetadata(llvm::LLVMContext::MD_tbaa,
// def->types->tbaa_luaState_topT);
}
// luaD_precall() returns following
@ -106,18 +121,19 @@ void RaviCodeGenerator::emit_CALL(RaviFunctionDef *def, llvm::Value *L_ci,
def->builder->SetInsertPoint(then1_block);
// TODO replace below with emit_refresh_L_top()
emit_refresh_L_top(def);
// Get pointer to ci->top
llvm::Value *citop = emit_gep(def, "ci_top", def->ci_val, 0, 1);
//llvm::Value *citop = emit_gep(def, "ci_top", def->ci_val, 0, 1);
// Load ci->top
llvm::Instruction *citop_val = def->builder->CreateLoad(citop);
//llvm::Instruction *citop_val = def->builder->CreateLoad(citop);
// TODO set tbaa
if (!top)
//if (!top)
// Get L->top
top = emit_gep(def, "L_top", def->L, 0, 4);
// top = emit_gep(def, "L_top", def->L, 0, 4);
// Assign ci>top to L->top
auto ins = def->builder->CreateStore(citop_val, top);
ins->setMetadata(llvm::LLVMContext::MD_tbaa,
def->types->tbaa_luaState_topT);
//auto ins = def->builder->CreateStore(citop_val, top);
//ins->setMetadata(llvm::LLVMContext::MD_tbaa,
// def->types->tbaa_luaState_topT);
}
def->builder->CreateBr(end_block);
def->f->getBasicBlockList().push_back(end_block);

@ -78,19 +78,6 @@ llvm::Value *RaviCodeGenerator::emit_array_get(RaviFunctionDef *def,
ptr, llvm::ConstantInt::get(def->types->C_intT, offset));
}
void RaviCodeGenerator::emit_JMP(RaviFunctionDef *def, int j) {
assert(def->jmp_targets[j].jmp1);
if (def->builder->GetInsertBlock()->getTerminator()) {
llvm::BasicBlock *jmp_block =
llvm::BasicBlock::Create(def->jitState->context(), "jump", def->f);
def->builder->SetInsertPoint(jmp_block);
}
def->builder->CreateBr(def->jmp_targets[j].jmp1);
llvm::BasicBlock *block =
llvm::BasicBlock::Create(def->jitState->context(), "postjump", def->f);
def->builder->SetInsertPoint(block);
}
llvm::Instruction *RaviCodeGenerator::emit_load_base(RaviFunctionDef *def) {
// Load pointer to base
llvm::Instruction *base_ptr = def->builder->CreateLoad(def->Ci_base);
@ -200,6 +187,31 @@ llvm::Value *RaviCodeGenerator::emit_gep_rkb(RaviFunctionDef *def,
return rb;
}
void RaviCodeGenerator::emit_refresh_L_top(RaviFunctionDef *def) {
// Get pointer to ci->top
llvm::Value *citop = emit_gep(def, "ci_top", def->ci_val, 0, 1);
// Load ci->top
llvm::Instruction *citop_val = def->builder->CreateLoad(citop);
// TODO set tbaa
// Get L->top
llvm::Value *top = emit_gep(def, "L_top", def->L, 0, 4);
// Assign ci>top to L->top
auto ins = def->builder->CreateStore(citop_val, top);
ins->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_luaState_topT);
}
void RaviCodeGenerator::emit_set_L_top_toreg(RaviFunctionDef *def, llvm::Instruction *base_ptr, int B) {
// L->top = R(B)
// Get pointer to register at R(B)
llvm::Value *ptr = emit_array_get(def, base_ptr, B);
// Get pointer to L->top
llvm::Value *top = emit_gep(def, "L.top", def->L, 0, 4);
// Assign to L->top
llvm::Instruction *ins = def->builder->CreateStore(ptr, top);
ins->setMetadata(llvm::LLVMContext::MD_tbaa,
def->types->tbaa_luaState_topT);
}
// Check if we can compile
// The cases we can compile will increase over time
bool RaviCodeGenerator::canCompile(Proto *p) {

@ -77,42 +77,43 @@ void RaviCodeGenerator::emit_MOVE(RaviFunctionDef *def, llvm::Value *L_ci,
// Load pointer to base
llvm::Instruction *base_ptr = emit_load_base(def);
llvm::Value *src;
llvm::Value *dest;
lua_assert(A != B);
if (A == 0) {
// If A is 0 we can use the base pointer which is &base[0]
dest = base_ptr;
} else {
// emit &base[A]
dest = emit_array_get(def, base_ptr, A);
}
if (B == 0) {
// If Bx is 0 we can use the base pointer which is &k[0]
src = base_ptr;
} else {
// emit &base[B]
src = emit_array_get(def, base_ptr, B);
}
// Below is more efficient that memcpy()
// destvalue->value->i = srcvalue->value->i;
llvm::Value *srcvalue = emit_gep(def, "src.value", src, 0, 0, 0);
llvm::Value *destvalue = emit_gep(def, "dest.value", dest, 0, 0, 0);
llvm::Instruction *load = def->builder->CreateLoad(srcvalue);
load->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_nT);
llvm::Instruction *store = def->builder->CreateStore(load, destvalue);
store->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_nT);
// destvalue->type = srcvalue->type
llvm::Value *srctype = emit_gep(def, "src.tt", src, 0, 1);
llvm::Value *desttype = emit_gep(def, "dest.tt", dest, 0, 1);
load = def->builder->CreateLoad(srctype);
load->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_ttT);
store = def->builder->CreateStore(load, desttype);
store->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_ttT);
llvm::Value *src = emit_gep_ra(def, base_ptr, B);
llvm::Value *dest = emit_gep_ra(def, base_ptr, A);
emit_assign(def, dest, src);
//if (A == 0) {
// // If A is 0 we can use the base pointer which is &base[0]
// dest = base_ptr;
//} else {
// // emit &base[A]
// dest = emit_array_get(def, base_ptr, A);
//}
//if (B == 0) {
// // If Bx is 0 we can use the base pointer which is &k[0]
// src = base_ptr;
//} else {
// // emit &base[B]
// src = emit_array_get(def, base_ptr, B);
//}
//// Below is more efficient that memcpy()
//// destvalue->value->i = srcvalue->value->i;
//llvm::Value *srcvalue = emit_gep(def, "src.value", src, 0, 0, 0);
//llvm::Value *destvalue = emit_gep(def, "dest.value", dest, 0, 0, 0);
//llvm::Instruction *load = def->builder->CreateLoad(srcvalue);
//load->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_nT);
//llvm::Instruction *store = def->builder->CreateStore(load, destvalue);
//store->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_nT);
//// destvalue->type = srcvalue->type
//llvm::Value *srctype = emit_gep(def, "src.tt", src, 0, 1);
//llvm::Value *desttype = emit_gep(def, "dest.tt", dest, 0, 1);
//load = def->builder->CreateLoad(srctype);
//load->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_ttT);
//store = def->builder->CreateStore(load, desttype);
//store->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_ttT);
}
void RaviCodeGenerator::emit_MOVEI(RaviFunctionDef *def, llvm::Value *L_ci,
@ -429,9 +430,7 @@ void RaviCodeGenerator::emit_LOADK(RaviFunctionDef *def, llvm::Value *L_ci,
// } break;
// Load pointer to base
llvm::Instruction *base_ptr = def->builder->CreateLoad(def->Ci_base);
base_ptr->setMetadata(llvm::LLVMContext::MD_tbaa,
def->types->tbaa_luaState_ci_baseT);
llvm::Instruction *base_ptr = emit_load_base(def);
// Load pointer to k
llvm::Value *k_ptr = def->k_ptr;
@ -439,16 +438,16 @@ void RaviCodeGenerator::emit_LOADK(RaviFunctionDef *def, llvm::Value *L_ci,
// LOADK requires a structure assignment
// in LLVM as far as I can tell this requires a call to
// an intrinsic memcpy
llvm::Value *src;
llvm::Value *dest;
llvm::Value *dest = emit_gep_ra(def, base_ptr, A);
if (A == 0) {
// If A is 0 we can use the base pointer which is &base[0]
dest = base_ptr;
} else {
// emit &base[A]
dest = emit_array_get(def, base_ptr, A);
}
//if (A == 0) {
// // If A is 0 we can use the base pointer which is &base[0]
// dest = base_ptr;
//} else {
// // emit &base[A]
// dest = emit_array_get(def, base_ptr, A);
//}
llvm::Value *src;
if (Bx == 0) {
// If Bx is 0 we can use the base pointer which is &k[0]
src = k_ptr;
@ -457,23 +456,25 @@ void RaviCodeGenerator::emit_LOADK(RaviFunctionDef *def, llvm::Value *L_ci,
src = emit_array_get(def, k_ptr, Bx);
}
// Below is more efficient that memcpy()
// destvalue->value->i = srcvalue->value->i;
// destvalue->value->i = srcvalue->value->i;
llvm::Value *srcvalue = emit_gep(def, "srcvalue", src, 0, 0, 0);
llvm::Value *destvalue = emit_gep(def, "destvalue", dest, 0, 0, 0);
llvm::Instruction *load = def->builder->CreateLoad(srcvalue);
load->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_nT);
llvm::Instruction *store = def->builder->CreateStore(load, destvalue);
store->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_nT);
// destvalue->type = srcvalue->type
llvm::Value *srctype = emit_gep(def, "srctype", src, 0, 1);
llvm::Value *desttype = emit_gep(def, "desttype", dest, 0, 1);
load = def->builder->CreateLoad(srctype);
load->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_ttT);
store = def->builder->CreateStore(load, desttype);
store->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_ttT);
emit_assign(def, dest, src);
//// Below is more efficient that memcpy()
//// destvalue->value->i = srcvalue->value->i;
//// destvalue->value->i = srcvalue->value->i;
//llvm::Value *srcvalue = emit_gep(def, "srcvalue", src, 0, 0, 0);
//llvm::Value *destvalue = emit_gep(def, "destvalue", dest, 0, 0, 0);
//llvm::Instruction *load = def->builder->CreateLoad(srcvalue);
//load->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_nT);
//llvm::Instruction *store = def->builder->CreateStore(load, destvalue);
//store->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_nT);
//// destvalue->type = srcvalue->type
//llvm::Value *srctype = emit_gep(def, "srctype", src, 0, 1);
//llvm::Value *desttype = emit_gep(def, "desttype", dest, 0, 1);
//load = def->builder->CreateLoad(srctype);
//load->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_ttT);
//store = def->builder->CreateStore(load, desttype);
//store->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_TValue_ttT);
}
void RaviCodeGenerator::emit_assign(RaviFunctionDef *def, llvm::Value *dest, llvm::Value *src) {

@ -57,9 +57,7 @@ void RaviCodeGenerator::emit_RETURN(RaviFunctionDef *def, llvm::Value *L_ci,
}
// Load pointer to base
llvm::Instruction *base_ptr = def->builder->CreateLoad(def->Ci_base);
base_ptr->setMetadata(llvm::LLVMContext::MD_tbaa,
def->types->tbaa_luaState_ci_baseT);
llvm::Instruction *base_ptr = emit_load_base(def);
llvm::Value *top = nullptr;
@ -68,14 +66,15 @@ void RaviCodeGenerator::emit_RETURN(RaviFunctionDef *def, llvm::Value *L_ci,
//* if (b != 0) L->top = ra + b - 1;
if (B != 0) {
emit_set_L_top_toreg(def, base_ptr, A + B - 1);
// Get pointer to register at ra + b - 1
llvm::Value *ptr = emit_array_get(def, base_ptr, A + B - 1);
//llvm::Value *ptr = emit_array_get(def, base_ptr, A + B - 1);
// Get pointer to L->top
top = emit_gep(def, "L_top", def->L, 0, 4);
//top = emit_gep(def, "L_top", def->L, 0, 4);
// Assign to L->top
llvm::Instruction *ins = def->builder->CreateStore(ptr, top);
ins->setMetadata(llvm::LLVMContext::MD_tbaa,
def->types->tbaa_luaState_topT);
//llvm::Instruction *ins = def->builder->CreateStore(ptr, top);
//ins->setMetadata(llvm::LLVMContext::MD_tbaa,
// def->types->tbaa_luaState_topT);
}
// if (cl->p->sizep > 0) luaF_close(L, base);

@ -24,19 +24,6 @@
namespace ravi {
void RaviCodeGenerator::emit_refresh_L_top(RaviFunctionDef *def) {
// Get pointer to ci->top
llvm::Value *citop = emit_gep(def, "ci_top", def->ci_val, 0, 1);
// Load ci->top
llvm::Instruction *citop_val = def->builder->CreateLoad(citop);
// TODO set tbaa
// Get L->top
llvm::Value *top = emit_gep(def, "L_top", def->L, 0, 4);
// Assign ci>top to L->top
auto ins = def->builder->CreateStore(citop_val, top);
ins->setMetadata(llvm::LLVMContext::MD_tbaa, def->types->tbaa_luaState_topT);
}
void RaviCodeGenerator::emit_TFORCALL(RaviFunctionDef *def, llvm::Value *L_ci,
llvm::Value *proto, int A, int B, int C,
int j, int jA) {

Loading…
Cancel
Save