Mercurial > projects > ldc
comparison gen/toir.cpp @ 1633:5c0cebff9be8
Improve array append performance.
Actually use the appropriate runtime function, instead of just
growing the array by one!
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sun, 14 Feb 2010 10:11:05 +0100 |
parents | 628433c343b4 |
children | 8f121883bce8 |
comparison
equal
deleted
inserted
replaced
1632:8c37dcd7cfde | 1633:5c0cebff9be8 |
---|---|
622 Type* t2 = e2->type->toBasetype(); | 622 Type* t2 = e2->type->toBasetype(); |
623 | 623 |
624 // valid array ops would have been transformed by optimize | 624 // valid array ops would have been transformed by optimize |
625 if ((t1->ty == Tarray || t1->ty == Tsarray) && | 625 if ((t1->ty == Tarray || t1->ty == Tsarray) && |
626 (t2->ty == Tarray || t2->ty == Tsarray) | 626 (t2->ty == Tarray || t2->ty == Tsarray) |
627 ) | 627 ) |
628 { | 628 { |
629 base->error("Array operation %s not recognized", base->toChars()); | 629 base->error("Array operation %s not recognized", base->toChars()); |
630 fatal(); | 630 fatal(); |
631 } | 631 } |
632 } | 632 } |
1011 // bitcast to requested type | 1011 // bitcast to requested type |
1012 assert(type->toBasetype()->ty == Tpointer); | 1012 assert(type->toBasetype()->ty == Tpointer); |
1013 return DtoBitCast(gep, DtoType(type)); | 1013 return DtoBitCast(gep, DtoType(type)); |
1014 } | 1014 } |
1015 else if ( | 1015 else if ( |
1016 e1->op == TOKstructliteral || | 1016 e1->op == TOKstructliteral || |
1017 e1->op == TOKslice) | 1017 e1->op == TOKslice) |
1018 { | 1018 { |
1019 error("non-constant expression '%s'", toChars()); | 1019 error("non-constant expression '%s'", toChars()); |
1020 fatal(); | 1020 fatal(); |
1021 } | 1021 } |
1136 | 1136 |
1137 // | 1137 // |
1138 // decide whether this function needs to be looked up in the vtable | 1138 // decide whether this function needs to be looked up in the vtable |
1139 // | 1139 // |
1140 bool vtbllookup = fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual()); | 1140 bool vtbllookup = fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual()); |
1141 | 1141 |
1142 // even virtual functions are looked up directly if super or DotTypeExp | 1142 // even virtual functions are looked up directly if super or DotTypeExp |
1143 // are used, thus we need to walk through the this expression and check | 1143 // are used, thus we need to walk through the this expression and check |
1144 Expression* e = e1; | 1144 Expression* e = e1; |
1145 while (e && vtbllookup) { | 1145 while (e && vtbllookup) { |
1146 if (e->op == TOKsuper || e->op == TOKdottype) | 1146 if (e->op == TOKsuper || e->op == TOKdottype) |
1148 else if (e->op == TOKcast) | 1148 else if (e->op == TOKcast) |
1149 e = ((CastExp*)e)->e1; | 1149 e = ((CastExp*)e)->e1; |
1150 else | 1150 else |
1151 break; | 1151 break; |
1152 } | 1152 } |
1153 | 1153 |
1154 // | 1154 // |
1155 // look up function | 1155 // look up function |
1156 // | 1156 // |
1157 if (!vtbllookup) { | 1157 if (!vtbllookup) { |
1158 fdecl->codegen(Type::sir); | 1158 fdecl->codegen(Type::sir); |
1235 LLValue* arrptr = 0; | 1235 LLValue* arrptr = 0; |
1236 if (e1type->ty == Tpointer) { | 1236 if (e1type->ty == Tpointer) { |
1237 arrptr = DtoGEP1(l->getRVal(),r->getRVal()); | 1237 arrptr = DtoGEP1(l->getRVal(),r->getRVal()); |
1238 } | 1238 } |
1239 else if (e1type->ty == Tsarray) { | 1239 else if (e1type->ty == Tsarray) { |
1240 if(global.params.useArrayBounds) | 1240 if(global.params.useArrayBounds) |
1241 DtoArrayBoundsCheck(loc, l, r, false); | 1241 DtoArrayBoundsCheck(loc, l, r, false); |
1242 arrptr = DtoGEP(l->getRVal(), zero, r->getRVal()); | 1242 arrptr = DtoGEP(l->getRVal(), zero, r->getRVal()); |
1243 } | 1243 } |
1244 else if (e1type->ty == Tarray) { | 1244 else if (e1type->ty == Tarray) { |
1245 if(global.params.useArrayBounds) | 1245 if(global.params.useArrayBounds) |
1246 DtoArrayBoundsCheck(loc, l, r, false); | 1246 DtoArrayBoundsCheck(loc, l, r, false); |
1247 arrptr = DtoArrayPtr(l); | 1247 arrptr = DtoArrayPtr(l); |
1248 arrptr = DtoGEP1(arrptr,r->getRVal()); | 1248 arrptr = DtoGEP1(arrptr,r->getRVal()); |
1249 } | 1249 } |
1250 else if (e1type->ty == Taarray) { | 1250 else if (e1type->ty == Taarray) { |
1767 | 1767 |
1768 InvariantDeclaration* invdecl; | 1768 InvariantDeclaration* invdecl; |
1769 | 1769 |
1770 // class invariants | 1770 // class invariants |
1771 if( | 1771 if( |
1772 global.params.useInvariants && | 1772 global.params.useInvariants && |
1773 condty->ty == Tclass && | 1773 condty->ty == Tclass && |
1774 !((TypeClass*)condty)->sym->isInterfaceDeclaration()) | 1774 !((TypeClass*)condty)->sym->isInterfaceDeclaration()) |
1775 { | 1775 { |
1776 Logger::println("calling class invariant"); | 1776 Logger::println("calling class invariant"); |
1777 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_invariant"); | 1777 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_invariant"); |
1778 LLValue* arg = DtoBitCast(cond->getRVal(), fn->getFunctionType()->getParamType(0)); | 1778 LLValue* arg = DtoBitCast(cond->getRVal(), fn->getFunctionType()->getParamType(0)); |
1779 gIR->CreateCallOrInvoke(fn, arg); | 1779 gIR->CreateCallOrInvoke(fn, arg); |
1780 } | 1780 } |
1781 // struct invariants | 1781 // struct invariants |
1782 else if( | 1782 else if( |
1783 global.params.useInvariants && | 1783 global.params.useInvariants && |
1784 condty->ty == Tpointer && condty->nextOf()->ty == Tstruct && | 1784 condty->ty == Tpointer && condty->nextOf()->ty == Tstruct && |
1785 (invdecl = ((TypeStruct*)condty->nextOf())->sym->inv) != NULL) | 1785 (invdecl = ((TypeStruct*)condty->nextOf())->sym->inv) != NULL) |
1786 { | 1786 { |
1787 Logger::print("calling struct invariant"); | 1787 Logger::print("calling struct invariant"); |
1788 DFuncValue invfunc(invdecl, invdecl->ir.irFunc->func, cond->getRVal()); | 1788 DFuncValue invfunc(invdecl, invdecl->ir.irFunc->func, cond->getRVal()); |
2232 Type* e1type = e1->type->toBasetype(); | 2232 Type* e1type = e1->type->toBasetype(); |
2233 Type* elemtype = e1type->nextOf()->toBasetype(); | 2233 Type* elemtype = e1type->nextOf()->toBasetype(); |
2234 Type* e2type = e2->type->toBasetype(); | 2234 Type* e2type = e2->type->toBasetype(); |
2235 | 2235 |
2236 if (e2type == elemtype) { | 2236 if (e2type == elemtype) { |
2237 DSliceValue* slice = DtoCatAssignElement(l,e2); | 2237 DtoCatAssignElement(e1type, l, e2); |
2238 DtoAssign(loc, l, slice); | |
2239 } | 2238 } |
2240 else if (e1type == e2type) { | 2239 else if (e1type == e2type) { |
2241 DSliceValue* slice = DtoCatAssignArray(l,e2); | 2240 DSliceValue* slice = DtoCatAssignArray(l,e2); |
2242 DtoAssign(loc, l, slice); | 2241 DtoAssign(loc, l, slice); |
2243 } | 2242 } |