[unladen-swallow] r1171 committed - Remove PushRel from exception handling....

1 view
Skip to first unread message

unladen...@googlecode.com

unread,
Aug 21, 2010, 2:18:05 PM8/21/10
to unladen...@googlegroups.com
Revision: 1171
Author: e...@4geeks.de
Date: Sat Aug 21 11:17:31 2010
Log: Remove PushRel from exception handling.
Exceptions are stored in additional allocas and wrote on the correct stack
position before entering the handler block.


http://code.google.com/p/unladen-swallow/source/detail?r=1171

Modified:
/trunk/JIT/llvm_fbuilder.cc
/trunk/JIT/llvm_fbuilder.h
/trunk/JIT/opcodes/block.cc

=======================================
--- /trunk/JIT/llvm_fbuilder.cc Sun Aug 15 03:03:27 2010
+++ /trunk/JIT/llvm_fbuilder.cc Sat Aug 21 11:17:31 2010
@@ -596,17 +596,38 @@
"_PyLlvm_FastEnterExceptOrFinally"),
exc_info,
block_type);
- this->PushRel(this->builder_.CreateLoad(
- this->builder_.CreateStructGEP(
- exc_info,
PyTypeBuilder<PyExcInfo>::FIELD_TB)));
- this->PushRel(this->builder_.CreateLoad(
- this->builder_.CreateStructGEP(
- exc_info,
- PyTypeBuilder<PyExcInfo>::FIELD_VAL)));
- this->PushRel(this->builder_.CreateLoad(
- this->builder_.CreateStructGEP(
- exc_info,
- PyTypeBuilder<PyExcInfo>::FIELD_EXC)));
+
+ // We don't know for sure what the absolute stack position will be
+ // after handling an exception. We store the exception in allocas,
+ // the opcode implementation must take care to copy it on the
stack.
+ this->exception_tb_ = this->state_->CreateAllocaInEntryBlock(
+ PyTypeBuilder<PyObject*>::get(this->context_),
+ NULL,
+ "exception_tb");
+ this->exception_val_ = this->state_->CreateAllocaInEntryBlock(
+ PyTypeBuilder<PyObject*>::get(this->context_),
+ NULL,
+ "exception_val");
+ this->exception_exc_ = this->state_->CreateAllocaInEntryBlock(
+ PyTypeBuilder<PyObject*>::get(this->context_),
+ NULL,
+ "exception_exc");
+
+ this->builder_.CreateStore(
+ this->builder_.CreateLoad(
+ this->builder_.CreateStructGEP(
+ exc_info, PyTypeBuilder<PyExcInfo>::FIELD_TB)),
+ this->exception_tb_);
+ this->builder_.CreateStore(
+ this->builder_.CreateLoad(
+ this->builder_.CreateStructGEP(
+ exc_info, PyTypeBuilder<PyExcInfo>::FIELD_VAL)),
+ this->exception_val_);
+ this->builder_.CreateStore(
+ this->builder_.CreateLoad(
+ this->builder_.CreateStructGEP(
+ exc_info, PyTypeBuilder<PyExcInfo>::FIELD_EXC)),
+ this->exception_exc_);
this->builder_.CreateBr(goto_block_handler);

this->builder_.SetInsertPoint(handle_finally);
@@ -633,7 +654,7 @@
this->builder_.SetInsertPoint(push_pseudo_exception);
Value *none = this->state()->GetGlobalVariableFor(&_Py_NoneStruct);
this->state()->IncRef(none);
- this->PushRel(none);
+ this->builder_.CreateStore(none, this->exception_tb_);

llvm::SwitchInst *should_push_retval = this->builder_.CreateSwitch(
unwind_reason, push_no_retval, 2);
@@ -647,12 +668,14 @@
push_retval);

this->builder_.SetInsertPoint(push_retval);
-
this->PushRel(this->builder_.CreateLoad(this->retval_addr_, "retval"));
+ this->builder_.CreateStore(
+ this->builder_.CreateLoad(this->retval_addr_, "retval"),
+ this->exception_val_);
this->builder_.CreateBr(handle_finally_end);

this->builder_.SetInsertPoint(push_no_retval);
this->state()->IncRef(none);
- this->PushRel(none);
+ this->builder_.CreateStore(none, this->exception_val_);

