RyuJIT: Optimize simple comparisons into branchless expressions by EgorBo · Pull Request #32716 · dotnet/runtime (original) (raw)
This PR optimizes simple conditions (BBJ_COND
+ two BBJ_RETURN
) into a single branchless BBJ_RETURN
block
E.g.
The new codegen is branchless and is more compact. In theory, it can be slower in some benchmarks where we constantly take the same branch over and over and the branch-prediction + speculative execution may perform better but it seems GCC doesn't really care. If you want I can add a sort of "IsHotBlock" check (if it makes sense with the current PGO state)
Found 52 files with textual diffs.
Summary of Code Size diffs:
(Lower is better)
Total bytes of diff: -3419 (-0.01% of base)
diff is an improvement.
Top file improvements (bytes):
-933 : System.Private.CoreLib.dasm (-0.02% of base)
-396 : Microsoft.CodeAnalysis.CSharp.dasm (-0.01% of base)
-348 : System.Data.Common.dasm (-0.02% of base)
-251 : System.Private.Xml.dasm (-0.01% of base)
-126 : System.Linq.Parallel.dasm (-0.01% of base)
-121 : System.Linq.Expressions.dasm (-0.02% of base)
-115 : System.DirectoryServices.dasm (-0.03% of base)
-86 : System.Reflection.MetadataLoadContext.dasm (-0.05% of base)
-80 : System.Management.dasm (-0.02% of base)
-75 : Newtonsoft.Json.dasm (-0.01% of base)
-70 : System.Threading.Channels.dasm (-0.04% of base)
-65 : System.Collections.dasm (-0.01% of base)
-52 : Microsoft.CSharp.dasm (-0.02% of base)
-50 : System.Net.WebSockets.WebSocketProtocol.dasm (-0.12% of base)
-44 : System.ComponentModel.TypeConverter.dasm (-0.01% of base)
-40 : Microsoft.Diagnostics.Tracing.TraceEvent.dasm (-0.00% of base)
-39 : System.Security.Principal.Windows.dasm (-0.08% of base)
-38 : Microsoft.CodeAnalysis.dasm (-0.00% of base)
-35 : System.Reflection.Metadata.dasm (-0.01% of base)
-32 : Microsoft.CodeAnalysis.VisualBasic.dasm (-0.00% of base)
52 total files with Code Size differences (52 improved, 0 regressed), 108 unchanged.
Top method improvements (bytes):
-50 (-2.38% of base) : System.Net.WebSockets.WebSocketProtocol.dasm - <WaitForServerToCloseConnectionAsync>d__64:MoveNext():this
-36 (-2.81% of base) : System.Private.CoreLib.dasm - System.Globalization.CompareInfo:Compare(System.String,System.String,int):int:this (2 methods)
-32 (-8.82% of base) : System.Private.CoreLib.dasm - System.Collections.Generic.Comparer`1[Vector`1][System.Numerics.Vector`1[System.Single]]:System.Collections.IComparer.Compare(System.Object,System.Object):int:this
-22 (-7.97% of base) : System.Data.Common.dasm - System.Data.DataColumn:CompareValueTo(int,System.Object,bool):bool:this
-22 (-17.60% of base) : System.Private.CoreLib.dasm - System.Globalization.HijriCalendar:GetDaysInMonth(int,int,int):int:this
-20 (-2.74% of base) : Newtonsoft.Json.dasm - Newtonsoft.Json.Serialization.JsonSerializerInternalReader:SetPropertyValue(Newtonsoft.Json.Serialization.JsonProperty,Newtonsoft.Json.JsonConverter,Newtonsoft.Json.Serialization.JsonContainerContract,Newtonsoft.Json.Serialization.JsonProperty,Newtonsoft.Json.JsonReader,System.Object):bool:this
-20 (-2.99% of base) : System.Private.CoreLib.dasm - System.DateTimeParse:MatchTimeMark(byref,System.Globalization.DateTimeFormatInfo,byref):bool
-19 (-4.22% of base) : Microsoft.CSharp.dasm - Microsoft.CSharp.RuntimeBinder.Semantics.ExpressionBinder:CompareTypes(Microsoft.CSharp.RuntimeBinder.Semantics.TypeArray,Microsoft.CSharp.RuntimeBinder.Semantics.TypeArray):int
-19 (-7.36% of base) : System.Private.CoreLib.dasm - System.DefaultBinder:FindMostSpecificMethod(System.Reflection.MethodBase,System.Int32[],System.Type,System.Reflection.MethodBase,System.Int32[],System.Type,System.Type[],System.Object[]):int
-19 (-6.53% of base) : System.Private.CoreLib.dasm - System.Collections.Generic.Comparer`1[Double][System.Double]:System.Collections.IComparer.Compare(System.Object,System.Object):int:this
-19 (-7.66% of base) : System.Reflection.MetadataLoadContext.dasm - System.DefaultBinder:FindMostSpecificMethod(System.Reflection.MethodBase,System.Int32[],System.Type,System.Reflection.MethodBase,System.Int32[],System.Type,System.Type[],System.Object[]):int
-18 (-3.48% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.CodeGen.StackOptimizerPass1:IsNestedLocalOfCompoundOperator(Microsoft.CodeAnalysis.CSharp.Symbols.LocalSymbol,Microsoft.CodeAnalysis.CSharp.BoundSequence):bool:this
-18 (-1.26% of base) : System.Private.CoreLib.dasm - System.Globalization.CompareInfo:IndexOf(System.String,System.String,int,int,int):int:this (2 methods)
-18 (-1.81% of base) : System.Private.CoreLib.dasm - System.String:LastIndexOf(System.String,int,int,int):int:this
-18 (-6.25% of base) : System.Private.CoreLib.dasm - System.Runtime.InteropServices.CustomMarshalers.EnumVariantViewOfEnumerator:Next(int,System.Object[],long):int:this
-18 (-3.99% of base) : System.Private.Xml.dasm - System.Xml.Schema.SchemaCollectionCompiler:IsGroupBaseFromGroupBase(System.Xml.Schema.XmlSchemaGroupBase,System.Xml.Schema.XmlSchemaGroupBase,bool):bool:this
-16 (-3.77% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.SourceMemberContainerTypeSymbol:DoOperatorsPair(Microsoft.CodeAnalysis.CSharp.Symbols.MethodSymbol,Microsoft.CodeAnalysis.CSharp.Symbols.MethodSymbol):bool
-15 (-2.50% of base) : System.Data.Common.dasm - System.Data.Common.DateTimeOffsetStorage:CompareValueTo(int,System.Object):int:this
-14 (-6.90% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.ConversionsBase:HasImplicitConversionFromDelegate(Microsoft.CodeAnalysis.CSharp.Symbols.TypeSymbol,Microsoft.CodeAnalysis.CSharp.Symbols.TypeSymbol,byref):bool:this
-14 (-5.34% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.AssemblySymbol:PerformIVTCheck(System.Collections.Immutable.ImmutableArray`1[Byte],Microsoft.CodeAnalysis.AssemblyIdentity):int:this
Top method improvements (percentages):
-5 (-31.25% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.ThreeStateHelpers:ToThreeState(bool):ubyte
-4 (-30.77% of base) : System.Private.CoreLib.dasm - System.Convert:ToInt32(bool):int
-4 (-30.77% of base) : System.Private.CoreLib.dasm - System.Convert:ToUInt32(bool):int
-4 (-30.77% of base) : System.Private.CoreLib.dasm - System.Convert:ToUInt16(bool):ushort
-4 (-30.77% of base) : System.Private.CoreLib.dasm - System.Convert:ToByte(bool):ubyte
-4 (-30.77% of base) : System.Private.CoreLib.dasm - System.Convert:ToInt16(bool):short
-4 (-30.77% of base) : System.Private.CoreLib.dasm - System.Convert:ToSByte(bool):byte
-4 (-30.77% of base) : System.Private.Xml.dasm - System.Xml.Xsl.XPathConvert:NotZero(int):int
-4 (-28.57% of base) : System.Private.CoreLib.dasm - System.Boolean:GetHashCode():int:this
-4 (-28.57% of base) : System.Private.CoreLib.dasm - System.Threading.SpinWait:get_NextSpinWillYield():bool:this
-5 (-27.78% of base) : Microsoft.CodeAnalysis.dasm - VersionResourceSerializer:get_FileType():int:this
-9 (-27.27% of base) : System.Linq.Expressions.dasm - System.Linq.Expressions.Compiler.LambdaCompiler:EmitExpressionStart(System.Linq.Expressions.Expression):int:this
-4 (-26.67% of base) : Microsoft.CSharp.dasm - BinOpFullSig:isLifted():bool:this
-4 (-26.67% of base) : Microsoft.CSharp.dasm - UnaOpFullSig:isLifted():bool:this
-4 (-26.67% of base) : System.ComponentModel.Composition.dasm - System.ComponentModel.Composition.ImportAttribute:System.ComponentModel.Composition.IAttributedImport.get_Cardinality():int:this
-4 (-26.67% of base) : System.ComponentModel.TypeConverter.dasm - FilterCacheItem:IsValid(System.ComponentModel.Design.ITypeDescriptorFilterService):bool:this
-4 (-26.67% of base) : System.Data.Common.dasm - System.Data.LookupNode:DependsOn(System.Data.DataColumn):bool:this
-8 (-26.67% of base) : System.Data.Common.dasm - System.Data.Common.ADP:SrcCompare(System.String,System.String):int
-8 (-26.67% of base) : System.Data.OleDb.dasm - System.Data.Common.ADP:SrcCompare(System.String,System.String):int
-8 (-26.67% of base) : System.Diagnostics.TraceSource.dasm - System.Diagnostics.BooleanSwitch:get_Enabled():bool:this
406 total methods with Code Size differences (406 improved, 0 regressed), 304680 unchanged.
and the jit-diff already looks promising, I think the GT_ASG ones should produce even bigger diffs.