[cfe-commits] r129206 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/DumpXML.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGCall.h lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaType.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/CodeGen/regparm-flag.c

Eli Friedman eli.friedman at gmail.com
Sat Apr 9 01:18:08 PDT 2011


Author: efriedma
Date: Sat Apr  9 03:18:08 2011
New Revision: 129206

URL: http://llvm.org/viewvc/llvm-project?rev=129206&view=rev
Log:
PR8369: make __attribute((regparm(0))) work correctly.  Original patch by
pageexec at freemail.hu, tweaks by me.


Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/DumpXML.cpp
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/CGCall.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/CodeGen/regparm-flag.c

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sat Apr  9 03:18:08 2011
@@ -2271,12 +2271,13 @@
     // you'll need to adjust both the Bits field below and
     // Type::FunctionTypeBitfields.
 
-    //   |  CC  |noreturn|regparm
-    //   |0 .. 2|   3    |4 ..  6
+    //   |  CC  |noreturn|hasregparm|regparm
+    //   |0 .. 2|   3    |    4     |5 ..  7
     enum { CallConvMask = 0x7 };
     enum { NoReturnMask = 0x8 };
+    enum { HasRegParmMask = 0x10 };
     enum { RegParmMask = ~(CallConvMask | NoReturnMask),
-           RegParmOffset = 4 };
+           RegParmOffset = 5 };
 
     unsigned char Bits;
 
@@ -2287,9 +2288,10 @@
    public:
     // Constructor with no defaults. Use this when you know that you
     // have all the elements (when reading an AST file for example).
-    ExtInfo(bool noReturn, unsigned regParm, CallingConv cc) {
+    ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc) {
       Bits = ((unsigned) cc) |
              (noReturn ? NoReturnMask : 0) |
+             (hasRegParm ? HasRegParmMask : 0) |
              (regParm << RegParmOffset);
     }
 
@@ -2298,6 +2300,7 @@
     ExtInfo() : Bits(0) {}
 
     bool getNoReturn() const { return Bits & NoReturnMask; }
+    bool getHasRegParm() const { return Bits & HasRegParmMask; }
     unsigned getRegParm() const { return Bits >> RegParmOffset; }
     CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
 
@@ -2319,7 +2322,7 @@
     }
 
     ExtInfo withRegParm(unsigned RegParm) const {
-      return ExtInfo((Bits & ~RegParmMask) | (RegParm << RegParmOffset));
+      return ExtInfo(HasRegParmMask | (Bits & ~RegParmMask) | (RegParm << RegParmOffset));
     }
 
     ExtInfo withCallingConv(CallingConv cc) const {
@@ -2355,7 +2358,8 @@
 public:
 
   QualType getResultType() const { return ResultType; }
-  
+
+  bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
   unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
   bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
   CallingConv getCallConv() const { return getExtInfo().getCC(); }

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat Apr  9 03:18:08 2011
@@ -5175,6 +5175,8 @@
     return QualType();
 
   // Regparm is part of the calling convention.
+  if (lbaseInfo.getHasRegParm() != rbaseInfo.getHasRegParm())
+    return QualType();
   if (lbaseInfo.getRegParm() != rbaseInfo.getRegParm())
     return QualType();
 
@@ -5187,6 +5189,7 @@
     allRTypes = false;
 
   FunctionType::ExtInfo einfo(NoReturn,
+                              lbaseInfo.getHasRegParm(),
                               lbaseInfo.getRegParm(),
                               lbaseInfo.getCC());
 

Modified: cfe/trunk/lib/AST/DumpXML.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DumpXML.cpp?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DumpXML.cpp (original)
+++ cfe/trunk/lib/AST/DumpXML.cpp Sat Apr  9 03:18:08 2011
@@ -955,7 +955,7 @@
   void visitFunctionTypeAttrs(FunctionType *T) {
     setFlag("noreturn", T->getNoReturnAttr());
     setCallingConv(T->getCallConv());
-    if (T->getRegParmType()) setInteger("regparm", T->getRegParmType());
+    if (T->getHasRegParm()) setInteger("regparm", T->getRegParmType());
   }
   void visitFunctionTypeChildren(FunctionType *T) {
     dispatch(T->getResultType());

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Sat Apr  9 03:18:08 2011
@@ -188,6 +188,7 @@
                          ArgTys,
                          FunctionType::ExtInfo(
                              /*NoReturn*/ false,
+                             /*HasRegParm*/ false,
                              /*RegParm*/ 0,
                              getCallingConventionForDecl(MD)));
 }
