Ejemplo n.º 1
0
 public ProjectedClass(string mdns, string mdname, string clrns, string clrname, ClrAssembly clrAsm, ClrAssembly contractAsm, bool winMDValueType, bool clrValueType)
 {
     this.WinMDClass       = new ClassName(mdns, mdname, winMDValueType);
     this.ClrClass         = new ClassName(clrns, clrname, clrValueType);
     this.ClrAssembly      = clrAsm;
     this.ContractAssembly = contractAsm;
 }
Ejemplo n.º 2
0
 public AssemblyArtifact(IDistributionSegment Segment, NodeFilePath ArtifactPath)
     : base(Segment, ArtifactPath)
 {
     Descriptor = from a in ClrAssembly.Get(ArtifactPath)
                  from d in a.Describe()
                  select d;
 }
Ejemplo n.º 3
0
        public static InputContext Create(string assemblyFile)
        {
            var assembly = ClrAssembly.LoadFile(assemblyFile);
            var document = XmlDocument.LoadFile(Path.ChangeExtension(assemblyFile, ".xml"));

            return(new InputContext(assembly, document));
        }
Ejemplo n.º 4
0
        private static Task OptimizeAssemblyAsync(
            ClrAssembly assembly,
            bool printIr,
            bool parallelOptimization)
        {
            var typeSystem = assembly.Resolver.TypeEnvironment;
            var pipeline   = new Optimization[]
            {
                //   * Expand LINQ queries.
                new ExpandLinq(typeSystem.Boolean, typeSystem.Int32),

                //   * Inline direct method calls and devirtualize calls.
                Inlining.Instance,
                CopyPropagation.Instance,
                CallDevirtualization.Instance,
                DeadValueElimination.Instance,

                //   * Box to alloca, aggregates to scalars, scalars to registers.
                //     Also throw in GVN.
                BoxToAlloca.Instance,
                CopyPropagation.Instance,
                PartialScalarReplacement.Instance,
                GlobalValueNumbering.Instance,
                CopyPropagation.Instance,
                DeadValueElimination.Instance,
                AllocaToRegister.Instance,

                //   * Optimize control flow.
                InstructionSimplification.Instance,
                new ConstantPropagation(),
                MemoryAccessElimination.Instance,
                DeadValueElimination.Instance,
                new JumpThreading(true),
                SwitchSimplification.Instance,
                DuplicateReturns.Instance,
                TailRecursionElimination.Instance,
                BlockFusion.Instance
            };

            // Create an on-demand optimizer, which will optimize methods
            // lazily.
            Optimizer optimizer;

            if (parallelOptimization)
            {
                optimizer = new ParallelOnDemandOptimizer(
                    pipeline,
                    method => GetInitialMethodBody(method, typeSystem));
            }
            else
            {
                optimizer = new OnDemandOptimizer(
                    pipeline,
                    method => GetInitialMethodBody(method, typeSystem));
            }

            return(optimizer.RunAllAsync(
                       GetAllMethods(assembly).Select(
                           method => UpdateMethodBodyAsync(method, optimizer, typeSystem, printIr))));
        }
Ejemplo n.º 5
0
 public Compiler(ClrAssembly assembly, Dependencies dependencies, ILog Log, OptionSet options)
 {
     this.Assembly        = assembly;
     this.Log             = Log;
     this.Dependencies    = dependencies;
     this.CompilerOptions = options;
 }
