Skip to content

Commit 94581f0

Browse files
committed
fix #1138
1 parent 44568f9 commit 94581f0

16 files changed

+276
-128
lines changed

src/compiler.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2175,6 +2175,20 @@ export class Compiler extends DiagnosticEmitter {
21752175
}
21762176
this.performAutoreleases(condFlow, bodyStmts);
21772177
flow.inherit(bodyFlow);
2178+
2179+
// Terminate if condition is always true and body never breaks
2180+
} else if (condKind == ConditionKind.TRUE && !bodyFlow.isAny(FlowFlags.BREAKS | FlowFlags.CONDITIONALLY_BREAKS)) {
2181+
if (hasSideEffects(condExpr)) {
2182+
bodyStmts.push(
2183+
module.drop(condExpr)
2184+
);
2185+
}
2186+
this.performAutoreleases(condFlow, bodyStmts);
2187+
bodyStmts.push(
2188+
module.br(continueLabel)
2189+
);
2190+
flow.set(FlowFlags.TERMINATES);
2191+
21782192
} else {
21792193
let tcond = condFlow.getTempLocal(Type.bool);
21802194
bodyStmts.push(
@@ -3082,13 +3096,22 @@ export class Compiler extends DiagnosticEmitter {
30823096
bodyStmts.push(this.compileStatement(body));
30833097
}
30843098

3085-
// Check if body terminates
3099+
// Simplify if body always terminates
30863100
if (bodyFlow.is(FlowFlags.TERMINATES)) {
30873101
bodyStmts.push(
30883102
module.unreachable()
30893103
);
30903104
if (condKind == ConditionKind.TRUE) flow.inherit(bodyFlow);
30913105
else flow.inheritBranch(bodyFlow);
3106+
3107+
// Terminate if condition is always true and body never breaks
3108+
} else if (condKind == ConditionKind.TRUE && !bodyFlow.isAny(FlowFlags.BREAKS | FlowFlags.CONDITIONALLY_BREAKS)) {
3109+
this.performAutoreleases(bodyFlow, bodyStmts);
3110+
bodyStmts.push(
3111+
module.br(continueLabel)
3112+
);
3113+
flow.set(FlowFlags.TERMINATES);
3114+
30923115
} else {
30933116
let breaks = bodyFlow.is(FlowFlags.BREAKS);
30943117
if (breaks) {

src/program.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,7 +2193,6 @@ export abstract class Element {
21932193
current = current.parent;
21942194
if (current.kind == ElementKind.FILE) return <File>current;
21952195
} while (true);
2196-
return <File>unreachable();
21972196
}
21982197

21992198
/** Tests if this element has a specific flag or flags. */
@@ -2215,7 +2214,7 @@ export abstract class Element {
22152214
}
22162215

22172216
/** Looks up the element with the specified name relative to this element, like in JS. */
2218-
/* abstract */ lookup(name: string): Element | null { return <Element | null>unreachable(); }
2217+
/* abstract */ lookup(name: string): Element | null { return unreachable(); }
22192218

22202219
/** Adds an element as a member of this one. Reports and returns `false` if a duplicate. */
22212220
add(name: string, element: DeclaredElement, localIdentifierIfImport: IdentifierExpression | null = null): bool {

std/assembly/util/number.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ function genDigits(buffer: usize, w_frc: u64, w_exp: i32, mp_frc: u64, mp_exp: i
499499
}
500500
}
501501

502-
while (1) {
502+
while (true) {
503503
p2 *= 10;
504504
delta *= 10;
505505

@@ -515,8 +515,6 @@ function genDigits(buffer: usize, w_frc: u64, w_exp: i32, mp_frc: u64, mp_exp: i
515515
return len;
516516
}
517517
}
518-
519-
return len;
520518
}
521519

522520
// @ts-ignore: decorator

tests/compiler/do.optimized.wat

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@
214214
if
215215
i32.const 0
216216
i32.const 32
217-
i32.const 107
217+
i32.const 116
218218
i32.const 2
219219
call $~lib/builtins/abort
220220
unreachable
@@ -251,7 +251,7 @@
251251
if
252252
i32.const 0
253253
i32.const 32
254-
i32.const 125
254+
i32.const 134
255255
i32.const 2
256256
call $~lib/builtins/abort
257257
unreachable
@@ -262,7 +262,7 @@
262262
if
263263
i32.const 0
264264
i32.const 32
265-
i32.const 126
265+
i32.const 135
266266
i32.const 2
267267
call $~lib/builtins/abort
268268
unreachable
@@ -1265,7 +1265,7 @@
12651265
if
12661266
i32.const 0
12671267
i32.const 32
1268-
i32.const 141
1268+
i32.const 150
12691269
i32.const 2
12701270
call $~lib/builtins/abort
12711271
unreachable
@@ -1274,7 +1274,7 @@
12741274
if
12751275
i32.const 0
12761276
i32.const 32
1277-
i32.const 142
1277+
i32.const 151
12781278
i32.const 2
12791279
call $~lib/builtins/abort
12801280
unreachable
@@ -1323,7 +1323,7 @@
13231323
if
13241324
i32.const 0
13251325
i32.const 32
1326-
i32.const 161
1326+
i32.const 170
13271327
i32.const 2
13281328
call $~lib/builtins/abort
13291329
unreachable
@@ -1332,7 +1332,7 @@
13321332
if
13331333
i32.const 0
13341334
i32.const 32
1335-
i32.const 162
1335+
i32.const 171
13361336
i32.const 2
13371337
call $~lib/builtins/abort
13381338
unreachable
@@ -1343,6 +1343,7 @@
13431343
call $~lib/rt/pure/__release
13441344
)
13451345
(func $start:do (; 24 ;)
1346+
(local $0 i32)
13461347
i32.const 0
13471348
global.set $do/ran
13481349
call $do/testSimple
@@ -1395,6 +1396,26 @@
13951396
call $~lib/builtins/abort
13961397
unreachable
13971398
end
1399+
loop $do-continue|0
1400+
local.get $0
1401+
i32.const 1
1402+
i32.add
1403+
local.tee $0
1404+
i32.const 10
1405+
i32.ne
1406+
br_if $do-continue|0
1407+
end
1408+
local.get $0
1409+
i32.const 10
1410+
i32.ne
1411+
if
1412+
i32.const 0
1413+
i32.const 32
1414+
i32.const 70
1415+
i32.const 0
1416+
call $~lib/builtins/abort
1417+
unreachable
1418+
end
13981419
i32.const 0
13991420
global.set $do/ran
14001421
i32.const 1
@@ -1415,7 +1436,7 @@
14151436
if
14161437
i32.const 0
14171438
i32.const 32
1418-
i32.const 112
1439+
i32.const 121
14191440
i32.const 0
14201441
call $~lib/builtins/abort
14211442
unreachable
@@ -1428,7 +1449,7 @@
14281449
if
14291450
i32.const 0
14301451
i32.const 32
1431-
i32.const 131
1452+
i32.const 140
14321453
i32.const 0
14331454
call $~lib/builtins/abort
14341455
unreachable
@@ -1441,7 +1462,7 @@
14411462
if
14421463
i32.const 0
14431464
i32.const 32
1444-
i32.const 147
1465+
i32.const 156
14451466
i32.const 0
14461467
call $~lib/builtins/abort
14471468
unreachable
@@ -1454,7 +1475,7 @@
14541475
if
14551476
i32.const 0
14561477
i32.const 32
1457-
i32.const 167
1478+
i32.const 176
14581479
i32.const 0
14591480
call $~lib/builtins/abort
14601481
unreachable

tests/compiler/do.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ ran = false;
6060
testAlwaysTrue();
6161
assert(ran);
6262

63+
function testAlwaysTrueNeverBreaks(): i32 {
64+
var i = 0;
65+
do {
66+
if (++i == 10) return i;
67+
} while (true);
68+
// no return required
69+
}
70+
assert(testAlwaysTrueNeverBreaks() == 10);
71+
6372
function testAlwaysFalse(): void {
6473
var i = 0;
6574
do {

0 commit comments

Comments
 (0)