Skip to content

Commit

Permalink
inline.d: remove copy/pasta, fix obtuse logic
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Sep 27, 2015
1 parent c5ee583 commit cd01efb
Showing 1 changed file with 66 additions and 70 deletions.
136 changes: 66 additions & 70 deletions src/inline.d
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
/**
* Compiler implementation of the D programming language
*
* Copyright: Copyright (c) 1999-2015 by Digital Mars, All Rights Reserved
* Authors: Walter Bright, http://www.digitalmars.com
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(DMDSRC inline.d)
*/

module ddmd.inline;

import core.stdc.stdio;
import core.stdc.string;

import ddmd.aggregate;
import ddmd.apply;
import ddmd.arraytypes;
Expand Down Expand Up @@ -1177,7 +1179,7 @@ public:
FuncDeclaration parent; // function being scanned
// As the visit method cannot return a value, these variables
// are used to pass the result from 'visit' back to 'inlineScan'
Statement result;
Statement sresult;
Expression eresult;
bool again;

Expand All @@ -1197,23 +1199,13 @@ public:
}
if (s.exp)
{
inlineScan(&s.exp);
/* See if we can inline as a statement rather than as
* an Expression.
inlineScan(&s.exp); // inline as an expression
/* If there's a TOKcall at the top, then it failed to inline
* as an Expression. Try to inline as a Statement instead.
* Note that inline scanning of s.exp.e1 and s.exp.arguments was already done.
*/
if (s.exp && s.exp.op == TOKcall)
{
CallExp ce = cast(CallExp)s.exp;
if (ce.e1.op == TOKvar)
{
VarExp ve = cast(VarExp)ce.e1;
FuncDeclaration fd = ve.var.isFuncDeclaration();
if (fd && fd != parent && canInline(fd, 0, 0, 1))
{
expandInline(fd, parent, null, null, ce.arguments, &result, again);
}
}
}
visitCallExp(cast(CallExp)s.exp, null, true);
}
}

Expand Down Expand Up @@ -1360,11 +1352,13 @@ public:
{
if (!*s)
return;
Statement save = result;
result = *s;
assert(sresult is null);
(*s).accept(this);
*s = result;
result = save;
if (sresult)
{
*s = sresult;
sresult = null;
}
}

/* -------------------------- */
Expand All @@ -1383,7 +1377,7 @@ public:
{
}

