Beispiel #1
0
        private static VarInfoContainer GetVarInfoContainer(VarFinderSyntaxVisitor VFVis, List<ReductionDirective> Reductions, List<string> PrivateVars, syntax_tree_visitor visitor, SyntaxTree.compiler_directive dir)
        {
            if (Reductions == null)
                Reductions = new List<ReductionDirective>();
            if (PrivateVars == null)
                PrivateVars = new List<string>();
            VarInfoContainer Result = new VarInfoContainer();

            //константы копируются сразу
            Result.Constants = VFVis.Constants;

            //список переменных для редукции
            //ищем переменные с такими именами, проверяем их наличие, тип и если все хорошо - добавляем в список
            foreach (ReductionDirective rd in Reductions)
                foreach (string rdVarName in rd.variables)
                {
                    if (LoopVariables.Contains(rdVarName))
                    {
                        visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_REDUCTION_WITH_LOOPVAR_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                        continue;
                    }
                    SymbolInfo si = visitor.context.find(rdVarName);
                    if (si == null)
                    {
                        visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_UNKNOWN_VARNAME_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                        continue;
                    }
                    if (!(si.sym_info is SemanticTree.IVAriableDefinitionNode))
                    {
                        visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_NAME_IS_NOT_VAR_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                        continue;
                    }
                    if (!IsValidVarForReduction(si.sym_info as SemanticTree.IVAriableDefinitionNode))
                    {
                        visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_IS_NOT_POSSIBLE_REDUCTION_WITH_THIS_VAR_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                        continue;
                    }
                    Result.ReductionVariables.Add(si.sym_info as SemanticTree.IVAriableDefinitionNode);
                    Result.ReductionActions.Add(rd.Oper);
                    //for (int i = 0; i < VFVis.Variables.Count; ++i)
                    //    if (VFVis.Variables[i].name.ToLower() == rdVarName.ToLower())
                    //    {
                    //        Result.ReductionVariables.Add(VFVis.Variables[i]);
                    //        Result.ReductionActions.Add(rd.Oper);
                    //        break;
                    //    }
                }

            //приватные переменные - аналогично, но без проверки на тип
            foreach (string privateVar in PrivateVars)
            {
                SymbolInfo si = visitor.context.find(privateVar);
                if (si == null)
                {
                    visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_UNKNOWN_VARNAME_{0}"), privateVar), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                    continue;
                }
                if (!(si.sym_info is SemanticTree.IVAriableDefinitionNode))
                {
                    visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_NAME_IS_NOT_VAR_{0}"), privateVar), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
                    continue;
                }
                Result.PrivateVariables.Add(si.sym_info as SemanticTree.IVAriableDefinitionNode);
            }

            //по всем переменным:
            //если она не приватная и по ней нет редукции - переписываем ее в список разделяемых
            foreach (SemanticTree.IVAriableDefinitionNode var in VFVis.Variables)
            {
                bool NotShared = false;
                foreach (SemanticTree.IVAriableDefinitionNode rdn in Result.ReductionVariables)
                    if (rdn.name.ToLower() == var.name.ToLower())
                    {
                        NotShared = true;
                        break;
                    }
                if (!NotShared)
                    foreach (SemanticTree.IVAriableDefinitionNode prVar in Result.PrivateVariables)
                        if (prVar.name.ToLower() == var.name.ToLower())
                        {
                            NotShared = true;
                            break;
                        }
                if (!NotShared)
                    Result.SharedVariables.Add(var);
            }

            return Result;
        }
Beispiel #2
0
        private static bool GenerateOMPParallelForCall(statement_node body, SyntaxTree.for_node for_node, var_definition_node loop_variable, statements_list omp_stmts, syntax_tree_visitor syntax_tree_visitor, expression_node fromInclusive, expression_node toInclusive)
        {
            SyntaxTree.statement syntax_body = for_node.statements;

            expression_node omp_call = null;
            base_function_call bfc = body as base_function_call;
            if (bfc != null && bfc.parameters.Count == 1 && bfc.parameters[0] is variable_reference &&
                ((variable_reference)bfc.parameters[0]).VariableDefinition == loop_variable && ((bfc.function.parameters[0].type as type_node).PrintableName.ToLower() == "integer"))
            {
                //если тело цикла - вызов функции с одни параметром - переменной цикла,
                //если при этом у вызываемой функции тип параметра - integer, а не какой-нибудь object, как это бывает с write и вообще может быть с перегрузкой
                //то генерировать класс не надо.
                //генерируем вызов и все
                omp_call = syntax_tree_visitor.CreateDelegateCall(bfc);
                if (omp_call == null)
                {
                    syntax_tree_visitor.AddWarning(new OMP_ConstructionNotSupportedNow(body.location));
                    syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
                    return false;
                }
                base_function_call omp_parallel_for_call = null;
                if (SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info is common_namespace_function_node)
                    omp_parallel_for_call = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info as common_namespace_function_node, body.location);
                else
                    omp_parallel_for_call = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info as compiled_function_node, body.location);
                omp_parallel_for_call.parameters.AddElement(fromInclusive);
                omp_parallel_for_call.parameters.AddElement(toInclusive);
                omp_parallel_for_call.parameters.AddElement(omp_call);
                omp_stmts.statements.AddElement(omp_parallel_for_call);
            }
            else
            {
                //ищем используемые переменные, получаем редукцию из директивы и составляем список переменных по типам
                VarFinderSyntaxVisitor VFvis = new VarFinderSyntaxVisitor(syntax_body, syntax_tree_visitor.context, true);
                SyntaxTree.compiler_directive dir = syntax_tree_visitor.DirectivesToNodesLinks[for_node];
                //if (DirInfosTable[dir].ErrorName == "WARNING_IN_CLAUSE_PARAMETERS_REPEATED_VARS")
                //    syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                //else if (DirInfosTable[dir].ErrorName == "ERROR_IN_CLAUSE_PARAMETERS")
                //{
                //    syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                //}
                //else
               
                if (DirInfosTable[dir].ErrorName !=null)//== "ERROR_IN_CLAUSE")
                {
                    syntax_tree_visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                }

                VarInfoContainer Vars = GetVarInfoContainer(VFvis, DirInfosTable[dir].Reductions, DirInfosTable[dir].Privates, syntax_tree_visitor, dir);

                //сохраняем контекст
                ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor);

                string ClassName = syntax_tree_visitor.context.get_free_name("$for_class{0}");

                try
                {
                    //создаем и конвертируем класс
                    SyntaxTree.class_members member;
                    SyntaxTree.type_declarations Decls = CreateClass(ClassName, out member, Vars);
                    member.members.Add(CreateMethod("Method", syntax_body, for_node.loop_variable.name, member, Vars));
                    syntax_tree_visitor.visit(Decls);
                }
                finally
                {
                    //восстанавливаем контекст
                    contextInfo.RestoreContext(syntax_tree_visitor);
                }

                //создаем инициализацию, вызов и финализацию
                string ObjName = syntax_tree_visitor.context.get_free_name("$for_obj{0}");

                SyntaxTree.dot_node dn = new SyntaxTree.dot_node(new SyntaxTree.ident(ObjName), new SyntaxTree.ident("Method"));

                SyntaxTree.statement_list stl = CreateInitPart(ClassName, ObjName, Vars);
                stl.subnodes.Add(CreateNestedRegionBorder(true));
                stl.subnodes.Add(CreateOMPParallelForCall(dn, for_node.initial_value, for_node.finish_value));
                stl.subnodes.Add(CreateNestedRegionBorder(false));
                stl.subnodes.AddRange(CreateFinalPart(ObjName, Vars).subnodes);
                omp_stmts.statements.AddElement(syntax_tree_visitor.ret.visit(stl));
            }
            return true;
        }
