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
COMMON_CXXFLAGS += -std=c++11
COMMON_CXXFLAGS += -Wextra -Wno-sign-compare
COMMON_CXXFLAGS += -Wno-unused-parameter # should use the "unused" attribute
COMMON_CXXFLAGS += -fexceptions -fno-rtti
ifeq ($(ENABLE_VALGRIND),0)
COMMON_CXXFLAGS += -DNVALGRIND
......
This diff is collapsed.
......@@ -103,7 +103,7 @@ public:
printf("call not defined for %s\n", debugName().c_str());
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());
abort();
}
......@@ -219,7 +219,7 @@ public:
const std::vector<CompilerVariable*>& args) = 0;
virtual CompilerVariable* call(IREmitter& emitter, const OpInfo& info, const std::vector<CompilerVariable*>& args)
= 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 CompilerVariable* getitem(IREmitter& emitter, const OpInfo& info, CompilerVariable*) = 0;
};
......@@ -283,7 +283,7 @@ public:
const std::vector<CompilerVariable*>& args) override {
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 {
return type->len(emitter, info, this);
}
......
......@@ -317,10 +317,10 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
SymbolTable* initial_syms = new SymbolTable();
// llvm::BranchInst::Create(llvm_entry_blocks[entry_descriptor->backedge->target->idx], entry_block);
std::unique_ptr<IREmitter> entry_emitter(createIREmitter(irstate));
entry_emitter->getBuilder()->SetInsertPoint(osr_entry_block);
std::unique_ptr<IREmitter> unbox_emitter(createIREmitter(irstate));
unbox_emitter->getBuilder()->SetInsertPoint(osr_unbox_block);
llvm::BasicBlock* osr_entry_block_end = osr_entry_block;
llvm::BasicBlock* osr_unbox_block_end = osr_unbox_block;
std::unique_ptr<IREmitter> entry_emitter(createIREmitter(irstate, osr_entry_block_end));
std::unique_ptr<IREmitter> unbox_emitter(createIREmitter(irstate, osr_unbox_block_end));
CFGBlock* target_block = entry_descriptor->backedge->target;
......@@ -493,8 +493,8 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
std::unique_ptr<IRGenerator> generator(
createIRGenerator(irstate, llvm_entry_blocks, block, types, out_guards, in_guards, is_partial));
std::unique_ptr<IREmitter> emitter(createIREmitter(irstate));
emitter->getBuilder()->SetInsertPoint(llvm_entry_blocks[block]);
llvm::BasicBlock* entry_block_end = llvm_entry_blocks[block];
std::unique_ptr<IREmitter> emitter(createIREmitter(irstate, entry_block_end));
PHITable* phis = NULL;
if (!is_partial) {
......@@ -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());
offramps.push_back(off_ramp);
IREmitter* emitter = createIREmitter(irstate);
emitter->getBuilder()->SetInsertPoint(off_ramp);
llvm::BasicBlock* off_ramp_end = off_ramp;
IREmitter* emitter = createIREmitter(irstate, off_ramp_end);
emitters.push_back(emitter);
block_guards[i]->branch->setSuccessor(1, off_ramp);
......
......@@ -15,6 +15,7 @@
#ifndef PYSTON_CODEGEN_IRGEN_H
#define PYSTON_CODEGEN_IRGEN_H
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IRBuilder.h"
......@@ -30,6 +31,18 @@ class AST_expr;
class GCBuilder;
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> {
private:
IREmitter* emitter;
......@@ -55,8 +68,14 @@ public:
virtual CompiledFunction* currentFunction() = 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,
......@@ -70,8 +89,10 @@ private:
TypeRecorder* const type_recorder;
public:
OpInfo(EffortLevel::EffortLevel effort, TypeRecorder* type_recorder)
: effort(effort), type_recorder(type_recorder) {}
const ExcInfo exc_info;
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; }
TypeRecorder* getTypeRecorder() const { return type_recorder; }
......
This diff is collapsed.
......@@ -190,7 +190,7 @@ public:
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,
CFGBlock* myblock, TypeAnalysis* types, GuardList& out_guards,
const GuardList& in_guards, bool is_partial);
......
......@@ -40,6 +40,11 @@
#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 {
static llvm::Function* lookupFunction(const std::string& name) {
......@@ -168,6 +173,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(unaryop);
GET(import);
GET(repr);
GET(isinstance);
GET(checkUnpackingLength);
GET(raiseAttributeError);
......@@ -203,6 +209,11 @@ void initGlobalFuncs(GlobalState& g) {
g.funcs.reoptCompiledFunc = addFunc((void*)reoptCompiledFunc, 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.mod_i64_i64 = getFunc((void*)mod_i64_i64, "mod_i64_i64");
g.funcs.pow_i64_i64 = getFunc((void*)pow_i64_i64, "pow_i64_i64");
......
......@@ -23,7 +23,7 @@ struct GlobalFuncs {
llvm::Value* boxInt, *unboxInt, *boxFloat, *unboxFloat, *boxStringPtr, *boxCLFunction, *unboxCLFunction,
*boxInstanceMethod, *boxBool, *unboxBool, *createTuple, *createDict, *createList, *createSlice, *createClass;
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,
*assertNameDefined, *assertFail;
llvm::Value* printFloat, *listAppendInternal;
......@@ -32,6 +32,8 @@ struct GlobalFuncs {
llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr;
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_float_float, *mod_float_float, *pow_float_float;
};
......
......@@ -1200,10 +1200,6 @@ bool PrintVisitor::visit_index(AST_Index* 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);
node->stmt->accept(this);
return true;
......
......@@ -182,12 +182,8 @@ Box* sorted(Box* obj) {
return rtn;
}
Box* isinstance(Box* obj, Box* cls) {
assert(cls->cls == type_cls);
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* isinstance_func(Box* obj, Box* cls) {
return boxBool(isinstance(obj, cls, 0));
}
Box* getattr2(Box* obj, Box* _str) {
......@@ -288,7 +284,7 @@ void setupBuiltins() {
addRTFunction(getattr_func, (void*)getattr3, NULL, 3, false);
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("sorted", new BoxedFunction(boxRTFunction((void*)sorted, NULL, 1, false)));
......
......@@ -34,6 +34,11 @@ static void forceLink(void* x) {
printf("%p\n", x);
}
extern "C" void __py_personality_v0() {
RELEASE_ASSERT(0, "not used");
}
namespace _force {
#define FORCE(name) forceLink((void*)name)
......@@ -71,6 +76,7 @@ void force() {
FORCE(unaryop);
FORCE(import);
FORCE(repr);
FORCE(isinstance);
FORCE(checkUnpackingLength);
FORCE(raiseAttributeError);
......
......@@ -1018,6 +1018,22 @@ extern "C" Box* repr(Box* 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) {
static StatCounter slowpath_hash("slowpath_hash");
slowpath_hash.log();
......
......@@ -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" BoxedString* str(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" Box* abs_(Box* obj);
// extern "C" Box* min_(Box* o0, Box* o1);
......
......@@ -136,7 +136,7 @@ public:
class BoxedList : public Box {
public:
class ElementArray : GCObject {
class ElementArray : public GCObject {
public:
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