Skip to content

Commit f0da7b6

Browse files
committed
Mult optimization in MemOp bug fix
1 parent f1a2cdc commit f0da7b6

File tree

5 files changed

+135
-9
lines changed

5 files changed

+135
-9
lines changed

lib/Backend/BackwardPass.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8848,19 +8848,22 @@ BackwardPass::RestoreInductionVariableValuesAfterMemOp(Loop *loop)
88488848

88498849
IR::Opnd *inductionVariableOpnd = IR::RegOpnd::New(sym, IRType::TyInt32, localFunc);
88508850
IR::Opnd *tempInductionVariableOpnd = IR::RegOpnd::New(IRType::TyInt32, localFunc);
8851-
IR::Opnd *sizeOpnd = globOpt->GenerateInductionVariableChangeForMemOp(loop, inductionVariableChangeInfo.unroll);
88528851

88538852
// The induction variable is restored to a temp register before the MemOp occurs. Once the MemOp is
88548853
// complete, the induction variable's register is set to the value of the temp register. This is done
88558854
// in order to avoid overwriting the induction variable's value after a bailout on the MemOp.
8856-
IR::Instr* restoreInductionVarToTemp = IR::Instr::New(opCode, tempInductionVariableOpnd, inductionVariableOpnd, sizeOpnd, loop->GetFunc());
8857-
IR::Instr* restoreInductionVar = IR::Instr::New(Js::OpCode::Ld_A, inductionVariableOpnd, tempInductionVariableOpnd, loop->GetFunc());
8855+
IR::Instr* restoreInductionVarToTemp = IR::Instr::New(opCode, tempInductionVariableOpnd, inductionVariableOpnd, loop->GetFunc());
88588856

88598857
// The IR that restores the induction variable's value is placed before the MemOp. Since this IR can
88608858
// bailout to the loop's landing pad, placing this IR before the MemOp avoids performing the MemOp,
88618859
// bailing out because of this IR, and then performing the effects of the loop again.
88628860
loop->landingPad->InsertInstrBefore(restoreInductionVarToTemp, loop->memOpInfo->instr);
88638861

8862+
// The amount to be added or subtraced (depends on opCode) to the induction vairable after the MemOp.
8863+
IR::Opnd *sizeOpnd = globOpt->GenerateInductionVariableChangeForMemOp(loop, inductionVariableChangeInfo.unroll, restoreInductionVarToTemp);
8864+
restoreInductionVarToTemp->SetSrc2(sizeOpnd);
8865+
IR::Instr* restoreInductionVar = IR::Instr::New(Js::OpCode::Ld_A, inductionVariableOpnd, tempInductionVariableOpnd, loop->GetFunc());
8866+
88648867
// If restoring an induction variable results in an overflow, bailout to the loop's landing pad.
88658868
restoreInductionVarToTemp->ConvertToBailOutInstr(loop->bailOutInfo, IR::BailOutOnOverflow);
88668869

lib/Backend/GlobOpt.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,7 +2230,13 @@ GlobOpt::CollectMemOpInfo(IR::Instr *instrBegin, IR::Instr *instr, Value *src1Va
22302230
{
22312231
Loop::InductionVariableChangeInfo inductionVariableChangeInfo = { 0, 0 };
22322232
inductionVariableChangeInfo = loop->memOpInfo->inductionVariableChangeInfoMap->Lookup(inductionSymID, inductionVariableChangeInfo);
2233-
inductionVariableChangeInfo.unroll++;
2233+
2234+
// If inductionVariableChangeInfo.unroll has been invalidated, do
2235+
// not modify the Js::Constants::InvalidLoopUnrollFactor value
2236+
if (inductionVariableChangeInfo.unroll != Js::Constants::InvalidLoopUnrollFactor)
2237+
{
2238+
inductionVariableChangeInfo.unroll++;
2239+
}
22342240
inductionVariableChangeInfo.isIncremental = isIncr;
22352241
loop->memOpInfo->inductionVariableChangeInfoMap->Item(inductionSymID, inductionVariableChangeInfo);
22362242
}
@@ -16855,12 +16861,12 @@ GlobOpt::GenerateInductionVariableChangeForMemOp(Loop *loop, byte unroll, IR::In
1685516861

1685616862
IR::Opnd *unrollOpnd = IR::IntConstOpnd::New(unroll, type, localFunc);
1685716863

16858-
InsertInstr(IR::Instr::New(Js::OpCode::Mul_I4,
16859-
sizeOpnd,
16860-
loopCountOpnd,
16861-
unrollOpnd,
16862-
localFunc));
16864+
IR::Instr *inductionChangeMultiplier = IR::Instr::New(
16865+
Js::OpCode::Mul_I4, sizeOpnd, loopCountOpnd, unrollOpnd, localFunc);
16866+
16867+
InsertInstr(inductionChangeMultiplier);
1686316868

16869+
inductionChangeMultiplier->ConvertToBailOutInstr(loop->bailOutInfo, IR::BailOutOnOverflow);
1686416870
}
1686516871
}
1686616872
else

