Permalink
Browse files

Choose which optional optimizations you want Sigil to perform.

  • Loading branch information...
JasonPunyon committed Feb 21, 2013
1 parent f9cfa3e commit 4ccb019efe14b897aea10ff327766415118ec250
Showing with 85 additions and 15 deletions.
  1. +2 −1 .gitignore
  2. +18 −14 Sigil/Emit.cs
  3. +26 −0 Sigil/OptimizationOptions.cs
  4. +1 −0 Sigil/Sigil.csproj
  5. +38 −0 SigilTests/Branches.cs
@@ -5,4 +5,5 @@ obj/
*.[Oobj]
*.user
*.suo
*.bak
*.bak
*TestResults*
@@ -220,11 +220,15 @@ public int ILOffset()
return IL.ByteDistance(0, IL.Index);
}

private void Seal()
private void Seal(OptimizationOptions optimizationOptions)
{
InjectTailCall();
InjectReadOnly();
PatchBranches();

if ((optimizationOptions & OptimizationOptions.EnableBranchPatching) != 0)
{
PatchBranches();
}

Validate();

@@ -245,7 +249,7 @@ private void Seal()
/// the returned delegate fails validation (indicative of a bug in Sigil) or
/// behaves unexpectedly (indicative of a logic bug in the consumer code).
/// </summary>
public DelegateType CreateDelegate(out string instructions)
public DelegateType CreateDelegate(out string instructions, OptimizationOptions optimizationOptions = OptimizationOptions.All)
{
if (DynMethod == null)
{
@@ -258,7 +262,7 @@ public DelegateType CreateDelegate(out string instructions)
return CreatedDelegate;
}

Seal();
Seal(optimizationOptions);

var il = DynMethod.GetILGenerator();
instructions = IL.UnBuffer(il);
@@ -278,10 +282,10 @@ public DelegateType CreateDelegate(out string instructions)
///
/// Once this method is called the Emit may no longer be modified.
/// </summary>
public DelegateType CreateDelegate()
public DelegateType CreateDelegate(OptimizationOptions optimizationOptions = OptimizationOptions.All)
{
string ignored;
return CreateDelegate(out ignored);
return CreateDelegate(out ignored, optimizationOptions);
}

/// <summary>
@@ -300,7 +304,7 @@ public DelegateType CreateDelegate()
/// the returned method fails validation (indicative of a bug in Sigil) or
/// behaves unexpectedly (indicative of a logic bug in the consumer code).
/// </summary>
public MethodBuilder CreateMethod(out string instructions)
public MethodBuilder CreateMethod(out string instructions, OptimizationOptions optimizationOptions = OptimizationOptions.All)
{
if (MtdBuilder == null)
{
@@ -313,7 +317,7 @@ public MethodBuilder CreateMethod(out string instructions)
return MtdBuilder;
}

Seal();
Seal(optimizationOptions);

MethodBuilt = true;

@@ -335,10 +339,10 @@ public MethodBuilder CreateMethod(out string instructions)
///
/// Returns a MethodBuilder, which can be used to define overrides or for further inspection.
/// </summary>
public MethodBuilder CreateMethod()
public MethodBuilder CreateMethod(OptimizationOptions optimizationOptions = OptimizationOptions.All)
{
string ignored;
return CreateMethod(out ignored);
return CreateMethod(out ignored, optimizationOptions);
}

/// <summary>
@@ -357,7 +361,7 @@ public MethodBuilder CreateMethod()
/// the returned constructor fails validation (indicative of a bug in Sigil) or
/// behaves unexpectedly (indicative of a logic bug in the consumer code).
/// </summary>
public ConstructorBuilder CreateConstructor(out string instructions)
public ConstructorBuilder CreateConstructor(out string instructions, OptimizationOptions optimizationOptions = OptimizationOptions.All)
{
if (ConstrBuilder == null)
{
@@ -372,7 +376,7 @@ public ConstructorBuilder CreateConstructor(out string instructions)

ConstructorBuilt = true;

Seal();
Seal(optimizationOptions);

var il = ConstrBuilder.GetILGenerator();
instructions = IL.UnBuffer(il);
@@ -392,10 +396,10 @@ public ConstructorBuilder CreateConstructor(out string instructions)
///
/// Returns a ConstructorBuilder, which can be used to define overrides or for further inspection.
/// </summary>
public ConstructorBuilder CreateConstructor()
public ConstructorBuilder CreateConstructor(OptimizationOptions optimizationOptions = OptimizationOptions.All)
{
string ignored;
return CreateConstructor(out ignored);
return CreateConstructor(out ignored, optimizationOptions);
}

private static void CheckIsDelegate<CheckDelegateType>()
@@ -0,0 +1,26 @@
using System;

namespace Sigil
{
/// <summary>
/// Sigil can perform optimizations to the emitted IL. This enum tells Sigil which optimizations to perform.
/// </summary>
[Flags]
public enum OptimizationOptions
{
/// <summary>
/// Perform no optional optimizations.
/// </summary>
None = 0,

/// <summary>
/// Tells Sigil to choose optimal branch instructions.
/// </summary>
EnableBranchPatching = 1 << 0,

/// <summary>
/// Perform all optimizations.
/// </summary>
All = ~0
}
}
@@ -208,6 +208,7 @@
<Compile Include="NativeIntType.cs" />
<Compile Include="NullType.cs" />
<Compile Include="LocalLookup.cs" />
<Compile Include="OptimizationOptions.cs" />
<Compile Include="Tuple.cs" />
<Compile Include="Emit.Unbox.cs">
<DependentUpon>Emit.cs</DependentUpon>
@@ -218,6 +218,44 @@ public void ShortForm()
}
}

[TestMethod]
public void ShortFormNoOptimizations()
{
{
var hasNormalBranch = new Regex("^br ", RegexOptions.Multiline);

for (var i = 0; i < 127; i++)
{
var e1 = Emit<Action>.NewDynamicMethod("E1");
var dead = e1.DefineLabel();
var end = e1.DefineLabel("end");

e1.Branch(end);

e1.MarkLabel(dead, Type.EmptyTypes);

for (var j = 0; j < i; j++)
{
e1.Nop();
}

e1.MarkLabel(end);
e1.Return();

string instrs;
var d1 = e1.CreateDelegate(out instrs, OptimizationOptions.None);

d1();

var shouldFail = !hasNormalBranch.IsMatch(instrs);
if (shouldFail)
{
Assert.Fail();
}
}
}
}

[TestMethod]
public void BinaryInput()
{

0 comments on commit 4ccb019

Please sign in to comment.