Commit cd769bc5 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Exceptions part #3: irgen

parent 7efd8225
...@@ -116,6 +116,7 @@ COMMON_CXXFLAGS := -g -Werror -Wreturn-type -Woverloaded-virtual -Wall -Wno-sign ...@@ -116,6 +116,7 @@ COMMON_CXXFLAGS := -g -Werror -Wreturn-type -Woverloaded-virtual -Wall -Wno-sign
COMMON_CXXFLAGS += -std=c++11 COMMON_CXXFLAGS += -std=c++11
COMMON_CXXFLAGS += -Wextra -Wno-sign-compare COMMON_CXXFLAGS += -Wextra -Wno-sign-compare
COMMON_CXXFLAGS += -Wno-unused-parameter # should use the "unused" attribute COMMON_CXXFLAGS += -Wno-unused-parameter # should use the "unused" attribute
COMMON_CXXFLAGS += -fexceptions -fno-rtti
ifeq ($(ENABLE_VALGRIND),0) ifeq ($(ENABLE_VALGRIND),0)
COMMON_CXXFLAGS += -DNVALGRIND COMMON_CXXFLAGS += -DNVALGRIND
......
This diff is collapsed.
...@@ -103,7 +103,7 @@ public: ...@@ -103,7 +103,7 @@ public:
printf("call not defined for %s\n", debugName().c_str()); printf("call not defined for %s\n", debugName().c_str());
abort(); abort();
} }
virtual void print(IREmitter& emitter, VAR* value) { virtual void print(IREmitter& emitter, const OpInfo& info, VAR* value) {
printf("print not defined for %s\n", debugName().c_str()); printf("print not defined for %s\n", debugName().c_str());
abort(); abort();
} }
...@@ -219,7 +219,7 @@ public: ...@@ -219,7 +219,7 @@ public:
const std::vector<CompilerVariable*>& args) = 0; const std::vector<CompilerVariable*>& args) = 0;
virtual CompilerVariable* call(IREmitter& emitter, const OpInfo& info, const std::vector<CompilerVariable*>& args) virtual CompilerVariable* call(IREmitter& emitter, const OpInfo& info, const std::vector<CompilerVariable*>& args)
= 0; = 0;
virtual void print(IREmitter& emitter) = 0; virtual void print(IREmitter& emitter, const OpInfo& info) = 0;
virtual ConcreteCompilerVariable* len(IREmitter& emitter, const OpInfo& info) = 0; virtual ConcreteCompilerVariable* len(IREmitter& emitter, const OpInfo& info) = 0;
virtual CompilerVariable* getitem(IREmitter& emitter, const OpInfo& info, CompilerVariable*) = 0; virtual CompilerVariable* getitem(IREmitter& emitter, const OpInfo& info, CompilerVariable*) = 0;
}; };
...@@ -283,7 +283,7 @@ public: ...@@ -283,7 +283,7 @@ public:
const std::vector<CompilerVariable*>& args) override { const std::vector<CompilerVariable*>& args) override {
return type->call(emitter, info, this, args); return type->call(emitter, info, this, args);
} }
void print(IREmitter& emitter) override { type->print(emitter, this); } void print(IREmitter& emitter, const OpInfo& info) override { type->print(emitter, info, this); }
ConcreteCompilerVariable* len(IREmitter& emitter, const OpInfo& info) override { ConcreteCompilerVariable* len(IREmitter& emitter, const OpInfo& info) override {
return type->len(emitter, info, this); return type->len(emitter, info, this);
} }
......
...@@ -317,10 +317,10 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua ...@@ -317,10 +317,10 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
SymbolTable* initial_syms = new SymbolTable(); SymbolTable* initial_syms = new SymbolTable();
// llvm::BranchInst::Create(llvm_entry_blocks[entry_descriptor->backedge->target->idx], entry_block); // llvm::BranchInst::Create(llvm_entry_blocks[entry_descriptor->backedge->target->idx], entry_block);
std::unique_ptr<IREmitter> entry_emitter(createIREmitter(irstate)); llvm::BasicBlock* osr_entry_block_end = osr_entry_block;
entry_emitter->getBuilder()->SetInsertPoint(osr_entry_block); llvm::BasicBlock* osr_unbox_block_end = osr_unbox_block;
std::unique_ptr<IREmitter> unbox_emitter(createIREmitter(irstate)); std::unique_ptr<IREmitter> entry_emitter(createIREmitter(irstate, osr_entry_block_end));
unbox_emitter->getBuilder()->SetInsertPoint(osr_unbox_block); std::unique_ptr<IREmitter> unbox_emitter(createIREmitter(irstate, osr_unbox_block_end));
CFGBlock* target_block = entry_descriptor->backedge->target; CFGBlock* target_block = entry_descriptor->backedge->target;
...@@ -493,8 +493,8 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua ...@@ -493,8 +493,8 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
std::unique_ptr<IRGenerator> generator( std::unique_ptr<IRGenerator> generator(
createIRGenerator(irstate, llvm_entry_blocks, block, types, out_guards, in_guards, is_partial)); createIRGenerator(irstate, llvm_entry_blocks, block, types, out_guards, in_guards, is_partial));
std::unique_ptr<IREmitter> emitter(createIREmitter(irstate)); llvm::BasicBlock* entry_block_end = llvm_entry_blocks[block];
emitter->getBuilder()->SetInsertPoint(llvm_entry_blocks[block]); std::unique_ptr<IREmitter> emitter(createIREmitter(irstate, entry_block_end));
PHITable* phis = NULL; PHITable* phis = NULL;
if (!is_partial) { if (!is_partial) {
...@@ -703,8 +703,8 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua ...@@ -703,8 +703,8 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
llvm::BasicBlock* off_ramp = llvm::BasicBlock::Create(g.context, "deopt_ramp", irstate->getLLVMFunction()); llvm::BasicBlock* off_ramp = llvm::BasicBlock::Create(g.context, "deopt_ramp", irstate->getLLVMFunction());
offramps.push_back(off_ramp); offramps.push_back(off_ramp);
IREmitter* emitter = createIREmitter(irstate); llvm::BasicBlock* off_ramp_end = off_ramp;
emitter->getBuilder()->SetInsertPoint(off_ramp); IREmitter* emitter = createIREmitter(irstate, off_ramp_end);
emitters.push_back(emitter); emitters.push_back(emitter);
block_guards[i]->branch->setSuccessor(1, off_ramp); block_guards[i]->branch->setSuccessor(1, off_ramp);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#ifndef PYSTON_CODEGEN_IRGEN_H #ifndef PYSTON_CODEGEN_IRGEN_H
#define PYSTON_CODEGEN_IRGEN_H #define PYSTON_CODEGEN_IRGEN_H
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Function.h" #include "llvm/IR/Function.h"
#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRBuilder.h"
...@@ -30,6 +31,18 @@ class AST_expr; ...@@ -30,6 +31,18 @@ class AST_expr;
class GCBuilder; class GCBuilder;
class IREmitter; class IREmitter;
struct ExcInfo {
public:
llvm::BasicBlock* exc_dest;
bool needsInvoke() { return exc_dest != NULL; }
ExcInfo(llvm::BasicBlock* exc_dest) : exc_dest(exc_dest) {}
static ExcInfo none() { return ExcInfo(NULL); }
};
// TODO get rid of this
class MyInserter : public llvm::IRBuilderDefaultInserter<true> { class MyInserter : public llvm::IRBuilderDefaultInserter<true> {
private: private:
IREmitter* emitter; IREmitter* emitter;
...@@ -55,8 +68,14 @@ public: ...@@ -55,8 +68,14 @@ public:
virtual CompiledFunction* currentFunction() = 0; virtual CompiledFunction* currentFunction() = 0;
virtual llvm::Function* getIntrinsic(llvm::Intrinsic::ID) = 0; virtual llvm::Function* getIntrinsic(llvm::Intrinsic::ID) = 0;
virtual llvm::Value* createPatchpoint(const PatchpointSetupInfo* pp, void* func_addr,
const std::vector<llvm::Value*>& args) = 0; virtual llvm::CallSite createCall(ExcInfo exc_info, llvm::Value* callee, const std::vector<llvm::Value*>& args) = 0;
virtual llvm::CallSite createCall(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1) = 0;
virtual llvm::CallSite createCall2(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2) = 0;
virtual llvm::CallSite createCall3(ExcInfo exc_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2,
llvm::Value* arg3) = 0;
virtual llvm::CallSite createPatchpoint(const PatchpointSetupInfo* pp, void* func_addr,
const std::vector<llvm::Value*>& args, ExcInfo exc_info) = 0;
}; };
CompiledFunction* compileFunction(SourceInfo* source, const OSREntryDescriptor* entry_descriptor, CompiledFunction* compileFunction(SourceInfo* source, const OSREntryDescriptor* entry_descriptor,
...@@ -70,8 +89,10 @@ private: ...@@ -70,8 +89,10 @@ private:
TypeRecorder* const type_recorder; TypeRecorder* const type_recorder;
public: public:
OpInfo(EffortLevel::EffortLevel effort, TypeRecorder* type_recorder) const ExcInfo exc_info;
: effort(effort), type_recorder(type_recorder) {}
OpInfo(EffortLevel::EffortLevel effort, TypeRecorder* type_recorder, ExcInfo exc_info)
: effort(effort), type_recorder(type_recorder), exc_info(exc_info) {}
bool isInterpreted() const { return effort == EffortLevel::INTERPRETED; } bool isInterpreted() const { return effort == EffortLevel::INTERPRETED; }
TypeRecorder* getTypeRecorder() const { return type_recorder; } TypeRecorder* getTypeRecorder() const { return type_recorder; }
......
This diff is collapsed.
...@@ -190,7 +190,7 @@ public: ...@@ -190,7 +190,7 @@ public:
virtual EndingState getEndingSymbolTable() = 0; virtual EndingState getEndingSymbolTable() = 0;
}; };
IREmitter* createIREmitter(IRGenState* irstate); IREmitter* createIREmitter(IRGenState* irstate, llvm::BasicBlock*& curblock);
IRGenerator* createIRGenerator(IRGenState* irstate, std::unordered_map<CFGBlock*, llvm::BasicBlock*>& entry_blocks, IRGenerator* createIRGenerator(IRGenState* irstate, std::unordered_map<CFGBlock*, llvm::BasicBlock*>& entry_blocks,
CFGBlock* myblock, TypeAnalysis* types, GuardList& out_guards, CFGBlock* myblock, TypeAnalysis* types, GuardList& out_guards,
const GuardList& in_guards, bool is_partial); const GuardList& in_guards, bool is_partial);
......
...@@ -40,6 +40,11 @@ ...@@ -40,6 +40,11 @@
#include "runtime/inline/boxing.h" #include "runtime/inline/boxing.h"
extern "C" void* __cxa_begin_catch(void*);
extern "C" void __cxa_end_catch();
extern "C" void* __cxa_allocate_exception(size_t);
extern "C" void __cxa_throw(void*, void*, void (*)(void*));
namespace pyston { namespace pyston {
static llvm::Function* lookupFunction(const std::string& name) { static llvm::Function* lookupFunction(const std::string& name) {
...@@ -168,6 +173,7 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -168,6 +173,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(unaryop); GET(unaryop);
GET(import); GET(import);
GET(repr); GET(repr);
GET(isinstance);
GET(checkUnpackingLength); GET(checkUnpackingLength);
GET(raiseAttributeError); GET(raiseAttributeError);
...@@ -203,6 +209,11 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -203,6 +209,11 @@ void initGlobalFuncs(GlobalState& g) {
g.funcs.reoptCompiledFunc = addFunc((void*)reoptCompiledFunc, g.i8_ptr, g.i8_ptr); g.funcs.reoptCompiledFunc = addFunc((void*)reoptCompiledFunc, g.i8_ptr, g.i8_ptr);
g.funcs.compilePartialFunc = addFunc((void*)compilePartialFunc, g.i8_ptr, g.i8_ptr); g.funcs.compilePartialFunc = addFunc((void*)compilePartialFunc, g.i8_ptr, g.i8_ptr);
GET(__cxa_begin_catch);
g.funcs.__cxa_end_catch = addFunc((void*)__cxa_end_catch, g.void_);
g.funcs.__cxa_allocate_exception = addFunc((void*)__cxa_allocate_exception, g.i8_ptr, g.i64);
g.funcs.__cxa_throw = addFunc((void*)__cxa_throw, g.void_, g.i8_ptr, g.i8_ptr, g.i8_ptr);
g.funcs.div_i64_i64 = getFunc((void*)div_i64_i64, "div_i64_i64"); g.funcs.div_i64_i64 = getFunc((void*)div_i64_i64, "div_i64_i64");
g.funcs.mod_i64_i64 = getFunc((void*)mod_i64_i64, "mod_i64_i64"); g.funcs.mod_i64_i64 = getFunc((void*)mod_i64_i64, "mod_i64_i64");
g.funcs.pow_i64_i64 = getFunc((void*)pow_i64_i64, "pow_i64_i64"); g.funcs.pow_i64_i64 = getFunc((void*)pow_i64_i64, "pow_i64_i64");
......
...@@ -23,7 +23,7 @@ struct GlobalFuncs { ...@@ -23,7 +23,7 @@ struct GlobalFuncs {
llvm::Value* boxInt, *unboxInt, *boxFloat, *unboxFloat, *boxStringPtr, *boxCLFunction, *unboxCLFunction, llvm::Value* boxInt, *unboxInt, *boxFloat, *unboxFloat, *boxStringPtr, *boxCLFunction, *unboxCLFunction,
*boxInstanceMethod, *boxBool, *unboxBool, *createTuple, *createDict, *createList, *createSlice, *createClass; *boxInstanceMethod, *boxBool, *unboxBool, *createTuple, *createDict, *createList, *createSlice, *createClass;
llvm::Value* getattr, *setattr, *print, *nonzero, *binop, *compare, *augbinop, *unboxedLen, *getitem, *getclsattr, llvm::Value* getattr, *setattr, *print, *nonzero, *binop, *compare, *augbinop, *unboxedLen, *getitem, *getclsattr,
*getGlobal, *setitem, *unaryop, *import, *repr; *getGlobal, *setitem, *unaryop, *import, *repr, *isinstance;
llvm::Value* checkUnpackingLength, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError, llvm::Value* checkUnpackingLength, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError,
*assertNameDefined, *assertFail; *assertNameDefined, *assertFail;
llvm::Value* printFloat, *listAppendInternal; llvm::Value* printFloat, *listAppendInternal;
...@@ -32,6 +32,8 @@ struct GlobalFuncs { ...@@ -32,6 +32,8 @@ struct GlobalFuncs {
llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr; llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr;
llvm::Value* reoptCompiledFunc, *compilePartialFunc; llvm::Value* reoptCompiledFunc, *compilePartialFunc;
llvm::Value* __cxa_begin_catch, *__cxa_end_catch, *__cxa_allocate_exception, *__cxa_throw;
llvm::Value* div_i64_i64, *mod_i64_i64, *pow_i64_i64; llvm::Value* div_i64_i64, *mod_i64_i64, *pow_i64_i64;
llvm::Value* div_float_float, *mod_float_float, *pow_float_float; llvm::Value* div_float_float, *mod_float_float, *pow_float_float;
}; };
......
...@@ -1200,10 +1200,6 @@ bool PrintVisitor::visit_index(AST_Index* node) { ...@@ -1200,10 +1200,6 @@ bool PrintVisitor::visit_index(AST_Index* node) {
} }
bool PrintVisitor::visit_invoke(AST_Invoke* node) { bool PrintVisitor::visit_invoke(AST_Invoke* node) {
// printf("invoke: ");
// node->value->accept(this);
// printf("; on success goto %d; on error goto %d", node->normal_dest->idx, node->exc_dest->idx);
printf("invoke %d %d: ", node->normal_dest->idx, node->exc_dest->idx); printf("invoke %d %d: ", node->normal_dest->idx, node->exc_dest->idx);
node->stmt->accept(this); node->stmt->accept(this);
return true; return true;
......
...@@ -182,12 +182,8 @@ Box* sorted(Box* obj) { ...@@ -182,12 +182,8 @@ Box* sorted(Box* obj) {
return rtn; return rtn;
} }
Box* isinstance(Box* obj, Box* cls) { Box* isinstance_func(Box* obj, Box* cls) {
assert(cls->cls == type_cls); return boxBool(isinstance(obj, cls, 0));
BoxedClass* ccls = static_cast<BoxedClass*>(cls);
// TODO need to check if it's a subclass, or if subclasshook exists
return boxBool(obj->cls == cls);
} }
Box* getattr2(Box* obj, Box* _str) { Box* getattr2(Box* obj, Box* _str) {
...@@ -288,7 +284,7 @@ void setupBuiltins() { ...@@ -288,7 +284,7 @@ void setupBuiltins() {
addRTFunction(getattr_func, (void*)getattr3, NULL, 3, false); addRTFunction(getattr_func, (void*)getattr3, NULL, 3, false);
builtins_module->giveAttr("getattr", new BoxedFunction(getattr_func)); builtins_module->giveAttr("getattr", new BoxedFunction(getattr_func));
Box* isinstance_obj = new BoxedFunction(boxRTFunction((void*)isinstance, NULL, 2, false)); Box* isinstance_obj = new BoxedFunction(boxRTFunction((void*)isinstance_func, NULL, 2, false));
builtins_module->giveAttr("isinstance", isinstance_obj); builtins_module->giveAttr("isinstance", isinstance_obj);
builtins_module->giveAttr("sorted", new BoxedFunction(boxRTFunction((void*)sorted, NULL, 1, false))); builtins_module->giveAttr("sorted", new BoxedFunction(boxRTFunction((void*)sorted, NULL, 1, false)));
......
...@@ -34,6 +34,11 @@ static void forceLink(void* x) { ...@@ -34,6 +34,11 @@ static void forceLink(void* x) {
printf("%p\n", x); printf("%p\n", x);
} }
extern "C" void __py_personality_v0() {
RELEASE_ASSERT(0, "not used");
}
namespace _force { namespace _force {
#define FORCE(name) forceLink((void*)name) #define FORCE(name) forceLink((void*)name)
...@@ -71,6 +76,7 @@ void force() { ...@@ -71,6 +76,7 @@ void force() {
FORCE(unaryop); FORCE(unaryop);
FORCE(import); FORCE(import);
FORCE(repr); FORCE(repr);
FORCE(isinstance);
FORCE(checkUnpackingLength); FORCE(checkUnpackingLength);
FORCE(raiseAttributeError); FORCE(raiseAttributeError);
......
...@@ -1018,6 +1018,22 @@ extern "C" Box* repr(Box* obj) { ...@@ -1018,6 +1018,22 @@ extern "C" Box* repr(Box* obj) {
return static_cast<BoxedString*>(obj); return static_cast<BoxedString*>(obj);
} }
extern "C" bool isinstance(Box* obj, Box* cls, int64_t flags) {
bool false_on_noncls = (flags & 0x1);
if (!false_on_noncls) {
assert(cls->cls == type_cls);
} else {
if (cls->cls != type_cls)
return false;
}
BoxedClass* ccls = static_cast<BoxedClass*>(cls);
// TODO more complicated than this, but there's no inheritance yet...
return ccls == obj->cls;
}
extern "C" BoxedInt* hash(Box* obj) { extern "C" BoxedInt* hash(Box* obj) {
static StatCounter slowpath_hash("slowpath_hash"); static StatCounter slowpath_hash("slowpath_hash");
slowpath_hash.log(); slowpath_hash.log();
......
...@@ -40,6 +40,7 @@ extern "C" Box* runtimeCall(Box*, int64_t, Box*, Box*, Box*, Box**); ...@@ -40,6 +40,7 @@ extern "C" Box* runtimeCall(Box*, int64_t, Box*, Box*, Box*, Box**);
extern "C" Box* callattr(Box*, std::string*, bool, int64_t, Box*, Box*, Box*, Box**); extern "C" Box* callattr(Box*, std::string*, bool, int64_t, Box*, Box*, Box*, Box**);
extern "C" BoxedString* str(Box* obj); extern "C" BoxedString* str(Box* obj);
extern "C" Box* repr(Box* obj); extern "C" Box* repr(Box* obj);
extern "C" bool isinstance(Box* obj, Box* cls, int64_t flags);
extern "C" BoxedInt* hash(Box* obj); extern "C" BoxedInt* hash(Box* obj);
// extern "C" Box* abs_(Box* obj); // extern "C" Box* abs_(Box* obj);
// extern "C" Box* min_(Box* o0, Box* o1); // extern "C" Box* min_(Box* o0, Box* o1);
......
...@@ -136,7 +136,7 @@ public: ...@@ -136,7 +136,7 @@ public:
class BoxedList : public Box { class BoxedList : public Box {
public: public:
class ElementArray : GCObject { class ElementArray : public GCObject {
public: public:
Box* elts[0]; Box* elts[0];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment