예제 #1
0
        private static Task <CudaModule> CompileAsync(
            MethodReference method,
            IEnumerable <MethodReference> methodRoots,
            IEnumerable <TypeReference> typeRoots,
            int threadIdParamIndex,
            CudaContext context)
        {
            var module      = method.Module;
            var flameModule = ClrAssembly.Wrap(module.Assembly);

            return(CompileAsync(
                       flameModule.Resolve(method),
                       methodRoots.Select(flameModule.Resolve).ToArray(),
                       typeRoots.Select(flameModule.Resolve).ToArray(),
                       threadIdParamIndex,
                       flameModule,
                       context));
        }
예제 #2
0
파일: Program.cs 프로젝트: anthrax3/Flame
        public static int Main(string[] args)
        {
            // Acquire a log.
            var rawLog = TerminalLog.Acquire();

            log = new TransformLog(
                rawLog,
                new Func <LogEntry, LogEntry>[]
            {
                MakeDiagnostic
            });

            // Parse command-line options.
            var parser = new GnuOptionSetParser(
                Options.All, Options.Input);

            var recLog        = new RecordingLog(log);
            var parsedOptions = parser.Parse(args, recLog);

            if (recLog.Contains(Severity.Error))
            {
                // Stop the program if the command-line arguments
                // are half baked.
                return(1);
            }

            if (parsedOptions.GetValue <bool>(Options.Help))
            {
                // Wrap the help message into a log entry and send it to the log.
                TerminalLog.AcquireStandardOutput().Log(
                    new LogEntry(
                        Severity.Info,
                        new HelpMessage(
                            "il2llvm is a command-line tool that compiles CIL assemblies to LLVM modules.",
                            "il2llvm path [options...]",
                            Options.All)));
                return(0);
            }

            var inputPath = parsedOptions.GetValue <string>(Options.Input);

            if (string.IsNullOrEmpty(inputPath))
            {
                log.Log(
                    new LogEntry(
                        Severity.Error,
                        "nothing to compile",
                        "no input file"));
                return(1);
            }

            var outputPath = parsedOptions.GetValue <string>(Options.Output);

            if (string.IsNullOrEmpty(outputPath))
            {
                outputPath = Path.GetFileNameWithoutExtension(inputPath) + ".ll";
            }

            var printIr = parsedOptions.GetValue <bool>(Options.PrintIr);

            // Read the assembly from disk.
            Mono.Cecil.AssemblyDefinition cecilAsm;
            try
            {
                cecilAsm = Mono.Cecil.AssemblyDefinition.ReadAssembly(
                    inputPath,
                    new Mono.Cecil.ReaderParameters
                {
                    ReadWrite = false
                });
            }
            catch (Exception)
            {
                log.Log(
                    new LogEntry(
                        Severity.Error,
                        "unreadable assembly",
                        Quotation.QuoteEvenInBold(
                            "cannot read assembly at ",
                            inputPath,
                            ".")));
                return(1);
            }

            if (cecilAsm.EntryPoint == null)
            {
                log.Log(
                    new LogEntry(
                        Severity.Error,
                        "unsuitable assembly",
                        "input assembly does not define an entry point."));
                return(1);
            }

            try
            {
                // Wrap the CIL assembly in a Flame assembly.
                var flameAsm = ClrAssembly.Wrap(cecilAsm);

                // Compile the assembly to an LLVM module.
                var module = CompileAsync(flameAsm).Result;

                // Write the LLVM module to disk.
                string error;
                if (LLVM.PrintModuleToFile(module, outputPath, out error))
                {
                    log.Log(new LogEntry(Severity.Error, "cannot write module", error));
                }

                LLVM.DisposeModule(module);
            }
            finally
            {
                // Be sure to dispose the assembly after we've used it.
                cecilAsm.Dispose();
            }

            return(0);
        }