Ejemplo n.º 6
0
        private static DataTable GetClusterCharacteristics(string strModel, string strClusterUniqueID, double dThreshold)
        {
            //if we don't know the path to the system data mining sprocs assembly, get it
            if (_cachedSystemDataMiningSprocsPath.Length == 0)
            {
                Microsoft.AnalysisServices.Server svr = new Microsoft.AnalysisServices.Server();
                svr.Connect(Context.CurrentServerID);
                ClrAssembly ass = (ClrAssembly)svr.Assemblies.GetByName("System");
                if (ass == null)
                {
                    throw new Exception("System (data mining sprocs) assembly not found");
                }
                foreach (ClrAssemblyFile file in ass.Files)
                {
                    if (file.Type == ClrAssemblyFileType.Main)
                    {
                        lock (_cachedSystemDataMiningSprocsPath) _cachedSystemDataMiningSprocsPath = file.Name;
                        break;
                    }
                }
                svr.Disconnect();
            }

            //get the DataMining sprocs assembly and call the GetClusterCharacteristics function
            System.Reflection.Assembly asAss = System.Reflection.Assembly.LoadFile(_cachedSystemDataMiningSprocsPath);
            Type   t           = asAss.GetType("Microsoft.AnalysisServices.System.DataMining.Clustering");
            object oClustering = t.GetConstructor(new Type[] { }).Invoke(new object[] { });

            return((DataTable)t.InvokeMember("GetClusterCharacteristics", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod, null, oClustering, new object[] { strModel, strClusterUniqueID, dThreshold }));
        }
Ejemplo n.º 7
0
        private static Task <AssemblyContentDescription> CreateContentDescriptionAsync(
            IMethod method,
            IEnumerable <ITypeMember> memberRoots,
            IEnumerable <IType> typeRoots,
            ClrAssembly assembly)
        {
            // TODO: deduplicate this logic (it also appears in IL2LLVM and ILOpt)

            var typeSystem = assembly.Resolver.TypeEnvironment;
            var pipeline   = new Optimization[]
            {
                new ConstantPropagation(),
                MemoryAccessElimination.Instance,
                DeadValueElimination.Instance,
                new JumpThreading(true),
                SwitchSimplification.Instance,
                DuplicateReturns.Instance,
                TailRecursionElimination.Instance,
                BlockFusion.Instance
            };

            var optimizer = new OnDemandOptimizer(
                pipeline,
                m => GetInitialMethodBody(m, typeSystem));

            return(AssemblyContentDescription.CreateTransitiveAsync(
                       new SimpleName("kernel").Qualify(),
                       assembly.Attributes,
                       null,
                       new ITypeMember[] { method }.Concat(memberRoots),
                       typeRoots,
                       optimizer));
        }
Ejemplo n.º 8
0
 private static IEnumerable <ClrMethodDefinition> GetAllMethods(
     Mono.Cecil.TypeDefinition typeDefinition,
     ClrAssembly parentAssembly)
 {
     return(typeDefinition.Methods
            .Select(parentAssembly.Resolve)
            .Cast <ClrMethodDefinition>()
            .Concat(
                typeDefinition.NestedTypes.SelectMany(
                    type => GetAllMethods(type, parentAssembly))));
 }
Ejemplo n.º 9
0
 private static void OptimizeAssembly(
     Mono.Cecil.AssemblyDefinition cecilAsm,
     ClrAssembly flameAsm,
     Func <ClrMethodDefinition, MethodBody> optimizeBody)
 {
     foreach (var module in cecilAsm.Modules)
     {
         foreach (var type in module.Types)
         {
             OptimizeType(type, flameAsm, optimizeBody);
         }
     }
 }
Ejemplo n.º 10
0
        private static ClrAssembly ResolveCorlib()
        {
            var env = new MutableTypeEnvironment(null);
            var asm = new ClrAssembly(
                Mono.Cecil.ModuleDefinition
                .ReadModule(typeof(object).Module.FullyQualifiedName)
                .Assembly,
                NullAssemblyResolver.Instance,
                env);

            env.InnerEnvironment = new CorlibTypeEnvironment(asm);
            return(asm);
        }
