Implemented first class delegates. closes #101

This commit is contained in:
Tomas Lindquist Olsen
2008-10-22 21:50:08 +02:00
parent 42ae090eaf
commit a52f0330d0
8 changed files with 151 additions and 125 deletions

View File

@@ -1517,6 +1517,9 @@ Statement *ForeachStatement::semantic(Scope *sc)
Expression *flde;
Identifier *id;
Type *tret;
TypeDelegate* dgty;
TypeDelegate* dgty2;
TypeDelegate* fldeTy;
tret = func->type->nextOf();
@@ -1600,6 +1603,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
*/
//LDC: Build arguments.
static FuncDeclaration *aaApply2_fd = NULL;
static TypeDelegate* aaApply2_dg;
if(!aaApply2_fd) {
Arguments* args = new Arguments;
args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL));
@@ -1607,25 +1611,28 @@ Statement *ForeachStatement::semantic(Scope *sc)
Arguments* dgargs = new Arguments;
dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
args->push(new Argument(STCin, dgty, NULL, NULL));
aaApply2_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
args->push(new Argument(STCin, aaApply2_dg, NULL, NULL));
aaApply2_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply2");
}
static FuncDeclaration *aaApply_fd = NULL;
static TypeDelegate* aaApply_dg;
if(!aaApply_fd) {
Arguments* args = new Arguments;
args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL));
args->push(new Argument(STCin, Type::tsize_t, NULL, NULL));
Arguments* dgargs = new Arguments;
dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
args->push(new Argument(STCin, dgty, NULL, NULL));
aaApply_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
args->push(new Argument(STCin, aaApply_dg, NULL, NULL));
aaApply_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply");
}
if (dim == 2) {
fdapply = aaApply2_fd;
fldeTy = aaApply2_dg;
} else {
fdapply = aaApply_fd;
fldeTy = aaApply_dg;
}
ec = new VarExp(0, fdapply);
Expressions *exps = new Expressions();
@@ -1633,7 +1640,15 @@ Statement *ForeachStatement::semantic(Scope *sc)
size_t keysize = taa->key->size();
keysize = (keysize + 3) & ~3;
exps->push(new IntegerExp(0, keysize, Type::tsize_t));
// LDC paint delegate argument to the type runtime expects
if (!fldeTy->equals(flde->type))
{
flde = new CastExp(loc, flde, flde->type);
flde->type = fldeTy;
}
exps->push(flde);
e = new CallExp(loc, ec, exps);
e->type = Type::tindex; // don't run semantic() on e
}
@@ -1674,13 +1689,13 @@ Statement *ForeachStatement::semantic(Scope *sc)
Arguments* dgargs = new Arguments;
dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
args->push(new Argument(STCin, dgty, NULL, NULL));
fdapply = FuncDeclaration::genCfunc(args, Type::tindex, fdname);
} else {
Arguments* dgargs = new Arguments;
dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
args->push(new Argument(STCin, dgty, NULL, NULL));
fdapply = FuncDeclaration::genCfunc(args, Type::tindex, fdname);
}
@@ -1690,7 +1705,15 @@ Statement *ForeachStatement::semantic(Scope *sc)
if (tab->ty == Tsarray)
aggr = aggr->castTo(sc, tn->arrayOf());
exps->push(aggr);
// LDC paint delegate argument to the type runtime expects
if (!dgty->equals(flde->type))
{
flde = new CastExp(loc, flde, flde->type);
flde->type = dgty;
}
exps->push(flde);
e = new CallExp(loc, ec, exps);
e->type = Type::tindex; // don't run semantic() on e
}

View File

