|
11 | 11 | using System.Runtime.InteropServices; |
12 | 12 | using JetBrains.Annotations; |
13 | 13 | using Llvm.NET.DebugInfo; |
| 14 | +using Llvm.NET.Instructions; |
14 | 15 | using Llvm.NET.Native; |
15 | 16 | using Llvm.NET.Types; |
16 | 17 | using Llvm.NET.Values; |
@@ -777,6 +778,40 @@ public Function CreateFunction( string name |
777 | 778 | return CreateFunction( name, isVarArg, returnType, ( IEnumerable<IDebugType<ITypeRef, DIType>> )argumentTypes ); |
778 | 779 | } |
779 | 780 |
|
| 781 | + /// <summary>Gets a declaration for an LLVM intrinsic function</summary> |
| 782 | + /// <param name="name">Name of the intrinsic</param> |
| 783 | + /// <param name="args">Args for the intrinsic</param> |
| 784 | + /// <returns>Function declaration</returns> |
| 785 | + public Function GetIntrinsicDeclaration( string name, params ITypeRef[ ] args ) |
| 786 | + { |
| 787 | + uint id = Intrinsic.LookupId( name ); |
| 788 | + return GetIntrinsicDeclaration( id, args ); |
| 789 | + } |
| 790 | + |
| 791 | + /// <summary>Gets a declaration for an LLVM intrinsic function</summary> |
| 792 | + /// <param name="id">id of the intrinsic</param> |
| 793 | + /// <param name="args">Args for the intrinsic</param> |
| 794 | + /// <returns>Function declaration</returns> |
| 795 | + public Function GetIntrinsicDeclaration( UInt32 id, params ITypeRef[] args) |
| 796 | + { |
| 797 | + if( !LLVMIsIntrinsicOverloaded( id ) && args.Length > 0 ) |
| 798 | + { |
| 799 | + throw new ArgumentException( $"intrinsic {id} is not overloaded and therefore does not require type arguments" ); |
| 800 | + } |
| 801 | + |
| 802 | + LLVMTypeRef[ ] llvmArgs = args.Select( a => a.GetTypeRef( ) ).ToArray( ); |
| 803 | + |
| 804 | + // have to pass a valid addressable object to native interop |
| 805 | + // so allocate space for a single value but tell LLVM the length is 0 |
| 806 | + uint argCount = (uint)llvmArgs.Length; |
| 807 | + if( llvmArgs.Length == 0 ) |
| 808 | + { |
| 809 | + llvmArgs = new LLVMTypeRef[ 1 ]; |
| 810 | + } |
| 811 | + |
| 812 | + return (Function) Value.FromHandle(LLVMIntrinsicGetDeclaration( ModuleHandle, id, out llvmArgs[ 0 ], argCount )); |
| 813 | + } |
| 814 | + |
780 | 815 | /// <summary>Clones the current module</summary> |
781 | 816 | /// <returns>Cloned module</returns> |
782 | 817 | public BitcodeModule Clone( ) |
@@ -953,7 +988,7 @@ private void ThrowIfDisposed( ) |
953 | 988 | // deal with C++ references. While that is manageable as |
954 | 989 | // a getter, it is problematic as a setter since there isn't |
955 | 990 | // any sort of ownership transfer and the ownership is a bit |
956 | | - // mirky, especially with a managed projection. Thus, the LLVM-C |
| 991 | + // murky, especially with a managed projection. Thus, the LLVM-C |
957 | 992 | // API sticks to the string form of the layout. |
958 | 993 | private DataLayout CachedLayout; |
959 | 994 |
|
@@ -984,5 +1019,12 @@ private static Context GetContextFor( LLVMModuleRef handle ) |
984 | 1019 |
|
985 | 1020 | [DllImport( LibraryPath, CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl )] |
986 | 1021 | private static extern LLVMNamedMDNodeRef LLVMModuleGetNextNamedMD( LLVMNamedMDNodeRef nodeRef ); |
| 1022 | + |
| 1023 | + [DllImport( LibraryPath, CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl )] |
| 1024 | + private static extern LLVMValueRef /*Function*/ LLVMIntrinsicGetDeclaration( LLVMModuleRef m, UInt32 id, out LLVMTypeRef paramTypes, uint paramCount ); |
| 1025 | + |
| 1026 | + [DllImport( LibraryPath, CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl )] |
| 1027 | + [return:MarshalAs(UnmanagedType.Bool)] |
| 1028 | + private static extern bool LLVMIsIntrinsicOverloaded( UInt32 id ); |
987 | 1029 | } |
988 | 1030 | } |
0 commit comments