Ejemplo n.º 11
0
        static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm)
        {
            var mscorlib = module == null ? null : module.CorLibTypes.AssemblyRef;

            var asm = new AssemblyRefUser(GetName(clrAsm), contractAsmVersion, new PublicKeyToken(GetPublicKeyToken(clrAsm)), UTF8String.Empty);

            if (mscorlib != null && mscorlib.Name == mscorlibName && mscorlib.Version != invalidWinMDVersion)
            {
                asm.Version = mscorlib.Version;
            }
            var mod = module as ModuleDefMD;

            if (mod != null)
            {
                Version ver = null;
                foreach (var asmRef in mod.GetAssemblyRefs())
                {
                    if (asmRef.IsContentTypeWindowsRuntime)
                    {
                        continue;
                    }
                    if (asmRef.Name != asm.Name)
                    {
                        continue;
                    }
                    if (asmRef.Culture != asm.Culture)
                    {
                        continue;
                    }
                    if (!PublicKeyBase.TokenEquals(asmRef.PublicKeyOrToken, asm.PublicKeyOrToken))
                    {
                        continue;
                    }
                    if (asmRef.Version == invalidWinMDVersion)
                    {
                        continue;
                    }

                    if (ver == null || asmRef.Version > ver)
                    {
                        ver = asmRef.Version;
                    }
                }
                if (ver != null)
                {
                    asm.Version = ver;
                }
            }

            return(asm);
        }
Ejemplo n.º 12
0
 private static void OptimizeType(
     Mono.Cecil.TypeDefinition typeDefinition,
     ClrAssembly parentAssembly,
     Func <ClrMethodDefinition, MethodBody> optimizeBody)
 {
     foreach (var method in typeDefinition.Methods)
     {
         OptimizeMethod(method, parentAssembly, optimizeBody);
     }
     foreach (var type in typeDefinition.NestedTypes)
     {
         OptimizeType(type, parentAssembly, optimizeBody);
     }
 }
Ejemplo n.º 13
0
 private CudaModule(
     ClrAssembly sourceAssembly,
     ModuleBuilder intermediateModule,
     LLVMTargetMachineRef targetMachine,
     CUmodule compiledModule,
     string entryPointName,
     CudaContext context)
 {
     this.SourceAssembly     = sourceAssembly;
     this.IntermediateModule = intermediateModule;
     this.TargetMachine      = targetMachine;
     this.TargetData         = LLVM.CreateTargetDataLayout(TargetMachine);
     this.CompiledModule     = compiledModule;
     this.EntryPointName     = entryPointName;
     this.Context            = context;
 }
Ejemplo n.º 14
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));
        }
Ejemplo n.º 15
0
        private static void OptimizeMethod(
            Mono.Cecil.MethodDefinition methodDefinition,
            ClrAssembly parentAssembly,
            Func <ClrMethodDefinition, MethodBody> optimizeBody)
        {
            if (methodDefinition.HasBody)
            {
                var flameMethod = (ClrMethodDefinition)parentAssembly.Resolve(methodDefinition);
                var irBody      = flameMethod.Body;

                var errors = irBody.Validate();
                if (errors.Count > 0)
                {
                    var sourceIr = FormatIr(irBody);
                    log.Log(
                        new LogEntry(
                            Severity.Warning,
                            "invalid IR",
                            Quotation.QuoteEvenInBold(
                                "the Flame IR produced by the CIL analyzer for ",
                                flameMethod.FullName.ToString(),
                                " is erroneous; skipping it."),

                            CreateRemark(
                                "errors in IR:",
                                new BulletedList(errors.Select(x => new Text(x)).ToArray())),

                            CreateRemark(
                                "generated Flame IR:",
                                new Paragraph(new WrapBox(sourceIr, 0, -sourceIr.Length)))));
                    return;
                }

                var optBody = optimizeBody(flameMethod);
                var emitter = new ClrMethodBodyEmitter(
                    methodDefinition,
                    optBody,
                    parentAssembly.Resolver.TypeEnvironment);
                var newCilBody = emitter.Compile();
                methodDefinition.Body = newCilBody;
            }
        }
Ejemplo n.º 16
0
        static UTF8String GetName(ClrAssembly clrAsm)
        {
            switch (clrAsm)
            {
            case ClrAssembly.Mscorlib: return(clrAsmName_Mscorlib);

            case ClrAssembly.SystemNumericsVectors: return(clrAsmName_SystemNumericsVectors);

            case ClrAssembly.SystemObjectModel: return(clrAsmName_SystemObjectModel);

            case ClrAssembly.SystemRuntime: return(clrAsmName_SystemRuntime);

            case ClrAssembly.SystemRuntimeInteropServicesWindowsRuntime: return(clrAsmName_SystemRuntimeInteropServicesWindowsRuntime);

            case ClrAssembly.SystemRuntimeWindowsRuntime: return(clrAsmName_SystemRuntimeWindowsRuntime);

            case ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml: return(clrAsmName_SystemRuntimeWindowsRuntimeUIXaml);

            default: throw new InvalidOperationException();
            }
        }
