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);