@@ -255,7 +256,7 @@
     return *FI;
 
   // Construct the function info.
-  FI = new CGFunctionInfo(CC, Info.getNoReturn(), Info.getRegParm(), ResTy,
+  FI = new CGFunctionInfo(CC, Info.getNoReturn(), Info.getHasRegParm(), Info.getRegParm(), ResTy,
                           ArgTys.data(), ArgTys.size());
   FunctionInfos.InsertNode(FI, InsertPos);
 
@@ -284,13 +285,13 @@
 }
 
 CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention,
-                               bool _NoReturn, unsigned _RegParm,
+                               bool _NoReturn, bool _HasRegParm, unsigned _RegParm,
                                CanQualType ResTy,
                                const CanQualType *ArgTys,
                                unsigned NumArgTys)
   : CallingConvention(_CallingConvention),
     EffectiveCallingConvention(_CallingConvention),
-    NoReturn(_NoReturn), RegParm(_RegParm)
+    NoReturn(_NoReturn), HasRegParm(_HasRegParm), RegParm(_RegParm)
 {
   NumArgs = NumArgTys;
 
@@ -762,8 +763,10 @@
     PAL.push_back(llvm::AttributeWithIndex::get(0, RetAttrs));
 
   // FIXME: RegParm should be reduced in case of global register variable.
-  signed RegParm = FI.getRegParm();
-  if (!RegParm)
+  signed RegParm;
+  if (FI.getHasRegParm())
+    RegParm = FI.getRegParm();
+  else
     RegParm = CodeGenOpts.NumRegisterParameters;
 
   unsigned PointerWidth = getContext().Target.getPointerWidth(0);

Modified: cfe/trunk/lib/CodeGen/CGCall.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.h?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.h (original)
+++ cfe/trunk/lib/CodeGen/CGCall.h Sat Apr  9 03:18:08 2011
@@ -83,6 +83,7 @@
     ArgInfo *Args;
 
     /// How many arguments to pass inreg.
+    bool HasRegParm;
     unsigned RegParm;
 
   public:
@@ -90,7 +91,7 @@
     typedef ArgInfo *arg_iterator;
 
     CGFunctionInfo(unsigned CallingConvention, bool NoReturn,
-                   unsigned RegParm, CanQualType ResTy,
+                   bool HasRegParm, unsigned RegParm, CanQualType ResTy,
                    const CanQualType *ArgTys, unsigned NumArgTys);
     ~CGFunctionInfo() { delete[] Args; }
 
@@ -116,6 +117,7 @@
       EffectiveCallingConvention = Value;
     }
 
+    bool getHasRegParm() const { return HasRegParm; }
     unsigned getRegParm() const { return RegParm; }
 
     CanQualType getReturnType() const { return Args[0].type; }
@@ -126,6 +128,7 @@
     void Profile(llvm::FoldingSetNodeID &ID) {
       ID.AddInteger(getCallingConvention());
       ID.AddBoolean(NoReturn);
+      ID.AddBoolean(HasRegParm);
       ID.AddInteger(RegParm);
       getReturnType().Profile(ID);
       for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it)