Ejemplo n.º 17
0
        static byte[] GetPublicKeyToken(ClrAssembly clrAsm)
        {
            switch (clrAsm)
            {
            case ClrAssembly.Mscorlib: return(neutralPublicKey);

            case ClrAssembly.SystemNumericsVectors: return(contractPublicKeyToken);

            case ClrAssembly.SystemObjectModel: return(contractPublicKeyToken);

            case ClrAssembly.SystemRuntime: return(contractPublicKeyToken);

            case ClrAssembly.SystemRuntimeInteropServicesWindowsRuntime: return(contractPublicKeyToken);

            case ClrAssembly.SystemRuntimeWindowsRuntime: return(neutralPublicKey);

            case ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml: return(neutralPublicKey);

            default: throw new InvalidOperationException();
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Called by the loader via <see cref="ClrAssembly"/>.
        /// </summary>
        internal ClrModule(ClrAssembly/*!*/ assembly)
            : base(assembly)
        {

        }
Ejemplo n.º 19
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);
        }
Ejemplo n.º 20
0
 public InputContext(ClrAssembly assembly, XmlDocument document)
 {
     Assembly = assembly ?? throw new ArgumentNullException(nameof(assembly));
     Document = document ?? throw new ArgumentNullException(nameof(document));
 }
