-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add explicit successor edges to finally handler exits
This fixes the regalloc problem described in #33. One downside of this approach is that it will require all ResumeInsts to be in sync with region exit targets, but there are currently no passes messing with those.
- Loading branch information
1 parent
271f7f3
commit 0210f69
Showing
13 changed files
with
213 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
namespace DistIL.PracticeTests; | ||
|
||
using DistIL.Attributes; | ||
|
||
[Optimize] | ||
public class EhRegionTests | ||
{ | ||
[Theory, InlineData(0), InlineData(1)] | ||
[CheckCodeGenAfterRun] | ||
public void MultiExit_Finally1(int path) | ||
{ | ||
int x = path; | ||
|
||
try { | ||
try { | ||
Utils.DoNotOptimize(x); // fake side effect | ||
|
||
if (x > 0) { | ||
goto Target1; | ||
} else { | ||
goto Target2; | ||
} | ||
} finally { | ||
x += 10; | ||
} | ||
Target1: | ||
x += 5; | ||
Target2: | ||
x += 2; | ||
} finally { | ||
Assert.Equal(path == 0 ? 12 : 18, x); | ||
} | ||
|
||
// CHECK: try finally | ||
// CHECK: leave [[target1:.*]] | ||
// CHECK: leave [[target2:.*]] | ||
// CHECK: resume [[target1]], [[target2]] | ||
} | ||
|
||
[Fact] | ||
public void CrossingVars_Catch1() | ||
{ | ||
int x = 1; | ||
string str = "1;0"; | ||
|
||
try { | ||
int y = int.Parse(str.Split(';')[1]); | ||
x = 2; | ||
x = 100 / y; | ||
} catch (DivideByZeroException) { | ||
Assert.Equal(2, x); | ||
x = 400; | ||
} | ||
Assert.Equal(400, x); | ||
} | ||
|
||
[Fact] | ||
public void CrossingVars_Finally1() | ||
{ | ||
int x = 1; | ||
string str = "123"; | ||
|
||
try { | ||
x = int.Parse(str) * 1000; | ||
} finally { | ||
x *= 2; | ||
} | ||
Assert.Equal(123 * 1000 * 2, x); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,11 @@ | ||
global using Xunit; | ||
global using Xunit; | ||
|
||
using System.Runtime.CompilerServices; | ||
|
||
using DistIL.Attributes; | ||
|
||
public static class Utils | ||
{ | ||
[DoNotOptimize, MethodImpl(MethodImplOptions.NoInlining)] | ||
public static T DoNotOptimize<T>(T value) => value; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
namespace DistIL.PracticeTests; | ||
|
||
using DistIL.Attributes; | ||
|
||
[Optimize] | ||
public class RegAllocTests | ||
{ | ||
[Fact] | ||
public void LiveReg_Loop_Finally() | ||
{ | ||
long a = 0, b = 0, c = 0; | ||
|
||
for (int i = 0; i < 100 && c < 100; i++, c++) { | ||
try { | ||
a += i; | ||
} finally { | ||
int tmp = (int)(a % 5); // buggy regalloc will reuse `i` | ||
if (tmp == 1 || tmp == 3) { | ||
b += a; | ||
} | ||
} | ||
} | ||
Assert.Equal(4950, a); | ||
Assert.Equal(99950, b); | ||
} | ||
} |