Skip to content

Commit f8036f0

Browse files
authored
Updated to use UTF8 literals for attribute names (UbiquityDotNET#242)
- This means less overhead at runtime as the strings are already in the native UTF8 format. - Some other places where `LazyEncodedString` were already used were also updated to use a UTF8 literal. - A few doc updates. Co-authored-by: smaillet <[email protected]>
1 parent 1959cb9 commit f8036f0

File tree

11 files changed

+83
-55
lines changed

11 files changed

+83
-55
lines changed

IgnoredWords.dic

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
ABI
2+
Accessor
23
Addr
34
alloca
45
anonymize
@@ -56,6 +57,7 @@ Identifier
5657
inline
5758
inlined
5859
Interop
60+
jit
5961
Lexer
6062
LibLLVM
6163
Llilum
@@ -99,10 +101,13 @@ Typedef
99101
uid
100102
unaryop
101103
undiscoverable
104+
uniqued
105+
uniqueing
102106
userdefinedop
103107
Users
104108
usings
105109
utils
110+
variadic
106111
vcxproj
107112
versioned
108113
versioning

src/Samples/CodeGenWithDebugInfo/CortexM3ABI.cs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System;
88
using System.Collections.Immutable;
99

10+
using Ubiquity.NET.InteropHelpers;
1011
using Ubiquity.NET.Llvm;
1112
using Ubiquity.NET.Llvm.DebugInfo;
1213
using Ubiquity.NET.Llvm.Types;
@@ -72,8 +73,8 @@ public void AddAttributesForByValueStructure( Function function, DebugFunctionTy
7273

7374
var layout = function.ParentModule.Layout;
7475
function.AddAttributes( FunctionAttributeIndex.Parameter0 + paramIndex
75-
, function.Context.CreateAttribute( "byval", ptrType.ElementType)
76-
, function.Context.CreateAttribute( "align", layout.AbiAlignmentOf( ptrType.ElementType! ) )
76+
, function.Context.CreateAttribute( "byval"u8, ptrType.ElementType)
77+
, function.Context.CreateAttribute( "align"u8, layout.AbiAlignmentOf( ptrType.ElementType! ) )
7778
);
7879
}
7980

@@ -86,27 +87,28 @@ public void AddModuleFlags( Module module )
8687

8788
public ImmutableArray<AttributeValue> BuildTargetDependentFunctionAttributes( IContext ctx )
8889
=> [
89-
ctx.CreateAttribute( "correctly-rounded-divide-sqrt-fp-math", "false" ),
90-
ctx.CreateAttribute( "disable-tail-calls", "false" ),
91-
ctx.CreateAttribute( "less-precise-fpmad", "false" ),
92-
ctx.CreateAttribute( "no-frame-pointer-elim", "true" ),
93-
ctx.CreateAttribute( "no-frame-pointer-elim-non-leaf" ),
94-
ctx.CreateAttribute( "no-infs-fp-math", "false" ),
95-
ctx.CreateAttribute( "no-jump-tables", "false" ),
96-
ctx.CreateAttribute( "no-nans-fp-math", "false" ),
97-
ctx.CreateAttribute( "no-signed-zeros-fp-math", "false" ),
98-
ctx.CreateAttribute( "no-trapping-math", "false" ),
99-
ctx.CreateAttribute( "stack-protector-buffer-size", "8" ),
100-
ctx.CreateAttribute( "target-cpu", Cpu ),
101-
ctx.CreateAttribute( "target-features", Features ),
102-
ctx.CreateAttribute( "unsafe-fp-math", "false" ),
103-
ctx.CreateAttribute( "use-soft-float", "false" )
90+
ctx.CreateAttribute( "correctly-rounded-divide-sqrt-fp-math"u8, "false"u8 ),
91+
ctx.CreateAttribute( "disable-tail-calls"u8, "false"u8 ),
92+
ctx.CreateAttribute( "less-precise-fpmad"u8, "false"u8 ),
93+
ctx.CreateAttribute( "no-frame-pointer-elim"u8, "true"u8 ),
94+
ctx.CreateAttribute( "no-frame-pointer-elim-non-leaf"u8 ),
95+
ctx.CreateAttribute( "no-infs-fp-math"u8, "false"u8 ),
96+
ctx.CreateAttribute( "no-jump-tables"u8, "false"u8 ),
97+
ctx.CreateAttribute( "no-nans-fp-math"u8, "false"u8 ),
98+
ctx.CreateAttribute( "no-signed-zeros-fp-math"u8, "false"u8 ),
99+
ctx.CreateAttribute( "no-trapping-math"u8, "false"u8 ),
100+
ctx.CreateAttribute( "stack-protector-buffer-size"u8, "8"u8 ),
101+
ctx.CreateAttribute( "target-cpu"u8, Cpu ),
102+
ctx.CreateAttribute( "target-features"u8, Features ),
103+
ctx.CreateAttribute( "unsafe-fp-math"u8, "false"u8 ),
104+
ctx.CreateAttribute( "use-soft-float"u8, "false"u8 )
104105
];
105106

106107
private readonly ILibLlvm LlvmLib;
107108

108-
private const string Cpu = "cortex-m3";
109-
private const string Features = "+hwdiv,+strict-align,+thumb-mode";
110-
private const string TripleName = "thumbv7m-none--eabi";
109+
// Sadly, these can't be utf8 literals, but, they can be static readonly LazyEncodedString!
110+
private static readonly LazyEncodedString Cpu = "cortex-m3"u8;
111+
private static readonly LazyEncodedString Features = "+hwdiv,+strict-align,+thumb-mode"u8;
112+
private static readonly LazyEncodedString TripleName = "thumbv7m-none--eabi"u8;
111113
}
112114
}