@@ -123,15 +123,24 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, co
const LLType* at = DtoType(argT);
// handle lazy args
if (arg->storageClass & STClazy)
{
Logger::println("lazy param");
TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd);
TypeDelegate *ltd = new TypeDelegate(ltf);
at = DtoType(ltd);
paramvec.push_back(at);
}
// opaque types need special handling
if (llvm::isa<llvm::OpaqueType>(at)) {
else if (llvm::isa<llvm::OpaqueType>(at)) {
Logger::println("opaque param");
assert(argT->ty == Tstruct || argT->ty == Tclass);
paramvec.push_back(getPtrToType(at));
}
// structs and delegates are passed as a reference, but by value
else if (argT->ty == Tstruct || argT->ty == Tdelegate) {
Logger::println("struct/sarray param");
// structs are passed as a reference, but by value
else if (argT->ty == Tstruct) {
Logger::println("struct param");
if (!refOrOut)
arg->llvmAttrs |= llvm::Attribute::ByVal;
paramvec.push_back(getPtrToType(at));
@@ -156,23 +165,6 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, co
arg->llvmAttrs |= ea;
paramvec.push_back(at);
}
// handle lazy args
if (arg->storageClass & STClazy)
{
if (Logger::enabled())
Logger::cout() << "for lazy got: " << *paramvec.back() << '\n';
TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd);
TypeDelegate *ltd = new TypeDelegate(ltf);
at = getPtrToType(DtoType(ltd));
if (Logger::enabled())
Logger::cout() << "lazy updated to: " << *at << '\n';
paramvec.back() = at;
// lazy doesn't need byval as the delegate is not visible to the user
}
}
// construct function type
@@ -652,13 +644,14 @@ void DtoDefineFunc(FuncDeclaration* fd)
IrLocal* irloc = vd->ir.irLocal;
assert(irloc);
bool refoutlazy = vd->storage_class & (STCref | STCout | STClazy);
bool refout = vd->storage_class & (STCref | STCout);
bool lazy = vd->storage_class & STClazy;
if (refoutlazy)
if (refout)
{
continue;
}
else if (DtoIsPassedByRef(vd->type))
else if (!lazy && DtoIsPassedByRef(vd->type))
{
LLValue* vdirval = irloc->value;
if (global.params.symdebug && !(isaArgument(vdirval) && !isaArgument(vdirval)->hasByValAttr()))
@@ -875,6 +868,13 @@ DValue* DtoArgument(Argument* fnarg, Expression* argexp)
else
arg = new DImValue(argexp->type, arg->getRVal());
}
// lazy arg
else if (fnarg && (fnarg->storageClass & STClazy))
{
assert(argexp->type->toBasetype()->ty == Tdelegate);
assert(!arg->isLVal());
return arg;
}
// byval arg, but expr has no storage yet
else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isNull()))
{

View File

@@ -452,15 +452,11 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs)
}
}
else if (t->ty == Tdelegate) {
if (rhs->isNull())
DtoAggrZeroInit(lhs->getLVal());
else {
LLValue* l = lhs->getLVal();
LLValue* r = rhs->getRVal();
if (Logger::enabled())
Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
DtoAggrCopy(l, r);
}
LLValue* l = lhs->getLVal();
LLValue* r = rhs->getRVal();
if (Logger::enabled())
Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
DtoStore(r, l);
}
else if (t->ty == Tclass) {
assert(t2->ty == Tclass);
@@ -694,21 +690,15 @@ DValue* DtoCastFloat(Loc& loc, DValue* val, Type* to)
DValue* DtoCastDelegate(Loc& loc, DValue* val, Type* to)
{
LLValue* res = 0;
to = to->toBasetype();
if (to->ty == Tdelegate)
if (to->toBasetype()->ty == Tdelegate)
{
const LLType* toll = getPtrToType(DtoType(to));
res = DtoBitCast(val->getRVal(), toll);
return DtoPaintType(loc, val, to);
}
else
{
error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars());
fatal();
}
return new DImValue(to, res);
}
DValue* DtoCast(Loc& loc, DValue* val, Type* to)
@@ -773,6 +763,31 @@ DValue* DtoPaintType(Loc& loc, DValue* val, Type* to)
return new DImValue(to, DtoAggrPair(len, ptr, "tmp"));
}
}
else if (from->ty == Tdelegate)
{
Type* dgty = to->toBasetype();
assert(dgty->ty == Tdelegate);
if (val->isLVal())
{
LLValue* ptr = val->getLVal();
assert(isaPointer(ptr));
ptr = DtoBitCast(ptr, getPtrToType(DtoType(dgty)));
if (Logger::enabled())
Logger::cout() << "dg ptr: " << *ptr << '\n';
return new DVarValue(to, ptr);
}
else
{
LLValue* dg = val->getRVal();
LLValue* context = gIR->ir->CreateExtractValue(dg, 0, ".context");
LLValue* funcptr = gIR->ir->CreateExtractValue(dg, 1, ".funcptr");
funcptr = DtoBitCast(funcptr, DtoType(dgty)->getContainedType(1));
LLValue* aggr = DtoAggrPair(context, funcptr, "tmp");
if (Logger::enabled())
Logger::cout() << "dg: " << *aggr << '\n';
return new DImValue(to, aggr);
}
}
else if (from->ty == Tpointer || from->ty == Tclass || from->ty == Taarray)
{
Type* b = to->toBasetype();

View File

@@ -119,11 +119,7 @@ static const LLType* rt_dg1()
types.push_back(rt_ptr(LLType::Int8Ty));
types.push_back(rt_ptr(LLType::Int8Ty));
const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::Int32Ty, types, false);
std::vector<const LLType*> t;
t.push_back(rt_ptr(LLType::Int8Ty));
t.push_back(rt_ptr(fty));
return rt_ptr(llvm::StructType::get(t));
return llvm::StructType::get(rt_ptr(LLType::Int8Ty), rt_ptr(fty), 0);
}
static const LLType* rt_dg2()
@@ -133,11 +129,7 @@ static const LLType* rt_dg2()
types.push_back(rt_ptr(LLType::Int8Ty));
types.push_back(rt_ptr(LLType::Int8Ty));
const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::Int32Ty, types, false);
std::vector<const LLType*> t;
t.push_back(rt_ptr(LLType::Int8Ty));
t.push_back(rt_ptr(fty));
return rt_ptr(llvm::StructType::get(t));
return llvm::StructType::get(rt_ptr(LLType::Int8Ty), rt_ptr(fty), 0);
}
static void LLVM_D_BuildRuntimeModule()
@@ -365,10 +357,8 @@ static void LLVM_D_BuildRuntimeModule()
types.push_back(TY); \
types.push_back(rt_dg1()); \
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
llvm::AttrListPtr palist; \
palist = palist.addAttr(2, llvm::Attribute::ByVal); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setAttributes(palist); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
}
STR_APPLY1(stringTy, "_aApplycw1", "_aApplycd1")
STR_APPLY1(wstringTy, "_aApplywc1", "_aApplywd1")
@@ -384,10 +374,8 @@ static void LLVM_D_BuildRuntimeModule()
types.push_back(TY); \
types.push_back(rt_dg2()); \
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
llvm::AttrListPtr palist; \
palist = palist.addAttr(2, llvm::Attribute::ByVal); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setAttributes(palist); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
}
STR_APPLY2(stringTy, "_aApplycw2", "_aApplycd2")
STR_APPLY2(wstringTy, "_aApplywc2", "_aApplywd2")
@@ -402,10 +390,8 @@ static void LLVM_D_BuildRuntimeModule()
types.push_back(TY); \
types.push_back(rt_dg1()); \
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
llvm::AttrListPtr palist; \
palist = palist.addAttr(2, llvm::Attribute::ByVal); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setAttributes(palist); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
}
STR_APPLY_R1(stringTy, "_aApplyRcw1", "_aApplyRcd1")
STR_APPLY_R1(wstringTy, "_aApplyRwc1", "_aApplyRwd1")
@@ -420,10 +406,8 @@ static void LLVM_D_BuildRuntimeModule()
types.push_back(TY); \
types.push_back(rt_dg2()); \
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
llvm::AttrListPtr palist; \
palist = palist.addAttr(2, llvm::Attribute::ByVal); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setAttributes(palist); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
}
STR_APPLY_R2(stringTy, "_aApplyRcw2", "_aApplyRcd2")
STR_APPLY_R2(wstringTy, "_aApplyRwc2", "_aApplyRwd2")
@@ -662,9 +646,7 @@ static void LLVM_D_BuildRuntimeModule()
types.push_back(sizeTy);
types.push_back(rt_dg1());
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::AttrListPtr palist;
palist = palist.addAttr(3, llvm::Attribute::ByVal);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// int _aaApply2(AA aa, size_t keysize, dg2_t dg)
@@ -675,9 +657,7 @@ static void LLVM_D_BuildRuntimeModule()
types.push_back(sizeTy);
types.push_back(rt_dg2());
const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
llvm::AttrListPtr palist;
palist = palist.addAttr(3, llvm::Attribute::ByVal);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setAttributes(palist);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
/////////////////////////////////////////////////////////////////////////////////////

