From 8044a67720a811421965146302a3e4d1e5d66277 Mon Sep 17 00:00:00 2001 From: Frits van Bommel Date: Mon, 8 Jun 2009 13:45:26 +0200 Subject: [PATCH] Apply changes from r1482 to D2 frontend too. Completely untested, but ldc2 compiles again. --- dmd2/aggregate.h | 5 +++++ dmd2/declaration.c | 15 +++++++++++++++ dmd2/declaration.h | 8 ++++++++ dmd2/func.c | 6 ++++++ dmd2/inline.c | 31 +++++++++++++++++++++++++++++++ dmd2/mars.h | 1 + dmd2/struct.c | 8 ++++++++ 7 files changed, 74 insertions(+) diff --git a/dmd2/aggregate.h b/dmd2/aggregate.h index aa195f96..7bdb9e18 100644 --- a/dmd2/aggregate.h +++ b/dmd2/aggregate.h @@ -121,6 +121,11 @@ struct AggregateDeclaration : ScopeDsymbol #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 --git a/dmd2/declaration.c b/dmd2/declaration.c index d03bdfc5..169194f7 100644 --- a/dmd2/declaration.c +++ b/dmd2/declaration.c @@ -638,6 +638,8 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer offset2 = 0; nakedUse = false; + + availableExternally = true; // assume this unless proven otherwise #endif } @@ -1182,6 +1184,16 @@ void VarDeclaration::semantic2(Scope *sc) } } +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 @@ Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s) void TypeInfoDeclaration::semantic(Scope *sc) { assert(linkage == LINKc); + // LDC + if (!global.params.useAvailableExternally) + availableExternally = false; } /***************************** TypeInfoConstDeclaration **********************/ diff --git a/dmd2/declaration.h b/dmd2/declaration.h index 65d8f5af..0791835f 100644 --- a/dmd2/declaration.h +++ b/dmd2/declaration.h @@ -312,6 +312,11 @@ struct VarDeclaration : Declaration /// 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 @@ struct FuncDeclaration : Declaration // 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 --git a/dmd2/func.c b/dmd2/func.c index 369c33c0..983ec84f 100644 --- a/dmd2/func.c +++ b/dmd2/func.c @@ -87,6 +87,8 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC s 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 @@ void FuncDeclaration::semantic3(Scope *sc) return; semanticRun = 3; + // LDC + if (!global.params.useAvailableExternally) + availableExternally = false; + if (!type || type->ty != Tfunction) return; f = (TypeFunction *)(type); diff --git a/dmd2/inline.c b/dmd2/inline.c index 132ec9cf..92e293e2 100644 --- a/dmd2/inline.c +++ b/dmd2/inline.c @@ -83,14 +83,17 @@ int IfStatement::inlineCost(InlineCostState *ics) { 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 @@ int IfStatement::inlineCost(InlineCostState *ics) //printf("cost = %d\n", cost); } else +#endif { ics->nested += 1; if (ifbody) @@ -121,9 +125,11 @@ int IfStatement::inlineCost(InlineCostState *ics) 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 VarExp::inlineCost(InlineCostState *ics) 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 StructLiteralExp::inlineCost(InlineCostState *ics) 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 @@ int DeclarationExp::inlineCost(InlineCostState *ics) 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 @@ int DeclarationExp::inlineCost(InlineCostState *ics) } // 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 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan) 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 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan) !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 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan) #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 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan) goto Lno; } } +#endif memset(&ics, 0, sizeof(ics)); ics.hasthis = hasthis; @@ -1334,8 +1363,10 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan) 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 --git a/dmd2/mars.h b/dmd2/mars.h index 869f17dd..5d47e3f5 100644 --- a/dmd2/mars.h +++ b/dmd2/mars.h @@ -242,6 +242,7 @@ struct Param bool llvmAnnotate; bool useInlineAsm; bool verbose_cg; + bool useAvailableExternally; // target stuff const char* llvmArch; diff --git a/dmd2/struct.c b/dmd2/struct.c index 8aa2112c..fb961398 100644 --- a/dmd2/struct.c +++ b/dmd2/struct.c @@ -56,6 +56,10 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id) 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::semantic2(Scope *sc) void AggregateDeclaration::semantic3(Scope *sc) { int i; + // LDC + if (!global.params.useAvailableExternally) + availableExternally = false; + //printf("AggregateDeclaration::semantic3(%s)\n", toChars()); if (members) {