# HG changeset patch # User Frits van Bommel # Date 1244461526 -7200 # Node ID f62347c22d8156a0652f177fff81ff4f2a1c407b # Parent 9ed0695cb93cab3db4573fadda891a36a205f4f2 Apply changes from r1482 to D2 frontend too. Completely untested, but ldc2 compiles again. diff -r 9ed0695cb93c -r f62347c22d81 dmd2/aggregate.h --- a/dmd2/aggregate.h Mon Jun 08 12:35:55 2009 +0200 +++ b/dmd2/aggregate.h Mon Jun 08 13:45:26 2009 +0200 @@ -121,6 +121,11 @@ #endif AggregateDeclaration *isAggregateDeclaration() { return this; } + +#if IN_LLVM + // Aggregates that wouldn't have gotten semantic3'ed if we weren't inlining set this flag. + bool availableExternally; +#endif }; struct AnonymousAggregateDeclaration : AggregateDeclaration diff -r 9ed0695cb93c -r f62347c22d81 dmd2/declaration.c --- a/dmd2/declaration.c Mon Jun 08 12:35:55 2009 +0200 +++ b/dmd2/declaration.c Mon Jun 08 13:45:26 2009 +0200 @@ -638,6 +638,8 @@ offset2 = 0; nakedUse = false; + + availableExternally = true; // assume this unless proven otherwise #endif } @@ -1182,6 +1184,16 @@ } } +void VarDeclaration::semantic3(Scope *sc) +{ + // LDC + if (!global.params.useAvailableExternally) + availableExternally = false; + + // Preserve call chain + Declaration::semantic3(sc); +} + const char *VarDeclaration::kind() { return "variable"; @@ -1576,6 +1588,9 @@ void TypeInfoDeclaration::semantic(Scope *sc) { assert(linkage == LINKc); + // LDC + if (!global.params.useAvailableExternally) + availableExternally = false; } /***************************** TypeInfoConstDeclaration **********************/ diff -r 9ed0695cb93c -r f62347c22d81 dmd2/declaration.h --- a/dmd2/declaration.h Mon Jun 08 12:35:55 2009 +0200 +++ b/dmd2/declaration.h Mon Jun 08 13:45:26 2009 +0200 @@ -312,6 +312,11 @@ /// Set during type generation. unsigned aggrIndex; + /// Variables that wouldn't have gotten semantic3'ed if we weren't inlining set this flag. + bool availableExternally; + /// Override added to set above flag. + void semantic3(Scope *sc); + // FIXME: we're not using these anymore! AnonDeclaration* anonDecl; unsigned offset2; @@ -777,6 +782,9 @@ // if this is an array operation it gets a little special attention bool isArrayOp; + // Functions that wouldn't have gotten semantic3'ed if we weren't inlining set this flag. + bool availableExternally; + // true if overridden with the pragma(allow_inline); stmt bool allowInlining; #endif diff -r 9ed0695cb93c -r f62347c22d81 dmd2/func.c --- a/dmd2/func.c Mon Jun 08 12:35:55 2009 +0200 +++ b/dmd2/func.c Mon Jun 08 13:45:26 2009 +0200 @@ -87,6 +87,8 @@ isArrayOp = false; allowInlining = false; + availableExternally = true; // assume this unless proven otherwise + // function types in ldc don't merge if the context parameter differs // so we actually don't care about the function declaration, but only // what kind of context parameter it has. @@ -672,6 +674,10 @@ return; semanticRun = 3; + // LDC + if (!global.params.useAvailableExternally) + availableExternally = false; + if (!type || type->ty != Tfunction) return; f = (TypeFunction *)(type); diff -r 9ed0695cb93c -r f62347c22d81 dmd2/inline.c --- a/dmd2/inline.c Mon Jun 08 12:35:55 2009 +0200 +++ b/dmd2/inline.c Mon Jun 08 13:45:26 2009 +0200 @@ -83,14 +83,17 @@ { int cost; +#if !IN_LLVM /* Can't declare variables inside ?: expressions, so * we cannot inline if a variable is declared. */ if (arg) return COST_MAX; +#endif cost = condition->inlineCost(ics); +#if !IN_LLVM /* Specifically allow: * if (condition) * return exp1; @@ -108,6 +111,7 @@ //printf("cost = %d\n", cost); } else +#endif { ics->nested += 1; if (ifbody) @@ -121,9 +125,11 @@ int ReturnStatement::inlineCost(InlineCostState *ics) { +#if !IN_LLVM // Can't handle return statements nested in if's if (ics->nested) return COST_MAX; +#endif return exp ? exp->inlineCost(ics) : 0; } @@ -157,19 +163,23 @@ int ThisExp::inlineCost(InlineCostState *ics) { +#if !IN_LLVM FuncDeclaration *fd = ics->fd; if (!ics->hdrscan) if (fd->isNested() || !ics->hasthis) return COST_MAX; +#endif return 1; } int SuperExp::inlineCost(InlineCostState *ics) { +#if !IN_LLVM FuncDeclaration *fd = ics->fd; if (!ics->hdrscan) if (fd->isNested() || !ics->hasthis) return COST_MAX; +#endif return 1; } @@ -195,12 +205,16 @@ int FuncExp::inlineCost(InlineCostState *ics) { + // This breaks on LDC too, since nested functions have internal linkage + // and thus can't be referenced from other objects. // Right now, this makes the function be output to the .obj file twice. return COST_MAX; } int DelegateExp::inlineCost(InlineCostState *ics) { + // This breaks on LDC too, since nested functions have internal linkage + // and thus can't be referenced from other objects. return COST_MAX; } @@ -229,6 +243,8 @@ return td->objects->dim; #endif } + // This breaks on LDC too, since nested static variables have internal + // linkage and thus can't be referenced from other objects. if (!ics->hdrscan && vd->isDataseg()) return COST_MAX; cost += 1; @@ -246,6 +262,8 @@ } // These can contain functions, which when copied, get output twice. + // These break on LDC too, since nested static variables and functions have + // internal linkage and thus can't be referenced from other objects. if (declaration->isStructDeclaration() || declaration->isClassDeclaration() || declaration->isFuncDeclaration() || @@ -1269,6 +1287,10 @@ if (type) { assert(type->ty == Tfunction); TypeFunction *tf = (TypeFunction *)(type); +#if IN_LLVM + // LDC: Only extern(C) varargs count. + if (tf->linkage != LINKd) +#endif if (tf->varargs == 1) // no variadic parameter lists goto Lno; @@ -1280,12 +1302,15 @@ !hdrscan) goto Lno; } +#if !IN_LLVM + // LDC: Only extern(C) varargs count, and ctors use extern(D). else { CtorDeclaration *ctor = isCtorDeclaration(); if (ctor && ctor->varargs == 1) goto Lno; } +#endif if ( !fbody || @@ -1299,17 +1324,20 @@ #endif isSynchronized() || isImportedSymbol() || +#if !IN_LLVM #if DMDV2 closureVars.dim || // no nested references to this frame #else nestedFrameRef || // no nested references to this frame #endif +#endif // !IN_LLVM (isVirtual() && !isFinal()) )) { goto Lno; } +#if !IN_LLVM /* If any parameters are Tsarray's (which are passed by reference) * or out parameters (also passed by reference), don't do inlining. */ @@ -1322,6 +1350,7 @@ goto Lno; } } +#endif memset(&ics, 0, sizeof(ics)); ics.hasthis = hasthis; @@ -1334,8 +1363,10 @@ if (cost >= COST_MAX) goto Lno; +#if !IN_LLVM if (!hdrscan) // Don't scan recursively for header content scan inlineScan(); +#endif Lyes: if (!hdrscan) // Don't modify inlineStatus for header content scan diff -r 9ed0695cb93c -r f62347c22d81 dmd2/mars.h --- a/dmd2/mars.h Mon Jun 08 12:35:55 2009 +0200 +++ b/dmd2/mars.h Mon Jun 08 13:45:26 2009 +0200 @@ -242,6 +242,7 @@ bool llvmAnnotate; bool useInlineAsm; bool verbose_cg; + bool useAvailableExternally; // target stuff const char* llvmArch; diff -r 9ed0695cb93c -r f62347c22d81 dmd2/struct.c --- a/dmd2/struct.c Mon Jun 08 12:35:55 2009 +0200 +++ b/dmd2/struct.c Mon Jun 08 13:45:26 2009 +0200 @@ -56,6 +56,10 @@ aliasthis = NULL; #endif dtor = NULL; + +#if IN_LLVM + availableExternally = true; // assume this unless proven otherwise +#endif } enum PROT AggregateDeclaration::prot() @@ -85,6 +89,10 @@ void AggregateDeclaration::semantic3(Scope *sc) { int i; + // LDC + if (!global.params.useAvailableExternally) + availableExternally = false; + //printf("AggregateDeclaration::semantic3(%s)\n", toChars()); if (members) {