@@ -139,6 +142,7 @@
                         Iterator end) {
       ID.AddInteger(Info.getCC());
       ID.AddBoolean(Info.getNoReturn());
+      ID.AddBoolean(Info.getHasRegParm());
       ID.AddInteger(Info.getRegParm());
       ResTy.Profile(ID);
       for (; begin != end; ++begin) {

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Apr  9 03:18:08 2011
@@ -1270,8 +1270,9 @@
   }
 
   // Merge regparm attribute.
-  if (OldTypeInfo.getRegParm() != NewTypeInfo.getRegParm()) {
-    if (NewTypeInfo.getRegParm()) {
+  if (OldTypeInfo.getHasRegParm() != NewTypeInfo.getHasRegParm() ||
+      OldTypeInfo.getRegParm() != NewTypeInfo.getRegParm()) {
+    if (NewTypeInfo.getHasRegParm()) {
       Diag(New->getLocation(), diag::err_regparm_mismatch)
         << NewType->getRegParmType()
         << OldType->getRegParmType();

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Apr  9 03:18:08 2011
@@ -9367,7 +9367,7 @@
   // If we don't have a function type, just build one from nothing.
   } else {
     FunctionProtoType::ExtProtoInfo EPI;
-    EPI.ExtInfo = FunctionType::ExtInfo(NoReturn, 0, CC_Default);
+    EPI.ExtInfo = FunctionType::ExtInfo(NoReturn, false, 0, CC_Default);
     BlockTy = Context.getFunctionType(RetTy, 0, 0, EPI);
   }
 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Sat Apr  9 03:18:08 2011
@@ -2976,7 +2976,7 @@
     }
 
     // Also diagnose fastcall with regparm.
-    if (fn->getRegParmType()) {
+    if (fn->getHasRegParm()) {
       S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible)
         << "regparm"
         << FunctionType::getNameForCallConv(CC);

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sat Apr  9 03:18:08 2011
@@ -3092,12 +3092,12 @@
   }
 
   case TYPE_FUNCTION_NO_PROTO: {
-    if (Record.size() != 4) {
+    if (Record.size() != 5) {
       Error("incorrect encoding of no-proto function type");
       return QualType();
     }
     QualType ResultType = GetType(Record[0]);
-    FunctionType::ExtInfo Info(Record[1], Record[2], (CallingConv)Record[3]);
+    FunctionType::ExtInfo Info(Record[1], Record[2], Record[3], (CallingConv)Record[4]);
     return Context->getFunctionNoProtoType(ResultType, Info);
   }
 
@@ -3106,10 +3106,11 @@
 
     FunctionProtoType::ExtProtoInfo EPI;
     EPI.ExtInfo = FunctionType::ExtInfo(/*noreturn*/ Record[1],
-                                        /*regparm*/ Record[2],
-                                        static_cast<CallingConv>(Record[3]));
+                                        /*hasregparm*/ Record[2],
+                                        /*regparm*/ Record[3],
+                                        static_cast<CallingConv>(Record[4]));
 
-    unsigned Idx = 4;
+    unsigned Idx = 5;
     unsigned NumParams = Record[Idx++];
     llvm::SmallVector<QualType, 16> ParamTypes;
     for (unsigned I = 0; I != NumParams; ++I)

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sat Apr  9 03:18:08 2011
@@ -161,6 +161,7 @@
   Writer.AddTypeRef(T->getResultType(), Record);
   FunctionType::ExtInfo C = T->getExtInfo();
   Record.push_back(C.getNoReturn());
+  Record.push_back(C.getHasRegParm());
   Record.push_back(C.getRegParm());
   // FIXME: need to stabilize encoding of calling convention...
   Record.push_back(C.getCC());

Modified: cfe/trunk/test/CodeGen/regparm-flag.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/regparm-flag.c?rev=129206&r1=129205&r2=129206&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/regparm-flag.c (original)
+++ cfe/trunk/test/CodeGen/regparm-flag.c Sat Apr  9 03:18:08 2011
@@ -4,12 +4,17 @@
 void f1(int a, int b, int c, int d,
         int e, int f, int g, int h);
 
+void f2(int a, int b) __attribute((regparm(0)));
+
 void f0() {
 // CHECK: call void @f1(i32 inreg 1, i32 inreg 2, i32 inreg 3, i32 inreg 4,
 // CHECK: i32 5, i32 6, i32 7, i32 8)
   f1(1, 2, 3, 4, 5, 6, 7, 8);
+// CHECK: call void @f2(i32 1, i32 2)
+  f2(1, 2);
 }
 
 // CHECK: declare void @f1(i32 inreg, i32 inreg, i32 inreg, i32 inreg,
 // CHECK: i32, i32, i32, i32)
+// CHECK: declare void @f2(i32, i32)
 





More information about the cfe-commits mailing list