Beispiel #3
0
        private static bool GenerateOMPParallelSectionsCall(statements_list stmts, SyntaxTree.statement_list syntax_stmts, statements_list omp_stmts, syntax_tree_visitor syntax_tree_visitor)
        {

            SyntaxTree.expression_list delegates = new PascalABCCompiler.SyntaxTree.expression_list();
            SyntaxTree.statement_list stlInit = new PascalABCCompiler.SyntaxTree.statement_list();
            SyntaxTree.statement_list stlFinal = new PascalABCCompiler.SyntaxTree.statement_list();
            VarInfoContainer Vars = new VarInfoContainer();
            string ClassName = syntax_tree_visitor.context.get_free_name("$section_class{0}");
            List<SyntaxTree.statement> Sections = new List<PascalABCCompiler.SyntaxTree.statement>();
            foreach (SyntaxTree.statement syntax_statement in syntax_stmts.subnodes)
            {
                if (syntax_statement is SyntaxTree.empty_statement)
                    continue;       //А зачем? ;-)
                if (syntax_statement is SyntaxTree.var_statement)
                {
                    //выдать предупреждение. Это не нормально для параллельных секций
                    syntax_tree_visitor.visit(syntax_statement as SyntaxTree.var_statement);
                }
                else
                {
                    //ищем используемые переменные
                    VarFinderSyntaxVisitor VFvis = new VarFinderSyntaxVisitor(syntax_statement, syntax_tree_visitor.context, false);
                    SyntaxTree.compiler_directive dir = syntax_tree_visitor.DirectivesToNodesLinks[syntax_stmts];
                    
                    //if (DirInfosTable[dir].ErrorName == "WARNING_IN_CLAUSE_PARAMETERS_REPEATED_VARS")
                    //    syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                    //else if (DirInfosTable[dir].ErrorName == "ERROR_IN_CLAUSE_PARAMETERS")
                    //{
                    //    syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                    //}
                    //else
                    if (DirInfosTable[dir].ErrorName != null)
                    {
                        syntax_tree_visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
                    }
                    Vars.UnionWith(GetVarInfoContainer(VFvis, null, DirInfosTable[dir].Privates, syntax_tree_visitor, dir));
                    Sections.Add(syntax_statement);
                }
            }
            //сохраняем контекст
            ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor);

            try
            {
                //создание и конвертирование класса
                SyntaxTree.class_members member;
                SyntaxTree.type_declarations Decls = CreateClass(ClassName, out member, Vars);
                for (int i = 0; i < Sections.Count; ++i)
                    member.members.Add(CreateMethod("method" + i.ToString(), Sections[i], "", member, Vars));
                syntax_tree_visitor.visit(Decls);
            }
            finally
            {
                //восстанавливаем контекст
                contextInfo.RestoreContext(syntax_tree_visitor);
            }
            //создаем инициализацию и финализацию
            int NameNum = 0;
            string ObjName = GetFreeName("$section_obj", ref NameNum, syntax_tree_visitor.context);

            stlInit.subnodes.AddRange(CreateInitPart(ClassName, ObjName, Vars).subnodes);
            stlFinal.subnodes.AddRange(CreateFinalPart(ObjName, Vars).subnodes);

            SyntaxTree.procedure_call pc = new PascalABCCompiler.SyntaxTree.procedure_call();
            SyntaxTree.method_call mc = new PascalABCCompiler.SyntaxTree.method_call();
            mc.dereferencing_value = CreateTPLFunctionReference("Invoke");
            pc.func_name = mc;
            SyntaxTree.expression_list exl = new PascalABCCompiler.SyntaxTree.expression_list();
            //foreach (string str in ObjNames)
            for (int i=0; i<Sections.Count; ++i)
                exl.Add(new SyntaxTree.dot_node(new SyntaxTree.ident(ObjName), new SyntaxTree.ident("Method"+i.ToString())));
            mc.parameters = exl;

            stlInit.subnodes.Add(CreateNestedRegionBorder(true));
            stlInit.subnodes.Add(pc);
            stlInit.subnodes.AddRange(stlFinal.subnodes);
            stlInit.subnodes.Add(CreateNestedRegionBorder(false));

            statement_node st = syntax_tree_visitor.ret.visit(stlInit);
            omp_stmts.statements.AddElement(st);
            return true;
        }