Introduce code_model macros

Summary:
gcc defines macros such as __code_model_small_ based on the user passed command line flag -mcmodel. clang accepts a flag with the same name and similar effects, but does not generate any macro that the user can use. This cl narrows the gap between gcc and clang behaviour.

However, achieving full compatibility with gcc is not trivial: The set of valid values for mcmodel in gcc and clang are not equal. Also, gcc defines different macros for different architectures. In this cl, we only tackle an easy part of the problem and define the macro only for x64 architecture. When the user does not specify a mcmodel, the macro for small code model is produced, as is the case with gcc.

Reviewers: compnerd, MaskRay

Reviewed By: MaskRay

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D52920

llvm-svn: 344000
This commit is contained in:
Ali Tamur 2018-10-08 22:25:20 +00:00
parent e2877ad3b9
commit bc1cd929bf
4 changed files with 35 additions and 19 deletions

View File

@ -67,6 +67,12 @@ public:
/// \brief If enabled, use 32-bit pointers for accessing const/local/shared /// \brief If enabled, use 32-bit pointers for accessing const/local/shared
/// address space. /// address space.
bool NVPTXUseShortPointers = false; bool NVPTXUseShortPointers = false;
// The code model to be used as specified by the user. Corresponds to
// CodeModel::Model enum defined in include/llvm/Support/CodeGen.h, plus
// "default" for the case when the user has not explicitly specified a
// code model.
std::string CodeModel;
}; };
} // end namespace clang } // end namespace clang

View File

@ -860,6 +860,11 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
/// definitions for this particular subtarget. /// definitions for this particular subtarget.
void X86TargetInfo::getTargetDefines(const LangOptions &Opts, void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const { MacroBuilder &Builder) const {
std::string CodeModel = getTargetOpts().CodeModel;
if (CodeModel == "default")
CodeModel = "small";
Builder.defineMacro("__code_model_" + CodeModel + "_");
// Target identification. // Target identification.
if (getTriple().getArch() == llvm::Triple::x86_64) { if (getTriple().getArch() == llvm::Triple::x86_64) {
Builder.defineMacro("__amd64__"); Builder.defineMacro("__amd64__");

View File

@ -669,7 +669,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.RegisterGlobalDtorsWithAtExit = Opts.RegisterGlobalDtorsWithAtExit =
Args.hasArg(OPT_fregister_global_dtors_with_atexit); Args.hasArg(OPT_fregister_global_dtors_with_atexit);
Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
Opts.CodeModel = getCodeModel(Args, Diags); Opts.CodeModel = TargetOpts.CodeModel;
Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass);
Opts.DisableFPElim = Opts.DisableFPElim =
(Args.hasArg(OPT_mdisable_fp_elim) || Args.hasArg(OPT_pg)); (Args.hasArg(OPT_mdisable_fp_elim) || Args.hasArg(OPT_pg));
@ -2975,6 +2975,7 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) { DiagnosticsEngine &Diags) {
Opts.CodeModel = getCodeModel(Args, Diags);
Opts.ABI = Args.getLastArgValue(OPT_target_abi); Opts.ABI = Args.getLastArgValue(OPT_target_abi);
if (Arg *A = Args.getLastArg(OPT_meabi)) { if (Arg *A = Args.getLastArg(OPT_meabi)) {
StringRef Value = A->getValue(); StringRef Value = A->getValue();

View File

@ -7978,6 +7978,7 @@
// X86_64:#define __WINT_WIDTH__ 32 // X86_64:#define __WINT_WIDTH__ 32
// X86_64:#define __amd64 1 // X86_64:#define __amd64 1
// X86_64:#define __amd64__ 1 // X86_64:#define __amd64__ 1
// X86_64:#define __code_model_small_ 1
// X86_64:#define __x86_64 1 // X86_64:#define __x86_64 1
// X86_64:#define __x86_64__ 1 // X86_64:#define __x86_64__ 1
// //
@ -7987,7 +7988,10 @@
// X86_64H:#define __x86_64__ 1 // X86_64H:#define __x86_64__ 1
// X86_64H:#define __x86_64h 1 // X86_64H:#define __x86_64h 1
// X86_64H:#define __x86_64h__ 1 // X86_64H:#define __x86_64h__ 1
//
// RUN: %clang -xc - -E -dM -mcmodel=medium --target=i386-unknown-linux < /dev/null | FileCheck -match-full-lines -check-prefix X86_MEDIUM %s
// X86_MEDIUM:#define __code_model_medium_ 1
//
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=x86_64-none-none-gnux32 < /dev/null | FileCheck -match-full-lines -check-prefix X32 %s // RUN: %clang_cc1 -E -dM -ffreestanding -triple=x86_64-none-none-gnux32 < /dev/null | FileCheck -match-full-lines -check-prefix X32 %s
// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=x86_64-none-none-gnux32 < /dev/null | FileCheck -match-full-lines -check-prefix X32 -check-prefix X32-CXX %s // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=x86_64-none-none-gnux32 < /dev/null | FileCheck -match-full-lines -check-prefix X32 -check-prefix X32-CXX %s
// //