Skip to content

Commit d53d952

Browse files
committedAug 13, 2020
[WebAssembly] Allow inlining functions with different features
Allow inlining only when the Callee has a subset of the Caller's features. In principle, we should be able to inline regardless of any features because WebAssembly supports features at module granularity, not function granularity, but without this restriction it would be possible for a module to "forget" about features if all the functions that used them were inlined. Requested in PR46812. Differential Revision: https://reviews.llvm.org/D85494
1 parent f59bec7 commit d53d952

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed
 

‎llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,21 @@ unsigned WebAssemblyTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val,
8484

8585
return Cost;
8686
}
87+
88+
bool WebAssemblyTTIImpl::areInlineCompatible(const Function *Caller,
89+
const Function *Callee) const {
90+
// Allow inlining only when the Callee has a subset of the Caller's
91+
// features. In principle, we should be able to inline regardless of any
92+
// features because WebAssembly supports features at module granularity, not
93+
// function granularity, but without this restriction it would be possible for
94+
// a module to "forget" about features if all the functions that used them
95+
// were inlined.
96+
const TargetMachine &TM = getTLI()->getTargetMachine();
97+
98+
const FeatureBitset &CallerBits =
99+
TM.getSubtargetImpl(*Caller)->getFeatureBits();
100+
const FeatureBitset &CalleeBits =
101+
TM.getSubtargetImpl(*Callee)->getFeatureBits();
102+
103+
return (CallerBits & CalleeBits) == CalleeBits;
104+
}

‎llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.h

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ class WebAssemblyTTIImpl final : public BasicTTIImplBase<WebAssemblyTTIImpl> {
6767
unsigned getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index);
6868

6969
/// @}
70+
71+
bool areInlineCompatible(const Function *Caller,
72+
const Function *Callee) const;
7073
};
7174

7275
} // end namespace llvm
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -mtriple=wasm32-unknown-unknown -S -inline | FileCheck %s
3+
4+
; Check that having functions can be inlined into callers only when
5+
; they have a subset of the caller's features.
6+
7+
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
8+
target triple = "wasm32-unknown-unknown"
9+
10+
declare void @foo()
11+
12+
define internal void @uses_simd() #0 {
13+
; CHECK-LABEL: @uses_simd(
14+
; CHECK-NEXT: tail call void @foo()
15+
; CHECK-NEXT: ret void
16+
;
17+
tail call void @foo()
18+
ret void
19+
}
20+
21+
define void @many_features() #1 {
22+
; CHECK-LABEL: @many_features(
23+
; CHECK-NEXT: tail call void @foo()
24+
; CHECK-NEXT: ret void
25+
;
26+
tail call fastcc void @uses_simd()
27+
ret void
28+
}
29+
30+
define void @few_features() #2 {
31+
; CHECK-LABEL: @few_features(
32+
; CHECK-NEXT: tail call fastcc void @uses_simd()
33+
; CHECK-NEXT: ret void
34+
;
35+
tail call fastcc void @uses_simd()
36+
ret void
37+
}
38+
39+
attributes #0 = { "target-cpu"="mvp" "target-features"="+simd128"}
40+
attributes #1 = { "target-cpu"="bleeding-edge" "target-features"="+simd128" }
41+
attributes #2 = { "target-cpu"="mvp" "target-features"="+multivalue" }

0 commit comments

Comments
 (0)
Please sign in to comment.