Skip to content

Commit 3875529

Browse files
authored
[Outlining] Insert Unreachable (#7400)
When the last instruction of the outlined sequence is unreachable, we need to insert an unreachable instruction immediately after the call to the outlined function. This maintains the unreachable type in the original scope of the outlined sequence.
1 parent 5f6ba29 commit 3875529

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

src/passes/Outlining.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,27 @@ struct ReconstructStringifyWalker
219219
// call will replace the instructions moved to the outlined function.
220220
ASSERT_OK(existingBuilder.makeCall(outlinedFunc->name, false));
221221
DBG(std::cerr << "\ncreated outlined fn: " << outlinedFunc->name << "\n");
222+
223+
// If the last instruction of the outlined sequence is unreachable, insert
224+
// an unreachable instruction immediately after the call to the outlined
225+
// function. This maintains the unreachable type in the original scope
226+
// of the outlined sequence.
227+
if (sequences[seqCounter].endsTypeUnreachable) {
228+
ASSERT_OK(existingBuilder.makeUnreachable());
229+
}
222230
}
223231

224232
void transitionToInSkipSeq() {
225233
Function* outlinedFunc =
226234
getModule()->getFunction(sequences[seqCounter].func);
227235
ASSERT_OK(existingBuilder.makeCall(outlinedFunc->name, false));
236+
// If the last instruction of the outlined sequence is unreachable, insert
237+
// an unreachable instruction immediately after the call to the outlined
238+
// function. This maintains the unreachable type in the original scope
239+
// of the outlined sequence.
240+
if (sequences[seqCounter].endsTypeUnreachable) {
241+
ASSERT_OK(existingBuilder.makeUnreachable());
242+
}
228243
DBG(std::cerr << "\nstarting to skip instructions "
229244
<< sequences[seqCounter].startIdx << " - "
230245
<< sequences[seqCounter].endIdx - 1 << " to "
@@ -351,8 +366,12 @@ struct Outlining : public Pass {
351366
// sequence relative to its function is better for outlining because we
352367
// walk functions.
353368
auto [relativeIdx, existingFunc] = stringify.makeRelative(seqIdx);
354-
auto seq =
355-
OutliningSequence(relativeIdx, relativeIdx + substring.Length, func);
369+
auto seq = OutliningSequence(
370+
relativeIdx,
371+
relativeIdx + substring.Length,
372+
func,
373+
stringify.exprs[seqIdx + substring.Length - 1]->type ==
374+
Type::unreachable);
356375
seqByFunc[existingFunc].push_back(seq);
357376
}
358377
}

src/passes/stringify-walker.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,14 @@ struct OutliningSequence {
254254
unsigned startIdx;
255255
unsigned endIdx;
256256
Name func;
257-
258-
OutliningSequence(unsigned startIdx, unsigned endIdx, Name func)
259-
: startIdx(startIdx), endIdx(endIdx), func(func) {}
257+
bool endsTypeUnreachable;
258+
259+
OutliningSequence(unsigned startIdx,
260+
unsigned endIdx,
261+
Name func,
262+
bool endsTypeUnreachable)
263+
: startIdx(startIdx), endIdx(endIdx), func(func),
264+
endsTypeUnreachable(endsTypeUnreachable) {}
260265
};
261266

262267
using Substrings = std::vector<SuffixTree::RepeatedSubstring>;

test/lit/passes/outlining.wast

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,3 +1074,38 @@
10741074
drop ;; End substring 2 repeat
10751075
)
10761076
)
1077+
1078+
;; Tests unreachable type handling
1079+
(module
1080+
;; CHECK: (type $0 (func))
1081+
1082+
;; CHECK: (type $1 (func (result f32)))
1083+
1084+
;; CHECK: (type $2 (func (result i32)))
1085+
1086+
;; CHECK: (func $outline$ (type $0)
1087+
;; CHECK-NEXT: (drop
1088+
;; CHECK-NEXT: (i32.const 0)
1089+
;; CHECK-NEXT: )
1090+
;; CHECK-NEXT: (unreachable)
1091+
;; CHECK-NEXT: )
1092+
1093+
;; CHECK: (func $a (type $1) (result f32)
1094+
;; CHECK-NEXT: (call $outline$)
1095+
;; CHECK-NEXT: (unreachable)
1096+
;; CHECK-NEXT: )
1097+
(func $a (result f32)
1098+
i32.const 0
1099+
drop
1100+
unreachable
1101+
)
1102+
;; CHECK: (func $b (type $2) (result i32)
1103+
;; CHECK-NEXT: (call $outline$)
1104+
;; CHECK-NEXT: (unreachable)
1105+
;; CHECK-NEXT: )
1106+
(func $b (result i32)
1107+
i32.const 0
1108+
drop
1109+
unreachable
1110+
)
1111+
)

0 commit comments

Comments
 (0)