this->FallThroughTo(handle_finally_end);
// END_FINALLY expects to find the unwind reason on the top of
@@ -665,7 +688,9 @@
this->builder_.CreateZExt(unwind_reason,

PyTypeBuilder<long>::get(this->context_)),
"unwind_reason_as_pyint");
- this->PushRel(unwind_reason_as_pyint);
+ this->builder_.CreateStore(
+ unwind_reason_as_pyint,
+ this->exception_exc_);

this->FallThroughTo(goto_block_handler);
// Clear the unwind reason while running through the block's
@@ -857,6 +882,17 @@
// TODO(collinwinter): exception block chaining needs to change this.
return this->propagate_exception_block_;
}
+
+void
+LlvmFunctionBuilder::PushException()
+{
+ this->SetOpcodeResult(0,
+ this->builder_.CreateLoad(this->exception_tb_));
+ this->SetOpcodeResult(1,
+ this->builder_.CreateLoad(this->exception_val_));
+ this->SetOpcodeResult(2,
+ this->builder_.CreateLoad(this->exception_exc_));
+}

void
LlvmFunctionBuilder::PopAndDecrefTo(Value *target_stack_pointer)
@@ -1175,20 +1211,6 @@
this->llvm_data_->tbaa_stack.MarkInstruction(from_bottom);
++this->stack_top_;
}
-
-void
-LlvmFunctionBuilder::PushRel(Value *value)
-{
- Value *stack_pointer =
this->builder_.CreateLoad(this->stack_pointer_addr_);
- this->llvm_data_->tbaa_stack.MarkInstruction(stack_pointer);
-
- this->builder_.CreateStore(value, stack_pointer);
- Value *new_stack_pointer = this->builder_.CreateGEP(
- stack_pointer, ConstantInt::get(Type::getInt32Ty(this->context_),
1));
- this->llvm_data_->tbaa_stack.MarkInstruction(stack_pointer);
-
- this->builder_.CreateStore(new_stack_pointer,
this->stack_pointer_addr_);
-}

Value *
LlvmFunctionBuilder::Pop()
=======================================
--- /trunk/JIT/llvm_fbuilder.h Sun Aug 15 03:03:27 2010
+++ /trunk/JIT/llvm_fbuilder.h Sat Aug 21 11:17:31 2010
@@ -302,6 +302,7 @@
/// Return the BasicBlock we should jump to in order to handle a Python
/// exception.
llvm::BasicBlock *GetExceptionBlock() const;
+ void PushException();

// Add a Type to the watch list.
void WatchType(PyTypeObject *type);
@@ -317,7 +318,6 @@
private:
// Stack pointer relative push and pop methods are for internal
// use only.
- void PushRel(llvm::Value *value);
llvm::Value *PopRel();

LlvmFunctionState *state_;
@@ -392,6 +392,9 @@
// Stores one of the UNWIND_XXX constants defined at the top of
// llvm_fbuilder.cc
llvm::Value *unwind_reason_addr_;
+ llvm::Value *exception_tb_;
+ llvm::Value *exception_val_;
+ llvm::Value *exception_exc_;
llvm::BasicBlock *do_return_block_;
llvm::Value *retval_addr_;

=======================================
--- /trunk/JIT/opcodes/block.cc Thu Jul 29 23:33:28 2010
+++ /trunk/JIT/opcodes/block.cc Sat Aug 21 11:17:31 2010
@@ -59,6 +59,10 @@
llvm::BasicBlock *fallthrough)
{
this->CallBlockSetup(::SETUP_EXCEPT, target, target_opindex);
+ llvm::BasicBlock *block = this->builder_.GetInsertBlock();
+ this->builder_.SetInsertPoint(target);
+ this->fbuilder_->PushException();
+ this->builder_.SetInsertPoint(block);
}

void
@@ -66,7 +70,14 @@
int target_opindex,
llvm::BasicBlock *fallthrough)
{
- this->CallBlockSetup(::SETUP_FINALLY, target, target_opindex);
+ BasicBlock *unwind =
+ this->state_->CreateBasicBlock("SETUP_FINALLY_unwind");
+ this->CallBlockSetup(::SETUP_FINALLY, unwind, target_opindex);
+ llvm::BasicBlock *block = this->builder_.GetInsertBlock();
+ this->builder_.SetInsertPoint(unwind);
+ this->fbuilder_->PushException();
+ this->builder_.CreateBr(target);
+ this->builder_.SetInsertPoint(block);
}

void

Reply all
Reply to author
Forward
0 new messages