src/Samples/CodeGenWithDebugInfo/Program.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ private static Function DeclareCopyFunc( ITargetABI abi
248248
, debugFlags: DebugInfoFlags.Prototyped
249249
, isOptimized: false
250250
).Linkage( Linkage.Internal ) // static function
251-
.AddAttributes( FunctionAttributeIndex.Function, "nounwind", "noinline", "optimizenone" )
251+
.AddAttributes( FunctionAttributeIndex.Function, "nounwind"u8, "noinline"u8, "optimizenone"u8 )
252252
.AddAttributes( FunctionAttributeIndex.Function, abiAttributes );
253253

254254
Debug.Assert( !fooPtr.IsOpaque(), "Expected the debug info for a pointer was created with a valid ElementType");
@@ -301,7 +301,7 @@ private static void CreateCopyFunctionBody( ref readonly DIBuilder diBuilder
301301
.RegisterName( "pDst.addr" )
302302
.SetAlignment( ptrAlign );
303303

304-
bool hasParam0ByVal = copyFunc.FindAttribute(FunctionAttributeIndex.Parameter0, "byval") is not null;
304+
bool hasParam0ByVal = copyFunc.FindAttribute(FunctionAttributeIndex.Parameter0, "byval"u8) is not null;
305305
if( hasParam0ByVal )
306306
{
307307
diBuilder.InsertDeclare( copyFunc.Parameters[ 0 ]
@@ -363,7 +363,7 @@ private static void CreateDoCopyFunctionBody( Module module
363363

364364
// create instruction builder to build the body
365365
using var instBuilder = new InstructionBuilder( blk );
366-
bool hasParam0ByVal = doCopyFunc.FindAttribute(FunctionAttributeIndex.Parameter0, "byval") is not null;
366+
bool hasParam0ByVal = doCopyFunc.FindAttribute(FunctionAttributeIndex.Parameter0, "byval"u8) is not null;
367367
if( !hasParam0ByVal )
368368
{
369369
// create a temp local copy of the global structure

src/Samples/CodeGenWithDebugInfo/X64ABI.cs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System;
88
using System.Collections.Immutable;
99

10+
using Ubiquity.NET.InteropHelpers;
1011
using Ubiquity.NET.Llvm;
1112
using Ubiquity.NET.Llvm.DebugInfo;
1213
using Ubiquity.NET.Llvm.Types;
@@ -67,23 +68,24 @@ public void AddModuleFlags( Module module )
6768

6869
public ImmutableArray<AttributeValue> BuildTargetDependentFunctionAttributes( IContext ctx )
6970
=> [
70-
ctx.CreateAttribute( "disable-tail-calls", "false" ),
71-
ctx.CreateAttribute( "less-precise-fpmad", "false" ),
72-
ctx.CreateAttribute( "no-frame-pointer-elim", "false" ),
73-
ctx.CreateAttribute( "no-infs-fp-math", "false" ),
74-
ctx.CreateAttribute( "no-nans-fp-math", "false" ),
75-
ctx.CreateAttribute( "stack-protector-buffer-size", "8" ),
76-
ctx.CreateAttribute( "target-cpu", Cpu ),
77-
ctx.CreateAttribute( "target-features", Features ),
78-
ctx.CreateAttribute( "unsafe-fp-math", "false" ),
79-
ctx.CreateAttribute( "use-soft-float", "false" ),
80-
ctx.CreateAttribute( "uwtable", (ulong)UWTableKind.Async)
71+
ctx.CreateAttribute( "disable-tail-calls"u8, "false"u8 ),
72+
ctx.CreateAttribute( "less-precise-fpmad"u8, "false"u8 ),
73+
ctx.CreateAttribute( "no-frame-pointer-elim"u8, "false"u8 ),
74+
ctx.CreateAttribute( "no-infs-fp-math"u8, "false"u8 ),
75+
ctx.CreateAttribute( "no-nans-fp-math"u8, "false"u8 ),
76+
ctx.CreateAttribute( "stack-protector-buffer-size"u8, "8"u8 ),
77+
ctx.CreateAttribute( "target-cpu"u8, Cpu ),
78+
ctx.CreateAttribute( "target-features"u8, Features ),
79+
ctx.CreateAttribute( "unsafe-fp-math"u8, "false"u8 ),
80+
ctx.CreateAttribute( "use-soft-float"u8, "false"u8 ),
81+
ctx.CreateAttribute( "uwtable"u8, (ulong)UWTableKind.Async)
8182
];
8283

8384
private readonly ILibLlvm LlvmLib;
8485

85-
private const string Cpu = "x86-64";
86-
private const string Features = "+sse,+sse2";
87-
private const string TripleName = "x86_64-pc-windows-msvc18.0.0";
86+
// Sadly, these can't be utf8 literals, but, they can be static readonly LazyEncodedString!
87+
private static readonly LazyEncodedString Cpu = "x86-64"u8;
88+
private static readonly LazyEncodedString Features = "+sse,+sse2"u8;
89+
private static readonly LazyEncodedString TripleName = "x86_64-pc-windows-msvc18.0.0"u8;
8890
}
8991
}

src/Samples/Kaleidoscope/Chapter2/Kaleidoscope-ch2.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ to implement)
2020
### Lexer symbols
2121

2222
The Kaleidoscope lexer consists of several tokens and is defined in the
23-
[Kaleidoscope.g4](https://github.com/UbiquityDotNET/Llvm.NET/blob/master/Samples/Kaleidoscope/Kaleidoscope.Parser/Kaleidoscope.g4)
23+
[Kaleidoscope.g4](https://github.com/UbiquityDotNET/Llvm.NET/blob/develop/src/Samples/Kaleidoscope/Kaleidoscope.Grammar/ANTLR/Kaleidoscope.g4)
2424
grammar file.
2525

2626
``` antlr

src/Samples/Kaleidoscope/Chapter3.5/CodeGenerator.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ private Function GetOrDeclareFunction(Prototype prototype)
211211

212212
var llvmSignature = Context.GetFunctionType( returnType: Context.DoubleType, args: prototype.Parameters.Select( _ => Context.DoubleType ) );
213213
var retVal = Module.CreateFunction( prototype.Name, llvmSignature );
214-
retVal.AddAttribute( FunctionAttributeIndex.Function, prototype.IsExtern ? "builtin" : "nobuiltin" );
215214

216215
int index = 0;
217216
foreach(var argId in prototype.Parameters)

src/Samples/Kaleidoscope/Chapter3.5/Kaleidoscope-ch3.5.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,24 @@ sample that actually uses the optimizations more is left as an exercise for the
2424
### Initialization
2525
The code generation maintains state for the transformation as private members. To support optimization
2626
generally only requires a set of named passes and to call the method to run the passes on a function or
27-
module. [Technically an overload provides the chance to set [PassBuilderOptions](xref:Ubiquity.NET.Llvm.PassBuilderOptions) but
28-
this sample just uses the overload that applies defaults.] The new pass management system
27+
module. [Technically an overload provides the chance to set [PassBuilderOptions](xref:Ubiquity.NET.Llvm.PassBuilderOptions)
28+
but this sample just uses the overload that applies defaults.] The new pass management system
2929
uses the string names of passes instead of a distinct type and named methods for adding them etc...
3030

3131
These Options are initialized in a private static member for the passes.
3232
[!code-csharp[Main](CodeGenerator.cs#PrivateMembers)]
3333

3434
### Special attributes for parsed functions
35+
>[!WARNING]
3536
When performing optimizations with the new pass builder system the TargetLibraryInfo (Internal LLVM concept) is
36-
used to determine what the "built-in" functions are. Unfortunately they leave little room for manipulating or
37-
customizing this set (In C++, in LLVM-C there is NO support for this type at all!). Unfortunately that means that
38-
if any function happens to have the same name as the TargetLibraryInfo for a given Triple then it will be optimized
39-
AS a built-in function (even if not declared as one). This is an unfortunate state of affairs with the LLVM support
40-
for C++ and highly problematic for `C` based bindings/projections like this library. Fortunately there is a scapegoat
41-
for this. The function can include a `nobuiltin` attribute to prevent the optimizer from assuming calls to it are
42-
one of the well known built-in functions. This is used for ALL methods that come from the AST, which is all functions
43-
at this point in the language design. Thus `GetOrDeclareFunction` will add that attribute for any function creations.
37+
used to determine what the "built-in" functions are. Unfortunately, they leave little room for manipulating or
38+
customizing this set (In C++ there is some "wiggle room", in LLVM-C there is NO support for this type at all!).
39+
Unfortunately, that means that if any function happens to have the same name as the TargetLibraryInfo for a given
40+
Triple then it will be optimized AS a built-in function (even if not declared as one). This is an unfortunate state
41+
of affairs with the LLVM support for C++ and highly problematic for `C` based bindings/projections like this library.
42+
Fortunately there is a scapegoat for this. The function can include a `nobuiltin` attribute at the call site to prevent
43+
the optimizer from assuming calls to it are one of the well known built-in functions. This isn't used for Kaleidoscope.
44+
But does leave room for problems with names that match some arbitrary set of "built-in" symbols.
4445

4546
[!code-csharp[Main](CodeGenerator.cs#GetOrDeclareFunction)]
4647

src/Samples/Kaleidoscope/Chapter8/CodeGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ public void Dispose( )
228228

229229
if( definition.IsAnonymous )
230230
{
231-
function.AddAttribute( FunctionAttributeIndex.Function, "alwaysinline")
231+
function.AddAttribute( FunctionAttributeIndex.Function, "alwaysinline"u8)
232232
.Linkage( Linkage.Private );
233233

234234
AnonymousFunctions.Add( function );

src/Samples/Kaleidoscope/IgnoredWords.dic

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ afterloop
33
alloca
44
alltmp
55
antlr
6+
ascii
7+
binaryop
8+
binop
9+
blockdiag
610
booltmp
711
builtin
12+
builtinop
813
calltmp
914
cmptmp
1015
conditionalexpression
@@ -15,19 +20,24 @@ divtmp
1520
fadd
1621
fibi
1722
fmul
23+
foo
24+
func
1825
hacky
1926
ifcond
2027
ifcont
2128
ifresult
2229
imag
2330
impl
31+
inline
2432
inlined
33+
lexer
2534
loopcond
2635
mandel
2736
mandelconverger
2837
multmp
2938
nextvar
3039
nobuiltin
40+
paren
3141
parsetree
3242
powtmp
3343
printchar
@@ -37,4 +47,8 @@ printstar
3747
putchard
3848
ret
3949
subtmp
50+
uid
51+
unaryop
4052
uniqued
53+
userdefinedop
54+
xref

src/Samples/OrcV2VeryLazy/Program.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,22 @@ private static void Main(/*string[] args*/)
3434
// occurs that prevents completion of the transfer. When transfer completes the
3535
// MU is marked as disposed but a call to Dispose() is a safe NOP. Thus, this handles
3636
// all conditions consistently
37-
using var fooMu = new CustomMaterializationUnit("FooMU", Materialize, fooSym);
37+
using var fooMu = new CustomMaterializationUnit("FooMU"u8, Materialize, fooSym);
3838
jit.MainLib.Define(fooMu);
3939

4040
using var internedBarBodyName = jit.MangleAndIntern(BarBodySymbolName);
4141
var barSym = new KvpArrayBuilder<SymbolStringPoolEntry, SymbolFlags> {
4242
[internedBarBodyName] = flags,
4343
}.ToImmutable();
4444

45-
using var barMu = new CustomMaterializationUnit("BarMU", Materialize, barSym);
45+
using var barMu = new CustomMaterializationUnit("BarMU"u8, Materialize, barSym);
4646
jit.MainLib.Define(barMu);
4747

4848
using var ism = new LocalIndirectStubsManager(triple);
4949
using var callThruMgr = jit.Session.CreateLazyCallThroughManager(triple);
5050

51-
using var internedFoo = jit.MangleAndIntern("foo");
52-
using var internedBar = jit.MangleAndIntern("bar");
51+
using var internedFoo = jit.MangleAndIntern("foo"u8);
52+
using var internedBar = jit.MangleAndIntern("bar"u8);
5353

5454
var reexports = new KvpArrayBuilder<SymbolStringPoolEntry, SymbolAliasMapEntry> {
5555
[internedFoo] = new(internedFooBodyName, flags),
@@ -59,7 +59,7 @@ private static void Main(/*string[] args*/)
5959
using var lazyReExports = new LazyReExportsMaterializationUnit(callThruMgr, ism, jit.MainLib, reexports);
6060
jit.MainLib.Define(lazyReExports);
6161

62-
UInt64 address = jit.Lookup("entry");
62+
UInt64 address = jit.Lookup("entry"u8);
6363

6464
unsafe
6565
{

src/Ubiquity.NET.InteropHelpers/LazyEncodedString.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ public static implicit operator ReadOnlySpan<byte>(LazyEncodedString self)
182182
[SuppressMessage( "Usage", "CA2225:Operator overloads have named alternates", Justification = "It's a convenience wrapper around an existing constructor" )]
183183
public static implicit operator LazyEncodedString(string managed) => new(managed);
184184

185+
/// <summary>Convenient implicit conversion of a managed string into a Lazily encoded string</summary>
186+
/// <param name="utf8Data">Span of UTF8 characters to wrap with lazy encoding support</param>
187+
[SuppressMessage( "Usage", "CA2225:Operator overloads have named alternates", Justification = "It's a convenience wrapper around an existing constructor" )]
188+
public static implicit operator LazyEncodedString(ReadOnlySpan<byte> utf8Data) => new(utf8Data);
189+
185190
private readonly Encoding Encoding;
186191
private readonly Lazy<string> ManagedString;
187192

0 commit comments

Comments
 (0)