Skip to content

Commit

Permalink
some refactoring
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@2296 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information
vincentisambart committed Aug 12, 2009
1 parent 4ac6227 commit 2a1240c
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 70 deletions.
120 changes: 50 additions & 70 deletions compiler.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2735,6 +2735,52 @@ RoxorCompiler::compile_node_error(const char *msg, NODE *node)
abort(); abort();
} }


void
RoxorCompiler::compile_keep_vars(BasicBlock *startBB, BasicBlock *mergeBB)
{
if (keepVarsFunc == NULL) {
// void rb_vm_keep_vars(rb_vm_var_uses *uses, int lvars_size, ...)
std::vector<const Type *> types;
types.push_back(PtrTy);
types.push_back(Type::Int32Ty);
FunctionType *ft = FunctionType::get(Type::VoidTy, types, true);
keepVarsFunc = cast<Function>
(module->getOrInsertFunction("rb_vm_keep_vars", ft));
}

BasicBlock *notNullBB = BasicBlock::Create("not_null", startBB->getParent());

bb = startBB;
Value *usesVal = new LoadInst(current_var_uses, "", bb);
Value *notNullCond = new ICmpInst(ICmpInst::ICMP_NE, usesVal, compile_const_pointer(NULL), "", bb);
// we only need to call keepVarsFunc if current_var_uses is not NULL
BranchInst::Create(notNullBB, mergeBB, notNullCond, bb);

bb = notNullBB;

// params must be filled each time because in AOT mode it contains instructions
std::vector<Value *> params;
params.push_back(new LoadInst(current_var_uses, "", bb));
params.push_back(NULL);
int vars_count = 0;
for (std::map<ID, Value *>::iterator iter = lvars.begin();
iter != lvars.end(); ++iter) {
ID name = iter->first;
Value *slot = iter->second;
if (std::find(dvars.begin(), dvars.end(), name) == dvars.end()) {
Value *id_val = compile_id(name);
params.push_back(id_val);
params.push_back(slot);
vars_count++;
}
}
params[1] = ConstantInt::get(Type::Int32Ty, vars_count);

CallInst::Create(keepVarsFunc, params.begin(), params.end(), "", bb);

BranchInst::Create(mergeBB, bb);
}

Value * Value *
RoxorCompiler::compile_node(NODE *node) RoxorCompiler::compile_node(NODE *node)
{ {
Expand Down Expand Up @@ -2932,16 +2978,6 @@ RoxorCompiler::compile_node(NODE *node)
// current_lvar_uses has 2 uses or more if it is really used // current_lvar_uses has 2 uses or more if it is really used
// (there is always a StoreInst in which we assign it NULL) // (there is always a StoreInst in which we assign it NULL)
if (current_var_uses != NULL && current_var_uses->hasNUsesOrMore(2)) { if (current_var_uses != NULL && current_var_uses->hasNUsesOrMore(2)) {
if (keepVarsFunc == NULL) {
// void rb_vm_keep_vars(rb_vm_var_uses *uses, int lvars_size, ...)
std::vector<const Type *> types;
types.push_back(PtrTy);
types.push_back(Type::Int32Ty);
FunctionType *ft = FunctionType::get(Type::VoidTy, types, true);
keepVarsFunc = cast<Function>
(module->getOrInsertFunction("rb_vm_keep_vars", ft));
}

// searches all ReturnInst in the function we just created and add before // searches all ReturnInst in the function we just created and add before
// a call to the function to save the local variables if necessary // a call to the function to save the local variables if necessary
// (we can't do this before finishing compiling the whole function // (we can't do this before finishing compiling the whole function
Expand All @@ -2959,47 +2995,18 @@ RoxorCompiler::compile_node(NODE *node)
} }
} }
} }
// we have to process the blocks in a second loop because
// we can't modify the blocks while iterating on them
for (std::vector<ReturnInst *>::iterator inst_it = to_fix.begin(); for (std::vector<ReturnInst *>::iterator inst_it = to_fix.begin();
inst_it != to_fix.end(); inst_it != to_fix.end();
++inst_it) { ++inst_it) {


ReturnInst *inst = *inst_it; ReturnInst *inst = *inst_it;

BasicBlock *startBB = inst->getParent(); BasicBlock *startBB = inst->getParent();
BasicBlock *mergeBB = startBB->splitBasicBlock(inst, "merge"); BasicBlock *mergeBB = startBB->splitBasicBlock(inst, "merge");
// we do not want the BranchInst added by splitBasicBlock // we do not want the BranchInst added by splitBasicBlock
startBB->getInstList().pop_back(); startBB->getInstList().pop_back();
BasicBlock *notNullBB = BasicBlock::Create("not_null", f); compile_keep_vars(startBB, mergeBB);

bb = startBB;
Value *usesVal = new LoadInst(current_var_uses, "", bb);
Value *notNullCond = new ICmpInst(ICmpInst::ICMP_NE, usesVal, compile_const_pointer(NULL), "", bb);
// we only need to call keepVarsFunc if current_var_uses is not NULL
BranchInst::Create(notNullBB, mergeBB, notNullCond, bb);

bb = notNullBB;

// params must be filled each time because in AOT mode it contains instructions
std::vector<Value *> params;
params.push_back(new LoadInst(current_var_uses, "", bb));
params.push_back(NULL);
int vars_count = 0;
for (std::map<ID, Value *>::iterator iter = lvars.begin();
iter != lvars.end(); ++iter) {
ID name = iter->first;
Value *slot = iter->second;
if (std::find(dvars.begin(), dvars.end(), name) == dvars.end()) {
Value *id_val = compile_id(name);
params.push_back(id_val);
params.push_back(slot);
vars_count++;
}
}
params[1] = ConstantInt::get(Type::Int32Ty, vars_count);

CallInst::Create(keepVarsFunc, params.begin(), params.end(), "", bb);

BranchInst::Create(mergeBB, bb);
} }


