]> granicus.if.org Git - clang/commitdiff
Basic support for regparm codegen
authorAnton Korobeynikov <asl@math.spbu.ru>
Sat, 4 Apr 2009 00:49:24 +0000 (00:49 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Sat, 4 Apr 2009 00:49:24 +0000 (00:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68414 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Attr.h
lib/CodeGen/CGCall.cpp
lib/CodeGen/CodeGenModule.cpp
lib/Sema/SemaDeclAttr.cpp

index 2a2d0f377b15120aa067cf2153641fa6903290f0..28f7ec2db6ce933f57fa8d444d3d86fa79e7133b 100644 (file)
@@ -552,7 +552,7 @@ class RegparmAttr : public Attr {
 public:
   RegparmAttr(unsigned np) : Attr(Regparm), NumParams(np) {}
 
-  unsigned getNumParams() { return NumParams; }
+  unsigned getNumParams() const { return NumParams; }
 
   // Implement isa/cast/dyncast/etc.
     
index 19f66b16715ce4e8d9ffb7167ab93e7f787b4a95..e3f824fc7428cddfb78d905b7011a32f3d1922e5 100644 (file)
@@ -1646,6 +1646,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
   unsigned FuncAttrs = 0;
   unsigned RetAttrs = 0;
 
+  // FIXME: handle sseregparm someday...
   if (TargetDecl) {
     if (TargetDecl->getAttr<NoThrowAttr>())
       FuncAttrs |= llvm::Attribute::NoUnwind;
@@ -1691,19 +1692,29 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
 
   if (RetAttrs)
     PAL.push_back(llvm::AttributeWithIndex::get(0, RetAttrs));
+
+  // FIXME: we need to honour command line settings also...
+  // FIXME: RegParm should be reduced in case of nested functions and/or global
+  // register variable.
+  signed RegParm = 0;
+  if (TargetDecl)
+    if (const RegparmAttr *RegParmAttr = TargetDecl->getAttr<RegparmAttr>())
+      RegParm = RegParmAttr->getNumParams();
+
+  unsigned PointerWidth = getContext().Target.getPointerWidth(0);
   for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(), 
          ie = FI.arg_end(); it != ie; ++it) {
     QualType ParamType = it->type;
     const ABIArgInfo &AI = it->info;
     unsigned Attributes = 0;
-    
+
     switch (AI.getKind()) {
     case ABIArgInfo::Coerce:
       break;
 
     case ABIArgInfo::Indirect:
       Attributes |= llvm::Attribute::ByVal;
-      Attributes |= 
+      Attributes |=
         llvm::Attribute::constructAlignmentFromInt(AI.getIndirectAlign());
       // byval disables readnone and readonly.
       FuncAttrs &= ~(llvm::Attribute::ReadOnly |
@@ -1718,8 +1729,16 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
           Attributes |= llvm::Attribute::ZExt;
         }
       }
+      if (RegParm > 0 &&
+          (ParamType->isIntegerType() || ParamType->isPointerType())) {
+        RegParm -=
+          (Context.getTypeSize(ParamType) + PointerWidth - 1) / PointerWidth;
+        if (RegParm >= 0)
+          Attributes |= llvm::Attribute::InReg;
+      }
+      // FIXME: handle sseregparm someday...
       break;
-     
+
     case ABIArgInfo::Ignore:
       // Skip increment, no matching LLVM parameter.
       continue; 
index b92776face028e072a09b2cb654384ab26292ddc..b4cf5331869de2f8773a457d0915d5a844df942e 100644 (file)
@@ -296,9 +296,6 @@ void CodeGenModule::SetFunctionAttributes(const Decl *D,
 
   if (D->getAttr<StdCallAttr>())
     F->setCallingConv(llvm::CallingConv::X86_StdCall);
-
-  if (D->getAttr<RegparmAttr>())
-    ErrorUnsupported(D, "regparm attribute");
 }
 
 /// SetFunctionAttributesForDefinition - Set function attributes
index a68ddf6c003c3de2917298f0595cc070e25d4123..cecae0e27b0f677bc94ee8db54a59c43fad9e7eb 100644 (file)
@@ -1471,7 +1471,6 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  // FIXME: we need to honour command line settings also...
   if (NumParams.getLimitedValue(4) > S.Context.Target.getRegParmMax()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
       << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();