Mercurial > projects > ldc
comparison dmd/inline.c @ 1482:d9c5f5a43403
Run `semantic3` on imported modules, and emit new symbols with
`available_externally` linkage. This allows the inliner to inline functions from
other modules while telling the code generator to ignore those functions (treat
them as declarations)
Still generates a few extra `TypeInfo`s and strings...
Disabled when generating debug info because I don't really understand it, and it
doesn't like this.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Sun, 07 Jun 2009 16:00:13 +0200 |
parents | 8026319762be |
children | def7a1d494fd |
comparison
equal
deleted
inserted
replaced
1481:e0f03e11cdf8 | 1482:d9c5f5a43403 |
---|---|
81 | 81 |
82 int IfStatement::inlineCost(InlineCostState *ics) | 82 int IfStatement::inlineCost(InlineCostState *ics) |
83 { | 83 { |
84 int cost; | 84 int cost; |
85 | 85 |
86 #if !IN_LLVM | |
86 /* Can't declare variables inside ?: expressions, so | 87 /* Can't declare variables inside ?: expressions, so |
87 * we cannot inline if a variable is declared. | 88 * we cannot inline if a variable is declared. |
88 */ | 89 */ |
89 if (arg) | 90 if (arg) |
90 return COST_MAX; | 91 return COST_MAX; |
92 #endif | |
91 | 93 |
92 cost = condition->inlineCost(ics); | 94 cost = condition->inlineCost(ics); |
93 | 95 |
96 #if !IN_LLVM | |
94 /* Specifically allow: | 97 /* Specifically allow: |
95 * if (condition) | 98 * if (condition) |
96 * return exp1; | 99 * return exp1; |
97 * else | 100 * else |
98 * return exp2; | 101 * return exp2; |
106 cost += ifbody->inlineCost(ics); | 109 cost += ifbody->inlineCost(ics); |
107 cost += elsebody->inlineCost(ics); | 110 cost += elsebody->inlineCost(ics); |
108 //printf("cost = %d\n", cost); | 111 //printf("cost = %d\n", cost); |
109 } | 112 } |
110 else | 113 else |
114 #endif | |
111 { | 115 { |
112 ics->nested += 1; | 116 ics->nested += 1; |
113 if (ifbody) | 117 if (ifbody) |
114 cost += ifbody->inlineCost(ics); | 118 cost += ifbody->inlineCost(ics); |
115 if (elsebody) | 119 if (elsebody) |
119 return cost; | 123 return cost; |
120 } | 124 } |
121 | 125 |
122 int ReturnStatement::inlineCost(InlineCostState *ics) | 126 int ReturnStatement::inlineCost(InlineCostState *ics) |
123 { | 127 { |
128 #if !IN_LLVM | |
124 // Can't handle return statements nested in if's | 129 // Can't handle return statements nested in if's |
125 if (ics->nested) | 130 if (ics->nested) |
126 return COST_MAX; | 131 return COST_MAX; |
132 #endif | |
127 return exp ? exp->inlineCost(ics) : 0; | 133 return exp ? exp->inlineCost(ics) : 0; |
128 } | 134 } |
129 | 135 |
130 /* -------------------------- */ | 136 /* -------------------------- */ |
131 | 137 |
155 return 1; | 161 return 1; |
156 } | 162 } |
157 | 163 |
158 int ThisExp::inlineCost(InlineCostState *ics) | 164 int ThisExp::inlineCost(InlineCostState *ics) |
159 { | 165 { |
166 #if !IN_LLVM | |
160 FuncDeclaration *fd = ics->fd; | 167 FuncDeclaration *fd = ics->fd; |
161 if (!ics->hdrscan) | 168 if (!ics->hdrscan) |
162 if (fd->isNested() || !ics->hasthis) | 169 if (fd->isNested() || !ics->hasthis) |
163 return COST_MAX; | 170 return COST_MAX; |
171 #endif | |
164 return 1; | 172 return 1; |
165 } | 173 } |
166 | 174 |
167 int SuperExp::inlineCost(InlineCostState *ics) | 175 int SuperExp::inlineCost(InlineCostState *ics) |
168 { | 176 { |
177 #if !IN_LLVM | |
169 FuncDeclaration *fd = ics->fd; | 178 FuncDeclaration *fd = ics->fd; |
170 if (!ics->hdrscan) | 179 if (!ics->hdrscan) |
171 if (fd->isNested() || !ics->hasthis) | 180 if (fd->isNested() || !ics->hasthis) |
172 return COST_MAX; | 181 return COST_MAX; |
182 #endif | |
173 return 1; | 183 return 1; |
174 } | 184 } |
175 | 185 |
176 int TupleExp::inlineCost(InlineCostState *ics) | 186 int TupleExp::inlineCost(InlineCostState *ics) |
177 { | 187 { |
193 return 1 + arrayInlineCost(ics, elements); | 203 return 1 + arrayInlineCost(ics, elements); |
194 } | 204 } |
195 | 205 |
196 int FuncExp::inlineCost(InlineCostState *ics) | 206 int FuncExp::inlineCost(InlineCostState *ics) |
197 { | 207 { |
208 // This breaks on LDC too, since nested functions have internal linkage | |
209 // and thus can't be referenced from other objects. | |
198 // Right now, this makes the function be output to the .obj file twice. | 210 // Right now, this makes the function be output to the .obj file twice. |
199 return COST_MAX; | 211 return COST_MAX; |
200 } | 212 } |
201 | 213 |
202 int DelegateExp::inlineCost(InlineCostState *ics) | 214 int DelegateExp::inlineCost(InlineCostState *ics) |
203 { | 215 { |
216 // This breaks on LDC too, since nested functions have internal linkage | |
217 // and thus can't be referenced from other objects. | |
204 return COST_MAX; | 218 return COST_MAX; |
205 } | 219 } |
206 | 220 |
207 int DeclarationExp::inlineCost(InlineCostState *ics) | 221 int DeclarationExp::inlineCost(InlineCostState *ics) |
208 { int cost = 0; | 222 { int cost = 0; |
227 return COST_MAX; | 241 return COST_MAX; |
228 } | 242 } |
229 return td->objects->dim; | 243 return td->objects->dim; |
230 #endif | 244 #endif |
231 } | 245 } |
246 // This breaks on LDC too, since nested static variables have internal | |
247 // linkage and thus can't be referenced from other objects. | |
232 if (!ics->hdrscan && vd->isDataseg()) | 248 if (!ics->hdrscan && vd->isDataseg()) |
233 return COST_MAX; | 249 return COST_MAX; |
234 cost += 1; | 250 cost += 1; |
235 | 251 |
236 // Scan initializer (vd->init) | 252 // Scan initializer (vd->init) |
244 } | 260 } |
245 } | 261 } |
246 } | 262 } |
247 | 263 |
248 // These can contain functions, which when copied, get output twice. | 264 // These can contain functions, which when copied, get output twice. |
265 // These break on LDC too, since nested static variables and functions have | |
266 // internal linkage and thus can't be referenced from other objects. | |
249 if (declaration->isStructDeclaration() || | 267 if (declaration->isStructDeclaration() || |
250 declaration->isClassDeclaration() || | 268 declaration->isClassDeclaration() || |
251 declaration->isFuncDeclaration() || | 269 declaration->isFuncDeclaration() || |
252 declaration->isTypedefDeclaration() || | 270 declaration->isTypedefDeclaration() || |
253 declaration->isTemplateMixin()) | 271 declaration->isTemplateMixin()) |
1267 } | 1285 } |
1268 | 1286 |
1269 if (type) | 1287 if (type) |
1270 { assert(type->ty == Tfunction); | 1288 { assert(type->ty == Tfunction); |
1271 TypeFunction *tf = (TypeFunction *)(type); | 1289 TypeFunction *tf = (TypeFunction *)(type); |
1290 #if IN_LLVM | |
1291 // LDC: Only extern(C) varargs count. | |
1292 if (tf->linkage != LINKd) | |
1293 #endif | |
1272 if (tf->varargs == 1) // no variadic parameter lists | 1294 if (tf->varargs == 1) // no variadic parameter lists |
1273 goto Lno; | 1295 goto Lno; |
1274 | 1296 |
1275 /* Don't inline a function that returns non-void, but has | 1297 /* Don't inline a function that returns non-void, but has |
1276 * no return expression. | 1298 * no return expression. |
1278 if (tf->next && tf->next->ty != Tvoid && | 1300 if (tf->next && tf->next->ty != Tvoid && |
1279 !(hasReturnExp & 1) && | 1301 !(hasReturnExp & 1) && |
1280 !hdrscan) | 1302 !hdrscan) |
1281 goto Lno; | 1303 goto Lno; |
1282 } | 1304 } |
1305 #if !IN_LLVM | |
1306 // LDC: Only extern(C) varargs count, and ctors use extern(D). | |
1283 else | 1307 else |
1284 { CtorDeclaration *ctor = isCtorDeclaration(); | 1308 { CtorDeclaration *ctor = isCtorDeclaration(); |
1285 | 1309 |
1286 if (ctor && ctor->varargs == 1) | 1310 if (ctor && ctor->varargs == 1) |
1287 goto Lno; | 1311 goto Lno; |
1288 } | 1312 } |
1313 #endif | |
1289 | 1314 |
1290 if ( | 1315 if ( |
1291 !fbody || | 1316 !fbody || |
1292 !hdrscan && | 1317 !hdrscan && |
1293 ( | 1318 ( |
1297 // to: | 1322 // to: |
1298 // return this; | 1323 // return this; |
1299 #endif | 1324 #endif |
1300 isSynchronized() || | 1325 isSynchronized() || |
1301 isImportedSymbol() || | 1326 isImportedSymbol() || |
1327 #if !IN_LLVM | |
1302 #if DMDV2 | 1328 #if DMDV2 |
1303 closureVars.dim || // no nested references to this frame | 1329 closureVars.dim || // no nested references to this frame |
1304 #else | 1330 #else |
1305 nestedFrameRef || // no nested references to this frame | 1331 nestedFrameRef || // no nested references to this frame |
1306 #endif | 1332 #endif |
1333 #endif // !IN_LLVM | |
1307 (isVirtual() && !isFinal()) | 1334 (isVirtual() && !isFinal()) |
1308 )) | 1335 )) |
1309 { | 1336 { |
1310 goto Lno; | 1337 goto Lno; |
1311 } | 1338 } |
1312 | 1339 |
1340 #if !IN_LLVM | |
1313 /* If any parameters are Tsarray's (which are passed by reference) | 1341 /* If any parameters are Tsarray's (which are passed by reference) |
1314 * or out parameters (also passed by reference), don't do inlining. | 1342 * or out parameters (also passed by reference), don't do inlining. |
1315 */ | 1343 */ |
1316 if (parameters) | 1344 if (parameters) |
1317 { | 1345 { |
1320 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; | 1348 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; |
1321 if (v->isOut() || v->isRef() || v->type->toBasetype()->ty == Tsarray) | 1349 if (v->isOut() || v->isRef() || v->type->toBasetype()->ty == Tsarray) |
1322 goto Lno; | 1350 goto Lno; |
1323 } | 1351 } |
1324 } | 1352 } |
1353 #endif | |
1325 | 1354 |
1326 memset(&ics, 0, sizeof(ics)); | 1355 memset(&ics, 0, sizeof(ics)); |
1327 ics.hasthis = hasthis; | 1356 ics.hasthis = hasthis; |
1328 ics.fd = this; | 1357 ics.fd = this; |
1329 ics.hdrscan = hdrscan; | 1358 ics.hdrscan = hdrscan; |
1332 printf("cost = %d\n", cost); | 1361 printf("cost = %d\n", cost); |
1333 #endif | 1362 #endif |
1334 if (cost >= COST_MAX) | 1363 if (cost >= COST_MAX) |
1335 goto Lno; | 1364 goto Lno; |
1336 | 1365 |
1366 #if !IN_LLVM | |
1337 if (!hdrscan) // Don't scan recursively for header content scan | 1367 if (!hdrscan) // Don't scan recursively for header content scan |
1338 inlineScan(); | 1368 inlineScan(); |
1369 #endif | |
1339 | 1370 |
1340 Lyes: | 1371 Lyes: |
1341 if (!hdrscan) // Don't modify inlineStatus for header content scan | 1372 if (!hdrscan) // Don't modify inlineStatus for header content scan |
1342 inlineStatus = ILSyes; | 1373 inlineStatus = ILSyes; |
1343 #if CANINLINE_LOG | 1374 #if CANINLINE_LOG |