[PATCH] D35479: [CodeGen][mips] Support `long_call/far/near` attributes

2017-07-20 Thread Simon Atanasyan via Phabricator via cfe-commits
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

2017-07-20 Thread John McCall via Phabricator via cfe-commits
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

2017-07-20 Thread Simon Atanasyan via Phabricator via cfe-commits
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

2017-07-20 Thread John McCall via Phabricator via cfe-commits
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

2017-07-20 Thread Simon Atanasyan via Phabricator via cfe-commits
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

2017-07-19 Thread John McCall via Phabricator via cfe-commits
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

2017-07-19 Thread John McCall via Phabricator via cfe-commits
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

2017-07-19 Thread Simon Dardis via Phabricator via cfe-commits
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

2017-07-19 Thread Simon Atanasyan via Phabricator via cfe-commits
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

2017-07-19 Thread John McCall via Phabricator via cfe-commits
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

2017-07-19 Thread Simon Dardis via Phabricator via cfe-commits
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

2017-07-19 Thread John McCall via Phabricator via cfe-commits
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

2017-07-19 Thread Simon Atanasyan via Phabricator via cfe-commits
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

2017-07-19 Thread John McCall via Phabricator via cfe-commits
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

2017-07-18 Thread Simon Atanasyan via Phabricator via cfe-commits
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

2017-07-18 Thread John McCall via Phabricator via cfe-commits
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

2017-07-18 Thread Simon Atanasyan via Phabricator via cfe-commits
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

2017-07-17 Thread John McCall via Phabricator via cfe-commits
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

2017-07-17 Thread Simon Atanasyan via Phabricator via cfe-commits
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();