Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5b16f0a
Equals to 0 optimization in Boolean logic
JulieLeeMSFT Feb 17, 2021
bac5938
Limit bool optimization to Integral return type only
JulieLeeMSFT Mar 10, 2021
8d9484c
Use the updated flowList:setEdgeWeights method with the 3rd parameter
JulieLeeMSFT Mar 11, 2021
635e605
Skip bool optimization for cases that require NOT transformation
JulieLeeMSFT Mar 11, 2021
b8858fc
Skip bool optimization when the third block GT_RETURN is not CNT_INT int
JulieLeeMSFT Mar 17, 2021
afbd075
format patch
JulieLeeMSFT Mar 17, 2021
a437514
Added more bool optimization cases
JulieLeeMSFT Mar 22, 2021
3b51938
format patch
JulieLeeMSFT Mar 23, 2021
854b011
Refactored setting fold type and comparison type to fix jitstress error
JulieLeeMSFT Mar 26, 2021
f28e0d6
format patch
JulieLeeMSFT Mar 26, 2021
ef65ee3
Refactored common codes for conditional block and return block boolea…
JulieLeeMSFT Mar 27, 2021
5746b61
format patch
JulieLeeMSFT Mar 27, 2021
7740064
Unit test changed to remove EH handling and add return value checks
ewhapdx Apr 2, 2021
d0c47e8
Unit test: add back test cases for ANDing and NE cases
ewhapdx Apr 3, 2021
f0adde5
Made OptBoolsDsc struct to pass it off to the helper methods.
ewhapdx Apr 23, 2021
29dc719
format patch
ewhapdx Apr 23, 2021
d02d18e
Changed to substructure OptTestInfo within OptBoolsDisc
JulieLeeMSFT Jun 19, 2021
ebf2010
Cleaned up tree variables in OptBoolsDsc struct
JulieLeeMSFT Jun 21, 2021
a7cdf1c
Moved some methods for Boolean Optimization to OptBoolsDsc struct
JulieLeeMSFT Jun 24, 2021
e3a6520
Moved all private methods for Boolean Optimization to OptBoolsDsc struct
JulieLeeMSFT Jun 24, 2021
5f02965
Boolean Optimization: Handled code review feedback
JulieLeeMSFT Jul 2, 2021
d14053e
Optimize bools: hoisted jump destination check to optOptimizeBools() …
JulieLeeMSFT Jul 9, 2021
12c7a8a
format patch
JulieLeeMSFT Jul 9, 2021
0e96608
Moved initialization to OptBoolsDsc constructor
JulieLeeMSFT Jul 13, 2021
1cdcdb8
format patch
JulieLeeMSFT Jul 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Optimize bools: hoisted jump destination check to optOptimizeBools() …
…and added test cases
  • Loading branch information
JulieLeeMSFT committed Jul 9, 2021
commit d14053e4f093d5ea85312f59ee3c9a5783fd7434
1 change: 0 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ class Instrumentor; // defined in fgprofile.cpp
class SpanningTreeVisitor; // defined in fgprofile.cpp
class CSE_DataFlow; // defined in OptCSE.cpp
class OptBoolsDsc; // defined in optimizer.cpp
struct OptTestInfo;
#ifdef DEBUG
struct IndentStack;
#endif
Expand Down
86 changes: 37 additions & 49 deletions src/coreclr/jit/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7701,7 +7701,37 @@ bool OptBoolsDsc::optOptimizeBoolsCondBlock()
// Check if m_b1 and m_b2 jump to the same target and get back pointers to m_testInfo1 and t2 tree nodes

m_t3 = nullptr;
m_sameTarget = false; // Do m_b1 and m_b2 have the same bbJumpDest?

// Check if m_b1 and m_b2 have the same bbJumpDest

if (m_b1->bbJumpDest == m_b2->bbJumpDest)
{
// Given the following sequence of blocks :
// B1: brtrue(t1, BX)
// B2: brtrue(t2, BX)
// B3:
// we will try to fold it to :
// B1: brtrue(t1|t2, BX)
// B3:

m_sameTarget = true;
}
else if (m_b1->bbJumpDest == m_b2->bbNext)
{
// Given the following sequence of blocks :
// B1: brtrue(t1, B3)
// B2: brtrue(t2, BX)
// B3:
// we will try to fold it to :
// B1: brtrue((!t1)&&t2, BX)
// B3:

m_sameTarget = false;
}
else
{
return false;
}

Statement* const s1 = optOptimizeBoolsChkBlkCond();
if (s1 == nullptr)
Expand Down Expand Up @@ -7852,54 +7882,6 @@ Statement* OptBoolsDsc::optOptimizeBoolsChkBlkCond()
optReturnBlock = true;
}

// Check jump destination condition