Expression scanVar(Dsymbol s)
void scanVar(Dsymbol s)
{
//printf("scanVar(%s %s)\n", s->kind(), s->toPrettyChars());
VarDeclaration vd = s.isVarDeclaration();
Expand All @@ -1392,7 +1386,7 @@ public:
TupleDeclaration td = vd.toAlias().isTupleDeclaration();
if (td)
{
for (size_t i = 0; i < td.objects.dim; i++)
foreach (i; 0 .. td.objects.dim)
{
DsymbolExp se = cast(DsymbolExp)(*td.objects)[i];
assert(se.op == TOKdsymbol);
Expand All @@ -1403,27 +1397,20 @@ public:
{
if (ExpInitializer ie = vd._init.isExpInitializer())
{
Expression e = ie.exp;
inlineScan(&e);
if (vd._init != ie) // DeclareExp with vd appears in e
return e;
ie.exp = e;
inlineScan(&ie.exp);
}
}
}
else
{
s.accept(this);
}
return null;
}

override void visit(DeclarationExp e)
{
//printf("DeclarationExp::inlineScan()\n");
Expression ed = scanVar(e.declaration);
if (ed)
eresult = ed;
scanVar(e.declaration);
}

override void visit(UnaExp e)
Expand All @@ -1445,6 +1432,7 @@ public:

override void visit(AssignExp e)
{
// Look for NRVO, as inlining NRVO function returns require special handling
if (e.op == TOKconstruct && e.e2.op == TOKcall)
{
CallExp ce = cast(CallExp)e.e2;
Expand All @@ -1467,10 +1455,12 @@ public:
*/
inlineScan(&e.e1);
}
visitCallExp(ce, e.e1);
inlineScan(&ce.e1);
arrayInlineScan(ce.arguments);
visitCallExp(ce, e.e1, false);
if (eresult)
{
//printf("call with nrvo: %s ==> %s\n", e->toChars(), eresult->toChars());
//printf("call with nrvo: %s ==> %s\n", e.toChars(), eresult.toChars());
return;
}
}
Expand All @@ -1481,34 +1471,37 @@ public:

override void visit(CallExp e)
{
visitCallExp(e, null);
inlineScan(&e.e1);
arrayInlineScan(e.arguments);
visitCallExp(e, null, false);
}

void visitCallExp(CallExp e, Expression eret)
/**************************************
* Check function call to see if can be inlined,
* and then inline it if it can.
* Params:
* e = the function call
* eret = if !null, then this is the lvalue of the nrvo function result
* asStatements = if inline as statements rather than as an Expression
*/
void visitCallExp(CallExp e, Expression eret, bool asStatements)
{
//printf("CallExp::inlineScan()\n");
inlineScan(&e.e1);
arrayInlineScan(e.arguments);
FuncDeclaration fd;
if (e.e1.op == TOKvar)
{
VarExp ve = cast(VarExp)e.e1;
FuncDeclaration fd = ve.var.isFuncDeclaration();
if (fd && fd != parent && canInline(fd, 0, 0, 0))
fd = ve.var.isFuncDeclaration();
if (fd && fd != parent && canInline(fd, 0, 0, asStatements))
{
Expression ex = expandInline(fd, parent, eret, null, e.arguments, null, again);
if (ex)
{
eresult = ex;
if (global.params.verbose)
fprintf(global.stdmsg, "inlined %s =>\n %s\n", fd.toPrettyChars(), parent.toPrettyChars());
}
eresult = expandInline(fd, parent, eret, null, e.arguments, asStatements ? &sresult : null, again);
}
}
else if (e.e1.op == TOKdotvar)
{
DotVarExp dve = cast(DotVarExp)e.e1;
FuncDeclaration fd = dve.var.isFuncDeclaration();
if (fd && fd != parent && canInline(fd, 1, 0, 0))
fd = dve.var.isFuncDeclaration();
if (fd && fd != parent && canInline(fd, 1, 0, asStatements))
{
if (dve.e1.op == TOKcall && dve.e1.type.toBasetype().ty == Tstruct)
{
Expand All @@ -1519,16 +1512,16 @@ public:
}
else
{
Expression ex = expandInline(fd, parent, eret, dve.e1, e.arguments, null, again);
if (ex)
{
eresult = ex;
if (global.params.verbose)
fprintf(global.stdmsg, "inlined %s =>\n %s\n", fd.toPrettyChars(), parent.toPrettyChars());
}
eresult = expandInline(fd, parent, eret, dve.e1, e.arguments, asStatements ? &sresult : null, again);
}
}
}
else
return;

if (global.params.verbose && (eresult || sresult))
fprintf(global.stdmsg, "inlined %s =>\n %s\n", fd.toPrettyChars(), parent.toPrettyChars());

if (eresult && e.type.ty != Tvoid)
{
Expression ex = eresult;
Expand Down Expand Up @@ -1598,12 +1591,13 @@ public:
{
if (!*e)
return;
Expression save = eresult;
eresult = *e;
assert(eresult is null);
(*e).accept(this);
assert(eresult);
*e = eresult;
eresult = save;
if (eresult)
{
*e = eresult;
eresult = null;
}
}

/*************************************
Expand Down Expand Up @@ -1687,7 +1681,7 @@ public:
}
}

bool canInline(FuncDeclaration fd, int hasthis, int hdrscan, int statementsToo)
bool canInline(FuncDeclaration fd, int hasthis, int hdrscan, bool statementsToo)
{
int cost;
enum CANINLINE_LOG = 0;
Expand Down Expand Up @@ -1883,11 +1877,10 @@ public void inlineScanModule(Module m)
* ethis = 'this' reference
* arguments = arguments passed to fd
* ps = if expanding to a statement, this is where the statement is written to
* (and ignore the return value)
* again = if true, then fd can be inline scanned again because there may be
* more opportunities for inlining
* Returns:
* Expression it expanded to
* Expression it expanded to (null if ps is not null)
*/
Expression expandInline(FuncDeclaration fd, FuncDeclaration parent, Expression eret,
Expression ethis, Expressions* arguments, Statement* ps, out bool again)
Expand Down Expand Up @@ -2050,7 +2043,10 @@ Expression expandInline(FuncDeclaration fd, FuncDeclaration parent, Expression e
if (ps)
{
if (e)
{
as.push(new ExpStatement(Loc(), e));
e = null;
}
fd.inlineNest++;
Statement s = inlineAsStatement(fd.fbody, &ids);
as.push(s);
Expand Down

0 comments on commit cd01efb

Please sign in to comment.