Commit b2d54051 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add HASNEXT opcode support to the llvm tier

parent 8baec850
t = 0 t = 0
for i in range(1000000): for i in range(1000000):
t = t + i t = t + i
for i in xrange(1000000):
t = t + i
print t print t
...@@ -376,6 +376,7 @@ private: ...@@ -376,6 +376,7 @@ private:
case AST_LangPrimitive::SET_EXC_INFO: case AST_LangPrimitive::SET_EXC_INFO:
case AST_LangPrimitive::UNCACHE_EXC_INFO: case AST_LangPrimitive::UNCACHE_EXC_INFO:
return NONE; return NONE;
case AST_LangPrimitive::HASNEXT:
case AST_LangPrimitive::NONZERO: case AST_LangPrimitive::NONZERO:
return BOOL; return BOOL;
default: default:
......
...@@ -237,6 +237,7 @@ public: ...@@ -237,6 +237,7 @@ public:
const std::vector<CompilerVariable*>& args, const std::vector<CompilerVariable*>& args,
const std::vector<const std::string*>* keyword_names) override; const std::vector<const std::string*>* keyword_names) override;
ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override; ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override;
ConcreteCompilerVariable* hasnext(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override;
void setattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, const std::string* attr, void setattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, const std::string* attr,
CompilerVariable* v) override { CompilerVariable* v) override {
...@@ -707,6 +708,23 @@ ConcreteCompilerVariable* UnknownType::nonzero(IREmitter& emitter, const OpInfo& ...@@ -707,6 +708,23 @@ ConcreteCompilerVariable* UnknownType::nonzero(IREmitter& emitter, const OpInfo&
return boolFromI1(emitter, rtn_val); return boolFromI1(emitter, rtn_val);
} }
ConcreteCompilerVariable* UnknownType::hasnext(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) {
bool do_patchpoint = ENABLE_ICS && !info.isInterpreted();
llvm::Value* rtn_val;
if (do_patchpoint) {
ICSetupInfo* pp = createHasnextIC(info.getTypeRecorder());
std::vector<llvm::Value*> llvm_args;
llvm_args.push_back(var->getValue());
llvm::Value* uncasted = emitter.createIC(pp, (void*)pyston::hasnext, llvm_args, info.unw_info);
rtn_val = emitter.getBuilder()->CreateTrunc(uncasted, g.i1);
} else {
rtn_val = emitter.createCall(info.unw_info, g.funcs.hasnext, var->getValue());
}
return boolFromI1(emitter, rtn_val);
}
CompilerVariable* makeFunction(IREmitter& emitter, CLFunction* f, CompilerVariable* closure, bool isGenerator, CompilerVariable* makeFunction(IREmitter& emitter, CLFunction* f, CompilerVariable* closure, bool isGenerator,
const std::vector<ConcreteCompilerVariable*>& defaults) { const std::vector<ConcreteCompilerVariable*>& defaults) {
// Unlike the CLFunction*, which can be shared between recompilations, the Box* around it // Unlike the CLFunction*, which can be shared between recompilations, the Box* around it
...@@ -1719,6 +1737,18 @@ public: ...@@ -1719,6 +1737,18 @@ public:
return UNKNOWN->nonzero(emitter, info, var); return UNKNOWN->nonzero(emitter, info, var);
} }
ConcreteCompilerVariable* hasnext(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override {
static const std::string attr("__hasnext__");
ConcreteCompilerVariable* called_constant
= tryCallattrConstant(emitter, info, var, &attr, true, ArgPassSpec(0, 0, 0, 0), {}, NULL, NULL);
if (called_constant)
return called_constant;
return UNKNOWN->hasnext(emitter, info, var);
}
static NormalObjectType* fromClass(BoxedClass* cls) { static NormalObjectType* fromClass(BoxedClass* cls) {
NormalObjectType*& rtn = made[cls]; NormalObjectType*& rtn = made[cls];
if (rtn == NULL) { if (rtn == NULL) {
......
...@@ -100,6 +100,10 @@ public: ...@@ -100,6 +100,10 @@ public:
printf("nonzero not defined for %s\n", debugName().c_str()); printf("nonzero not defined for %s\n", debugName().c_str());
abort(); abort();
} }
virtual ConcreteCompilerVariable* hasnext(IREmitter& emitter, const OpInfo& info, VAR* var) {
printf("hasnext not defined for %s\n", debugName().c_str());
abort();
}
virtual CompilerVariable* getattr(IREmitter& emitter, const OpInfo& info, VAR* var, const std::string* attr, virtual CompilerVariable* getattr(IREmitter& emitter, const OpInfo& info, VAR* var, const std::string* attr,
bool cls_only) { bool cls_only) {
printf("getattr not defined for %s\n", debugName().c_str()); printf("getattr not defined for %s\n", debugName().c_str());
...@@ -256,6 +260,7 @@ public: ...@@ -256,6 +260,7 @@ public:
virtual BoxedClass* guaranteedClass() = 0; virtual BoxedClass* guaranteedClass() = 0;
virtual ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info) = 0; virtual ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info) = 0;
virtual ConcreteCompilerVariable* hasnext(IREmitter& emitter, const OpInfo& info) = 0;
virtual CompilerVariable* getattr(IREmitter& emitter, const OpInfo& info, const std::string* attr, bool cls_only) virtual CompilerVariable* getattr(IREmitter& emitter, const OpInfo& info, const std::string* attr, bool cls_only)
= 0; = 0;
virtual void setattr(IREmitter& emitter, const OpInfo& info, const std::string* attr, CompilerVariable* v) = 0; virtual void setattr(IREmitter& emitter, const OpInfo& info, const std::string* attr, CompilerVariable* v) = 0;
...@@ -327,6 +332,9 @@ public: ...@@ -327,6 +332,9 @@ public:
ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info) override { ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info) override {
return type->nonzero(emitter, info, this); return type->nonzero(emitter, info, this);
} }
ConcreteCompilerVariable* hasnext(IREmitter& emitter, const OpInfo& info) override {
return type->hasnext(emitter, info, this);
}
CompilerVariable* getattr(IREmitter& emitter, const OpInfo& info, const std::string* attr, bool cls_only) override { CompilerVariable* getattr(IREmitter& emitter, const OpInfo& info, const std::string* attr, bool cls_only) override {
return type->getattr(emitter, info, this, attr, cls_only); return type->getattr(emitter, info, this, attr, cls_only);
} }
......
...@@ -576,13 +576,16 @@ private: ...@@ -576,13 +576,16 @@ private:
CompilerVariable* obj = evalExpr(node->args[0], unw_info); CompilerVariable* obj = evalExpr(node->args[0], unw_info);
ConcreteCompilerVariable* rtn = obj->nonzero(emitter, getOpInfoForNode(node, unw_info)); ConcreteCompilerVariable* rtn = obj->nonzero(emitter, getOpInfoForNode(node, unw_info));
assert(rtn->getType() == BOOL);
llvm::Value* v = i1FromBool(emitter, rtn);
assert(v->getType() == g.i1);
obj->decvref(emitter); obj->decvref(emitter);
return rtn;
}
case AST_LangPrimitive::HASNEXT: {
assert(node->args.size() == 1);
CompilerVariable* obj = evalExpr(node->args[0], unw_info);
return boolFromI1(emitter, v); ConcreteCompilerVariable* rtn = obj->hasnext(emitter, getOpInfoForNode(node, unw_info));
obj->decvref(emitter);
return rtn;
} }
case AST_LangPrimitive::SET_EXC_INFO: { case AST_LangPrimitive::SET_EXC_INFO: {
assert(node->args.size() == 3); assert(node->args.size() == 3);
......
...@@ -336,4 +336,8 @@ ICSetupInfo* createNonzeroIC(TypeRecorder* type_recorder) { ...@@ -336,4 +336,8 @@ ICSetupInfo* createNonzeroIC(TypeRecorder* type_recorder) {
return ICSetupInfo::initialize(true, 2, 64, ICSetupInfo::Nonzero, type_recorder); return ICSetupInfo::initialize(true, 2, 64, ICSetupInfo::Nonzero, type_recorder);
} }
ICSetupInfo* createHasnextIC(TypeRecorder* type_recorder) {
return ICSetupInfo::initialize(true, 2, 64, ICSetupInfo::Hasnext, type_recorder);
}
} // namespace pyston } // namespace pyston
...@@ -105,6 +105,7 @@ public: ...@@ -105,6 +105,7 @@ public:
Delitem, Delitem,
Binexp, Binexp,
Nonzero, Nonzero,
Hasnext,
}; };
private: private:
...@@ -146,6 +147,7 @@ ICSetupInfo* createSetitemIC(TypeRecorder* type_recorder); ...@@ -146,6 +147,7 @@ ICSetupInfo* createSetitemIC(TypeRecorder* type_recorder);
ICSetupInfo* createDelitemIC(TypeRecorder* type_recorder); ICSetupInfo* createDelitemIC(TypeRecorder* type_recorder);
ICSetupInfo* createBinexpIC(TypeRecorder* type_recorder); ICSetupInfo* createBinexpIC(TypeRecorder* type_recorder);
ICSetupInfo* createNonzeroIC(TypeRecorder* type_recorder); ICSetupInfo* createNonzeroIC(TypeRecorder* type_recorder);
ICSetupInfo* createHasnextIC(TypeRecorder* type_recorder);
} // namespace pyston } // namespace pyston
......
...@@ -209,6 +209,7 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -209,6 +209,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(isinstance); GET(isinstance);
GET(yield); GET(yield);
GET(getiterHelper); GET(getiterHelper);
GET(hasnext);
GET(unpackIntoArray); GET(unpackIntoArray);
GET(raiseAttributeError); GET(raiseAttributeError);
......
...@@ -38,7 +38,7 @@ struct GlobalFuncs { ...@@ -38,7 +38,7 @@ struct GlobalFuncs {
*decodeUTF8StringPtr; *decodeUTF8StringPtr;
llvm::Value* getattr, *setattr, *delattr, *delitem, *delGlobal, *nonzero, *binop, *compare, *augbinop, *unboxedLen, llvm::Value* getattr, *setattr, *delattr, *delitem, *delGlobal, *nonzero, *binop, *compare, *augbinop, *unboxedLen,
*getitem, *getclsattr, *getGlobal, *setitem, *unaryop, *import, *importFrom, *importStar, *repr, *str, *getitem, *getclsattr, *getGlobal, *setitem, *unaryop, *import, *importFrom, *importStar, *repr, *str,
*isinstance, *yield, *getiterHelper; *isinstance, *yield, *getiterHelper, *hasnext;
llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError, llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError,
*assertNameDefined, *assertFail; *assertNameDefined, *assertFail;
......
...@@ -90,6 +90,7 @@ void force() { ...@@ -90,6 +90,7 @@ void force() {
FORCE(isinstance); FORCE(isinstance);
FORCE(yield); FORCE(yield);
FORCE(getiterHelper); FORCE(getiterHelper);
FORCE(hasnext);
FORCE(unpackIntoArray); FORCE(unpackIntoArray);
FORCE(raiseAttributeError); FORCE(raiseAttributeError);
......
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