Skip to content

Commit e4d63a9

Browse files
authored
Generalizing Intrinsics support (#52)
* Fixed bug causing Appending Module flags to fail * Restored Entrypoint names on overloaded P/Invokes * Added tests to validate appending ModuleFLags operate correctly. * * Updated intrinsic method support to use new generalized implementation that allows for all LLVM intrinsic functions in a consistent fashion. * Added *.WithOverflow intrinsics generators to InstructionBuilder to allow operations with overflow checking
1 parent 8926842 commit e4d63a9

File tree

13 files changed

+167
-227
lines changed

13 files changed

+167
-227
lines changed

Samples/CodeGenWithDebugInfo/Program.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,7 @@ private static void CreateCopyFunctionBody( BitcodeModule module
348348
var srcPtr = instBuilder.BitCast( copyFunc.Parameters[ 0 ], module.Context.Int8Type.CreatePointerType( ) );
349349

350350
uint pointerSize = module.Layout.IntPtrType( module.Context ).IntegerBitWidth;
351-
instBuilder.MemCpy( module
352-
, dstPtr
351+
instBuilder.MemCpy( dstPtr
353352
, srcPtr
354353
, module.Context.CreateConstant( pointerSize, module.Layout.ByteSizeOf( foo ), false )
355354
, ( int )module.Layout.AbiAlignmentOf( foo )
@@ -388,8 +387,7 @@ private static void CreateDoCopyFunctionBody( BitcodeModule module
388387
var bitCastDst = instBuilder.BitCast( dstAddr, bytePtrType );
389388
var bitCastSrc = instBuilder.BitCast( bar, bytePtrType );
390389

391-
instBuilder.MemCpy( module
392-
, bitCastDst
390+
instBuilder.MemCpy( bitCastDst
393391
, bitCastSrc
394392
, module.Context.CreateConstant( module.Layout.ByteSizeOf( foo ) )
395393
, ( int )module.Layout.CallFrameAlignmentOf( foo )

docfx/templates/Ubiquity/partials/class.header.tmpl.partial

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<h1 id="{{id}}" data-uid="{{uid}}" class="text-break">{{>partials/title}}</h1>
1+
<h1 id="{{id}}" data-uid="{{uid}}">{{>partials/title}}</h1>
22
<div class="markdown level0 summary">{{{summary}}}</div>
33
<div class="markdown level0 conceptual">{{{conceptual}}}</div>
44

docfx/templates/Ubiquity/partials/namespace.tmpl.partial

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<h1 id="{{id}}" data-uid="{{uid}}" class="text-break">{{>partials/title}}</h1>
1+
<h1 id="{{id}}" data-uid="{{uid}}">{{>partials/title}}</h1>
22
<div class="markdown level0 summary">{{{summary}}}</div>
33
<div class="markdown level0 conceptual">{{{conceptual}}}</div>
44
<div class="markdown level0 remarks">{{{remarks}}}</div>

src/LibLLVM/EXPORTS.DEF

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ LLVMFunctionAppendBasicBlock
8686
LLVMValueAsMetadataGetValue
8787
LLVMExecutionEngineClearGlobalMappingsFromModule
8888
LLVMContextCreateBasicBlock
89+
LLVMIntrinsicGetDeclaration
90+
LLVMIsIntrinsicOverloaded
91+
LLVMLookupInstrinsicId
8992
LLVMAttributeToString
9093

9194
LLVMCreateValueCache

src/LibLLVM/IRBindings.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,20 @@ extern "C"
180180
)
181181
);
182182
}
183+
184+
LLVMValueRef /*Function*/ LLVMIntrinsicGetDeclaration( LLVMModuleRef m, unsigned id, LLVMTypeRef* argTypes, unsigned count )
185+
{
186+
ArrayRef<Type*> Tys( unwrap( argTypes ), count );
187+
return wrap( Intrinsic::getDeclaration( unwrap( m ), static_cast< Intrinsic::ID >( id ), Tys ) );
188+
}
189+
190+
LLVMBool LLVMIsIntrinsicOverloaded( unsigned id )
191+
{
192+
return Intrinsic::isOverloaded( static_cast< Intrinsic::ID >( id ) );
193+
}
194+
195+
unsigned LLVMLookupInstrinsicId( char const* name )
196+
{
197+
return Function::lookupIntrinsicID( name );
198+
}
183199
}

src/LibLLVM/IRBindings.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ extern "C" {
6767
LLVMMetadataRef LLVMDIGlobalVarExpGetVariable( LLVMMetadataRef /*DIGlobalVariableExpression*/ metadataHandle );
6868
void LLVMExecutionEngineClearGlobalMappingsFromModule( LLVMExecutionEngineRef ee, LLVMModuleRef m );
6969
LLVMBasicBlockRef LLVMContextCreateBasicBlock( LLVMContextRef context, char const* name, LLVMValueRef /*Function*/ function, LLVMBasicBlockRef insertBefore );
70+
71+
LLVMValueRef /*Function*/ LLVMIntrinsicGetDeclaration( LLVMModuleRef m, unsigned id, LLVMTypeRef* argTypes, unsigned count );
72+
LLVMBool LLVMIsIntrinsicOverloaded( unsigned id );
73+
unsigned LLVMLookupInstrinsicId( char const* name );
74+
7075
#ifdef __cplusplus
7176
}
7277
#endif

src/Llvm.NET/BitcodeModule.cs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Runtime.InteropServices;
1212
using JetBrains.Annotations;
1313
using Llvm.NET.DebugInfo;
14+
using Llvm.NET.Instructions;
1415
using Llvm.NET.Native;
1516
using Llvm.NET.Types;
1617
using Llvm.NET.Values;
@@ -777,6 +778,40 @@ public Function CreateFunction( string name
777778
return CreateFunction( name, isVarArg, returnType, ( IEnumerable<IDebugType<ITypeRef, DIType>> )argumentTypes );
778779
}
779780

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+
780815
/// <summary>Clones the current module</summary>
781816
/// <returns>Cloned module</returns>
782817
public BitcodeModule Clone( )
@@ -953,7 +988,7 @@ private void ThrowIfDisposed( )
953988
// deal with C++ references. While that is manageable as
954989
// a getter, it is problematic as a setter since there isn't
955990
// 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
957992
// API sticks to the string form of the layout.
958993
private DataLayout CachedLayout;
959994

@@ -984,5 +1019,12 @@ private static Context GetContextFor( LLVMModuleRef handle )
9841019

9851020
[DllImport( LibraryPath, CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl )]
9861021
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 );
9871029
}
9881030
}

0 commit comments

Comments
 (0)