test/loop/MemOp.baseline

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
200
2+
2147483649
3+
30
4+
300
5+
2147483650
6+
40
7+
0
8+
2147483647
9+
10
10+
0
11+
2147483647
12+
10
13+
0
14+
2147483647
15+
10
16+
100
17+
2147483648
18+
20

test/loop/MemOp.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
function f0(a, start, end) {
7+
for (var i = start, j = start; i < end; i++, j++) {
8+
j = j + 1
9+
a[i] = 1
10+
}
11+
a[j]
12+
print(j)
13+
14+
}
15+
16+
function f1(a, start, end) {
17+
for (var i = start, j = start; i < end; i++, j++) {
18+
j = j + 2
19+
a[i] = 1
20+
}
21+
a[j]
22+
print(j)
23+
24+
}
25+
26+
function f2(a, start, end) {
27+
for (var i = start, j = start; i >= end; i--, j--) {
28+
j = j - 1
29+
a[i] = 1
30+
}
31+
a[j]
32+
print(j)
33+
}
34+
35+
function f3(a, start, end) {
36+
for (var i = start, j = start; i >= end; i--, j--) {
37+
j = j - 2
38+
a[i] = 1
39+
}
40+
a[j]
41+
print(j)
42+
}
43+
44+
function f4(a, start, end) {
45+
for (var i = start, j = start; i < end; i++, j--) {
46+
j = j + 1
47+
a[i] = 1
48+
}
49+
a[j]
50+
print(j)
51+
}
52+
53+
function f5(a, start, end) {
54+
for (var i = start, j = start; i < end; i++, j--) {
55+
j = j + 2
56+
a[i] = 1
57+
}
58+
a[j]
59+
print(j)
60+
}
61+
62+
var a = new Float64Array(0xfff);
63+
f0(a, 0, 100)
64+
f0(a, 0x7fffffff, 0x80000000)
65+
f0(a, 10, 20)
66+
67+
f1(a, 0, 100)
68+
f1(a, 0x7fffffff, 0x80000000)
69+
f1(a, 10, 20)
70+
71+
f2(a, 0, 100)
72+
f2(a, 0x7fffffff, 0x80000000)
73+
f2(a, 10, 20)
74+
75+
f3(a, 0, 100)
76+
f3(a, 0x7fffffff, 0x80000000)
77+
f3(a, 10, 20)
78+
79+
f4(a, 0, 100)
80+
f4(a, 0x7fffffff, 0x80000000)
81+
f4(a, 10, 20)
82+
83+
f5(a, 0, 100)
84+
f5(a, 0x7fffffff, 0x80000000)
85+
f5(a, 10, 20)

test/loop/rlexe.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,18 @@
4646
<files>infinite.js</files>
4747
</default>
4848
</test>
49+
<test>
50+
<default>
51+
<files>MemOp.js</files>
52+
<compile-flags>-off:simplejit -mic:1 -bgjit-</compile-flags>
53+
<baseline>MemOp.baseline</baseline>
54+
</default>
55+
</test>
56+
<test>
57+
<default>
58+
<files>MemOp.js</files>
59+
<compile-flags></compile-flags>
60+
<baseline>MemOp.baseline</baseline>
61+
</default>
62+
</test>
4963
</regress-exe>

0 commit comments

Comments
 (0)