-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][X86] Support __attribute__((model("small"/"large"))) #124834
Changes from all commits
7c40169
8aa6b3f
2fdf2ee
1a32c31
7ce06bd
526e8c3
6779705
2263db1
bf8f7d4
d314c8e
1729029
c664880
f3ecb7b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,16 @@ def CodeModelDocs : Documentation { | |
let Content = [{ | ||
The ``model`` attribute allows overriding the translation unit's | ||
code model (specified by ``-mcmodel``) for a specific global variable. | ||
|
||
On LoongArch, allowed values are "normal", "medium", "extreme". | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suspect aaron would like to see more details on this, including what each of those things mean. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added some description at least on the x86-64 side of things |
||
|
||
On x86-64, allowed values are ``"small"`` and ``"large"``. ``"small"`` is | ||
roughly equivalent to ``-mcmodel=small``, meaning the global is considered | ||
"small" placed closer to the ``.text`` section relative to "large" globals, and | ||
to prefer using 32-bit relocations to access the global. ``"large"`` is roughly | ||
equivalent to ``-mcmodel=large``, meaning the global is considered "large" and | ||
placed further from the ``.text`` section relative to "small" globals, and | ||
64-bit relocations must be used to access the global. | ||
}]; | ||
let Heading = "model"; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,6 +64,7 @@ | |
#include "llvm/IR/DerivedTypes.h" | ||
#include "llvm/MC/MCSectionMachO.h" | ||
#include "llvm/Support/Error.h" | ||
#include "llvm/Support/ErrorHandling.h" | ||
#include "llvm/Support/MathExtras.h" | ||
#include "llvm/Support/raw_ostream.h" | ||
#include "llvm/TargetParser/Triple.h" | ||
|
@@ -2949,15 +2950,49 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |
} | ||
} | ||
|
||
static bool isValidCodeModelAttr(llvm::Triple &Triple, StringRef Str) { | ||
if (Triple.isLoongArch()) { | ||
return Str == "normal" || Str == "medium" || Str == "extreme"; | ||
} else { | ||
assert(Triple.getArch() == llvm::Triple::x86_64 && | ||
"only loongarch/x86-64 supported"); | ||
return Str == "small" || Str == "large"; | ||
} | ||
} | ||
|
||
static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | ||
StringRef Str; | ||
SourceLocation LiteralLoc; | ||
auto IsTripleSupported = [](llvm::Triple &Triple) { | ||
return Triple.getArch() == llvm::Triple::ArchType::x86_64 || | ||
Triple.isLoongArch(); | ||
}; | ||
|
||
// Check that it is a string. | ||
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc)) | ||
return; | ||
|
||
SmallVector<llvm::Triple, 2> Triples = { | ||
S.Context.getTargetInfo().getTriple()}; | ||
if (auto *aux = S.Context.getAuxTargetInfo()) { | ||
Triples.push_back(aux->getTriple()); | ||
} else if (S.Context.getTargetInfo().getTriple().isNVPTX() || | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not actionable in this patch, but this points to the need for some kind of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i agree. |
||
S.Context.getTargetInfo().getTriple().isAMDGPU() || | ||
S.Context.getTargetInfo().getTriple().isSPIRV()) { | ||
// Ignore the attribute for pure GPU device compiles since it only applies | ||
// to host globals. | ||
return; | ||
} | ||
|
||
auto SupportedTripleIt = llvm::find_if(Triples, IsTripleSupported); | ||
if (SupportedTripleIt == Triples.end()) { | ||
Comment on lines
+2987
to
+2988
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this was done this way because we also need the |
||
S.Diag(LiteralLoc, diag::warn_unknown_attribute_ignored) << AL; | ||
return; | ||
} | ||
|
||
llvm::CodeModel::Model CM; | ||
if (!CodeModelAttr::ConvertStrToModel(Str, CM)) { | ||
if (!CodeModelAttr::ConvertStrToModel(Str, CM) || | ||
!isValidCodeModelAttr(*SupportedTripleIt, Str)) { | ||
S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str; | ||
return; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown %s -o - | FileCheck %s | ||
|
||
// CHECK: @_ZL2v1 ={{.*}} global i32 0, code_model "small" | ||
static int v1 __attribute__((model("small"))); | ||
|
||
void use1() { | ||
v1 = 1; | ||
} | ||
|
||
// CHECK: @v2 ={{.*}} global float 0.000000e+00, code_model "large" | ||
float v2 __attribute__((model("large"))); | ||
|
||
// CHECK: @_ZL2v3IiE ={{.*}} global i32 0, code_model "small" | ||
template <typename T> | ||
static T v3 __attribute__((model("small"))); | ||
|
||
void use2() { | ||
v3<int> = 1; | ||
} | ||
struct S { | ||
double d; | ||
}; | ||
|
||
typedef void (*F)(); | ||
|
||
// CHECK: @v4 ={{.*}} global ptr null, code_model "large" | ||
F v4 __attribute__((model("large"))); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,70 @@ | ||
// RUN: %clang_cc1 -triple aarch64 -verify=expected,aarch64 -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple loongarch64 -verify=expected,loongarch64 -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple mips64 -verify=expected,mips64 -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple powerpc64 -verify=expected,powerpc64 -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple riscv64 -verify=expected,riscv64 -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple x86_64 -verify=expected,x86_64 -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple aarch64 -verify=unsupported -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple loongarch64 -verify=loongarch64 -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple mips64 -verify=unsupported -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple powerpc64 -verify=unsupported -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple riscv64 -verify=unsupported -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple x86_64 -verify=x86_64 -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple nvptx64-unknown-cuda -fcuda-is-device -x cuda -verify=ignored -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple amdgcn -verify=ignored -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple r600 -verify=ignored -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -verify=ignored -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple spirv32-unknown-unknown -verify=ignored -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple spirv64-unknown-unknown -verify=ignored -fsyntax-only %s | ||
|
||
#if defined(__loongarch__) && !__has_attribute(model) | ||
// RUN: %clang_cc1 -triple x86_64 -aux-triple nvptx64 -x cuda -verify=x86_64 -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple nvptx64 -aux-triple x86_64 -x cuda -fcuda-is-device -verify=nvptx64-x86_64 -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple aarch64 -aux-triple nvptx64 -x cuda -verify=unsupported -fsyntax-only %s | ||
// RUN: %clang_cc1 -triple nvptx64 -aux-triple aarch64 -x cuda -fcuda-is-device -verify=nvptx64-unsupported -fsyntax-only %s | ||
|
||
#if (defined(__loongarch__) || defined(__x86_64__)) && !__has_attribute(model) | ||
#error "Should support model attribute" | ||
#endif | ||
|
||
int a __attribute((model("tiny"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ | ||
int a __attribute((model("tiny"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// loongarch64-error {{code model 'tiny' is not supported on this target}} \ | ||
// mips64-warning {{unknown attribute 'model' ignored}} \ | ||
// powerpc64-warning {{unknown attribute 'model' ignored}} \ | ||
// riscv64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-warning {{unknown attribute 'model' ignored}} | ||
int b __attribute((model("small"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-error {{code model 'tiny' is not supported on this target}} \ | ||
// nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// nvptx64-x86_64-error {{code model 'tiny' is not supported on this target}} | ||
int b __attribute((model("small"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// loongarch64-error {{code model 'small' is not supported on this target}} \ | ||
// mips64-warning {{unknown attribute 'model' ignored}} \ | ||
// powerpc64-warning {{unknown attribute 'model' ignored}} \ | ||
// riscv64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-warning {{unknown attribute 'model' ignored}} | ||
int c __attribute((model("normal"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ | ||
// mips64-warning {{unknown attribute 'model' ignored}} \ | ||
// powerpc64-warning {{unknown attribute 'model' ignored}} \ | ||
// riscv64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-warning {{unknown attribute 'model' ignored}} | ||
int d __attribute((model("kernel"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ | ||
// nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} | ||
int c __attribute((model("normal"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-error {{code model 'normal' is not supported on this target}} \ | ||
// nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// nvptx64-x86_64-error {{code model 'normal' is not supported on this target}} | ||
int d __attribute((model("kernel"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// loongarch64-error {{code model 'kernel' is not supported on this target}} \ | ||
// mips64-warning {{unknown attribute 'model' ignored}} \ | ||
// powerpc64-warning {{unknown attribute 'model' ignored}} \ | ||
// riscv64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-warning {{unknown attribute 'model' ignored}} | ||
int e __attribute((model("medium"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ | ||
// mips64-warning {{unknown attribute 'model' ignored}} \ | ||
// powerpc64-warning {{unknown attribute 'model' ignored}} \ | ||
// riscv64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-warning {{unknown attribute 'model' ignored}} | ||
int f __attribute((model("large"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-error {{code model 'kernel' is not supported on this target}} \ | ||
// nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// nvptx64-x86_64-error {{code model 'kernel' is not supported on this target}} | ||
int e __attribute((model("medium"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-error {{code model 'medium' is not supported on this target}} \ | ||
// nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// nvptx64-x86_64-error {{code model 'medium' is not supported on this target}} | ||
int f __attribute((model("large"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// loongarch64-error {{code model 'large' is not supported on this target}} \ | ||
// mips64-warning {{unknown attribute 'model' ignored}} \ | ||
// powerpc64-warning {{unknown attribute 'model' ignored}} \ | ||
// riscv64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-warning {{unknown attribute 'model' ignored}} | ||
int g __attribute((model("extreme"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ | ||
// mips64-warning {{unknown attribute 'model' ignored}} \ | ||
// powerpc64-warning {{unknown attribute 'model' ignored}} \ | ||
// riscv64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-warning {{unknown attribute 'model' ignored}} | ||
// nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} | ||
int g __attribute((model("extreme"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-error {{code model 'extreme' is not supported on this target}} \ | ||
// nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// nvptx64-x86_64-error {{code model 'extreme' is not supported on this target}} | ||
|
||
void __attribute((model("extreme"))) h() {} // aarch64-warning {{unknown attribute 'model' ignored}} \ | ||
void __attribute((model("extreme"))) h() {} // unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// ignored-error {{'model' attribute only applies to non-TLS global variables}} \ | ||
// loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ | ||
// mips64-warning {{unknown attribute 'model' ignored}} \ | ||
// powerpc64-warning {{unknown attribute 'model' ignored}} \ | ||
// riscv64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-warning {{unknown attribute 'model' ignored}} | ||
// x86_64-error {{'model' attribute only applies to non-TLS global variables}} \ | ||
// nvptx64-unsupported-error {{'model' attribute only applies to non-TLS global variables}} \ | ||
// nvptx64-x86_64-error {{'model' attribute only applies to non-TLS global variables}} | ||
|
||
thread_local int i __attribute((model("extreme"))); // aarch64-warning {{unknown attribute 'model' ignored}} \ | ||
// loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ | ||
// mips64-warning {{unknown attribute 'model' ignored}} \ | ||
// powerpc64-warning {{unknown attribute 'model' ignored}} \ | ||
// riscv64-warning {{unknown attribute 'model' ignored}} \ | ||
// x86_64-warning {{unknown attribute 'model' ignored}} | ||
#if !defined(__CUDA__) || !defined(__CUDA_ARCH__) | ||
// if we are compiling for non-cuda host, or host mode in a CUDA compile | ||
#if !defined(__AMDGCN__) && !defined(__R600__) && !defined(__SPIRV__) | ||
// for all non-cuda hosts, above targets don't support thread_local | ||
thread_local | ||
#endif | ||
#endif | ||
int i __attribute((model("extreme"))); // unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// loongarch64-error {{'model' attribute only applies to non-TLS global variables}} \ | ||
// x86_64-error {{'model' attribute only applies to non-TLS global variables}} \ | ||
// nvptx64-unsupported-warning {{unknown attribute 'model' ignored}} \ | ||
// nvptx64-x86_64-error {{code model 'extreme' is not supported on this target}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated AttrDocs.td.
updated description, hopefully that makes sense and the previous discussion makes sense