[svn r19] * Added support for reassigning 'this' inside class constructors.

* Added preliminary support for UnrolledLoopStatement. That is foreach on a tuple.
This commit is contained in:
Tomas Lindquist Olsen
2007-10-03 04:56:32 +02:00
parent 50d79d4098
commit 766fc30a30
10 changed files with 138 additions and 9 deletions

View File

@@ -511,6 +511,7 @@ struct FuncDeclaration : Declaration
FuncDeclaration *isFuncDeclaration() { return this; }
bool llvmQueued;
llvm::Value* llvmThisVar;
};
struct FuncAliasDeclaration : FuncDeclaration

View File

@@ -74,6 +74,7 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC s
nrvo_var = NULL;
shidden = NULL;
llvmQueued = false;
llvmThisVar = NULL;
}
Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)

View File

@@ -18,6 +18,7 @@ elem::elem()
inplace = false;
field = false;
callconv = (unsigned)-1;
isthis = false;
vardecl = 0;
funcdecl = 0;

View File

@@ -32,6 +32,7 @@ public:
bool inplace;
bool field;
unsigned callconv;
bool isthis;
VarDeclaration* vardecl;
FuncDeclaration* funcdecl;

View File

@@ -78,9 +78,11 @@ struct IRState : Object
// classes TODO move into IRClass
typedef std::vector<ClassDeclaration*> ClassDeclVec;
ClassDeclVec classes;
typedef std::vector<FuncDeclaration*> FuncDeclVec;
typedef std::vector<FuncDeclVec> ClassMethodVec;
ClassMethodVec classmethods;
typedef std::vector<bool> BoolVec;
BoolVec queueClassMethods;
@@ -111,6 +113,9 @@ struct IRState : Object
// VarDeclaration for __dollar, but I can't see how to get the
// array pointer from this :(
LvalVec arrays;
// keeping track of the declaration for the current function body
FuncDeclVec funcdecls;
};
#endif // LLVMDC_GEN_IRSTATE_H

View File

@@ -27,7 +27,7 @@
#include "gen/runtime.h"
#include "gen/arrays.h"
/* --------------------------------------------------------------------------------------- */
//////////////////////////////////////////////////////////////////////////////
void CompoundStatement::toIR(IRState* p)
{
@@ -71,6 +71,8 @@ void CompoundStatement::toIR(IRState* p)
//p->bbs.pop();
}
//////////////////////////////////////////////////////////////////////////////
void ReturnStatement::toIR(IRState* p)
{
static int rsi = 0;
@@ -134,6 +136,8 @@ void ReturnStatement::toIR(IRState* p)
p->scope().returned = true;
}
//////////////////////////////////////////////////////////////////////////////
void ExpStatement::toIR(IRState* p)
{
static int esi = 0;
@@ -150,6 +154,8 @@ void ExpStatement::toIR(IRState* p)
p->buf.writenl();*/
}
//////////////////////////////////////////////////////////////////////////////
void IfStatement::toIR(IRState* p)
{
static int wsi = 0;
@@ -204,6 +210,8 @@ void IfStatement::toIR(IRState* p)
gIR->scope() = IRScope(endbb,oldend);
}
//////////////////////////////////////////////////////////////////////////////
void ScopeStatement::toIR(IRState* p)
{
Logger::println("ScopeStatement::toIR(): %s", toChars());
@@ -240,6 +248,8 @@ void ScopeStatement::toIR(IRState* p)
*/
}
//////////////////////////////////////////////////////////////////////////////
void WhileStatement::toIR(IRState* p)
{
static int wsi = 0;
@@ -281,6 +291,8 @@ void WhileStatement::toIR(IRState* p)
gIR->scope() = IRScope(endbb,oldend);
}
//////////////////////////////////////////////////////////////////////////////
void DoStatement::toIR(IRState* p)
{
static int wsi = 0;
@@ -313,6 +325,8 @@ void DoStatement::toIR(IRState* p)
gIR->scope() = IRScope(endbb,oldend);
}
//////////////////////////////////////////////////////////////////////////////
void ForStatement::toIR(IRState* p)
{
static int wsi = 0;
@@ -374,6 +388,8 @@ void ForStatement::toIR(IRState* p)
gIR->scope() = IRScope(endbb,oldend);
}
//////////////////////////////////////////////////////////////////////////////
void BreakStatement::toIR(IRState* p)
{
static int wsi = 0;
@@ -389,6 +405,8 @@ void BreakStatement::toIR(IRState* p)
}
}
//////////////////////////////////////////////////////////////////////////////
void ContinueStatement::toIR(IRState* p)
{
static int wsi = 0;
@@ -404,6 +422,8 @@ void ContinueStatement::toIR(IRState* p)
}
}
//////////////////////////////////////////////////////////////////////////////
void OnScopeStatement::toIR(IRState* p)
{
static int wsi = 0;
@@ -414,6 +434,8 @@ void OnScopeStatement::toIR(IRState* p)
//statement->toIR(p); // this seems to be redundant
}
//////////////////////////////////////////////////////////////////////////////
void TryFinallyStatement::toIR(IRState* p)
{
static int wsi = 0;
@@ -446,6 +468,8 @@ void TryFinallyStatement::toIR(IRState* p)
gIR->scope() = IRScope(endbb,oldend);
}
//////////////////////////////////////////////////////////////////////////////
void TryCatchStatement::toIR(IRState* p)
{
static int wsi = 0;
@@ -465,6 +489,8 @@ void TryCatchStatement::toIR(IRState* p)
}
}
//////////////////////////////////////////////////////////////////////////////
void ThrowStatement::toIR(IRState* p)
{
static int wsi = 0;
@@ -478,6 +504,8 @@ void ThrowStatement::toIR(IRState* p)
delete e;
}
//////////////////////////////////////////////////////////////////////////////
void SwitchStatement::toIR(IRState* p)
{
Logger::println("SwitchStatement::toIR(): %s", toChars());
@@ -561,6 +589,35 @@ void SwitchStatement::toIR(IRState* p)
gIR->scope() = IRScope(endbb,oldend);
}
//////////////////////////////////////////////////////////////////////////////
void UnrolledLoopStatement::toIR(IRState* p)
{
Logger::println("UnrolledLoopStatement::toIR(): %s", toChars());
LOG_SCOPE;
llvm::BasicBlock* oldend = gIR->scopeend();
llvm::BasicBlock* endbb = new llvm::BasicBlock("unrolledend", p->topfunc(), oldend);
p->scope() = IRScope(p->scopebb(),endbb);
p->loopbbs.push_back(IRScope(p->scopebb(),endbb));
for (int i=0; i<statements->dim; ++i)
{
Statement* s = (Statement*)statements->data[i];
s->toIR(p);
}
p->loopbbs.pop_back();
new llvm::BranchInst(endbb, p->scopebb());
p->scope() = IRScope(endbb,oldend);
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();}
//STUBST(BreakStatement);
//STUBST(ForStatement);
@@ -589,5 +646,5 @@ STUBST(LabelStatement);
STUBST(GotoCaseStatement);
STUBST(GotoDefaultStatement);
STUBST(GotoStatement);
STUBST(UnrolledLoopStatement);
//STUBST(UnrolledLoopStatement);
//STUBST(OnScopeStatement);

