From e6a0d05c5af8234abb98f32bec40c691207fc647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=B7=D0=B4=D0=B0=D0=B9=D1=89=D0=B8=D0=BA?= Date: Fri, 15 May 2020 22:34:19 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F:=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=B0=D0=BD=D1=8B=20=D1=84=D1=83=D0=BD=D0=BA=D1=86?= =?UTF-8?q?=D0=B8=D0=B8,=20=D0=B8=D0=BC=D0=B5=D1=8E=D1=89=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=B8=D0=BD=D0=BE=D0=BC=D0=B8=D0=B0=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=83=D1=8E=20=D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=8C=20(#194)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Глобальная оптимизация (#255) выявила участки кода, имеющие сверхлинейную зависимость по времени от входных данных. Если при компиляции отдельных небольших файлов проблемы заметны не были, то теперь, на конкатенации всех деревьев они встали в полный рост. Часть кода удалось оптимизировать, заменив Map на MapAccum, и соответственно, передавать константное значение не как параметр, а через аккумулятор: • FilterDeclaration в Desugaring.ref, • GenCommand-Globals в Generator-RASL.ref А некоторые функции пришлось переписать явно в линейные. Или, вернее, «прямоугольные» O(m×n) вместо «квадратных» O(max(m,n)²): • Переписана борьба с дублированием новых функций в прогонщике. Вместо DistinctFuncs, которая содержала две открытые переменные, делается два прохода по синтаксическому дереву: на первом все новые функции извлекаются (тут же исключается их дублирование), на втором удаляются те, которые в дереве уже присутствуют. • Переписан проход Pass-RemoveRedundantDriveInline в рассахаривателе. В нём ранее при помощи двойной открытой переменной обнаруживались парные (избыточные) метки Drive/Inline, функция вызывалась до тех пор, пока все избыточные пары не будут разрешены. Теперь делается два прохода по дереву: сначала все метки извлекаются, а потом они фильтруются. Преобразование является точным рефакторингом — позиции оставленных меток сохраняются. Формальных замеров я не делал, но цикл самоприменения с ключами -X-ODGS ускорился примерно в два раза (если не больше). --- src/compiler/Desugaring.ref | 57 +++++++++++++++++++++++++------- src/compiler/Generator-RASL.ref | 58 +++++++++++++++++++-------------- src/compiler/OptTree-Drive.ref | 56 +++++++++++++++++-------------- 3 files changed, 109 insertions(+), 62 deletions(-) diff --git a/src/compiler/Desugaring.ref b/src/compiler/Desugaring.ref index df0806c8..0f5168cf 100644 --- a/src/compiler/Desugaring.ref +++ b/src/compiler/Desugaring.ref @@ -192,17 +192,47 @@ Pass-AttachEntries { } Pass-RemoveRedundantDriveInline { - e.B (s.Label e.FuncName) e.M (s.Label e.FuncName) e.E - , : True - = ; + e.AST + = ; + (e.Labels) (Drive e.Name) + = (e.Labels (e.Name Drive)) (Drive e.Name); + + (e.Labels) (Inline e.Name) + = (e.Labels (e.Name Inline)) (Inline e.Name); + + (e.Labels) t.Other = (e.Labels) t.Other; + } + (/* labels */) e.AST + > + : (e.Labels) e.AST^ - e.B (Inline e.FuncName) e.M (Drive e.FuncName) e.E - = ; + = + : () e.AST^ - e.AST = e.AST; + = e.AST; } Pass-EnumerateVariables { @@ -888,15 +918,18 @@ Pass-CleanupRedudandExterns { e.AST > : (e.DefinedFunctions) e.AST^ - = ; + = + : (e.DefinedFunctions^) e.AST^ + = e.AST; } FilterDeclarations { - e.DefinedFunctions-B (e.Name) e.DefinedFunctions-E + (e.DefinedFunctions-B (e.Name) e.DefinedFunctions-E) (Declaration s.ScopeClass e.Name) - = /* пусто */; + = (e.DefinedFunctions-B (e.Name) e.DefinedFunctions-E) + /* пусто */; - e.DefinedFunctions t.OtherItem = t.OtherItem; + (e.DefinedFunctions) t.OtherItem = (e.DefinedFunctions) t.OtherItem; } Pass-UnfoldEnums { diff --git a/src/compiler/Generator-RASL.ref b/src/compiler/Generator-RASL.ref index 490b10d3..e3748c8b 100644 --- a/src/compiler/Generator-RASL.ref +++ b/src/compiler/Generator-RASL.ref @@ -50,7 +50,9 @@ $ENTRY GenProgram-RASL { e.StringsAsBytes > - ; + + > } BytesFromFunctionList { @@ -132,45 +134,51 @@ NameWithSign-Bytes { } GenCommand-Globals { - e.Labels (UnitName e.SrcName) = - >; - - e.Labels (CmdEnumDescr s.ScopeClass e.Name) = - >; - - e.Labels-B (s.Label s.Offset) e.Labels-E - (CmdInterpretFuncDescr s.ScopeClass e.Name s.Label) = - - - >; + (e.Labels) (UnitName e.SrcName) + = (e.Labels) >; + + (e.Labels) (CmdEnumDescr s.ScopeClass e.Name) + = (e.Labels) >; + + (e.Labels-B (s.Label s.Offset) e.Labels-E) + (CmdInterpretFuncDescr s.ScopeClass e.Name s.Label) + = (e.Labels-B (s.Label s.Offset) e.Labels-E) + + + >; - e.Labels (CmdMetatable s.ScopeClass (e.Name) e.Table) + (e.Labels) (CmdMetatable s.ScopeClass (e.Name) e.Table) = : s.Count e.Table^ - = ; + (s.Ident s.Function) + = ; } e.Table > >; - e.Labels (CmdSwapDescr s.ScopeClass e.Name) = - >; + (e.Labels) (CmdSwapDescr s.ScopeClass e.Name) + = (e.Labels) >; - e.Labels (CmdConditionFuncDecsrRasl s.ScopeClass e.Name) = - >; + (e.Labels) (CmdConditionFuncDecsrRasl s.ScopeClass e.Name) + = (e.Labels) + >; - e.Labels (CmdConditionFuncDecsrNative s.ScopeClass e.Name) = - >; + (e.Labels) (CmdConditionFuncDecsrNative s.ScopeClass e.Name) + = (e.Labels) + >; - e.Labels (CmdNativeFuncDescr s.ScopeClass e.Name) = - >; + (e.Labels) (CmdNativeFuncDescr s.ScopeClass e.Name) + = (e.Labels) + >; } Assemble { diff --git a/src/compiler/OptTree-Drive.ref b/src/compiler/OptTree-Drive.ref index e528af75..dffb6797 100644 --- a/src/compiler/OptTree-Drive.ref +++ b/src/compiler/OptTree-Drive.ref @@ -168,32 +168,38 @@ DriveInlineOptimizerTick { e.AST > : (e.OptInfo) e.AST^ - = (DriveInfo e.OptInfo) -} -DistinctFuncs { - e.AST - = : e.AST^ - = ; -} - -$SPEC DistinctFuncs-Aux s.TAG e.ast; - -DistinctFuncs-Aux { - s.FunctionTag - e.AST-B - (s.FunctionTag s.ScopeClass (e.Name) e.Body1) - e.AST-M - (Function s.ScopeClass (e.Name) e.Body2) - e.AST-E - = e.AST-B - ; + = + : (e.NewFunctions) e.AST^ + + = : True + = (e.News-B e.News-E) + (s.Function s.ScopeClass (e.Name) e.Body); + + (e.NewFunctions^) t.Other = (e.NewFunctions) t.Other; + } + (e.NewFunctions) e.AST + > + : (e.NewFunctions^) e.AST^ - s.FunctionTag e.AST = e.AST + = (DriveInfo e.OptInfo) e.AST e.NewFunctions; } IsPassiveCall { @@ -366,7 +372,7 @@ MakeColdSolution { = ( ((ColdCallBrackets (Symbol Name e.Name) e.Args)) ((/* нет присваиваний */) (/* нет сужений */)) - ((Function s.ScopeClass (e.Name) Sentences e.Body)) + ((NewFunction s.ScopeClass (e.Name) Sentences e.Body)) ); (s.FuncMode s.ScopeClass (e.Name) Sentences e.Body) e.Args