mirror of
https://github.com/intel/llvm.git
synced 2026-01-31 07:27:33 +08:00
The PNaCl target no longer permits __attribute__((regparm)).
Remove the custom lowering code dealing with it, disallow it in PNaclTargetInfo and adjust tests accordingly. llvm-svn: 179059
This commit is contained in:
@@ -621,7 +621,7 @@ class NaClTargetInfo : public OSTargetInfo<Target> {
|
||||
this->SizeType = TargetInfo::UnsignedInt;
|
||||
this->PtrDiffType = TargetInfo::SignedInt;
|
||||
this->IntPtrType = TargetInfo::SignedInt;
|
||||
this->RegParmMax = 2;
|
||||
// RegParmMax is inherited from the underlying architecture
|
||||
this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
||||
this->DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
|
||||
"f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
|
||||
@@ -4862,7 +4862,7 @@ public:
|
||||
this->SizeType = TargetInfo::UnsignedInt;
|
||||
this->PtrDiffType = TargetInfo::SignedInt;
|
||||
this->IntPtrType = TargetInfo::SignedInt;
|
||||
this->RegParmMax = 2;
|
||||
this->RegParmMax = 0; // Disallow regparm
|
||||
DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
|
||||
"f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
|
||||
}
|
||||
|
||||
@@ -398,6 +398,9 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// le32/PNaCl bitcode ABI Implementation
|
||||
//
|
||||
// This is a simplified version of the x86_32 ABI. Arguments and return values
|
||||
// are always passed on the stack.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class PNaClABIInfo : public ABIInfo {
|
||||
@@ -405,7 +408,7 @@ class PNaClABIInfo : public ABIInfo {
|
||||
PNaClABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
|
||||
|
||||
ABIArgInfo classifyReturnType(QualType RetTy) const;
|
||||
ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs) const;
|
||||
ABIArgInfo classifyArgumentType(QualType RetTy) const;
|
||||
|
||||
virtual void computeInfo(CGFunctionInfo &FI) const;
|
||||
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
@@ -421,13 +424,9 @@ class PNaClTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const {
|
||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
|
||||
|
||||
// Obtain the initial number of registers available for passing integers
|
||||
// from the function's regparm attribute.
|
||||
unsigned FreeRegs = FI.getHasRegParm() ? FI.getRegParm() : 0;
|
||||
|
||||
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
||||
it != ie; ++it)
|
||||
it->info = classifyArgumentType(it->type, FreeRegs);
|
||||
it->info = classifyArgumentType(it->type);
|
||||
}
|
||||
|
||||
llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
@@ -435,42 +434,25 @@ llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Classify argument of given type \p Ty. \p FreeRegs is the number of
|
||||
/// registers available for passing arguments - it can be updated by this
|
||||
/// method.
|
||||
ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty,
|
||||
unsigned &FreeRegs) const {
|
||||
/// \brief Classify argument of given type \p Ty.
|
||||
ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const {
|
||||
if (isAggregateTypeForABI(Ty)) {
|
||||
// In the PNaCl ABI we always pass records/structures on the stack. The
|
||||
// byval attribute can be used if the record doesn't have non-trivial
|
||||
// constructors/destructors.
|
||||
FreeRegs = 0;
|
||||
if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
|
||||
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
|
||||
return ABIArgInfo::getIndirect(0);
|
||||
}
|
||||
|
||||
// Treat an enum type as its underlying type.
|
||||
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
||||
} else if (const EnumType *EnumTy = Ty->getAs<EnumType>()) {
|
||||
// Treat an enum type as its underlying type.
|
||||
Ty = EnumTy->getDecl()->getIntegerType();
|
||||
|
||||
ABIArgInfo BaseInfo = (Ty->isPromotableIntegerType() ?
|
||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||
|
||||
// Figure out how many of the free registers can be occupied by this type.
|
||||
// regparm registers are 32-bit.
|
||||
unsigned NumRegsRequired = (getContext().getTypeSize(Ty) + 31) / 32;
|
||||
if (NumRegsRequired == 0) return BaseInfo;
|
||||
if (NumRegsRequired > FreeRegs) {
|
||||
// If this type needs more registers than we have available, no more
|
||||
// passing in-registers can happen.
|
||||
FreeRegs = 0;
|
||||
return BaseInfo;
|
||||
} else if (Ty->isFloatingType()) {
|
||||
// Floating-point types don't go inreg.
|
||||
return ABIArgInfo::getDirect();
|
||||
}
|
||||
FreeRegs -= NumRegsRequired;
|
||||
return BaseInfo.isDirect() ?
|
||||
ABIArgInfo::getDirectInReg(BaseInfo.getCoerceToType()) :
|
||||
ABIArgInfo::getExtendInReg(BaseInfo.getCoerceToType());
|
||||
|
||||
return (Ty->isPromotableIntegerType() ?
|
||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||
}
|
||||
|
||||
ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
|
||||
|
||||
@@ -1,41 +1,4 @@
|
||||
// RUN: %clang_cc1 -triple le32-unknown-nacl %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple le32-unknown-nacl %s -fsyntax-only -verify
|
||||
|
||||
#define FASTCALL __attribute__((regparm(2)))
|
||||
void __attribute__((regparm(2))) fc_f1(int i, int j, int k) {} // expected-error{{'regparm' is not valid on this platform}}
|
||||
|
||||
typedef struct {
|
||||
int aaa;
|
||||
double bbbb;
|
||||
int ccc[200];
|
||||
} foo;
|
||||
|
||||
// 2 inreg arguments are supported.
|
||||
void FASTCALL f1(int i, int j, int k);
|
||||
// CHECK: define void @f1(i32 inreg %i, i32 inreg %j, i32 %k)
|
||||
void f1(int i, int j, int k) { }
|
||||
|
||||
// inreg structs are not supported.
|
||||
// CHECK: define void @f2(%struct.foo* inreg %a)
|
||||
void __attribute__((regparm(1))) f2(foo* a) {}
|
||||
|
||||
// Only the first 2 arguments can be passed inreg, and the first
|
||||
// non-integral type consumes remaining available registers.
|
||||
// CHECK: define void @f3(%struct.foo* byval %a, i32 %b)
|
||||
void __attribute__((regparm(2))) f3(foo a, int b) {}
|
||||
|
||||
// Only 64 total bits are supported
|
||||
// CHECK: define void @f4(i64 inreg %g, i32 %h)
|
||||
void __attribute__((regparm(2))) f4(long long g, int h) {}
|
||||
|
||||
typedef void (*FType)(int, int) __attribute ((regparm (2)));
|
||||
FType bar;
|
||||
extern void FASTCALL reduced(char b, double c, foo* d, double e, int f);
|
||||
|
||||
int
|
||||
main(void) {
|
||||
// The presence of double c means that foo* d is not passed inreg. This
|
||||
// behavior is different from current x86-32 behavior
|
||||
// CHECK: call void @reduced(i8 inreg signext 0, {{.*}} %struct.foo* null
|
||||
reduced(0, 0.0, 0, 0.0, 0);
|
||||
// CHECK: call void {{.*}}(i32 inreg 1, i32 inreg 2)
|
||||
bar(1,2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user