View File

@@ -384,8 +384,19 @@ elem* AssignExp::toElem(IRState* p)
else if (e1ty == Tclass) {
if (e2ty == Tclass) {
llvm::Value* tmp = r->getValue();
Logger::cout() << "tmp: " << *tmp << ", " << *l->mem << '\n';
new llvm::StoreInst(tmp, l->mem, p->scopebb());
Logger::cout() << "tmp: " << *tmp << " ||| " << *l->mem << '\n';
// assignment to this in constructor special case
if (l->isthis) {
FuncDeclaration* fdecl = p->funcdecls.back();
// respecify the this param
if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar))
fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", p->topallocapoint());
new llvm::StoreInst(tmp, fdecl->llvmThisVar, p->scopebb());
}
// regular class ref -> class ref assignment
else {
new llvm::StoreInst(tmp, l->mem, p->scopebb());
}
}
else
assert(0);
@@ -1218,7 +1229,7 @@ elem* DotVarExp::toElem(IRState* p)
TypeStruct* ts = (TypeStruct*)e1->type->next;
ts->sym->offsetToIndex(vd->offset, vdoffsets);
Logger::println("Struct member offset:%d", vd->offset);
src = l->val;
src = l->val ? l->val : l->mem;
}
else if (e1->type->ty == Tclass) {
TypeClass* tc = (TypeClass*)e1->type;
@@ -1279,7 +1290,7 @@ elem* ThisExp::toElem(IRState* p)
elem* e = new elem;
if (VarDeclaration* vd = var->isVarDeclaration()) {
assert(vd->llvmValue == 0);
/*assert(vd->llvmValue == 0);
llvm::Function* fn = p->topfunc();
assert(fn);
@@ -1292,10 +1303,14 @@ elem* ThisExp::toElem(IRState* p)
v = ++fn->arg_begin();
else
v = fn->arg_begin();
assert(v);
assert(v);*/
e->val = v;
llvm::Value* v = p->funcdecls.back()->llvmThisVar;
if (llvm::isa<llvm::AllocaInst>(v))
v = new llvm::LoadInst(v, "tmp", p->scopebb());
e->mem = v;
e->type = elem::VAL;
e->isthis = true;
}
else {
assert(0);
@@ -1794,7 +1809,7 @@ elem* NewExp::toElem(IRState* p)
e->inplace = true;
e->type = elem::VAR;
return e;
}

View File

@@ -665,9 +665,20 @@ void FuncDeclaration::toObjFile()
// function definition
if (allow_fbody && fbody != 0)
{
gIR->funcdecls.push_back(this);
// first make absolutely sure the type is up to date
f->llvmType = llvmValue->getType()->getContainedType(0);
// this handling
if (f->llvmUsesThis) {
if (f->llvmRetInPtr)
llvmThisVar = ++func->arg_begin();
else
llvmThisVar = func->arg_begin();
assert(llvmThisVar != 0);
}
if (isMain())
gIR->emitMain = true;
@@ -716,6 +727,8 @@ void FuncDeclaration::toObjFile()
// possibly assert(lastbb->getNumPredecessors() == 0); ??? try it out sometime ...
new llvm::UnreachableInst(lastbb);
}
gIR->funcdecls.pop_back();
}
}
}

22
test/classes8.d Normal file
View File

@@ -0,0 +1,22 @@
class A {
int i;
int l;
this(bool b,bool b2=false) {
if (b) this = new B;
i = 4;
if (b2) this = new C;
l = 64;
}
}
class B : A{
this() {
super(false);
}
}
class C : A{
this() {
super(false);
}
}
void main() {
}

13
test/unrolled.d Normal file
View File

@@ -0,0 +1,13 @@
module unrolled;
void test(T...)(T t) {
foreach (value; t) {
printf("%d\n", value);
if (value == 2)
break;
}
}
void main() {
test(1,4,3);
}