View File

@@ -75,11 +75,18 @@ LLValue* DtoCallableValue(DValue* fn)
}
else if (type->ty == Tdelegate)
{
LLValue* dg = fn->getRVal();
if (Logger::enabled())
Logger::cout() << "delegate: " << *dg << '\n';
LLValue* funcptr = DtoGEPi(dg, 0, 1);
return DtoLoad(funcptr);
if (fn->isLVal())
{
LLValue* dg = fn->getLVal();
LLValue* funcptr = DtoGEPi(dg, 0, 1);
return DtoLoad(funcptr);
}
else
{
LLValue* dg = fn->getRVal();
assert(isaStruct(dg));
return gIR->ir->CreateExtractValue(dg, 1, ".funcptr");
}
}
else
{
@@ -266,7 +273,15 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
// ... or a delegate context arg
else if (delegatecall)
{
LLValue* ctxarg = DtoLoad(DtoGEPi(fnval->getRVal(), 0,0));
LLValue* ctxarg;
if (fnval->isLVal())
{
ctxarg = DtoLoad(DtoGEPi(fnval->getLVal(), 0,0));
}
else
{
ctxarg = gIR->ir->CreateExtractValue(fnval->getRVal(), 0, ".ptr");
}
assert(ctxarg->getType() == argiter->get());
++argiter;
args.push_back(ctxarg);

View File

@@ -110,11 +110,17 @@ DValue* VarExp::toElem(IRState* p)
// function parameter
else if (vd->isParameter()) {
Logger::println("function param");
Logger::println("type: %s", vd->type->toChars());
FuncDeclaration* fd = vd->toParent2()->isFuncDeclaration();
if (fd && fd != p->func()->decl) {
Logger::println("nested parameter");
return DtoNestedVariable(loc, type, vd);
}
else if (vd->storage_class & STClazy) {
Logger::println("lazy parameter");
assert(type->ty == Tdelegate);
return new DVarValue(type, vd->ir.getIrValue());
}
else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue())) {
return new DVarValue(type, vd, vd->ir.getIrValue());
}
@@ -1833,7 +1839,8 @@ DValue* DelegateExp::toElem(IRState* p)
const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty);
LLValue* lval = DtoAlloca(DtoType(type), "tmpdelegate");
assert(type->toBasetype()->ty == Tdelegate);
const LLType* dgty = DtoType(type);
DValue* u = e1->toElem(p);
LLValue* uval;
@@ -1859,11 +1866,7 @@ DValue* DelegateExp::toElem(IRState* p)
if (Logger::enabled())
Logger::cout() << "context = " << *uval << '\n';
LLValue* context = DtoGEPi(lval,0,0);
LLValue* castcontext = DtoBitCast(uval, int8ptrty);
DtoStore(castcontext, context);
LLValue* fptr = DtoGEPi(lval,0,1);
Logger::println("func: '%s'", func->toPrettyChars());
@@ -1880,10 +1883,9 @@ DValue* DelegateExp::toElem(IRState* p)
castfptr = func->ir.irFunc->func;
}
castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0));
DtoStore(castfptr, fptr);
castfptr = DtoBitCast(castfptr, dgty->getContainedType(1));
return new DImValue(type, lval);
return new DImValue(type, DtoAggrPair(castcontext, castfptr, ".dg"));
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2098,12 +2100,9 @@ DValue* FuncExp::toElem(IRState* p)
DtoForceDefineDsymbol(fd);
assert(fd->ir.irFunc->func);
LLValue *lval, *fptr;
if(fd->tok == TOKdelegate) {
const LLType* dgty = DtoType(type);
lval = DtoAlloca(dgty,"dgstorage");
LLValue* context = DtoGEPi(lval,0,0);
LLValue* cval;
IrFunction* irfn = p->func();
if (irfn->nestedVar)
@@ -2112,15 +2111,11 @@ DValue* FuncExp::toElem(IRState* p)
cval = irfn->nestArg;
else
cval = getNullPtr(getVoidPtrType());
cval = DtoBitCast(cval, context->getType()->getContainedType(0));
DtoStore(cval, context);
cval = DtoBitCast(cval, dgty->getContainedType(0));
fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb());
LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, dgty->getContainedType(1));
LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0));
DtoStore(castfptr, fptr);
return new DVarValue(type, lval);
return new DImValue(type, DtoAggrPair(cval, castfptr, ".func"));
} else if(fd->tok == TOKfunction) {
return new DImValue(type, fd->ir.irFunc->func);

View File

@@ -25,14 +25,14 @@ bool DtoIsPassedByRef(Type* type)
{
Type* typ = type->toBasetype();
TY t = typ->ty;
return (t == Tstruct || t == Tdelegate || t == Tsarray);
return (t == Tstruct || t == Tsarray);
}
bool DtoIsReturnedInArg(Type* type)
{
Type* typ = type->toBasetype();
TY t = typ->ty;
return (t == Tstruct || t == Tdelegate || t == Tsarray);
return (t == Tstruct || t == Tsarray);
}
unsigned DtoShouldExtend(Type* type)
@@ -221,6 +221,7 @@ const LLType* DtoTypeNotVoid(Type* t)
const LLStructType* DtoDelegateType(Type* t)
{
assert(t->ty == Tdelegate);
const LLType* i8ptr = getVoidPtrType();
const LLType* func = DtoFunctionType(t->next, NULL, i8ptr);
const LLType* funcptr = getPtrToType(func);
@@ -235,25 +236,22 @@ LLValue* DtoDelegateEquals(TOK op, LLValue* lhs, LLValue* rhs)
llvm::Value *b1, *b2;
if (rhs == NULL)
{
LLValue* l = DtoLoad(DtoGEPi(lhs,0,0));
LLValue* r = llvm::Constant::getNullValue(l->getType());
b1 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp");
l = DtoLoad(DtoGEPi(lhs,0,1));
r = llvm::Constant::getNullValue(l->getType());
b2 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp");
}
else
{
LLValue* l = DtoLoad(DtoGEPi(lhs,0,0));
LLValue* r = DtoLoad(DtoGEPi(rhs,0,0));
b1 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp");
l = DtoLoad(DtoGEPi(lhs,0,1));
r = DtoLoad(DtoGEPi(rhs,0,1));
b2 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp");
rhs = LLConstant::getNullValue(lhs->getType());
}
LLValue* l = gIR->ir->CreateExtractValue(lhs, 0);
LLValue* r = gIR->ir->CreateExtractValue(rhs, 0);
b1 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp");
l = gIR->ir->CreateExtractValue(lhs, 1);
r = gIR->ir->CreateExtractValue(rhs, 1);
b2 = gIR->ir->CreateICmp(llvm::ICmpInst::ICMP_EQ,l,r,"tmp");
LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp");
if (op == TOKnotequal || op == TOKnotidentity)
return gIR->ir->CreateNot(b,"tmp");
return b;
}
@@ -557,8 +555,8 @@ LLConstant* DtoConstStringPtr(const char* str, const char* section)
LLValue* DtoLoad(LLValue* src, const char* name)
{
if (Logger::enabled())
Logger::cout() << "loading " << *src << '\n';
// if (Logger::enabled())
// Logger::cout() << "loading " << *src << '\n';
LLValue* ld = gIR->ir->CreateLoad(src, name ? name : "tmp");
//ld->setVolatile(gIR->func()->inVolatile);
return ld;
@@ -566,8 +564,8 @@ LLValue* DtoLoad(LLValue* src, const char* name)
void DtoStore(LLValue* src, LLValue* dst)
{
if (Logger::enabled())
Logger::cout() << "storing " << *src << " into " << *dst << '\n';
// if (Logger::enabled())
// Logger::cout() << "storing " << *src << " into " << *dst << '\n';
LLValue* st = gIR->ir->CreateStore(src,dst);
//st->setVolatile(gIR->func()->inVolatile);
}

View File

@@ -75,7 +75,7 @@ void Module::genobjfile(int multiobj, char** envp)
Logger::println("Generating module: %s\n", (md ? md->toChars() : toChars()));
LOG_SCOPE;
//printf("codegen: %s\n", srcfile->toChars());
printf("codegen: %s\n", srcfile->toChars());
// start by deleting the old object file
deleteObjFile();