Skip to content
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
37 changes: 37 additions & 0 deletions sources/LLVMSharp/Comdat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information.

using System;
using LLVMSharp.Interop;

namespace LLVMSharp;

public sealed class Comdat(LLVMComdatRef handle) : IEquatable<Comdat>
{
public LLVMComdatRef Handle { get; } = handle;

public LLVMComdatSelectionKind SelectionKind
{
get
{
return Handle.SelectionKind;
}

set
{
var handle = Handle;
handle.SelectionKind = value;
}
}

public static bool operator ==(Comdat? left, Comdat? right) => ReferenceEquals(left, right) || (left?.Handle == right?.Handle);

public static bool operator !=(Comdat? left, Comdat? right) => !(left == right);

public override bool Equals(object? obj) => (obj is Comdat other) && Equals(other);

public bool Equals(Comdat? other) => this == other;

public override int GetHashCode() => Handle.GetHashCode();

public override string ToString() => Handle.ToString();
}
2 changes: 2 additions & 0 deletions sources/LLVMSharp/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ public Function GetOrInsertFunction(string name, FunctionType functionType)
return GetFunction(name) ?? AddFunction(name, functionType);
}

public Comdat GetOrInsertComdat(string name) => new Comdat(Handle.GetOrInsertComdat(name));

public StructType? GetTypeByName(string name)
{
var handle = Handle.GetTypeByName(name);
Expand Down
4 changes: 4 additions & 0 deletions sources/LLVMSharp/Types/CompositeType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ public class CompositeType : Type
private protected CompositeType(LLVMTypeRef handle, LLVMTypeKind expectedTypeKind) : base(handle, expectedTypeKind)
{
}

private protected CompositeType(LLVMTypeRef handle, LLVMTypeKind expectedTypeKind1, LLVMTypeKind expectedTypeKind2) : base(handle, expectedTypeKind1, expectedTypeKind2)
{
}
}
4 changes: 4 additions & 0 deletions sources/LLVMSharp/Types/SequentialType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ private protected SequentialType(LLVMTypeRef handle, LLVMTypeKind expectedTypeKi
{
}

private protected SequentialType(LLVMTypeRef handle, LLVMTypeKind expectedTypeKind1, LLVMTypeKind expectedTypeKind2) : base(handle, expectedTypeKind1, expectedTypeKind2)
{
}

public Type ElementType => Context.GetOrCreate(Handle.ElementType);
}
11 changes: 10 additions & 1 deletion sources/LLVMSharp/Types/Type.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ private protected Type(LLVMTypeRef handle, LLVMTypeKind expectedTypeKind)
Handle = handle;
}

private protected Type(LLVMTypeRef handle, LLVMTypeKind expectedTypeKind1, LLVMTypeKind expectedTypeKind2)
{
if ((handle.Kind != expectedTypeKind1) && (handle.Kind != expectedTypeKind2))
{
throw new ArgumentOutOfRangeException(nameof(handle));
}
Handle = handle;
}

public LLVMTypeRef Handle { get; }

public LLVMContext Context => LLVMContext.GetOrCreate(Handle.Context);
Expand Down Expand Up @@ -198,7 +207,7 @@ public static Type GetX86_FP80Ty(LLVMContext c)
LLVMTypeKind.LLVMVectorTypeKind => new VectorType(handle),
LLVMTypeKind.LLVMMetadataTypeKind => new Type(handle, LLVMTypeKind.LLVMMetadataTypeKind),
LLVMTypeKind.LLVMTokenTypeKind => new Type(handle, LLVMTypeKind.LLVMTokenTypeKind),
LLVMTypeKind.LLVMScalableVectorTypeKind => new Type(handle, LLVMTypeKind.LLVMScalableVectorTypeKind),
LLVMTypeKind.LLVMScalableVectorTypeKind => new VectorType(handle),
LLVMTypeKind.LLVMBFloatTypeKind => new Type(handle, LLVMTypeKind.LLVMBFloatTypeKind),
LLVMTypeKind.LLVMX86_AMXTypeKind => new Type(handle, LLVMTypeKind.LLVMX86_AMXTypeKind),
LLVMTypeKind.LLVMTargetExtTypeKind => new Type(handle, LLVMTypeKind.LLVMTargetExtTypeKind),
Expand Down
4 changes: 3 additions & 1 deletion sources/LLVMSharp/Types/VectorType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ namespace LLVMSharp;

