[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
This revision was automatically updated to reflect the committed changes. Closed by commit rL308667: [CodeGen][mips] Support `long_call/far/near` attributes (authored by atanasyan). Changed prior to commit: https://reviews.llvm.org/D35479?vs=107461=107578#toc Repository: rL LLVM https://reviews.llvm.org/D35479 Files: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Basic/AttrDocs.td cfe/trunk/lib/CodeGen/CodeGenModule.cpp cfe/trunk/lib/CodeGen/CodeGenModule.h cfe/trunk/lib/CodeGen/TargetInfo.cpp cfe/trunk/lib/CodeGen/TargetInfo.h cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/CodeGen/long-call-attr.c cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test cfe/trunk/test/Sema/attr-long-call.c Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp === --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp @@ -1080,7 +1080,7 @@ GO->setSection(SA->getName()); } - getTargetCodeGenInfo().setTargetAttributes(D, GO, *this); + getTargetCodeGenInfo().setTargetAttributes(D, GO, *this, ForDefinition); } void CodeGenModule::SetInternalFunctionAttributes(const Decl *D, @@ -1147,7 +1147,9 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, bool IsIncompleteFunction, - bool IsThunk) { + bool IsThunk, + ForDefinition_t IsForDefinition) { + if (llvm::Intrinsic::ID IID = F->getIntrinsicID()) { // If this is an intrinsic function, set the function's attributes // to the intrinsic's attributes. @@ -1157,8 +1159,13 @@ const auto *FD = cast(GD.getDecl()); - if (!IsIncompleteFunction) + if (!IsIncompleteFunction) { SetLLVMFunctionAttributes(FD, getTypes().arrangeGlobalDeclaration(GD), F); +// Setup target-specific attributes. +if (!IsForDefinition) + getTargetCodeGenInfo().setTargetAttributes(FD, F, *this, + NotForDefinition); + } // Add the Returned attribute for "this", except for iOS 5 and earlier // where substantial code, including the libstdc++ dylib, was compiled with @@ -2123,7 +2130,8 @@ assert(F->getName() == MangledName && "name was uniqued!"); if (D) -SetFunctionAttributes(GD, F, IsIncompleteFunction, IsThunk); +SetFunctionAttributes(GD, F, IsIncompleteFunction, IsThunk, + IsForDefinition); if (ExtraAttrs.hasAttributes(llvm::AttributeList::FunctionIndex)) { llvm::AttrBuilder B(ExtraAttrs, llvm::AttributeList::FunctionIndex); F->addAttributes(llvm::AttributeList::FunctionIndex, B); Index: cfe/trunk/lib/CodeGen/TargetInfo.h === --- cfe/trunk/lib/CodeGen/TargetInfo.h +++ cfe/trunk/lib/CodeGen/TargetInfo.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H #define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H +#include "CodeGenModule.h" #include "CGValue.h" #include "clang/AST/Type.h" #include "clang/Basic/LLVM.h" @@ -34,7 +35,6 @@ namespace CodeGen { class ABIInfo; class CallArgList; -class CodeGenModule; class CodeGenFunction; class CGFunctionInfo; @@ -55,7 +55,8 @@ /// setTargetAttributes - Provides a convenient hook to handle extra /// target-specific attributes for the given global. virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule ) const {} + CodeGen::CodeGenModule , + ForDefinition_t IsForDefinition) const {} /// emitTargetMD - Provides a convenient hook to handle extra /// target-specific metadata for the given global. Index: cfe/trunk/lib/CodeGen/TargetInfo.cpp === --- cfe/trunk/lib/CodeGen/TargetInfo.cpp +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp @@ -1037,7 +1037,8 @@ const llvm::Triple , const CodeGenOptions ); void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule ) const override; + CodeGen::CodeGenModule , + ForDefinition_t IsForDefinition) const override; int getDwarfEHStackPointer(CodeGen::CodeGenModule ) const override { // Darwin uses different dwarf register numbers for EH. @@ -1904,9 +1905,11 @@ } } -void X86_32TargetCodeGenInfo::setTargetAttributes(const Decl *D, - llvm::GlobalValue *GV, -CodeGen::CodeGenModule ) const { +void X86_32TargetCodeGenInfo::setTargetAttributes( +const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule , +ForDefinition_t
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
rjmccall accepted this revision. rjmccall added a comment. This revision is now accepted and ready to land. Thanks, that looks great! Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
atanasyan updated this revision to Diff 107461. atanasyan added a comment. Addressed review comments. Repository: rL LLVM https://reviews.llvm.org/D35479 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/TargetInfo.cpp lib/CodeGen/TargetInfo.h lib/Sema/SemaDeclAttr.cpp test/CodeGen/long-call-attr.c test/Misc/pragma-attribute-supported-attributes-list.test test/Sema/attr-long-call.c Index: test/Sema/attr-long-call.c === --- /dev/null +++ test/Sema/attr-long-call.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s + +__attribute__((long_call(0))) void foo1(); // expected-error {{'long_call' attribute takes no arguments}} +__attribute__((far(0))) void foo2(); // expected-error {{'far' attribute takes no arguments}} +__attribute__((near(0))) void foo3(); // expected-error {{'near' attribute takes no arguments}} + +__attribute((long_call)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((far)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((near)) int a; // expected-warning {{attribute only applies to functions}} + +__attribute((long_call)) void foo4(); +__attribute((far)) void foo5(); +__attribute((near)) void foo6(); + +__attribute((long_call, far)) void foo7(); + +__attribute((far, near)) void foo8(); // expected-error {{'far' and 'near' attributes are not compatible}} \ + // expected-note {{conflicting attribute is here}} Index: test/Misc/pragma-attribute-supported-attributes-list.test === --- test/Misc/pragma-attribute-supported-attributes-list.test +++ test/Misc/pragma-attribute-supported-attributes-list.test @@ -2,7 +2,7 @@ // The number of supported attributes should never go down! -// CHECK: #pragma clang attribute supports 62 attributes: +// CHECK: #pragma clang attribute supports 64 attributes: // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) @@ -31,6 +31,8 @@ // CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record) // CHECK-NEXT: MicroMips (SubjectMatchRule_function) +// CHECK-NEXT: MipsLongCall (SubjectMatchRule_function) +// CHECK-NEXT: MipsShortCall (SubjectMatchRule_function) // CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter) // CHECK-NEXT: NoDuplicate (SubjectMatchRule_function) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) Index: test/CodeGen/long-call-attr.c === --- /dev/null +++ test/CodeGen/long-call-attr.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s + +void __attribute__((long_call)) foo1 (void); + +void __attribute__((far)) foo2 (void) {} + +// CHECK: define void @foo2() [[FAR:#[0-9]+]] + +void __attribute__((near)) foo3 (void) { foo1(); } + +// CHECK: define void @foo3() [[NEAR:#[0-9]+]] + +// CHECK: declare void @foo1() [[LONGDECL:#[0-9]+]] + +// CHECK: attributes [[FAR]] = { {{.*}} "long-call" {{.*}} } +// CHECK: attributes [[NEAR]] = { {{.*}} "short-call" {{.*}} } +// CHECK: attributes [[LONGDECL]] = { {{.*}} "long-call" {{.*}} } Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5965,6 +5965,14 @@ case AttributeList::AT_NoMicroMips: handleSimpleAttribute(S, D, Attr); break; + case AttributeList::AT_MipsLongCall: +handleSimpleAttributeWithExclusions( +S, D, Attr); +break; + case AttributeList::AT_MipsShortCall: +handleSimpleAttributeWithExclusions ( +S, D, Attr); +break; case AttributeList::AT_AMDGPUFlatWorkGroupSize: handleAMDGPUFlatWorkGroupSizeAttr(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.h === --- lib/CodeGen/TargetInfo.h +++ lib/CodeGen/TargetInfo.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H #define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H +#include "CodeGenModule.h" #include "CGValue.h" #include "clang/AST/Type.h" #include "clang/Basic/LLVM.h" @@ -34,7 +35,6 @@ namespace CodeGen { class ABIInfo; class CallArgList; -class CodeGenModule; class CodeGenFunction; class CGFunctionInfo; @@ -55,7 +55,8 @@ /// setTargetAttributes - Provides a convenient hook to handle extra /// target-specific
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
rjmccall added a comment. Hmm. Could you invert those conditions so that they early-return, just for consistency? Sorry this is dragging out so long, and thanks for being so patient. Comment at: lib/CodeGen/TargetInfo.cpp:2357 +return; + X86_32TargetCodeGenInfo::setTargetAttributes(D, GV, CGM, IsForDefinition); rjmccall wrote: > That function has its own early exit, so do the early exit after calling it, > please. Here. Comment at: lib/CodeGen/TargetInfo.cpp:2401 + if (!IsForDefinition) +return; + TargetCodeGenInfo::setTargetAttributes(D, GV, CGM, IsForDefinition); And this one should go after the call; I just missed it in the earlier reviews. Comment at: lib/CodeGen/TargetInfo.cpp:5535 + ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM, IsForDefinition); + if (IsForDefinition) +addStackProbeSizeTargetAttribute(D, GV, CGM); Here. Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
atanasyan updated this revision to Diff 107446. atanasyan added a comment. My bad. I did not read your comment thoroughly. - Restore `IsForDefinition` checkings in `WinX86_32TargetCodeGenInfo::setTargetAttributes` and `WindowsARMTargetCodeGenInfo::setTargetAttributes` methods. Repository: rL LLVM https://reviews.llvm.org/D35479 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/TargetInfo.cpp lib/CodeGen/TargetInfo.h lib/Sema/SemaDeclAttr.cpp test/CodeGen/long-call-attr.c test/Misc/pragma-attribute-supported-attributes-list.test test/Sema/attr-long-call.c Index: test/Sema/attr-long-call.c === --- /dev/null +++ test/Sema/attr-long-call.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s + +__attribute__((long_call(0))) void foo1(); // expected-error {{'long_call' attribute takes no arguments}} +__attribute__((far(0))) void foo2(); // expected-error {{'far' attribute takes no arguments}} +__attribute__((near(0))) void foo3(); // expected-error {{'near' attribute takes no arguments}} + +__attribute((long_call)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((far)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((near)) int a; // expected-warning {{attribute only applies to functions}} + +__attribute((long_call)) void foo4(); +__attribute((far)) void foo5(); +__attribute((near)) void foo6(); + +__attribute((long_call, far)) void foo7(); + +__attribute((far, near)) void foo8(); // expected-error {{'far' and 'near' attributes are not compatible}} \ + // expected-note {{conflicting attribute is here}} Index: test/Misc/pragma-attribute-supported-attributes-list.test === --- test/Misc/pragma-attribute-supported-attributes-list.test +++ test/Misc/pragma-attribute-supported-attributes-list.test @@ -2,7 +2,7 @@ // The number of supported attributes should never go down! -// CHECK: #pragma clang attribute supports 62 attributes: +// CHECK: #pragma clang attribute supports 64 attributes: // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) @@ -31,6 +31,8 @@ // CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record) // CHECK-NEXT: MicroMips (SubjectMatchRule_function) +// CHECK-NEXT: MipsLongCall (SubjectMatchRule_function) +// CHECK-NEXT: MipsShortCall (SubjectMatchRule_function) // CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter) // CHECK-NEXT: NoDuplicate (SubjectMatchRule_function) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) Index: test/CodeGen/long-call-attr.c === --- /dev/null +++ test/CodeGen/long-call-attr.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s + +void __attribute__((long_call)) foo1 (void); + +void __attribute__((far)) foo2 (void) {} + +// CHECK: define void @foo2() [[FAR:#[0-9]+]] + +void __attribute__((near)) foo3 (void) { foo1(); } + +// CHECK: define void @foo3() [[NEAR:#[0-9]+]] + +// CHECK: declare void @foo1() [[LONGDECL:#[0-9]+]] + +// CHECK: attributes [[FAR]] = { {{.*}} "long-call" {{.*}} } +// CHECK: attributes [[NEAR]] = { {{.*}} "short-call" {{.*}} } +// CHECK: attributes [[LONGDECL]] = { {{.*}} "long-call" {{.*}} } Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5965,6 +5965,14 @@ case AttributeList::AT_NoMicroMips: handleSimpleAttribute(S, D, Attr); break; + case AttributeList::AT_MipsLongCall: +handleSimpleAttributeWithExclusions( +S, D, Attr); +break; + case AttributeList::AT_MipsShortCall: +handleSimpleAttributeWithExclusions ( +S, D, Attr); +break; case AttributeList::AT_AMDGPUFlatWorkGroupSize: handleAMDGPUFlatWorkGroupSizeAttr(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.h === --- lib/CodeGen/TargetInfo.h +++ lib/CodeGen/TargetInfo.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H #define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H +#include "CodeGenModule.h" #include "CGValue.h" #include "clang/AST/Type.h" #include "clang/Basic/LLVM.h" @@ -34,7 +35,6 @@ namespace CodeGen { class ABIInfo; class CallArgList; -class
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
rjmccall added inline comments. Comment at: lib/CodeGen/TargetInfo.cpp:2356 + X86_32TargetCodeGenInfo::setTargetAttributes(D, GV, CGM, IsForDefinition); addStackProbeSizeTargetAttribute(D, GV, CGM); No, sorry, I must not have been clear. We still need a check here, but we should do it after the first call. The idea is that we want to give the generic x86-32 target an opportunity to add target attributes, whether this is a declaration or a definition. , Having done that, we come back to this function to add any Windows-specific target attributes. Since all the Windows-specific attributes are definition-only, we can just exit if it's only for a declaration. Comment at: lib/CodeGen/TargetInfo.cpp:5534 +ForDefinition_t IsForDefinition) const { + ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM, IsForDefinition); addStackProbeSizeTargetAttribute(D, GV, CGM); Same thing here: please add a check, but only after you've given the generic ARM target an opportunity to set attributes in all cases. Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
rjmccall added inline comments. Comment at: include/clang/Basic/AttrDocs.td:1336 +if code compiled using ``-mlong-calls`` switch, it forces compiler to use +the ``jal`` instruction to call the function. + }]; sdardis wrote: > rjmccall wrote: > > sdardis wrote: > > > rjmccall wrote: > > > > I suggest the following wording: > > > > > > > > Clang supports the ``__attribute__((long_call))``, > > > > ``__attribute__((far))``, and > > > > ``__attribute__((near))`` attributes on MIPS targets. These attributes > > > > may only be > > > > added to function declarations and change the code generated by the > > > > compiler when > > > > directly calling the function. The ``near`` attribute allows calls to > > > > the function to > > > > be made using the ``jal`` instruction, which requires the function to > > > > be defined in the > > > > same 256MB segment as the caller. The ``long_call`` and ``far`` > > > > attributes are > > > > synonyms and require the use of a different call sequence that works > > > > regardless of > > > > the distance between the functions. > > > > > > > > These attributes take priority over command line switches such as > > > > ``-mlong-calls``. > > > > requires the function to be defined > > > > > > I'd change the "defined" to be "located". > > > > > > > in the same 256MB segment as the caller. > > > > > > I'd change this to: "in the same naturally aligned 256MB segment as the > > > caller." > > > > > > This also needs a note saying that it has no effect for code compiled > > > with -fpic. > > Oh, yes, if these statements are true then it's absolutely important to > > include them. I was going off of the raw ISA specification, since jal just > > takes a relative offset, but if the toolchain has more specific > > requirements then those are what should be documented. > > > > This whole feature is strange to me; do MIPS linkers just never introduce > > things like branch islands and lazy-binding functions? > > since jal just takes a relative offset, > > jal doesn't take an offset, the instruction takes an 26-bit immediate > (called the instruction index) shifts it left 2 bits and combines it with the > remaining upper bits of the address of the instruction in the delay slot of > jal to form the new $pc--so it's possible to jump from the bottom of a 256MB > segment to the top. > > (My apologies for the long answer here, jal is one of the odder control > transfer instruction for MIPS.) > > > This whole feature is strange to me; do MIPS linkers just never introduce > > things like branch islands and lazy-binding functions? > > This feature is orthogonal to lazy-binding functions. The usage of > 'long-call' and 'near' is to support bare-metal / static relocation model > environments where the caller and callee might be in different memory > segments (e.g. KSEG0 and KSEG1) or have a custom memory layout for their > program's sections. > > To the best of my knowledge, the GNU linker for MIPS only inserts stub > functions / branch islands when compiling static code that calls PIC code. Well, that's what I get for skimming the first search hit instead of taking the time to read the real documentation. Thank you for the correction. Oh, and of course that's why you can't really use JAL in PIC: the linker could statically resolve instruction indexes within the current image, but only if the image gets loaded at a base address that's a multiple of 256MB! That's obviously too coarse-grained to be workable. What an unfortunate instruction design. Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
sdardis added inline comments. Comment at: include/clang/Basic/AttrDocs.td:1336 +if code compiled using ``-mlong-calls`` switch, it forces compiler to use +the ``jal`` instruction to call the function. + }]; rjmccall wrote: > sdardis wrote: > > rjmccall wrote: > > > I suggest the following wording: > > > > > > Clang supports the ``__attribute__((long_call))``, > > > ``__attribute__((far))``, and > > > ``__attribute__((near))`` attributes on MIPS targets. These attributes > > > may only be > > > added to function declarations and change the code generated by the > > > compiler when > > > directly calling the function. The ``near`` attribute allows calls to > > > the function to > > > be made using the ``jal`` instruction, which requires the function to be > > > defined in the > > > same 256MB segment as the caller. The ``long_call`` and ``far`` > > > attributes are > > > synonyms and require the use of a different call sequence that works > > > regardless of > > > the distance between the functions. > > > > > > These attributes take priority over command line switches such as > > > ``-mlong-calls``. > > > requires the function to be defined > > > > I'd change the "defined" to be "located". > > > > > in the same 256MB segment as the caller. > > > > I'd change this to: "in the same naturally aligned 256MB segment as the > > caller." > > > > This also needs a note saying that it has no effect for code compiled with > > -fpic. > Oh, yes, if these statements are true then it's absolutely important to > include them. I was going off of the raw ISA specification, since jal just > takes a relative offset, but if the toolchain has more specific requirements > then those are what should be documented. > > This whole feature is strange to me; do MIPS linkers just never introduce > things like branch islands and lazy-binding functions? > since jal just takes a relative offset, jal doesn't take an offset, the instruction takes an 26-bit immediate (called the instruction index) shifts it left 2 bits and combines it with the remaining upper bits of the address of the instruction in the delay slot of jal to form the new $pc--so it's possible to jump from the bottom of a 256MB segment to the top. (My apologies for the long answer here, jal is one of the odder control transfer instruction for MIPS.) > This whole feature is strange to me; do MIPS linkers just never introduce > things like branch islands and lazy-binding functions? This feature is orthogonal to lazy-binding functions. The usage of 'long-call' and 'near' is to support bare-metal / static relocation model environments where the caller and callee might be in different memory segments (e.g. KSEG0 and KSEG1) or have a custom memory layout for their program's sections. To the best of my knowledge, the GNU linker for MIPS only inserts stub functions / branch islands when compiling static code that calls PIC code. Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
atanasyan updated this revision to Diff 107381. atanasyan added a comment. - New wording of attributes documentation and comments. - Remove redundant `if-return` statements. Repository: rL LLVM https://reviews.llvm.org/D35479 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/TargetInfo.cpp lib/CodeGen/TargetInfo.h lib/Sema/SemaDeclAttr.cpp test/CodeGen/long-call-attr.c test/Misc/pragma-attribute-supported-attributes-list.test test/Sema/attr-long-call.c Index: test/Sema/attr-long-call.c === --- /dev/null +++ test/Sema/attr-long-call.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s + +__attribute__((long_call(0))) void foo1(); // expected-error {{'long_call' attribute takes no arguments}} +__attribute__((far(0))) void foo2(); // expected-error {{'far' attribute takes no arguments}} +__attribute__((near(0))) void foo3(); // expected-error {{'near' attribute takes no arguments}} + +__attribute((long_call)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((far)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((near)) int a; // expected-warning {{attribute only applies to functions}} + +__attribute((long_call)) void foo4(); +__attribute((far)) void foo5(); +__attribute((near)) void foo6(); + +__attribute((long_call, far)) void foo7(); + +__attribute((far, near)) void foo8(); // expected-error {{'far' and 'near' attributes are not compatible}} \ + // expected-note {{conflicting attribute is here}} Index: test/Misc/pragma-attribute-supported-attributes-list.test === --- test/Misc/pragma-attribute-supported-attributes-list.test +++ test/Misc/pragma-attribute-supported-attributes-list.test @@ -2,7 +2,7 @@ // The number of supported attributes should never go down! -// CHECK: #pragma clang attribute supports 62 attributes: +// CHECK: #pragma clang attribute supports 64 attributes: // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) @@ -31,6 +31,8 @@ // CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record) // CHECK-NEXT: MicroMips (SubjectMatchRule_function) +// CHECK-NEXT: MipsLongCall (SubjectMatchRule_function) +// CHECK-NEXT: MipsShortCall (SubjectMatchRule_function) // CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter) // CHECK-NEXT: NoDuplicate (SubjectMatchRule_function) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) Index: test/CodeGen/long-call-attr.c === --- /dev/null +++ test/CodeGen/long-call-attr.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s + +void __attribute__((long_call)) foo1 (void); + +void __attribute__((far)) foo2 (void) {} + +// CHECK: define void @foo2() [[FAR:#[0-9]+]] + +void __attribute__((near)) foo3 (void) { foo1(); } + +// CHECK: define void @foo3() [[NEAR:#[0-9]+]] + +// CHECK: declare void @foo1() [[LONGDECL:#[0-9]+]] + +// CHECK: attributes [[FAR]] = { {{.*}} "long-call" {{.*}} } +// CHECK: attributes [[NEAR]] = { {{.*}} "short-call" {{.*}} } +// CHECK: attributes [[LONGDECL]] = { {{.*}} "long-call" {{.*}} } Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5965,6 +5965,14 @@ case AttributeList::AT_NoMicroMips: handleSimpleAttribute(S, D, Attr); break; + case AttributeList::AT_MipsLongCall: +handleSimpleAttributeWithExclusions( +S, D, Attr); +break; + case AttributeList::AT_MipsShortCall: +handleSimpleAttributeWithExclusions ( +S, D, Attr); +break; case AttributeList::AT_AMDGPUFlatWorkGroupSize: handleAMDGPUFlatWorkGroupSizeAttr(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.h === --- lib/CodeGen/TargetInfo.h +++ lib/CodeGen/TargetInfo.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H #define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H +#include "CodeGenModule.h" #include "CGValue.h" #include "clang/AST/Type.h" #include "clang/Basic/LLVM.h" @@ -34,7 +35,6 @@ namespace CodeGen { class ABIInfo; class CallArgList; -class CodeGenModule; class CodeGenFunction; class CGFunctionInfo; @@ -55,7 +55,8 @@ /// setTargetAttributes -
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
rjmccall added inline comments. Comment at: include/clang/Basic/AttrDocs.td:1336 +if code compiled using ``-mlong-calls`` switch, it forces compiler to use +the ``jal`` instruction to call the function. + }]; sdardis wrote: > rjmccall wrote: > > I suggest the following wording: > > > > Clang supports the ``__attribute__((long_call))``, > > ``__attribute__((far))``, and > > ``__attribute__((near))`` attributes on MIPS targets. These attributes may > > only be > > added to function declarations and change the code generated by the > > compiler when > > directly calling the function. The ``near`` attribute allows calls to the > > function to > > be made using the ``jal`` instruction, which requires the function to be > > defined in the > > same 256MB segment as the caller. The ``long_call`` and ``far`` attributes > > are > > synonyms and require the use of a different call sequence that works > > regardless of > > the distance between the functions. > > > > These attributes take priority over command line switches such as > > ``-mlong-calls``. > > requires the function to be defined > > I'd change the "defined" to be "located". > > > in the same 256MB segment as the caller. > > I'd change this to: "in the same naturally aligned 256MB segment as the > caller." > > This also needs a note saying that it has no effect for code compiled with > -fpic. Oh, yes, if these statements are true then it's absolutely important to include them. I was going off of the raw ISA specification, since jal just takes a relative offset, but if the toolchain has more specific requirements then those are what should be documented. This whole feature is strange to me; do MIPS linkers just never introduce things like branch islands and lazy-binding functions? Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
sdardis added a comment. Some comments on the documentation. Comment at: include/clang/Basic/AttrDocs.td:1336 +if code compiled using ``-mlong-calls`` switch, it forces compiler to use +the ``jal`` instruction to call the function. + }]; rjmccall wrote: > I suggest the following wording: > > Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``, > and > ``__attribute__((near))`` attributes on MIPS targets. These attributes may > only be > added to function declarations and change the code generated by the compiler > when > directly calling the function. The ``near`` attribute allows calls to the > function to > be made using the ``jal`` instruction, which requires the function to be > defined in the > same 256MB segment as the caller. The ``long_call`` and ``far`` attributes > are > synonyms and require the use of a different call sequence that works > regardless of > the distance between the functions. > > These attributes take priority over command line switches such as > ``-mlong-calls``. > requires the function to be defined I'd change the "defined" to be "located". > in the same 256MB segment as the caller. I'd change this to: "in the same naturally aligned 256MB segment as the caller." This also needs a note saying that it has no effect for code compiled with -fpic. Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
rjmccall added a comment. A few more minor tweaks. Comment at: lib/CodeGen/TargetInfo.cpp:2357 +return; + X86_32TargetCodeGenInfo::setTargetAttributes(D, GV, CGM, IsForDefinition); That function has its own early exit, so do the early exit after calling it, please. Comment at: lib/CodeGen/TargetInfo.cpp:5538 +return; + ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM, IsForDefinition); addStackProbeSizeTargetAttribute(D, GV, CGM); Same thing here. Comment at: lib/CodeGen/TargetInfo.cpp:6643 + +// Other attributes do not have a sense for declarations. +if (!IsForDefinition) "meaning" is a better word here. Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
atanasyan updated this revision to Diff 107281. atanasyan added a comment. - Early return from `setTargetAttributes` methods if `IsForDefinition` is not true in all cases except handling MIPS "call style" attributes. Repository: rL LLVM https://reviews.llvm.org/D35479 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/TargetInfo.cpp lib/CodeGen/TargetInfo.h lib/Sema/SemaDeclAttr.cpp test/CodeGen/long-call-attr.c test/Misc/pragma-attribute-supported-attributes-list.test test/Sema/attr-long-call.c Index: test/Sema/attr-long-call.c === --- /dev/null +++ test/Sema/attr-long-call.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s + +__attribute__((long_call(0))) void foo1(); // expected-error {{'long_call' attribute takes no arguments}} +__attribute__((far(0))) void foo2(); // expected-error {{'far' attribute takes no arguments}} +__attribute__((near(0))) void foo3(); // expected-error {{'near' attribute takes no arguments}} + +__attribute((long_call)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((far)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((near)) int a; // expected-warning {{attribute only applies to functions}} + +__attribute((long_call)) void foo4(); +__attribute((far)) void foo5(); +__attribute((near)) void foo6(); + +__attribute((long_call, far)) void foo7(); + +__attribute((far, near)) void foo8(); // expected-error {{'far' and 'near' attributes are not compatible}} \ + // expected-note {{conflicting attribute is here}} Index: test/Misc/pragma-attribute-supported-attributes-list.test === --- test/Misc/pragma-attribute-supported-attributes-list.test +++ test/Misc/pragma-attribute-supported-attributes-list.test @@ -2,7 +2,7 @@ // The number of supported attributes should never go down! -// CHECK: #pragma clang attribute supports 62 attributes: +// CHECK: #pragma clang attribute supports 64 attributes: // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) @@ -31,6 +31,8 @@ // CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record) // CHECK-NEXT: MicroMips (SubjectMatchRule_function) +// CHECK-NEXT: MipsLongCall (SubjectMatchRule_function) +// CHECK-NEXT: MipsShortCall (SubjectMatchRule_function) // CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter) // CHECK-NEXT: NoDuplicate (SubjectMatchRule_function) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) Index: test/CodeGen/long-call-attr.c === --- /dev/null +++ test/CodeGen/long-call-attr.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s + +void __attribute__((long_call)) foo1 (void); + +void __attribute__((far)) foo2 (void) {} + +// CHECK: define void @foo2() [[FAR:#[0-9]+]] + +void __attribute__((near)) foo3 (void) { foo1(); } + +// CHECK: define void @foo3() [[NEAR:#[0-9]+]] + +// CHECK: declare void @foo1() [[LONGDECL:#[0-9]+]] + +// CHECK: attributes [[FAR]] = { {{.*}} "long-call" {{.*}} } +// CHECK: attributes [[NEAR]] = { {{.*}} "short-call" {{.*}} } +// CHECK: attributes [[LONGDECL]] = { {{.*}} "long-call" {{.*}} } Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5965,6 +5965,14 @@ case AttributeList::AT_NoMicroMips: handleSimpleAttribute(S, D, Attr); break; + case AttributeList::AT_MipsLongCall: +handleSimpleAttributeWithExclusions( +S, D, Attr); +break; + case AttributeList::AT_MipsShortCall: +handleSimpleAttributeWithExclusions ( +S, D, Attr); +break; case AttributeList::AT_AMDGPUFlatWorkGroupSize: handleAMDGPUFlatWorkGroupSizeAttr(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.h === --- lib/CodeGen/TargetInfo.h +++ lib/CodeGen/TargetInfo.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H #define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H +#include "CodeGenModule.h" #include "CGValue.h" #include "clang/AST/Type.h" #include "clang/Basic/LLVM.h" @@ -34,7 +35,6 @@ namespace CodeGen { class ABIInfo; class CallArgList; -class CodeGenModule; class CodeGenFunction; class CGFunctionInfo; @@
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
rjmccall added inline comments. Comment at: lib/CodeGen/TargetInfo.cpp:1910 +const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule , +ForDefinition_t IsForDefinition) const { if (const FunctionDecl *FD = dyn_cast_or_null(D)) { To preserve existing behavior, please make all of the existing implementations you've modified just do an early return if !IsForDefinition. In the MIPS implementation, you can just handle the long-call attributes first and then exit, unless you feel up to auditing the rest of the attributes there to see if they belong on declarations. Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
atanasyan updated this revision to Diff 107246. atanasyan added a comment. - Pass `IsForDefinition` argument to the `setTargetAttributes` method. Repository: rL LLVM https://reviews.llvm.org/D35479 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/TargetInfo.cpp lib/CodeGen/TargetInfo.h lib/Sema/SemaDeclAttr.cpp test/CodeGen/long-call-attr.c test/Misc/pragma-attribute-supported-attributes-list.test test/Sema/attr-long-call.c Index: test/Sema/attr-long-call.c === --- /dev/null +++ test/Sema/attr-long-call.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s + +__attribute__((long_call(0))) void foo1(); // expected-error {{'long_call' attribute takes no arguments}} +__attribute__((far(0))) void foo2(); // expected-error {{'far' attribute takes no arguments}} +__attribute__((near(0))) void foo3(); // expected-error {{'near' attribute takes no arguments}} + +__attribute((long_call)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((far)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((near)) int a; // expected-warning {{attribute only applies to functions}} + +__attribute((long_call)) void foo4(); +__attribute((far)) void foo5(); +__attribute((near)) void foo6(); + +__attribute((long_call, far)) void foo7(); + +__attribute((far, near)) void foo8(); // expected-error {{'far' and 'near' attributes are not compatible}} \ + // expected-note {{conflicting attribute is here}} Index: test/Misc/pragma-attribute-supported-attributes-list.test === --- test/Misc/pragma-attribute-supported-attributes-list.test +++ test/Misc/pragma-attribute-supported-attributes-list.test @@ -2,7 +2,7 @@ // The number of supported attributes should never go down! -// CHECK: #pragma clang attribute supports 62 attributes: +// CHECK: #pragma clang attribute supports 64 attributes: // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) @@ -31,6 +31,8 @@ // CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record) // CHECK-NEXT: MicroMips (SubjectMatchRule_function) +// CHECK-NEXT: MipsLongCall (SubjectMatchRule_function) +// CHECK-NEXT: MipsShortCall (SubjectMatchRule_function) // CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter) // CHECK-NEXT: NoDuplicate (SubjectMatchRule_function) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) Index: test/CodeGen/long-call-attr.c === --- /dev/null +++ test/CodeGen/long-call-attr.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s + +void __attribute__((long_call)) foo1 (void); + +void __attribute__((far)) foo2 (void) {} + +// CHECK: define void @foo2() [[FAR:#[0-9]+]] + +void __attribute__((near)) foo3 (void) { foo1(); } + +// CHECK: define void @foo3() [[NEAR:#[0-9]+]] + +// CHECK: declare void @foo1() [[LONGDECL:#[0-9]+]] + +// CHECK: attributes [[FAR]] = { {{.*}} "long-call" {{.*}} } +// CHECK: attributes [[NEAR]] = { {{.*}} "short-call" {{.*}} } +// CHECK: attributes [[LONGDECL]] = { {{.*}} "long-call" {{.*}} } Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5965,6 +5965,14 @@ case AttributeList::AT_NoMicroMips: handleSimpleAttribute(S, D, Attr); break; + case AttributeList::AT_MipsLongCall: +handleSimpleAttributeWithExclusions( +S, D, Attr); +break; + case AttributeList::AT_MipsShortCall: +handleSimpleAttributeWithExclusions ( +S, D, Attr); +break; case AttributeList::AT_AMDGPUFlatWorkGroupSize: handleAMDGPUFlatWorkGroupSizeAttr(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.h === --- lib/CodeGen/TargetInfo.h +++ lib/CodeGen/TargetInfo.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H #define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H +#include "CodeGenModule.h" #include "CGValue.h" #include "clang/AST/Type.h" #include "clang/Basic/LLVM.h" @@ -34,7 +35,6 @@ namespace CodeGen { class ABIInfo; class CallArgList; -class CodeGenModule; class CodeGenFunction; class CGFunctionInfo; @@ -55,7 +55,8 @@ /// setTargetAttributes - Provides a convenient hook to
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
rjmccall added a comment. One minor revision, but otherwise looks great, thank you. Comment at: lib/CodeGen/CodeGenModule.cpp:1166 +if (!IsForDefinition) + getTargetCodeGenInfo().setTargetAttributes(FD, F, *this); + } I think you should probably pass IsForDefinition to setTargetAttributes. Targets may want to only set certain attributes on function definitions. Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
atanasyan updated this revision to Diff 107193. atanasyan added a comment. Addressed review comment: - Split MipsLongCall into a couple of attributes MipsLongCall and MipsShortCall. - Change the documentation wording. - Keep the attributes handling in the setTargetAttributes. - Show error in case of combining incompatible attributes. Repository: rL LLVM https://reviews.llvm.org/D35479 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/long-call-attr.c test/Misc/pragma-attribute-supported-attributes-list.test test/Sema/attr-long-call.c Index: test/Sema/attr-long-call.c === --- /dev/null +++ test/Sema/attr-long-call.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s + +__attribute__((long_call(0))) void foo1(); // expected-error {{'long_call' attribute takes no arguments}} +__attribute__((far(0))) void foo2(); // expected-error {{'far' attribute takes no arguments}} +__attribute__((near(0))) void foo3(); // expected-error {{'near' attribute takes no arguments}} + +__attribute((long_call)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((far)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((near)) int a; // expected-warning {{attribute only applies to functions}} + +__attribute((long_call)) void foo4(); +__attribute((far)) void foo5(); +__attribute((near)) void foo6(); + +__attribute((long_call, far)) void foo7(); + +__attribute((far, near)) void foo8(); // expected-error {{'far' and 'near' attributes are not compatible}} \ + // expected-note {{conflicting attribute is here}} Index: test/Misc/pragma-attribute-supported-attributes-list.test === --- test/Misc/pragma-attribute-supported-attributes-list.test +++ test/Misc/pragma-attribute-supported-attributes-list.test @@ -2,7 +2,7 @@ // The number of supported attributes should never go down! -// CHECK: #pragma clang attribute supports 62 attributes: +// CHECK: #pragma clang attribute supports 64 attributes: // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) @@ -31,6 +31,8 @@ // CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record) // CHECK-NEXT: MicroMips (SubjectMatchRule_function) +// CHECK-NEXT: MipsLongCall (SubjectMatchRule_function) +// CHECK-NEXT: MipsShortCall (SubjectMatchRule_function) // CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter) // CHECK-NEXT: NoDuplicate (SubjectMatchRule_function) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) Index: test/CodeGen/long-call-attr.c === --- /dev/null +++ test/CodeGen/long-call-attr.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s + +void __attribute__((long_call)) foo1 (void); + +void __attribute__((far)) foo2 (void) {} + +// CHECK: define void @foo2() [[FAR:#[0-9]+]] + +void __attribute__((near)) foo3 (void) { foo1(); } + +// CHECK: define void @foo3() [[NEAR:#[0-9]+]] + +// CHECK: declare void @foo1() [[LONGDECL:#[0-9]+]] + +// CHECK: attributes [[FAR]] = { {{.*}} "long-call" {{.*}} } +// CHECK: attributes [[NEAR]] = { {{.*}} "short-call" {{.*}} } +// CHECK: attributes [[LONGDECL]] = { {{.*}} "long-call" {{.*}} } Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5965,6 +5965,14 @@ case AttributeList::AT_NoMicroMips: handleSimpleAttribute(S, D, Attr); break; + case AttributeList::AT_MipsLongCall: +handleSimpleAttributeWithExclusions( +S, D, Attr); +break; + case AttributeList::AT_MipsShortCall: +handleSimpleAttributeWithExclusions ( +S, D, Attr); +break; case AttributeList::AT_AMDGPUFlatWorkGroupSize: handleAMDGPUFlatWorkGroupSizeAttr(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6619,6 +6619,11 @@ else if (FD->hasAttr()) Fn->addFnAttr("nomicromips"); +if (FD->hasAttr()) + Fn->addFnAttr("long-call"); +else if (FD->hasAttr()) + Fn->addFnAttr("short-call"); + const MipsInterruptAttr *Attr = FD->getAttr();
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
rjmccall added inline comments. Comment at: include/clang/Basic/Attr.td:1191 +def MipsLongCall : InheritableAttr, TargetSpecificAttr { + let Spellings = [GCC<"long_call">, GCC<"far">, GCC<"near">]; Because this is used for all three attributes, I think you should call it something more general. Perhaps MipsCallStyle? Comment at: include/clang/Basic/Attr.td:1195 + let Accessors = [Accessor<"longCall", [GCC<"long_call">, GCC<"far">]>, + Accessor<"nearCall", [GCC<"near">]>]; + let Documentation = [MipsLongCallDocs]; This is not the standard naming convention for accessors. I suggest isLongCall() and isNearCall(). Comment at: include/clang/Basic/AttrDocs.td:1336 +if code compiled using ``-mlong-calls`` switch, it forces compiler to use +the ``jal`` instruction to call the function. + }]; I suggest the following wording: Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``, and ``__attribute__((near))`` attributes on MIPS targets. These attributes may only be added to function declarations and change the code generated by the compiler when directly calling the function. The ``near`` attribute allows calls to the function to be made using the ``jal`` instruction, which requires the function to be defined in the same 256MB segment as the caller. The ``long_call`` and ``far`` attributes are synonyms and require the use of a different call sequence that works regardless of the distance between the functions. These attributes take priority over command line switches such as ``-mlong-calls``. Comment at: lib/CodeGen/CGCall.cpp:1810 +FuncAttrs.addAttribute("near-call"); +} + You should really put this in TargetCodeGenInfo::setTargetAttributes. Please just add a ForDefinition_t argument to that function and SetFunctionAttributes, then call setTargetAttributes from SetFunctionAttributes. Comment at: lib/Sema/SemaDeclAttr.cpp:5955 +handleSimpleAttribute(S, D, Attr); +break; case AttributeList::AT_AMDGPUFlatWorkGroupSize: You need to check for conflicts between the different attributes, and please add a test for that. Repository: rL LLVM https://reviews.llvm.org/D35479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes
atanasyan created this revision. atanasyan added a project: clang. Herald added subscribers: arichardson, javed.absar. This patch adds support for the `long_call`, `far`, and `near` attributes for MIPS targets. The `long_call` and `far` attributes are synonyms. All these attributes override `-mlong-calls` / `-mno-long-calls` command line options for particular function. The main non-trivial part is the change in `CodeGenModule::ConstructAttributeList` routine. It is not enough to configure attributes in `MIPSTargetCodeGenInfo::setTargetAttributes` because this method applied to the function definitions only while we need to configure the attributes for function declarations as well. Repository: rL LLVM https://reviews.llvm.org/D35479 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/CGCall.cpp lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/long-call-attr.c test/Misc/pragma-attribute-supported-attributes-list.test test/Sema/attr-long-call.c Index: test/Sema/attr-long-call.c === --- /dev/null +++ test/Sema/attr-long-call.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s + +__attribute__((long_call(0))) void foo1(); // expected-error {{'long_call' attribute takes no arguments}} +__attribute__((far(0))) void foo2(); // expected-error {{'far' attribute takes no arguments}} +__attribute__((near(0))) void foo3(); // expected-error {{'near' attribute takes no arguments}} + +__attribute((long_call)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((far)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((near)) int a; // expected-warning {{attribute only applies to functions}} + +__attribute((long_call)) void foo4(); +__attribute((far)) void foo5(); +__attribute((near)) void foo6(); Index: test/Misc/pragma-attribute-supported-attributes-list.test === --- test/Misc/pragma-attribute-supported-attributes-list.test +++ test/Misc/pragma-attribute-supported-attributes-list.test @@ -2,7 +2,7 @@ // The number of supported attributes should never go down! -// CHECK: #pragma clang attribute supports 62 attributes: +// CHECK: #pragma clang attribute supports 63 attributes: // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) @@ -31,6 +31,7 @@ // CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record) // CHECK-NEXT: MicroMips (SubjectMatchRule_function) +// CHECK-NEXT: MipsLongCall (SubjectMatchRule_function) // CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter) // CHECK-NEXT: NoDuplicate (SubjectMatchRule_function) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) Index: test/CodeGen/long-call-attr.c === --- /dev/null +++ test/CodeGen/long-call-attr.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s + +void __attribute__((long_call)) foo1 (void); + +void __attribute__((far)) foo2 (void) {} + +// CHECK: define void @foo2() [[FAR:#[0-9]+]] + +void __attribute__((near)) foo3 (void) { foo1(); } + +// CHECK: define void @foo3() [[NEAR:#[0-9]+]] +// CHECK: call void @foo1() [[LONGCALL:#[0-9]+]] + +// CHECK: declare void @foo1() [[LONGDECL:#[0-9]+]] + +// CHECK: attributes [[FAR]] = { {{.*}} "long-call" {{.*}} } +// CHECK: attributes [[NEAR]] = { {{.*}} "near-call" {{.*}} } +// CHECK: attributes [[LONGDECL]] = { {{.*}} "long-call" {{.*}} } +// CHECK: attributes [[LONGCALL]] = { "long-call" } Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5950,6 +5950,9 @@ case AttributeList::AT_NoMicroMips: handleSimpleAttribute(S, D, Attr); break; + case AttributeList::AT_MipsLongCall: +handleSimpleAttribute(S, D, Attr); +break; case AttributeList::AT_AMDGPUFlatWorkGroupSize: handleAMDGPUFlatWorkGroupSizeAttr(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6619,6 +6619,13 @@ else if (FD->hasAttr()) Fn->addFnAttr("nomicromips"); +if (const auto *LongCallAttr = FD->getAttr()) { + if (LongCallAttr->longCall()) +Fn->addFnAttr("long-call"); + else if (LongCallAttr->nearCall()) +Fn->addFnAttr("near-call"); +} + const MipsInterruptAttr *Attr = FD->getAttr();