Make "aa[key]" use the same runtime call as "key in aa". The runtime calls

these were using were different, but with equivalent definitions.

With `ldc -O3`, the following functions now all compile to the exact same code:
{{{
int[int] y;
void foo(int x) {
    if (x in y) {
        auto z = x in y;
        sink(*z);
    }
}

void bar(int x) {
    if (x in y) {
        sink(y[x]);
    }
}

void baz(int x) {
    if (auto p = x in y) {
        sink(*p);
    }
}
}}}
This commit is contained in:
Frits van Bommel
2009-05-25 12:50:40 +02:00
parent c8665ddc88
commit e7b3f5415f
3 changed files with 13 additions and 57 deletions

View File

@@ -64,10 +64,10 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
// call:
// extern(C) void* _aaGet(AA* aa, TypeInfo keyti, size_t valuesize, void* pkey)
// or
// extern(C) void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void* pkey)
// extern(C) void* _aaIn(AA aa*, TypeInfo keyti, void* pkey)
// first get the runtime function
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGet":"_aaGetRvalue");
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGet":"_aaIn");
const llvm::FunctionType* funcTy = func->getFunctionType();
// aa param
@@ -78,15 +78,20 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
LLValue* keyti = to_keyti(key);
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
// valuesize param
LLValue* valsize = DtoConstSize_t(getTypePaddedSize(DtoType(type)));
// pkey param
LLValue* pkey = to_pkey(loc, key);
pkey = DtoBitCast(pkey, funcTy->getParamType(3));
pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2));
// call runtime
LLValue* ret = gIR->CreateCallOrInvoke4(func, aaval, keyti, valsize, pkey, "aa.index").getInstruction();
LLValue* ret;
if (lvalue) {
// valuesize param
LLValue* valsize = DtoConstSize_t(getTypePaddedSize(DtoType(type)));
ret = gIR->CreateCallOrInvoke4(func, aaval, keyti, valsize, pkey, "aa.index").getInstruction();
} else {
ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.index").getInstruction();
}
// cast return value
const LLType* targettype = getPtrToType(DtoType(type));