public sealed class VectorType : SequentialType
{
internal VectorType(LLVMTypeRef handle) : base(handle, LLVMTypeKind.LLVMVectorTypeKind)
internal VectorType(LLVMTypeRef handle) : base(handle, LLVMTypeKind.LLVMVectorTypeKind, LLVMTypeKind.LLVMScalableVectorTypeKind)
{
}

public bool IsScalable => Handle.Kind == LLVMTypeKind.LLVMScalableVectorTypeKind;

public uint NumElements => Handle.VectorSize;
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public string GC

public uint IntrinsicID => Handle.IntrinsicID;

public bool IsIntrinsic => Handle.IntrinsicID != 0;

public uint NumParams => Handle.ParamsCount;

public Constant? PersonalityFn
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information.

using System;
using LLVMSharp.Interop;

namespace LLVMSharp;
Expand All @@ -10,6 +11,23 @@ private protected GlobalObject(LLVMValueRef handle, LLVMValueKind expectedValueK
{
}

public Comdat? Comdat
{
get
{
var comdat = Handle.Comdat;
return (comdat.Handle != IntPtr.Zero) ? new Comdat(comdat) : null;
}

set
{
var handle = Handle;
handle.Comdat = (value is not null) ? value.Handle : default;
}
}

public bool HasComdat => Handle.Comdat.Handle != IntPtr.Zero;

public string Section
{
get
Expand Down
151 changes: 151 additions & 0 deletions sources/LLVMSharp/Values/Users/Instructions/CmpInst.Predicate.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information.

using System;
using LLVMSharp.Interop;

namespace LLVMSharp;
Expand Down Expand Up @@ -36,4 +37,154 @@ public enum Predicate
ICMP_SLT = LLVMIntPredicate.LLVMIntSLT,
ICMP_SLE = LLVMIntPredicate.LLVMIntSLE,
}

public static bool IsFPPredicate(Predicate predicate) => predicate <= Predicate.FCMP_TRUE;

public static bool IsIntPredicate(Predicate predicate) => predicate is >= Predicate.ICMP_EQ and <= Predicate.ICMP_SLE;

public static Predicate GetInversePredicate(Predicate predicate) => predicate switch
{
Predicate.ICMP_EQ => Predicate.ICMP_NE,
Predicate.ICMP_NE => Predicate.ICMP_EQ,
Predicate.ICMP_UGT => Predicate.ICMP_ULE,
Predicate.ICMP_ULT => Predicate.ICMP_UGE,
Predicate.ICMP_UGE => Predicate.ICMP_ULT,
Predicate.ICMP_ULE => Predicate.ICMP_UGT,
Predicate.ICMP_SGT => Predicate.ICMP_SLE,
Predicate.ICMP_SLT => Predicate.ICMP_SGE,
Predicate.ICMP_SGE => Predicate.ICMP_SLT,
Predicate.ICMP_SLE => Predicate.ICMP_SGT,
Predicate.FCMP_OEQ => Predicate.FCMP_UNE,
Predicate.FCMP_ONE => Predicate.FCMP_UEQ,
Predicate.FCMP_OGT => Predicate.FCMP_ULE,
Predicate.FCMP_OLT => Predicate.FCMP_UGE,
Predicate.FCMP_OGE => Predicate.FCMP_ULT,
Predicate.FCMP_OLE => Predicate.FCMP_UGT,
Predicate.FCMP_UEQ => Predicate.FCMP_ONE,
Predicate.FCMP_UNE => Predicate.FCMP_OEQ,
Predicate.FCMP_UGT => Predicate.FCMP_OLE,
Predicate.FCMP_ULT => Predicate.FCMP_OGE,
Predicate.FCMP_UGE => Predicate.FCMP_OLT,
Predicate.FCMP_ULE => Predicate.FCMP_OGT,
Predicate.FCMP_ORD => Predicate.FCMP_UNO,
Predicate.FCMP_UNO => Predicate.FCMP_ORD,
Predicate.FCMP_TRUE => Predicate.FCMP_FALSE,
Predicate.FCMP_FALSE => Predicate.FCMP_TRUE,
_ => throw new ArgumentOutOfRangeException(nameof(predicate)),
};

public static Predicate GetOrderedPredicate(Predicate predicate) => (Predicate)((int)predicate & (int)Predicate.FCMP_ORD);

public static Predicate GetUnorderedPredicate(Predicate predicate) => (Predicate)((int)predicate | (int)Predicate.FCMP_UNO);

public static Predicate GetSwappedPredicate(Predicate predicate) => predicate switch
{
Predicate.ICMP_SGT => Predicate.ICMP_SLT,
Predicate.ICMP_SLT => Predicate.ICMP_SGT,
Predicate.ICMP_SGE => Predicate.ICMP_SLE,
Predicate.ICMP_SLE => Predicate.ICMP_SGE,
Predicate.ICMP_UGT => Predicate.ICMP_ULT,
Predicate.ICMP_ULT => Predicate.ICMP_UGT,
Predicate.ICMP_UGE => Predicate.ICMP_ULE,
Predicate.ICMP_ULE => Predicate.ICMP_UGE,
Predicate.FCMP_OGT => Predicate.FCMP_OLT,
Predicate.FCMP_OLT => Predicate.FCMP_OGT,
Predicate.FCMP_OGE => Predicate.FCMP_OLE,
Predicate.FCMP_OLE => Predicate.FCMP_OGE,
Predicate.FCMP_UGT => Predicate.FCMP_ULT,
Predicate.FCMP_ULT => Predicate.FCMP_UGT,
Predicate.FCMP_UGE => Predicate.FCMP_ULE,
Predicate.FCMP_ULE => Predicate.FCMP_UGE,
_ => predicate,
};

public static bool IsStrictPredicate(Predicate predicate) => predicate switch
{
Predicate.ICMP_SGT or Predicate.ICMP_SLT or Predicate.ICMP_UGT or Predicate.ICMP_ULT or
Predicate.FCMP_OGT or Predicate.FCMP_OLT or Predicate.FCMP_UGT or Predicate.FCMP_ULT => true,
_ => false,
};

public static Predicate GetStrictPredicate(Predicate predicate) => predicate switch
{
Predicate.ICMP_SGE => Predicate.ICMP_SGT,
Predicate.ICMP_SLE => Predicate.ICMP_SLT,
Predicate.ICMP_UGE => Predicate.ICMP_UGT,
Predicate.ICMP_ULE => Predicate.ICMP_ULT,
Predicate.FCMP_OGE => Predicate.FCMP_OGT,
Predicate.FCMP_OLE => Predicate.FCMP_OLT,
Predicate.FCMP_UGE => Predicate.FCMP_UGT,
Predicate.FCMP_ULE => Predicate.FCMP_ULT,
_ => predicate,
};

public static Predicate GetNonStrictPredicate(Predicate predicate) => predicate switch
{
Predicate.ICMP_SGT => Predicate.ICMP_SGE,
Predicate.ICMP_SLT => Predicate.ICMP_SLE,
Predicate.ICMP_UGT => Predicate.ICMP_UGE,
Predicate.ICMP_ULT => Predicate.ICMP_ULE,
Predicate.FCMP_OGT => Predicate.FCMP_OGE,
Predicate.FCMP_OLT => Predicate.FCMP_OLE,
Predicate.FCMP_UGT => Predicate.FCMP_UGE,
Predicate.FCMP_ULT => Predicate.FCMP_ULE,
_ => predicate,
};

public static bool IsEquality(Predicate predicate)
{
if (IsIntPredicate(predicate))
{
return ICmpInst.IsEquality(predicate);
}

if (IsFPPredicate(predicate))
{
return FCmpInst.IsEquality(predicate);
}

throw new ArgumentOutOfRangeException(nameof(predicate));
}

public static bool IsRelational(Predicate predicate) => !IsEquality(predicate);

public static bool IsSigned(Predicate predicate) => predicate switch
{
Predicate.ICMP_SLT or Predicate.ICMP_SLE or Predicate.ICMP_SGT or Predicate.ICMP_SGE => true,
_ => false,
};

public static bool IsUnsigned(Predicate predicate) => predicate switch
{
Predicate.ICMP_ULT or Predicate.ICMP_ULE or Predicate.ICMP_UGT or Predicate.ICMP_UGE => true,
_ => false,
};

public static bool IsOrdered(Predicate predicate) => predicate switch
{
Predicate.FCMP_OEQ or Predicate.FCMP_ONE or Predicate.FCMP_OGT or
Predicate.FCMP_OLT or Predicate.FCMP_OGE or Predicate.FCMP_OLE or Predicate.FCMP_ORD => true,
_ => false,
};

public static bool IsUnordered(Predicate predicate) => predicate switch
{
Predicate.FCMP_UEQ or Predicate.FCMP_UNE or Predicate.FCMP_UGT or
Predicate.FCMP_ULT or Predicate.FCMP_UGE or Predicate.FCMP_ULE or Predicate.FCMP_UNO => true,
_ => false,
};

public static bool IsTrueWhenEqual(Predicate predicate) => predicate switch
{
Predicate.ICMP_EQ or Predicate.ICMP_UGE or Predicate.ICMP_ULE or Predicate.ICMP_SGE or Predicate.ICMP_SLE or
Predicate.FCMP_TRUE or Predicate.FCMP_UEQ or Predicate.FCMP_UGE or Predicate.FCMP_ULE => true,
_ => false,
};

public static bool IsFalseWhenEqual(Predicate predicate) => predicate switch
{
Predicate.ICMP_NE or Predicate.ICMP_UGT or Predicate.ICMP_ULT or Predicate.ICMP_SGT or Predicate.ICMP_SLT or
Predicate.FCMP_FALSE or Predicate.FCMP_ONE or Predicate.FCMP_OGT or Predicate.FCMP_OLT => true,
_ => false,
};
}
36 changes: 36 additions & 0 deletions sources/LLVMSharp/Values/Users/Instructions/CmpInst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,42 @@ private protected CmpInst(LLVMValueRef handle) : base(handle.IsACmpInst)
[SuppressMessage("Design", "CA1024:Use properties where appropriate", Justification = "Mirrors C++ CmpInst::getPredicate(); the 'Predicate' name is the nested predicate enum type.")]
public Predicate GetPredicate() => (Handle.IsAICmpInst != null) ? (Predicate)Handle.ICmpPredicate : (Predicate)Handle.FCmpPredicate;

[SuppressMessage("Design", "CA1024:Use properties where appropriate", Justification = "Mirrors C++ CmpInst::getInversePredicate(); overloads the static predicate transform.")]
public Predicate GetInversePredicate() => GetInversePredicate(GetPredicate());

[SuppressMessage("Design", "CA1024:Use properties where appropriate", Justification = "Mirrors C++ CmpInst::getSwappedPredicate(); overloads the static predicate transform.")]
public Predicate GetSwappedPredicate() => GetSwappedPredicate(GetPredicate());

[SuppressMessage("Design", "CA1024:Use properties where appropriate", Justification = "Mirrors C++ CmpInst::getOrderedPredicate(); overloads the static predicate transform.")]
public Predicate GetOrderedPredicate() => GetOrderedPredicate(GetPredicate());

[SuppressMessage("Design", "CA1024:Use properties where appropriate", Justification = "Mirrors C++ CmpInst::getUnorderedPredicate(); overloads the static predicate transform.")]
public Predicate GetUnorderedPredicate() => GetUnorderedPredicate(GetPredicate());

[SuppressMessage("Design", "CA1024:Use properties where appropriate", Justification = "Mirrors C++ CmpInst::getStrictPredicate(); overloads the static predicate transform.")]
public Predicate GetStrictPredicate() => GetStrictPredicate(GetPredicate());

[SuppressMessage("Design", "CA1024:Use properties where appropriate", Justification = "Mirrors C++ CmpInst::getNonStrictPredicate(); overloads the static predicate transform.")]
public Predicate GetNonStrictPredicate() => GetNonStrictPredicate(GetPredicate());

public bool IsFPPredicate() => IsFPPredicate(GetPredicate());

public bool IsIntPredicate() => IsIntPredicate(GetPredicate());

public bool IsStrictPredicate() => IsStrictPredicate(GetPredicate());

public bool IsEquality() => IsEquality(GetPredicate());

public bool IsRelational() => IsRelational(GetPredicate());

public bool IsSigned() => IsSigned(GetPredicate());

public bool IsUnsigned() => IsUnsigned(GetPredicate());

public bool IsTrueWhenEqual() => IsTrueWhenEqual(GetPredicate());

public bool IsFalseWhenEqual() => IsFalseWhenEqual(GetPredicate());

internal static new CmpInst Create(LLVMValueRef handle) => handle switch
{
_ when handle.IsAFCmpInst != null => new FCmpInst(handle),
Expand Down
6 changes: 6 additions & 0 deletions sources/LLVMSharp/Values/Users/Instructions/FCmpInst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@ public sealed class FCmpInst : CmpInst
internal FCmpInst(LLVMValueRef handle) : base(handle.IsAFCmpInst)
{
}

public static new bool IsEquality(Predicate predicate) => predicate is Predicate.FCMP_OEQ or Predicate.FCMP_ONE or Predicate.FCMP_UEQ or Predicate.FCMP_UNE;

public bool IsOrdered() => IsOrdered(GetPredicate());

public bool IsUnordered() => IsUnordered(GetPredicate());
}
Loading
Loading