Ejemplo n.º 21
0
        private DataTable getFunctionList(AssemblyCollection assColl)
        {
            Context.TraceEvent(100, 0, "ListFunctions: Starting");
            // build the structure for the datatable which is returned
            DataTable dtFuncs = new DataTable("dtFunctions");

            dtFuncs.Columns.Add("Assembly", typeof(String));
            dtFuncs.Columns.Add("Class", typeof(String));
            dtFuncs.Columns.Add("Method", typeof(String));
            dtFuncs.Columns.Add("ReturnType", typeof(String));
            dtFuncs.Columns.Add("Parameters", typeof(String));

            if (Context.ExecuteForPrepare)
            {
                // we can exit after building the table function if this is only
                // being executed for a prepare.
                Context.TraceEvent(100, 0, "ListFunctions: Finished (ExecuteForPrepare)");
                return(dtFuncs);
            }

            foreach (Microsoft.AnalysisServices.Assembly ass in assColl)
            {
                Context.CheckCancelled();

                if (ass is ClrAssembly) // we can only use reflection against .Net assemblies
                {
                    Type t = ass.GetType();

                    ClrAssembly clrAss = (ClrAssembly)ass;

                    Context.TraceEvent(100, 0, "ListFunctions: Processing the " + clrAss.Name + " Assembly");

                    foreach (ClrAssemblyFile f in clrAss.Files) // an assembly can have multiple files
                    {
                        Context.CheckCancelled();

                        // We only want to get the "main" asembly file and only files which have data
                        // (Some of the system assemblies appear to be registrations only and do not
                        // have any data.
                        if (f.Data.Count > 0 && f.Type == ClrAssemblyFileType.Main)
                        {
                            // assembly the assembly back into a single byte from the blocks of base64 strings
                            byte[] rawAss = new byte[0];
                            int    iPos   = 0;
                            byte[] buff   = new byte[0];

                            foreach (string block in f.Data)
                            {
                                Context.CheckCancelled();

                                buff = System.Convert.FromBase64String(block);
                                System.Array.Resize(ref rawAss, rawAss.Length + buff.Length);
                                buff.CopyTo(rawAss, iPos);
                                iPos += buff.Length;
                            }

                            // use reflection to extract the public types and methods from the
                            // re-assembled assembly.
                            Context.TraceEvent(100, 0, "ListFunctions: Starting reflection against " + f.Name);
                            System.Reflection.Assembly asAss = System.Reflection.Assembly.Load(rawAss);
                            Type[] assTypes = asAss.GetTypes();
                            for (int i = 0; i < assTypes.Length; i++)
                            {
                                Type t2 = assTypes[i];
                                if (t2.IsPublic)
                                {
                                    MethodInfo[] methods;
                                    methods = t2.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);

                                    int paramCnt = 0;
                                    foreach (MethodInfo meth in methods)
                                    {
                                        Context.CheckCancelled();

                                        // build the parameter signature as a string
                                        ParameterInfo[]           Params    = meth.GetParameters();
                                        System.Text.StringBuilder paramList = new System.Text.StringBuilder();
                                        paramCnt = Params.Length;
                                        string[] paramArray = new string[paramCnt];
                                        // add the first parameter
                                        if (paramCnt > 0)
                                        {
                                            paramList.Append(Params[0].Name);
                                            paramList.Append(" as ");
                                            paramList.Append(StripNamespace(Params[0].ParameterType.ToString()));
                                        }
                                        // add subsequent parameters, inserting a comma before each new one.
                                        for (int j = 1; j < paramCnt; j++)
                                        {
                                            paramList.Append(", ");
                                            paramList.Append(Params[j].Name);
                                            paramList.Append(" as ");
                                            paramList.Append(StripNamespace(Params[j].ParameterType.ToString()));
                                        }

                                        DataRow  rowFunc = dtFuncs.NewRow();
                                        Object[] items   = new Object[5];
                                        items[0] = ass.Name;
                                        items[1] = t2.Name;
                                        items[2] = meth.Name;
                                        items[3] = StripNamespace(meth.ReturnType.ToString());
                                        items[4] = paramList.ToString();

                                        rowFunc.ItemArray = items;
                                        dtFuncs.Rows.Add(rowFunc);
                                        rowFunc.AcceptChanges();
                                    } // foreach meth
                                }     // if t2.IsPublic
                            }         // assTypes.Length
                            Context.TraceEvent(100, 0, "ListFunctions: Finished reflecting against " + f.Name);
                        }             // if f.data.count > 0 && f.Type == main
                    }                 // foreach f
                }                     // if ass is clrAssembly
            }                         // foreach ass
            dtFuncs.AcceptChanges();
            Context.TraceEvent(100, dtFuncs.Rows.Count, "ListFunctions: Finished (" + dtFuncs.Rows.Count.ToString() + " function signatures)");
            return(dtFuncs);
        }
Ejemplo n.º 22
0
 /// <summary>
 /// Returns the defining system as determined by convention alignment
 /// </summary>
 /// <param name="a">The assembly to evaluate</param>
 /// <returns></returns>
 public static SystemIdentifier DefiningSystem(this ClrAssembly a)
 => a.ReflectedElement.DefiningSystem();
Ejemplo n.º 23
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(
                            "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);
        }
Ejemplo n.º 24
0
        private static Task <AssemblyContentDescription> CreateContentDescriptionAsync(ClrAssembly assembly)
        {
            var typeSystem = assembly.Resolver.TypeEnvironment;
            var pipeline   = new Optimization[]
            {
                new ConstantPropagation(),
                MemoryAccessElimination.Instance,
                DeadValueElimination.Instance,
                new JumpThreading(true),
                SwitchSimplification.Instance,
                DuplicateReturns.Instance,
                TailRecursionElimination.Instance,
                BlockFusion.Instance
            };

            var optimizer = new OnDemandOptimizer(
                pipeline,
                method => GetInitialMethodBody(method, typeSystem));

            return(AssemblyContentDescription.CreateTransitiveAsync(
                       assembly.FullName,
                       assembly.Attributes,
                       assembly.Resolve(assembly.Definition.EntryPoint),
                       optimizer));
        }
Ejemplo n.º 25
0
        private static async Task <LLVMModuleRef> CompileAsync(ClrAssembly assembly)
        {
            var desc = await CreateContentDescriptionAsync(assembly);

            return(LlvmBackend.Compile(desc, assembly.Resolver.TypeEnvironment).Module);
        }
