private BitcodeModule CreateSimpleModule(Context ctx, string name) { var retVal = new BitcodeModule(ctx, name); CreateSimpleVoidNopTestFunction(retVal, name); return(retVal); }
public void ComdatFunctionTest( ) { using (var context = new Context( )) using (var module = new BitcodeModule(context, TestModuleName)) { const string comdatName = "testcomdat"; const string globalName = "globalwithcomdat"; Comdat comdat = module.Comdats.InsertOrUpdate(comdatName, ComdatKind.SameSize); Assert.AreEqual(comdatName, comdat.Name); Assert.AreEqual(ComdatKind.SameSize, comdat.Kind); Assert.AreEqual(1, module.Comdats.Count); CreateSimpleVoidNopTestFunction(module, globalName) .Linkage(Linkage.LinkOnceODR) .Comdat(globalName); Assert.AreEqual(2, module.Comdats.Count, "Unsaved module should have all comdats even if unused"); Assert.IsTrue(module.Comdats.Contains(comdatName)); Assert.IsTrue(module.Comdats.Contains(globalName)); Assert.AreEqual(comdatName, module.Comdats[comdatName].Name); Assert.AreEqual(globalName, module.Comdats[globalName].Name); Assert.AreEqual(ComdatKind.SameSize, module.Comdats[comdatName].Kind); Assert.AreEqual(ComdatKind.Any, module.Comdats[globalName].Kind); using (var context2 = new Context( )) { var clone = module.Clone(context2); Assert.AreEqual(1, clone.Comdats.Count, "Comdat count should contain the one and only referenced comdat after save/clone"); Assert.IsTrue(clone.Comdats.Contains(globalName), "Cloned module should have the referenced comdat"); var clonedGlobal = clone.GetFunction(globalName); Assert.AreEqual(globalName, clonedGlobal.Comdat.Name, "Name of the comdat on the cloned global should match the one set in the original module"); Assert.AreEqual(ComdatKind.Any, module.Comdats[globalName].Kind); } } }
private static void AddModuleFlags(BitcodeModule module) { module.AddModuleFlag(ModuleFlagBehavior.Warning, BitcodeModule.DwarfVersionValue, 4); module.AddModuleFlag(ModuleFlagBehavior.Warning, BitcodeModule.DebugVersionValue, BitcodeModule.DebugMetadataVersion); TargetDetails.AddModuleFlags(module); module.AddVersionIdentMetadata(VersionIdentString); }
public void WriteToFileTest( ) { string path = Path.GetTempFileName( ); try { using (var context = new Context( )) using (var module = new BitcodeModule(context, TestModuleName)) { Function testFunc = CreateSimpleVoidNopTestFunction(module, "foo"); module.WriteToFile(path); } using (var ctx = new Context( )) using (var module2 = BitcodeModule.LoadFrom(path, ctx)) { Function testFunc = module2.GetFunction("foo"); // verify basics Assert.IsNotNull(testFunc); string txt = module2.WriteToString( ); Assert.IsFalse(string.IsNullOrWhiteSpace(txt)); string expectedText = string.Format(TestModuleTemplate, Environment.NewLine, path); Assert.AreEqual(expectedText, txt); } } finally { File.Delete(path); } }
public void ConstructorTestWithName( ) { using (var context = new Context( )) using (var module = new BitcodeModule(context, TestModuleName)) { Assert.AreEqual(TestModuleName, module.Name); Assert.AreEqual(TestModuleName, module.SourceFileName); Assert.IsNotNull(module); Assert.IsNotNull(module.Context); Assert.AreSame(string.Empty, module.DataLayoutString); Assert.IsNull(module.Layout); Assert.AreSame(string.Empty, module.TargetTriple); Assert.IsNotNull(module.DIBuilder); // until explicitly created DICompileUnit should be null Assert.IsNull(module.DICompileUnit); // Functions collection should be valid but empty Assert.IsNotNull(module.Functions); Assert.IsFalse(module.Functions.Any( )); // Globals collection should be valid but empty Assert.IsNotNull(module.Globals); Assert.IsFalse(module.Globals.Any( )); } }
/// <summary>Initializes a new instance of the <see cref="DebugBasicType"/> class.</summary> /// <param name="llvmType">Type to wrap debug information for</param> /// <param name="module">Module to use when constructing the debug information</param> /// <param name="name">Source language name of the type</param> /// <param name="encoding">Encoding for the type</param> public DebugBasicType(ITypeRef llvmType, BitcodeModule module, string name, DiTypeKind encoding) : base(llvmType, module.ValidateNotNull(nameof(module)) .DIBuilder .CreateBasicType(name , module.Layout.BitSizeOf(llvmType) , encoding ) ) { name.ValidateNotNullOrWhiteSpace(nameof(name)); if (module.Layout == null) { throw new ArgumentException(Resources.Module_needs_Layout_to_build_basic_types, nameof(module)); } switch (llvmType.Kind) { case TypeKind.Void: case TypeKind.Float16: case TypeKind.Float32: case TypeKind.Float64: case TypeKind.X86Float80: case TypeKind.Float128m112: case TypeKind.Float128: case TypeKind.Integer: break; default: throw new ArgumentException(Resources.Expected_a_primitive_type, nameof(llvmType)); } }
public void DisposeTest( ) { using (var context = new Context( )) using (var module = new BitcodeModule(context, TestModuleName)) { } }
/// <summary>Initializes a new instance of the <see cref="DebugUnionType"/> class.</summary> /// <param name="llvmType">Underlying native type this debug type describes</param> /// <param name="module">Module to contain the debug metadata for this type</param> /// <param name="scope">Scope containing this type</param> /// <param name="name">Debug/source name of the type</param> /// <param name="file">Source file containing this type</param> /// <param name="line">Line number for this type</param> /// <param name="debugFlags">Debug flags for this type</param> /// <param name="elements">Descriptors for the members of the type</param> public DebugUnionType(IStructType llvmType , BitcodeModule module , DIScope scope , string name , DIFile file , uint line , DebugInfoFlags debugFlags , IEnumerable <DebugMemberInfo> elements ) : base(llvmType) { llvmType.ValidateNotNull(nameof(llvmType)); module.ValidateNotNull(nameof(module)); scope.ValidateNotNull(nameof(scope)); file.ValidateNotNull(nameof(file)); if (!llvmType.IsOpaque) { throw new ArgumentException(Resources.Struct_type_used_as_basis_for_a_union_must_not_have_a_body, nameof(llvmType)); } DIType = module.DIBuilder .CreateReplaceableCompositeType(Tag.UnionType , name , scope , file , line ); SetBody(module, scope, file, line, debugFlags, elements); }
public void WriteToFileTest( ) { string path = Path.GetTempFileName( ); try { using (var context = new Context( )) using (var module = context.CreateBitcodeModule(TestModuleName)) { _ = CreateSimpleVoidNopTestFunction(module, "foo"); module.WriteToFile(path); } using var ctx = new Context( ); using var module2 = BitcodeModule.LoadFrom(path, ctx); // force a GC to ensure buffer created in LoadFrom is handled correctly GC.Collect(GC.MaxGeneration); Assert.IsTrue(module2.TryGetFunction("foo", out IrFunction? testFunc)); // verify basics Assert.IsNotNull(testFunc); string txt = module2.WriteToString( ); Assert.IsFalse(string.IsNullOrWhiteSpace(txt)); string expectedText = string.Format(CultureInfo.InvariantCulture, TestModuleTemplate, Environment.NewLine, path); Assert.AreEqual(expectedText, txt); } finally { File.Delete(path); } }
private DIDerivedType CreateMemberType(BitcodeModule module, DebugMemberInfo memberInfo) { UInt64 bitSize; UInt32 bitAlign; UInt64 bitOffset; // if explicit layout info provided, use it; // otherwise use module.Layout as the default if (memberInfo.ExplicitLayout != null) { bitSize = memberInfo.ExplicitLayout.BitSize; bitAlign = memberInfo.ExplicitLayout.BitAlignment; bitOffset = memberInfo.ExplicitLayout.BitOffset; } else { bitSize = module.Layout.BitSizeOf(memberInfo.DebugType.NativeType); bitAlign = 0; bitOffset = module.Layout.BitOffsetOfElement(NativeType, memberInfo.Index); } return(module.DIBuilder.CreateMemberType(scope: DIType , name: memberInfo.Name , file: memberInfo.File , line: memberInfo.Line , bitSize: bitSize , bitAlign: bitAlign , bitOffset: bitOffset , debugFlags: memberInfo.DebugInfoFlags , type: memberInfo.DebugType.DIType )); }
public DebugStructType(IStructType llvmType , BitcodeModule module , DIScope scope , string name , DIFile file , uint line , DebugInfoFlags debugFlags , DIType derivedFrom , IEnumerable <DIType> elements , uint bitAlignment = 0 ) : base(llvmType) { module.ValidateNotNull(nameof(module)); DIType = module.DIBuilder .CreateStructType(scope , name , file , line , module.Layout.BitSizeOf(llvmType) , bitAlignment , debugFlags , derivedFrom , elements ); }
private static DICompositeType BuildDebugType([ValidatedNotNull] IArrayType llvmType , [ValidatedNotNull] IDebugType <ITypeRef, DIType> elementType , [ValidatedNotNull] BitcodeModule module , uint count , uint lowerBound , uint alignment ) { llvmType.ValidateNotNull(nameof(llvmType)); elementType.ValidateNotNull(nameof(elementType)); module.ValidateNotNull(nameof(module)); if (llvmType.ElementType.GetTypeRef( ) != elementType.GetTypeRef( )) { throw new ArgumentException(Resources.ElementType_doesn_t_match_array_element_type); } if (llvmType.IsSized) { return(module.DIBuilder.CreateArrayType(module.Layout.BitSizeOf(llvmType) , alignment , elementType.DIType ! // validated not null in constructor , module.DIBuilder.CreateSubRange(lowerBound, count) )); } return(module.DIBuilder.CreateReplaceableCompositeType(Tag.ArrayType , string.Empty , module.DICompileUnit ?? default , default
private void CreateEngine(BitcodeModule module) { LLVMStatus status; string errMsg; switch (Kind) { case EngineKind.Jit: status = LLVMCreateJITCompilerForModule(out EngineHandle, module.ModuleHandle, ( uint )Optimization, out errMsg); break; case EngineKind.Interpreter: status = LLVMCreateInterpreterForModule(out EngineHandle, module.ModuleHandle, out errMsg); break; case EngineKind.Either: status = LLVMCreateExecutionEngineForModule(out EngineHandle, module.ModuleHandle, out errMsg); break; default: throw new ArgumentException("Invalid EngineKind", nameof(Kind)); } if (status.Failed) { throw new InternalCodeGeneratorException(errMsg); } }
/// <summary>Set the body of a type</summary> /// <param name="packed">Flag to indicate if the body elements are packed (e.g. no padding)</param> /// <param name="module">Module to contain the debug metadata for the type</param> /// <param name="scope">Scope containing this type</param> /// <param name="file">File containing the type</param> /// <param name="line">Line in <paramref name="file"/> for this type</param> /// <param name="debugFlags">Debug flags for this type</param> /// <param name="nativeElements">LLVM type of each element</param> /// <param name="debugElements">Descriptors for each element in the type</param> /// <param name="derivedFrom">Base type, if any for this type</param> /// <param name="bitSize">Total bit sice for this type or <see langword="null"/> to use default for target</param> /// <param name="bitAlignment">Alignment of the type in bits, 0 indicates default for taret</param> public void SetBody(bool packed , BitcodeModule module , DIScope scope , DIFile file , uint line , DebugInfoFlags debugFlags , IEnumerable <ITypeRef> nativeElements , IEnumerable <DebugMemberInfo> debugElements , DIType derivedFrom = null , uint?bitSize = null , uint bitAlignment = 0 ) { DebugMembers = new ReadOnlyCollection <DebugMemberInfo>(debugElements as IList <DebugMemberInfo> ?? debugElements.ToList( )); SetBody(packed, nativeElements.ToArray()); var memberTypes = from memberInfo in DebugMembers select CreateMemberType(module, memberInfo); var concreteType = module.DIBuilder.CreateStructType(scope: scope , name: DIType.Name , file: file , line: line , bitSize: bitSize ?? module.Layout.BitSizeOf(NativeType) , bitAlign: bitAlignment , debugFlags: debugFlags , derivedFrom: derivedFrom , elements: memberTypes ); DIType = concreteType; }
/// <summary>Initializes a new instance of the <see cref="DebugBasicType"/> class.</summary> /// <param name="llvmType">Type to wrap debug information for</param> /// <param name="module">Module to use when constructing the debug information</param> /// <param name="name">Source language name of the type</param> /// <param name="encoding">Encoding for the type</param> public DebugBasicType(ITypeRef llvmType, BitcodeModule module, string name, DiTypeKind encoding) { llvmType.ValidateNotNull(nameof(llvmType)); module.ValidateNotNull(nameof(module)); name.ValidateNotNullOrWhiteSpace(nameof(name)); if (module.Layout == null) { throw new ArgumentException("Module needs Layout to build basic types", nameof(module)); } switch (llvmType.Kind) { case TypeKind.Void: case TypeKind.Float16: case TypeKind.Float32: case TypeKind.Float64: case TypeKind.X86Float80: case TypeKind.Float128m112: case TypeKind.Float128: case TypeKind.Integer: break; default: throw new ArgumentException("Expected a primitive type", nameof(llvmType)); } NativeType = llvmType; DIType = module.DIBuilder .CreateBasicType(name , module.Layout.BitSizeOf(llvmType) , encoding ); }
public CodeGenerator(LanguageLevel level) { Context = new Context( ); Module = new BitcodeModule(Context, "Kaleidoscope"); InstructionBuilder = new InstructionBuilder(Context); NamedValues = new Dictionary <string, Value>( ); ParserStack = new ReplParserStack(level); }
private DIDerivedType CreateMemberType(BitcodeModule module, DebugMemberInfo memberInfo) { ulong bitSize; if (!(memberInfo.ExplicitLayout is null)) { bitSize = memberInfo.ExplicitLayout.BitSize; }
/// <summary>Initializes a new instance of the <see cref="DebugPointerType"/> class.</summary> /// <param name="llvmElementType">Native type of the pointee</param> /// <param name="module"><see cref="BitcodeModule"/> used for creating the pointer type and debug information</param> /// <param name="elementType">Debug type of the pointee</param> /// <param name="addressSpace">Target address space for the pointer [Default: 0]</param> /// <param name="name">Name of the type [Default: null]</param> /// <param name="alignment">Alignment of pointer</param> public DebugPointerType(ITypeRef llvmElementType, BitcodeModule module, DIType elementType, uint addressSpace = 0, string name = null, uint alignment = 0) : this(llvmElementType.ValidateNotNull(nameof(llvmElementType)).CreatePointerType(addressSpace) , module , elementType , name , alignment ) { }
private void AddAndExecuteTestModule(OrcJit orcJit, BitcodeModule module, int magicNumber) { ulong orcHandle = orcJit.AddEagerlyCompiledModule(module); var main = orcJit.GetFunctionDelegate <TestMain>("main"); Assert.IsNotNull(main); Assert.AreEqual(magicNumber, main( )); orcJit.RemoveModule(orcHandle); }
/// <summary>Initializes a new instance of the <see cref="DebugArrayType"/> class.</summary> /// <param name="elementType">Type of elements in the array</param> /// <param name="module"><see cref="BitcodeModule"/> to use for the context of the debug information</param> /// <param name="count">Number of elements in the array</param> /// <param name="lowerBound"><see cref="LowerBound"/> value for the array indices [Default: 0]</param> public DebugArrayType(IDebugType <ITypeRef, DIType> elementType, BitcodeModule module, uint count, uint lowerBound = 0) : this(elementType.ValidateNotNull(nameof(elementType)).CreateArrayType(count) , elementType , module , count , lowerBound ) { }
private void InitializeModuleAndPassManager( ) { Module = new BitcodeModule(Context, "Kaleidoscope"); FunctionPassManager = new FunctionPassManager(Module); FunctionPassManager.AddInstructionCombiningPass( ) .AddReassociatePass( ) .AddGVNPass( ) .AddCFGSimplificationPass( ) .Initialize( ); }
/// <summary>Initializes a new instance of the <see cref="DebugPointerType"/> class.</summary> /// <param name="debugElementType">Debug type of the pointee</param> /// <param name="module"><see cref="BitcodeModule"/> used for creating the pointer type and debug information</param> /// <param name="addressSpace">Target address space for the pointer [Default: 0]</param> /// <param name="name">Name of the type [Default: null]</param> /// <param name="alignment">Alignment on pointer</param> public DebugPointerType(IDebugType <ITypeRef, DIType> debugElementType, BitcodeModule module, uint addressSpace = 0, string name = null, uint alignment = 0) : this(debugElementType.ValidateNotNull(nameof(debugElementType)).NativeType , module , debugElementType.ValidateNotNull(nameof(debugElementType)).DIType , addressSpace , name , alignment ) { }
private static IrFunction CreateInvalidFunction(BitcodeModule module, string name) { var ctx = module.Context; var testFunc = module.CreateFunction(name, ctx.GetFunctionType(ctx.VoidType)); testFunc.AppendBasicBlock("entry"); // UNTERMINATED BLOCK INTENTIONAL return(testFunc); }
public void AddGlobalTest( ) { using (var context = new Context( )) using (var module = new BitcodeModule(context, TestModuleName)) { module.AddGlobal(module.Context.Int32Type, "TestInt"); GlobalVariable globalVar = module.GetNamedGlobal("TestInt"); Assert.AreEqual("TestInt", globalVar.Name); Assert.AreSame(module.Context.Int32Type.CreatePointerType( ), globalVar.NativeType); } }
public DebugPointerType(IPointerType llvmPtrType, BitcodeModule module, DIType elementType, string name = null, uint alignment = 0) : base(llvmPtrType) { module.ValidateNotNull(nameof(module)); DIType = module.DIBuilder .CreatePointerType(elementType , name , module.Layout.BitSizeOf(llvmPtrType) , alignment ); }
public void BasicLinkTest( ) { // verifies linked modules can be disposed using (var ctx = new Context( )) using (var module = new BitcodeModule(ctx, TestModuleName)) using (var otherModule = new BitcodeModule(ctx, "Other")) { module.Link(otherModule); Assert.IsTrue(otherModule.IsDisposed); } }
private static void CreateDoCopyFunctionBody(BitcodeModule module , DataLayout layout , Function doCopyFunc , IStructType foo , GlobalVariable bar , GlobalVariable baz , Function copyFunc ) { var bytePtrType = module.Context.Int8Type.CreatePointerType( ); // create block for the function body, only need one for this simple sample var blk = doCopyFunc.AppendBasicBlock("entry"); // create instruction builder to build the body var instBuilder = new InstructionBuilder(blk); bool param0ByVal = copyFunc.Attributes[FunctionAttributeIndex.Parameter0].Contains(AttributeKind.ByVal); if (!param0ByVal) { // create a temp local copy of the global structure var dstAddr = instBuilder.Alloca(foo) .RegisterName("agg.tmp") .Alignment(layout.CallFrameAlignmentOf(foo)); var bitCastDst = instBuilder.BitCast(dstAddr, bytePtrType) .SetDebugLocation(25, 11, doCopyFunc.DISubProgram); var bitCastSrc = instBuilder.BitCast(bar, bytePtrType) .SetDebugLocation(25, 11, doCopyFunc.DISubProgram); instBuilder.MemCpy(module , bitCastDst , bitCastSrc , module.Context.CreateConstant(layout.ByteSizeOf(foo)) , ( int )layout.CallFrameAlignmentOf(foo) , false ).SetDebugLocation(25, 11, doCopyFunc.DISubProgram); instBuilder.Call(copyFunc, dstAddr, baz) .SetDebugLocation(25, 5, doCopyFunc.DISubProgram); } else { instBuilder.Call(copyFunc, bar, baz) .SetDebugLocation(25, 5, doCopyFunc.DISubProgram) .AddAttributes(FunctionAttributeIndex.Parameter0, copyFunc.Parameters[0].Attributes); } instBuilder.Return( ) .SetDebugLocation(26, 1, doCopyFunc.DISubProgram); }
private static InstructionBuilder CreateFunctionAndGetBuilder(BitcodeModule module, DebugBasicType doubleType, string name, string section, uint line) { DIFile file = module.DIBuilder.CreateFile(TestSrcFileName); DebugFunctionType signature = module.Context.CreateFunctionType(module.DIBuilder, doubleType, doubleType, doubleType); var func = module.CreateFunction(module.DICompileUnit !, name, name, file, line, signature, true, true, line + 1, DebugInfoFlags.None, false); func.Section = section; var entry = func.AppendBasicBlock("entry"); return(new InstructionBuilder(entry)); }
/// <summary>Add a module to the engine</summary> /// <param name="module">The module to add to the engine</param> /// <param name="resolver">Symbol resolver delegate</param> /// <returns>Handle for the module in the engine</returns> /// <remarks> /// <note type="note"> /// With <see cref="OrcJit"/> the module is shared with the engine using a reference /// count. In this case the module is not disposed and the <see cref="BitcodeModule.IsShared"/> /// property is set to <see langword="true"/>. Callers may continue to use the module in this case, /// though modifying it or interned data from it's context may result in undefined behavior. /// </note> /// </remarks> public OrcJitHandle AddModule(BitcodeModule module, SymbolResolver resolver) { module.MakeShared( ); var err = LLVMOrcAddEagerlyCompiledIR(JitStackHandle, out LLVMOrcModuleHandle retHandle, module.SharedModuleRef, resolver, IntPtr.Zero); if (err != LLVMOrcErrorCode.LLVMOrcErrSuccess) { throw new Exception(LLVMOrcGetErrorMsg(JitStackHandle)); } return(new OrcJitHandle(retHandle)); }
public void OperandsAreAccessibleTest() { using (var ctx = new Context( )) using (var module = new BitcodeModule(ctx, "test.bc", SourceLanguage.CSharp, "test.cs", "unittests")) using (var targetMachine = TargetTests.GetTargetMachine( )) { module.Layout = targetMachine.TargetData; var intType = new DebugBasicType(module.Context.Int32Type, module, "int", DiTypeKind.Signed); var arrayType = new DebugArrayType(intType, module, 3u); Assert.IsNotNull(arrayType); var mdnode = arrayType.DIType as DICompositeType; Assert.IsNotNull(mdnode.Operands); Assert.AreEqual(8, mdnode.Operands.Count); Assert.IsNotNull(mdnode.Operands[0]); // File Assert.AreSame(mdnode, mdnode.Operands[0].OwningNode); Assert.IsNull(mdnode.Operands[0].Metadata); Assert.IsNotNull(mdnode.Operands[1]); // Scope Assert.AreSame(mdnode, mdnode.Operands[1].OwningNode); Assert.IsNull(mdnode.Operands[1].Metadata); Assert.IsNotNull(mdnode.Operands[2]); // Name Assert.AreSame(mdnode, mdnode.Operands[2].OwningNode); Assert.IsNull(mdnode.Operands[2].Metadata); Assert.IsNotNull(mdnode.Operands[3]); // BaseType Assert.AreSame(mdnode, mdnode.Operands[3].OwningNode); Assert.IsNotNull(mdnode.Operands[3].Metadata); Assert.IsNotNull(mdnode.Operands[4]); // Elements Assert.AreSame(mdnode, mdnode.Operands[4].OwningNode); Assert.IsNotNull(mdnode.Operands[4].Metadata); Assert.IsNotNull(mdnode.Operands[5]); // VTableHolder Assert.AreSame(mdnode, mdnode.Operands[5].OwningNode); Assert.IsNull(mdnode.Operands[5].Metadata); Assert.IsNotNull(mdnode.Operands[6]); // TemplateParams Assert.AreSame(mdnode, mdnode.Operands[6].OwningNode); Assert.IsNull(mdnode.Operands[6].Metadata); Assert.IsNotNull(mdnode.Operands[7]); // Identifier Assert.AreSame(mdnode, mdnode.Operands[7].OwningNode); Assert.IsNull(mdnode.Operands[7].Metadata); Assert.AreSame(intType.DIType, mdnode.BaseType); Assert.AreEqual(1, mdnode.Elements.Count); var subRange = mdnode.Elements[0] as DISubRange; Assert.IsNotNull(subRange); } }