Skip to content

Commit 26b9025

Browse files
committed
Add must tail support
1 parent f9c22f8 commit 26b9025

File tree

8 files changed

+25
-6
lines changed

8 files changed

+25
-6
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
483483
def TargetSPIRV : TargetArch<["spirv", "spirv32", "spirv64"]>;
484484
def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>;
485485
def TargetNVPTX : TargetArch<["nvptx", "nvptx64"]>;
486+
def TargetPowerPC : TargetArch<["ppc", "ppcle", "ppc64", "ppc64le"]>;
486487
def TargetWindows : TargetSpec {
487488
let OSes = ["Win32"];
488489
}
@@ -508,6 +509,10 @@ def TargetMicrosoftRecordLayout : TargetArch<["x86", "x86_64", "arm", "thumb",
508509
let CustomCode = [{ Target.hasMicrosoftRecordLayout() }];
509510
}
510511

512+
def TargetMustTailAvaiable: TargetArch<!listconcat(TargetARM.Arches, TargetAArch64.Arches, TargetAnyX86.Arches, TargetWebAssembly.Arches, TargetPowerPC.Arches)> {
513+
let CustomCode = [{ Target.hasMustTail() }];
514+
}
515+
511516
def TargetELF : TargetSpec {
512517
let ObjectFormats = ["ELF"];
513518
}
@@ -1896,7 +1901,7 @@ def NoMerge : DeclOrStmtAttr {
18961901
"functions, statements and variables">;
18971902
}
18981903

1899-
def MustTail : StmtAttr {
1904+
def MustTail : StmtAttr, TargetSpecificAttr<TargetMustTailAvaiable> {
19001905
let Spellings = [Clang<"musttail">];
19011906
let Documentation = [MustTailDocs];
19021907
let Subjects = SubjectList<[ReturnStmt], ErrorDiag, "return statements">;

clang/include/clang/Basic/DiagnosticCommonKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ def err_ppc_impossible_musttail: Error<
374374
>;
375375
def err_aix_musttail_unsupported: Error<
376376
"'musttail' attribute is not supported on AIX">;
377+
def err_wasm_musttail_unsupported: Error<
378+
"'musttail' attribute is not supported on this target without tail-call feature">;
377379

378380
// Source manager
379381
def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;

clang/include/clang/Basic/TargetInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ class TargetInfo : public TransferrableTargetInfo,
229229
protected:
230230
// Target values set by the ctor of the actual target implementation. Default
231231
// values are specified by the TargetInfo constructor.
232+
bool HasMustTail;
232233
bool BigEndian;
233234
bool TLSSupported;
234235
bool VLASupported;
@@ -669,6 +670,8 @@ class TargetInfo : public TransferrableTargetInfo,
669670
: getLongFractScale() + 1;
670671
}
671672

673+
virtual bool hasMustTail() const { return HasMustTail; }
674+
672675
/// Determine whether the __int128 type is supported on this target.
673676
virtual bool hasInt128Type() const {
674677
return (getPointerWidth(LangAS::Default) >= 64) ||

clang/lib/Basic/TargetInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static const LangASMap FakeAddrSpaceMap = {
5959
TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
6060
// Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or
6161
// SPARC. These should be overridden by concrete targets as needed.
62+
HasMustTail = true;
6263
BigEndian = !T.isLittleEndian();
6364
TLSSupported = true;
6465
VLASupported = true;

clang/lib/Basic/Targets/WebAssembly.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ bool WebAssemblyTargetInfo::initFeatureMap(
213213

214214
bool WebAssemblyTargetInfo::handleTargetFeatures(
215215
std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
216+
HasMustTail = false;
216217
for (const auto &Feature : Features) {
217218
if (Feature == "+atomics") {
218219
HasAtomics = true;
@@ -345,10 +346,12 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
345346
}
346347
if (Feature == "+tail-call") {
347348
HasTailCall = true;
349+
HasMustTail = true;
348350
continue;
349351
}
350352
if (Feature == "-tail-call") {
351353
HasTailCall = false;
354+
HasMustTail = false;
352355
continue;
353356
}
354357
if (Feature == "+wide-arithmetic") {

clang/lib/Sema/SemaStmt.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,6 @@ bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) {
695695

696696
const Expr *E = cast<ReturnStmt>(St)->getRetValue();
697697
const auto *CE = dyn_cast_or_null<CallExpr>(IgnoreParenImplicitAsWritten(E));
698-
699698
if (!CE) {
700699
Diag(St->getBeginLoc(), diag::err_musttail_needs_call) << &MTA;
701700
return false;

clang/lib/Sema/SemaStmtAttr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,12 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
672672
!(A.existsInTarget(S.Context.getTargetInfo()) ||
673673
(S.Context.getLangOpts().SYCLIsDevice && Aux &&
674674
A.existsInTarget(*Aux)))) {
675+
// Special case: musttail on WebAssembly without tail-call feature
676+
if (A.getKind() == ParsedAttr::AT_MustTail &&
677+
!S.Context.getTargetInfo().hasMustTail()) {
678+
S.Diag(A.getLoc(), diag::err_wasm_musttail_unsupported);
679+
return nullptr;
680+
}
675681
if (A.isRegularKeywordAttribute()) {
676682
S.Diag(A.getLoc(), diag::err_keyword_not_supported_on_target)
677683
<< A << A.getRange();
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -target-feature +tail-call -o /dev/null -emit-llvm -verify=good
2-
// RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -target-feature +tail-call -o /dev/null -emit-llvm -verify=good
1+
// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -target-feature +tail-call -o /dev/null -emit-llvm -verify=tail
32
// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -o /dev/null -emit-llvm -verify=notail
43

54
int foo(int x) {
65
return x;
76
}
87

98
#if __has_attribute(musttail)
10-
// good-warning@+2 {{HAS IT}}
11-
// notail-warning@+1 {{HAS IT}}
9+
// tail-warning@+1 {{HAS IT}}
1210
#warning HAS IT
1311
#else
12+
// notail-warning@+1 {{DOES NOT HAVE}}
1413
#warning DOES NOT HAVE
1514
#endif
1615

1716
int bar(int x)
1817
{
18+
// notail-error@+1 {{'musttail' attribute is not supported on this target without tail-call feature}}
1919
[[clang::musttail]] return foo(1);
2020
}

0 commit comments

Comments
 (0)