Ejemplo n.º 26
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);
        }
Ejemplo n.º 27
0
 private static IEnumerable <ClrMethodDefinition> GetAllMethods(ClrAssembly assembly)
 {
     return(assembly.Definition.Modules
            .SelectMany(module => module.Types)
            .SelectMany(type => GetAllMethods(type, assembly)));
 }
Ejemplo n.º 28
0
        private static async Task <CudaModule> CompileAsync(
            IMethod method,
            IEnumerable <ITypeMember> memberRoots,
            IEnumerable <IType> typeRoots,
            int threadIdParamIndex,
            ClrAssembly assembly,
            CudaContext context)
        {
            // Figure out which members we need to compile.
            var desc = await CreateContentDescriptionAsync(method, memberRoots, typeRoots, assembly);

            // Compile those members to LLVM IR. Use an Itanium name mangling scheme.
            var mangler       = new ItaniumMangler(assembly.Resolver.TypeEnvironment);
            var moduleBuilder = LlvmBackend.Compile(desc, assembly.Resolver.TypeEnvironment);
            var module        = moduleBuilder.Module;

            // Generate type metadata for all type roots.
            foreach (var type in typeRoots)
            {
                moduleBuilder.Metadata.GetMetadata(type, moduleBuilder);
            }

            // Get the compiled kernel function.
            var kernelFuncName = mangler.Mangle(method, true);
            var kernelFunc     = LLVM.GetNamedFunction(module, kernelFuncName);

            if (threadIdParamIndex >= 0)
            {
                // If we have a thread ID parameter, then we need to generate a thunk
                // kernel function that calls our actual kernel function. This thunk's
                // responsibility is to determine the thread ID of the kernel.
                var thunkKernelName = "kernel";
                var thunkTargetType = kernelFunc.TypeOf().GetElementType();
                var thunkParamTypes = new List <LLVMTypeRef>(thunkTargetType.GetParamTypes());
                if (threadIdParamIndex < thunkParamTypes.Count)
                {
                    thunkParamTypes.RemoveAt(threadIdParamIndex);
                }
                var thunkKernel = LLVM.AddFunction(
                    module,
                    thunkKernelName,
                    LLVM.FunctionType(
                        thunkTargetType.GetReturnType(),
                        thunkParamTypes.ToArray(),
                        thunkTargetType.IsFunctionVarArg));

                using (var builder = new IRBuilder(moduleBuilder.Context))
                {
                    builder.PositionBuilderAtEnd(thunkKernel.AppendBasicBlock("entry"));
                    var args = new List <LLVMValueRef>(thunkKernel.GetParams());
                    args.Insert(threadIdParamIndex, ComputeUniqueThreadId(builder, module));
                    var call = builder.CreateCall(kernelFunc, args.ToArray(), "");
                    if (call.TypeOf().TypeKind == LLVMTypeKind.LLVMVoidTypeKind)
                    {
                        builder.CreateRetVoid();
                    }
                    else
                    {
                        builder.CreateRet(call);
                    }
                }

                kernelFuncName = thunkKernelName;
                kernelFunc     = thunkKernel;
            }

            // Mark the compiled kernel as a kernel symbol.
            LLVM.AddNamedMetadataOperand(
                module,
                "nvvm.annotations",
                LLVM.MDNode(new LLVMValueRef[]
            {
                kernelFunc,
                MDString("kernel"),
                LLVM.ConstInt(LLVM.Int32TypeInContext(LLVM.GetModuleContext(module)), 1, false)
            }));

            // LLVM.DumpModule(module);

            // Compile that LLVM IR down to PTX.
            LLVMTargetMachineRef machine;
            var ptx = CompileToPtx(module, context.GetDeviceComputeCapability(), out machine);

            // Console.WriteLine(System.Text.Encoding.UTF8.GetString(ptx));

            // Load the PTX kernel.
            return(new CudaModule(assembly, moduleBuilder, machine, context.LoadModulePTX(ptx), kernelFuncName, context));
        }