if (new_rescue_bb->use_empty()) { if (new_rescue_bb->use_empty()) {
Expand All @@ -3009,35 +3016,8 @@ RoxorCompiler::compile_node(NODE *node)
bb = new_rescue_bb; bb = new_rescue_bb;
compile_landing_pad_header(); compile_landing_pad_header();


// call keepVarsFunc if current_var_uses is not NULL
BasicBlock *notNullBB = BasicBlock::Create("not_null", f);
BasicBlock *mergeBB = BasicBlock::Create("merge", f); BasicBlock *mergeBB = BasicBlock::Create("merge", f);
Value *usesVal = new LoadInst(current_var_uses, "", bb); compile_keep_vars(new_rescue_bb, mergeBB);
Value *notNullCond = new ICmpInst(ICmpInst::ICMP_NE, usesVal, compile_const_pointer(NULL), "", bb);
BranchInst::Create(notNullBB, mergeBB, notNullCond, bb);
bb = notNullBB;

// params must be filled again because in AOT mode it contains instructions
std::vector<Value *> params;
params.push_back(new LoadInst(current_var_uses, "", bb));
params.push_back(NULL);
int vars_count = 0;
for (std::map<ID, Value *>::iterator iter = lvars.begin();
iter != lvars.end(); ++iter) {
ID name = iter->first;
Value *slot = iter->second;
if (std::find(dvars.begin(), dvars.end(), name) == dvars.end()) {
Value *id_val = compile_id(name);
params.push_back(id_val);
params.push_back(slot);
vars_count++;
}
}
params[1] = ConstantInt::get(Type::Int32Ty, vars_count);

CallInst::Create(keepVarsFunc, params.begin(), params.end(), "", bb);

BranchInst::Create(mergeBB, bb);


bb = mergeBB; bb = mergeBB;
compile_rethrow_exception(); compile_rethrow_exception();
Expand Down
1 change: 1 addition & 0 deletions compiler.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ class RoxorCompiler {
bool float_op, bool *is_predicate); bool float_op, bool *is_predicate);
Value *compile_double_coercion(Value *val, Value *mask, Value *compile_double_coercion(Value *val, Value *mask,
BasicBlock *fallback_bb, Function *f); BasicBlock *fallback_bb, Function *f);
void compile_keep_vars(BasicBlock *startBB, BasicBlock *mergeBB);


SEL mid_to_sel(ID mid, int arity); SEL mid_to_sel(ID mid, int arity);
}; };
Expand Down

0 comments on commit 2a1240c

Please sign in to comment.