if (!optReturnBlock)
{
if (m_b1->bbJumpDest == m_b2->bbJumpDest)
{
// Given the following sequence of blocks :
// B1: brtrue(t1, BX)
// B2: brtrue(t2, BX)
// B3:
// we will try to fold it to :
// B1: brtrue(t1|t2, BX)
// B3:

m_sameTarget = true;
}
else if (m_b1->bbJumpDest == m_b2->bbNext)
{
// Given the following sequence of blocks :
// B1: brtrue(t1, B3)
// B2: brtrue(t2, BX)
// B3:
// we will try to fold it to :
// B1: brtrue((!t1)&&t2, BX)
// B3:

m_sameTarget = false;
}
else
{
return nullptr;
}
}
else
{
// Does m_b1 jump to m_b3?
// One example: Given the following sequence of blocks :
// B1: brtrue(!t1, B3)
// B2: return(t2)
// B3: return(false)
// we will try to fold it to :
// B1: return(t1|t2)
if (m_b1->bbJumpDest != m_b3)
{
return nullptr;
}
}

// Find the block conditions of m_b1 and m_b2

if (m_b2->countOfInEdges() > 1 || (optReturnBlock && m_b3->countOfInEdges() > 1))
Expand Down Expand Up @@ -8582,12 +8564,18 @@ void Compiler::optOptimizeBools()

if (b2->bbJumpKind == BBJ_COND)
{
if ((b1->bbJumpDest != b2->bbJumpDest) && (b1->bbJumpDest != b2->bbNext))
{
continue;
}

// When it is conditional jumps
OptBoolsDsc optBoolsDsc;
optBoolsDsc.m_b1 = b1;
optBoolsDsc.m_b2 = b2;
optBoolsDsc.m_b3 = nullptr;
optBoolsDsc.m_comp = this;

if (optBoolsDsc.optOptimizeBoolsCondBlock())
{
change = true;
Expand Down
71 changes: 61 additions & 10 deletions src/tests/JIT/opt/OptimizeBools/optboolsreturn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,25 @@ public static int Main()

if (!AreZero(0, 0))
{
Console.WriteLine("CBoolTest:AreZero failed");
Console.WriteLine("CBoolTest:AreZero(0, 0) failed");
return 101;
}

if (AreZero(1, 1))
{
Console.WriteLine("CBoolTest:AreZero(1, 1) failed");
return 101;
}

if (AreZero(0, 2))
{
Console.WriteLine("CBoolTest:AreZero(0, 2) failed");
return 101;
}

if (AreZero(3, 0))
{
Console.WriteLine("CBoolTest:AreZero(3, 0) failed");
return 101;
}

Expand All @@ -79,27 +97,39 @@ public static int Main()
return 101;
}

if (AreZero(1, 1))
if (!AreZero2(0, 0))
{
Console.WriteLine("CBoolTest:AreZero(1, 1) failed");
Console.WriteLine("CBoolTest:AreZero2(0, 0) failed");
return 101;
}

if (!AreZero2(0, 0))
if (AreZero2(2, 1))
{
Console.WriteLine("CBoolTest:AreZero2 failed");
Console.WriteLine("CBoolTest:AreZero2(2, 1) failed");
return 101;
}

if (!AreZero3(0, 0, 0))
{
Console.WriteLine("CBoolTest:AreZero3 failed");
Console.WriteLine("CBoolTest:AreZero3(0, 0, 0) failed");
return 101;
}

if (AreZero3(0, 1, 2))
{
Console.WriteLine("CBoolTest:AreZero3(0, 1, 2) failed");
return 101;
}

if (!AreZero4(0, 0, 0, 0))
{
Console.WriteLine("CBoolTest:AreZero4 failed");
Console.WriteLine("CBoolTest:AreZero4(0, 0, 0, 0) failed");
return 101;
}

if (AreZero4(0, 1, 2, 3))
{
Console.WriteLine("CBoolTest:AreZero4(0, 1, 2, 3) failed");
return 101;
}

Expand All @@ -108,21 +138,42 @@ public static int Main()
// Test if ANDing or GT_NE requires both operands to be boolean
if (!AreOne(1, 1))
{
Console.WriteLine("CBoolTest:AreOne failed");
Console.WriteLine("CBoolTest:AreOne(1, 1) failed");
return 101;
}

// Skip cases where x or y is greather than 1
if (AreOne(3, 1))
{
Console.WriteLine("CBoolTest:AreOne(1, 3) failed");
return 101;
}

// Test if ANDing requires both operands to be boolean
if (!IsEitherZero(0, 1))
{
Console.WriteLine("CBoolTest:IsEitherZero failed");
Console.WriteLine("CBoolTest:IsEitherZero(0, 1) failed");
return 101;
}

// Skip cases where x and y have opposite bits set
if (IsEitherZero(2, 1))
{
Console.WriteLine("CBoolTest:IsEitherZero(2, 1) failed");
return 101;
}

// Test if GT_NE requires both operands to be boolean
if (!IsEitherOne(0, 1))
{
Console.WriteLine("CBoolTest:IsEitherOne failed");
Console.WriteLine("CBoolTest:IsEitherOne(0, 1) failed");
return 101;
}

// Skip cases where either x or y is greater than 1
if (IsEitherOne(2, 0))
{
Console.WriteLine("CBoolTest:IsEitherOne(2, 0) failed");
return 101;
}

Expand Down