[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