Mercurial > projects > ldc
comparison gen/aa.cpp @ 1418:f5f8c21ce6ef
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);
}
}
}}}
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Mon, 25 May 2009 12:50:40 +0200 |
parents | 15e9762bb620 |
children | 09734fb929c0 |
comparison
equal
deleted
inserted
replaced
1417:c3c23d2c5407 | 1418:f5f8c21ce6ef |
---|---|
62 DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) | 62 DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) |
63 { | 63 { |
64 // call: | 64 // call: |
65 // extern(C) void* _aaGet(AA* aa, TypeInfo keyti, size_t valuesize, void* pkey) | 65 // extern(C) void* _aaGet(AA* aa, TypeInfo keyti, size_t valuesize, void* pkey) |
66 // or | 66 // or |
67 // extern(C) void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void* pkey) | 67 // extern(C) void* _aaIn(AA aa*, TypeInfo keyti, void* pkey) |
68 | 68 |
69 // first get the runtime function | 69 // first get the runtime function |
70 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGet":"_aaGetRvalue"); | 70 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGet":"_aaIn"); |
71 const llvm::FunctionType* funcTy = func->getFunctionType(); | 71 const llvm::FunctionType* funcTy = func->getFunctionType(); |
72 | 72 |
73 // aa param | 73 // aa param |
74 LLValue* aaval = lvalue ? aa->getLVal() : aa->getRVal(); | 74 LLValue* aaval = lvalue ? aa->getLVal() : aa->getRVal(); |
75 aaval = DtoBitCast(aaval, funcTy->getParamType(0)); | 75 aaval = DtoBitCast(aaval, funcTy->getParamType(0)); |
76 | 76 |
77 // keyti param | 77 // keyti param |
78 LLValue* keyti = to_keyti(key); | 78 LLValue* keyti = to_keyti(key); |
79 keyti = DtoBitCast(keyti, funcTy->getParamType(1)); | 79 keyti = DtoBitCast(keyti, funcTy->getParamType(1)); |
80 | 80 |
81 // valuesize param | |
82 LLValue* valsize = DtoConstSize_t(getTypePaddedSize(DtoType(type))); | |
83 | |
84 // pkey param | 81 // pkey param |
85 LLValue* pkey = to_pkey(loc, key); | 82 LLValue* pkey = to_pkey(loc, key); |
86 pkey = DtoBitCast(pkey, funcTy->getParamType(3)); | 83 pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2)); |
87 | 84 |
88 // call runtime | 85 // call runtime |
89 LLValue* ret = gIR->CreateCallOrInvoke4(func, aaval, keyti, valsize, pkey, "aa.index").getInstruction(); | 86 LLValue* ret; |
87 if (lvalue) { | |
88 // valuesize param | |
89 LLValue* valsize = DtoConstSize_t(getTypePaddedSize(DtoType(type))); | |
90 | |
91 ret = gIR->CreateCallOrInvoke4(func, aaval, keyti, valsize, pkey, "aa.index").getInstruction(); | |
92 } else { | |
93 ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.index").getInstruction(); | |
94 } | |
90 | 95 |
91 // cast return value | 96 // cast return value |
92 const LLType* targettype = getPtrToType(DtoType(type)); | 97 const LLType* targettype = getPtrToType(DtoType(type)); |
93 if (ret->getType() != targettype) | 98 if (ret->getType() != targettype) |
94 ret = DtoBitCast(ret, targettype); | 99 ret = DtoBitCast(ret, targettype); |