예제 #3
0
        public static int Main(string[] args)
        {
            // Acquire a log.
            var rawLog = TerminalLog.Acquire();

            log = new TransformLog(
                rawLog,
                new Func <LogEntry, LogEntry>[]
            {
                MakeDiagnostic
            });

            // Parse command-line options.
            var parser = new GnuOptionSetParser(
                Options.All, Options.Input);

            var recLog        = new RecordingLog(log);
            var parsedOptions = parser.Parse(args, recLog);

            if (recLog.Contains(Severity.Error))
            {
                // Stop the program if the command-line arguments
                // are half baked.
                return(1);
            }

            if (parsedOptions.GetValue <bool>(Options.Help))
            {
                // Wrap the help message into a log entry and send it to the log.
                TerminalLog.AcquireStandardOutput().Log(
                    new LogEntry(
                        Severity.Info,
                        new HelpMessage(
                            "ilopt is a command-line tool that optimizes CIL assemblies.",
                            "ilopt path [options...]",
                            Options.All)));
                return(0);
            }

            var inputPath = parsedOptions.GetValue <string>(Options.Input);

            if (string.IsNullOrEmpty(inputPath))
            {
                log.Log(
                    new LogEntry(
                        Severity.Error,
                        "nothing to optimize",
                        "no input file"));
                return(1);
            }

            var outputPath = parsedOptions.GetValue <string>(Options.Output);

            if (string.IsNullOrEmpty(outputPath))
            {
                outputPath = Path.GetFileNameWithoutExtension(inputPath) + ".opt" + Path.GetExtension(inputPath);
            }

            var printIr = parsedOptions.GetValue <bool>(Options.PrintIr);

            // Read the assembly from disk.
            Mono.Cecil.AssemblyDefinition cecilAsm;
            try
            {
                cecilAsm = Mono.Cecil.AssemblyDefinition.ReadAssembly(
                    inputPath,
                    new Mono.Cecil.ReaderParameters
                {
                    ReadWrite = false
                });
            }
            catch (Exception)
            {
                log.Log(
                    new LogEntry(
                        Severity.Error,
                        "unreadable assembly",
                        Quotation.QuoteEvenInBold(
                            "cannot read assembly at ",
                            inputPath,
                            ".")));
                return(1);
            }

            try
            {
                // Make all non-public types, methods and fields in the assembly
                // internal if the user requests it. This will work to
                // our advantage.
                if (parsedOptions.GetValue <bool>(Options.Internalize))
                {
                    MakeInternal(cecilAsm);
                }

                // Wrap the CIL assembly in a Flame assembly.
                var flameAsm = ClrAssembly.Wrap(cecilAsm);

                // Optimize the assembly.
                OptimizeAssemblyAsync(
                    flameAsm,
                    printIr,
                    parsedOptions.GetValue <bool>(Options.Parallel)).Wait();

                // Write the optimized assembly to disk.
                cecilAsm.Write(outputPath);
            }
            finally
            {
                // Be sure to dispose the assembly after we've used it.
                cecilAsm.Dispose();
            }

            return(0);
        }
예제 #4
0
        public static int Main(string[] args)
        {
            // Acquire a log.
            var rawLog = TerminalLog.Acquire();
            var log    = new TransformLog(
                rawLog,
                new Func <LogEntry, LogEntry>[]
            {
                MakeDiagnostic
            });

            // Parse command-line options.
            var parser = new GnuOptionSetParser(
                Options.All, Options.Input);

            var recLog        = new RecordingLog(log);
            var parsedOptions = parser.Parse(args, recLog);

            if (recLog.Contains(Severity.Error))
            {
                // Stop the program if the command-line arguments
                // are half baked.
                return(1);
            }

            if (parsedOptions.GetValue <bool>(Options.Help))
            {
                // Wrap the help message into a log entry and send it to the log.
                rawLog.Log(
                    new LogEntry(
                        Severity.Info,
                        new HelpMessage(
                            "fbfc is a compiler that turns Brainfuck code into CIL assemblies.",
                            "fbfc path [options...]",
                            Options.All)));
                return(0);
            }

            var inputPath = parsedOptions.GetValue <string>(Options.Input);

            if (string.IsNullOrEmpty(inputPath))
            {
                log.Log(
                    new LogEntry(
                        Severity.Error,
                        "nothing to compile",
                        "no input file"));
                return(1);
            }

            var outputPath = parsedOptions.GetValue <string>(Options.Output);

            if (string.IsNullOrEmpty(outputPath))
            {
                outputPath = Path.GetFileNameWithoutExtension(inputPath) + ".exe";
            }

            // Read the Brainfuck source code from disk.
            SourceDocument source;

            try
            {
                source = new StringDocument(inputPath, File.ReadAllText(inputPath));
            }
            catch (Exception)
            {
                log.Log(
                    new LogEntry(
                        Severity.Error,
                        "invalid source path",
                        Quotation.QuoteEvenInBold(
                            "cannot read Brainfuck source code at ",
                            inputPath,
                            ".")));
                return(1);
            }

            var asmName  = Path.GetFileNameWithoutExtension(outputPath);
            var cecilAsm = Mono.Cecil.AssemblyDefinition.CreateAssembly(
                new Mono.Cecil.AssemblyNameDefinition(asmName, new Version(1, 0, 0, 0)),
                asmName,
                Mono.Cecil.ModuleKind.Console);

            var flameAsm = ClrAssembly.Wrap(cecilAsm);

            var typeEnv  = flameAsm.Resolver.TypeEnvironment;
            var compiler = new Compiler(
                flameAsm,
                Dependencies.Resolve(
                    typeEnv,
                    new ReadOnlyTypeResolver(typeEnv.Object.Parent.Assembly),
                    log),
                log,
                parsedOptions);

            compiler.Compile(source);

            cecilAsm.Write(outputPath);

            return(0);
        }