Skip to content

Updated to new LLVM APIs #256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions src/Samples/CodeGenWithDebugInfo/CortexM3ABI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,13 @@ namespace CodeGenWithDebugInfo
internal sealed class CortexM3ABI
: ITargetABI
{
public CortexM3ABI( )
public CortexM3ABI( ILibLlvm library)
{
LlvmLib = Library.InitializeLLVM();
LlvmLib.RegisterTarget( CodeGenTarget.ARM );
library.RegisterTarget( CodeGenTarget.ARM );
}

public string ShortName => "M3";

public void Dispose( )
{
LlvmLib.Dispose();
}

public TargetMachine CreateTargetMachine( )
{
using var triple = new Triple( TripleName );
Expand Down Expand Up @@ -81,8 +75,8 @@ public void AddAttributesForByValueStructure( Function function, DebugFunctionTy
public void AddModuleFlags( Module module )
{
// Specify ABI const sizes so linker can detect mismatches
module.AddModuleFlag( ModuleFlagBehavior.Error, "wchar_size", 4 );
module.AddModuleFlag( ModuleFlagBehavior.Error, "min_enum_size", 4 );
module.AddModuleFlag( ModuleFlagBehavior.Error, "wchar_size"u8, 4 );
module.AddModuleFlag( ModuleFlagBehavior.Error, "min_enum_size"u8, 4 );
}

public ImmutableArray<AttributeValue> BuildTargetDependentFunctionAttributes( IContext ctx )
Expand All @@ -104,8 +98,6 @@ public ImmutableArray<AttributeValue> BuildTargetDependentFunctionAttributes( IC
ctx.CreateAttribute( "use-soft-float"u8, "false"u8 )
];

private readonly ILibLlvm LlvmLib;

// Sadly, these can't be utf8 literals, but, they can be static readonly LazyEncodedString!
private static readonly LazyEncodedString Cpu = "cortex-m3"u8;
private static readonly LazyEncodedString Features = "+hwdiv,+strict-align,+thumb-mode"u8;
Expand Down
1 change: 0 additions & 1 deletion src/Samples/CodeGenWithDebugInfo/ITargetABI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ namespace CodeGenWithDebugInfo
/// </remarks>
/// <seealso href="https://discourse.llvm.org/t/llvm-introduce-an-abi-lowering-library/84554"/>
internal interface ITargetABI
: IDisposable
{
string ShortName { get; }

Expand Down
17 changes: 9 additions & 8 deletions src/Samples/CodeGenWithDebugInfo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
using Ubiquity.NET.Llvm;
using Ubiquity.NET.Llvm.DebugInfo;
using Ubiquity.NET.Llvm.Instructions;

using Ubiquity.NET.Llvm.Types;
using Ubiquity.NET.Llvm.Values;

Expand Down Expand Up @@ -58,8 +57,10 @@ public static void Main( string[] args )
srcPath = Path.GetFullPath( srcPath );
#endregion

using ILibLlvm library = Library.InitializeLLVM();

#region TargetABISelection
using var targetABI = AbiFactory(args[0]);
ITargetABI? targetABI = AbiFactory(library, args[0]);
if(targetABI is null)
{
ShowUsage();
Expand Down Expand Up @@ -126,7 +127,7 @@ public static void Main( string[] args )
// add module flags and compiler identifiers...
// this can technically occur at any point, though placing it here makes
// comparing against clang generated files easier
AddModuleFlags( targetABI, module );
AddModuleFlags( targetABI, module, library );
#endregion

#region CreatingQualifiedTypes
Expand Down Expand Up @@ -172,12 +173,12 @@ private static void ShowUsage( )
Console.Error.WriteLine( "Usage: CodeGenWithDebugInfo [X64|M3] <source file path>" );
}

private static ITargetABI? AbiFactory( string arg )
private static ITargetABI? AbiFactory( ILibLlvm library, string arg )
{
return arg.ToUpperInvariant() switch
{
"M3" => new CortexM3ABI(),
"X64" => new X64ABI(),
"M3" => new CortexM3ABI(library),
"X64" => new X64ABI(library),
_ => null,
};
}
Expand Down Expand Up @@ -258,10 +259,10 @@ private static Function DeclareCopyFunc( ITargetABI abi
#endregion

#region AddModuleFlags
private static void AddModuleFlags( ITargetABI abi, Module module )
private static void AddModuleFlags( ITargetABI abi, Module module, ILibLlvm library )
{
module.AddModuleFlag( ModuleFlagBehavior.Warning, Module.DwarfVersionValue, 4 );
module.AddModuleFlag( ModuleFlagBehavior.Warning, Module.DebugVersionValue, Module.DebugMetadataVersion );
module.AddModuleFlag( ModuleFlagBehavior.Warning, Module.DebugVersionValue, library.DebugMetadataVersion );
abi.AddModuleFlags( module );
module.AddVersionIdentMetadata( VersionIdentString );
}
Expand Down
14 changes: 3 additions & 11 deletions src/Samples/CodeGenWithDebugInfo/X64ABI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,13 @@ namespace CodeGenWithDebugInfo
internal sealed class X64ABI
: ITargetABI
{
public X64ABI( )
public X64ABI( ILibLlvm library )
{
LlvmLib = Library.InitializeLLVM();
LlvmLib.RegisterTarget( CodeGenTarget.X86 );
library.RegisterTarget( CodeGenTarget.X86 );
}

public string ShortName => "x86";

public void Dispose( )
{
LlvmLib.Dispose();
}

public TargetMachine CreateTargetMachine( )
{
using var triple = new Triple( TripleName );
Expand Down Expand Up @@ -63,7 +57,7 @@ public void AddAttributesForByValueStructure( Function function, DebugFunctionTy

public void AddModuleFlags( Module module )
{
module.AddModuleFlag( ModuleFlagBehavior.Error, "PIC Level", 2 );
module.AddModuleFlag( ModuleFlagBehavior.Error, "PIC Level"u8, 2 );
}

public ImmutableArray<AttributeValue> BuildTargetDependentFunctionAttributes( IContext ctx )
Expand All @@ -81,8 +75,6 @@ public ImmutableArray<AttributeValue> BuildTargetDependentFunctionAttributes( IC
ctx.CreateAttribute( "uwtable"u8, (ulong)UWTableKind.Async)
];

private readonly ILibLlvm LlvmLib;

// Sadly, these can't be utf8 literals, but, they can be static readonly LazyEncodedString!
private static readonly LazyEncodedString Cpu = "x86-64"u8;
private static readonly LazyEncodedString Features = "+sse,+sse2"u8;
Expand Down
6 changes: 4 additions & 2 deletions src/Ubiquity.NET.Llvm.Tests/ModuleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,11 +393,13 @@ public void GetTypeByNameTest( )
[TestMethod]
public void AddModuleFlagTest( )
{
Assert.IsNotNull(ModuleFixtures.LibLLVM);

using var context = new Context( );
using var module = context.CreateBitcodeModule( TestModuleName );

module.AddModuleFlag( ModuleFlagBehavior.Warning, Module.DwarfVersionValue, 4 );
module.AddModuleFlag( ModuleFlagBehavior.Warning, Module.DebugVersionValue, Module.DebugMetadataVersion );
module.AddModuleFlag( ModuleFlagBehavior.Warning, Module.DebugVersionValue, ModuleFixtures.LibLLVM.DebugMetadataVersion );
module.AddModuleFlag( ModuleFlagBehavior.Error, "wchar_size", 4 );
module.AddModuleFlag( ModuleFlagBehavior.Error, "min_enum_size", 4 );
module.AddVersionIdentMetadata( "unit-tests 1.0" );
Expand All @@ -424,7 +426,7 @@ public void AddModuleFlagTest( )

var debugVerConst = ( ( ConstantAsMetadata )debugVerFlag.Metadata ).Constant;
Assert.IsInstanceOfType<ConstantInt>( debugVerConst );
Assert.AreEqual( Module.DebugMetadataVersion, ((ConstantInt)debugVerConst).ZeroExtendedValue );
Assert.AreEqual( ModuleFixtures.LibLLVM.DebugMetadataVersion, ((ConstantInt)debugVerConst).ZeroExtendedValue );

var wcharSizeFlag = module.ModuleFlags[ "wchar_size" ];
Assert.AreEqual( ModuleFlagBehavior.Error, wcharSizeFlag.Behavior );
Expand Down
2 changes: 1 addition & 1 deletion src/Ubiquity.NET.Llvm/DebugInfo/DIBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1095,7 +1095,7 @@ public readonly DIGlobalVariableExpression CreateGlobalVariableExpression( DINod
public readonly void Finish( DISubProgram subProgram )
{
ArgumentNullException.ThrowIfNull( subProgram );
LibLLVMDIBuilderFinalizeSubProgram( Handle.ThrowIfInvalid(), subProgram.Handle );
LLVMDIBuilderFinalizeSubprogram( Handle.ThrowIfInvalid(), subProgram.Handle );
}

/// <summary>Finalizes debug information for all items built by this builder</summary>
Expand Down
3 changes: 3 additions & 0 deletions src/Ubiquity.NET.Llvm/ILibLLVM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,8 @@ public interface ILibLlvm
/// attributes not yet known to, or considered stable by, the LLVM core native code.
/// </remarks>
ImmutableDictionary<LazyEncodedString, AttributeInfo> AttributeMap { get; }

/// <summary>Gets the current debug metadata version for this library</summary>
uint DebugMetadataVersion { get; }
}
}
7 changes: 7 additions & 0 deletions src/Ubiquity.NET.Llvm/IModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ public interface IModule
/// <summary>Gets or sets the module level inline assembly</summary>
public LazyEncodedString ModuleInlineAsm { get; set; }

/// <summary>Gets the Debug metadata version that is present in this module</summary>
public uint DebugMetadataVersion { get; }

/// <summary>Appends inline assembly to the module's inline assembly</summary>
/// <param name="asm">assembly text</param>
public void AppendInlineAsm( LazyEncodedString asm );
Expand Down Expand Up @@ -391,6 +394,10 @@ public Function CreateFunction( ref readonly DIBuilder diBuilder
/// <param name="targetContext"><see cref="IContext"/> to clone the module into</param>
/// <returns>Cloned copy of the module</returns>
public Module Clone( IContext targetContext );

/// <summary>Strips debug information from this module</summary>
/// <returns><see langword="true"/> if the module was modified; <see langword="false"/> if not</returns>
public bool StripDebugInformation();
}

// Internal helper to get the underlying ABI handle as an "Alias" handle
Expand Down
4 changes: 4 additions & 0 deletions src/Ubiquity.NET.Llvm/Library.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ the low level interop (Test code sometimes does) it must explicitly reference it
using System.Collections.Immutable;

using static Ubiquity.NET.Llvm.Interop.ABI.libllvm_c.AttributeBindings;
using static Ubiquity.NET.Llvm.Interop.ABI.llvm_c.DebugInfo;

// Apply using aliases to simplify avoidance of name conflicts.
using InteropCodeGenTarget = Ubiquity.NET.Llvm.Interop.ABI.libllvm_c.LibLLVMCodeGenTarget;
Expand Down Expand Up @@ -55,6 +56,9 @@ public static ILibLlvm InitializeLLVM( )
/// <summary>Gets the native target for the current runtime</summary>
public static CodeGenTarget NativeTarget => (CodeGenTarget)RuntimeInformation.ProcessArchitecture.AsLLVMTarget();

/// <inheritdoc/>
public uint DebugMetadataVersion => LLVMDebugMetadataVersion();

// "MOVE" construction, this instance takes over responsibility
// of calling dispose.
internal Library( InteropItf impl )
Expand Down
9 changes: 6 additions & 3 deletions src/Ubiquity.NET.Llvm/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@ public override bool Equals( object? obj ) => obj is Module owner
/// <summary>Name of the Dwarf Version module flag</summary>
public static readonly LazyEncodedString DwarfVersionValue = "Dwarf Version"u8;

/// <summary>Gets the current Version of the Debug information used by LLVM</summary>
public static UInt32 DebugMetadataVersion => LLVMDebugMetadataVersion();

/// <summary>Gets a value indicating whether this instance is already disposed</summary>
public bool IsDisposed => NativeHandle is null || NativeHandle.IsInvalid || NativeHandle.IsClosed;

Expand Down Expand Up @@ -191,6 +188,9 @@ public Function CreateFunction( ref readonly DIBuilder diBuilder, LazyEncodedStr
/// <inheritdoc/>
public Module Clone( IContext targetContext ) => Impl.Clone( targetContext );

/// <inheritdoc/>
public bool StripDebugInformation() => Impl.StripDebugInformation();

/// <inheritdoc/>
public LazyEncodedString SourceFileName { get => Impl.SourceFileName; set => Impl.SourceFileName = value; }

Expand Down Expand Up @@ -236,6 +236,9 @@ public Function CreateFunction( ref readonly DIBuilder diBuilder, LazyEncodedStr

/// <inheritdoc/>
public LazyEncodedString ModuleInlineAsm { get => Impl.ModuleInlineAsm; set => Impl.ModuleInlineAsm = value; }

/// <inheritdoc/>
public uint DebugMetadataVersion => Impl.DebugMetadataVersion;
#endregion

/// <summary>Load a bit-code module from a given file</summary>
Expand Down
10 changes: 10 additions & 0 deletions src/Ubiquity.NET.Llvm/ModuleAlias.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using static Ubiquity.NET.Llvm.Interop.ABI.llvm_c.Analysis;
using static Ubiquity.NET.Llvm.Interop.ABI.llvm_c.BitWriter;
using static Ubiquity.NET.Llvm.Interop.ABI.llvm_c.Core;
using static Ubiquity.NET.Llvm.Interop.ABI.llvm_c.DebugInfo;
using static Ubiquity.NET.Llvm.Interop.ABI.llvm_c.Linker;
using static Ubiquity.NET.Llvm.Interop.ABI.llvm_c.PassBuilder;
using static Ubiquity.NET.Llvm.Interop.ABI.llvm_c.Target;
Expand Down Expand Up @@ -198,6 +199,9 @@ public LazyEncodedString ModuleInlineAsm
set => LLVMSetModuleInlineAsm2( NativeHandle, value.ThrowIfNull() );
}

/// <inheritdoc/>
public uint DebugMetadataVersion => LLVMGetModuleDebugMetadataVersion(NativeHandle);

/// <inheritdoc/>
public void AppendInlineAsm( LazyEncodedString asm )
{
Expand Down Expand Up @@ -616,6 +620,12 @@ public Module Clone( IContext targetContext )
return retVal;
}

/// <inheritdoc/>
public bool StripDebugInformation()
{
return LLVMStripModuleDebugInfo(NativeHandle);
}

internal ModuleAlias( LLVMModuleRefAlias handle )
{
handle.ThrowIfInvalid();
Expand Down
Loading