[cfe-commits] r51839 - in /cfe/trunk/lib/CodeGen: CGExpr.cpp CodeGenFunction.cpp CodeGenModule.cpp CodeGenModule.h

Eli Friedman eli.friedman at gmail.com
Sun Jun 1 08:54:50 PDT 2008


Author: efriedma
Date: Sun Jun  1 10:54:49 2008
New Revision: 51839

URL: http://llvm.org/viewvc/llvm-project?rev=51839&view=rev
Log:
First cut at setting attributes for functions and calls; this puts us 
much closer to passing the gcc struct layout tests.

It might be possible to refactor this a bit, but I'm not sure there's 
actually enough common code for that to be useful.

To get the calling convention completely correct, a bit of 
platform-specific code is necessary even for x86-Linux. On x86-Linux, the
alignment of function parameters is extremely strange; as far as I can tell,
it's always 4 except for SSE vectors or structs containing SSE vectors.  I'm 
continuing to investigate this.


Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=51839&r1=51838&r2=51839&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sun Jun  1 10:54:49 2008
@@ -711,6 +711,29 @@
   }
   
   llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
+
+  // Note that there is parallel code in SetFunctionAttributes in CodeGenModule
+  llvm::SmallVector<llvm::ParamAttrsWithIndex, 8> ParamAttrList;
+  if (hasAggregateLLVMType(ResultType))
+    ParamAttrList.push_back(
+        llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet));
+  unsigned increment = hasAggregateLLVMType(ResultType) ? 2 : 1;
+  for (unsigned i = 0; i < NumArgs; i++) {
+    QualType ParamType = ArgExprs[i]->getType();
+    unsigned ParamAttrs = 0;
+    if (ParamType->isRecordType())
+      ParamAttrs |= llvm::ParamAttr::ByVal;
+    if (ParamType->isSignedIntegerType() && ParamType->isPromotableIntegerType())
+      ParamAttrs |= llvm::ParamAttr::SExt;
+    if (ParamType->isUnsignedIntegerType() && ParamType->isPromotableIntegerType())
+      ParamAttrs |= llvm::ParamAttr::ZExt;
+    if (ParamAttrs)
+      ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(i + increment,
+                                                             ParamAttrs));
+  }
+  CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
+                                         ParamAttrList.size()));
+
   if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee))
     CI->setCallingConv(F->getCallingConv());
   if (CI->getType() != llvm::Type::VoidTy)

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=51839&r1=51838&r2=51839&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Sun Jun  1 10:54:49 2008
@@ -167,37 +167,6 @@
 
   CurFn = cast<llvm::Function>(CGM.GetAddrOfFunctionDecl(FD, true));
   assert(CurFn->isDeclaration() && "Function already has body?");
-  
-  // TODO: Set up linkage and many other things.  Note, this is a simple 
-  // approximation of what we really want.
-  if (FD->getStorageClass() == FunctionDecl::Static)
-    CurFn->setLinkage(llvm::Function::InternalLinkage);
-  else if (FD->getAttr<DLLImportAttr>())
-    CurFn->setLinkage(llvm::Function::DLLImportLinkage);
-  else if (FD->getAttr<DLLExportAttr>())
-    CurFn->setLinkage(llvm::Function::DLLExportLinkage);
-  else if (FD->getAttr<WeakAttr>() || FD->isInline())
-    CurFn->setLinkage(llvm::Function::WeakLinkage);
-
-  if (FD->getAttr<FastCallAttr>())
-    CurFn->setCallingConv(llvm::CallingConv::Fast);
-
-  if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>())
-    CodeGenModule::setVisibility(CurFn, attr->getVisibility());
-  // FIXME: else handle -fvisibility
-
-
-  unsigned FuncAttrs = 0;
-  if (FD->getAttr<NoThrowAttr>())
-    FuncAttrs |= llvm::ParamAttr::NoUnwind;
-  if (FD->getAttr<NoReturnAttr>())
-    FuncAttrs |= llvm::ParamAttr::NoReturn;
-  
-  if (FuncAttrs) {
-    llvm::ParamAttrsWithIndex PAWI = 
-      llvm::ParamAttrsWithIndex::get(0, FuncAttrs);
-    CurFn->setParamAttrs(llvm::PAListPtr::get(&PAWI, 1));
-  }
 
   llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
   

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=51839&r1=51838&r2=51839&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sun Jun  1 10:54:49 2008
@@ -183,6 +183,66 @@
     if (I->second == OldVal) I->second = NewVal;
 }
 
+bool hasAggregateLLVMType(QualType T) {
+  return !T->isRealType() && !T->isPointerLikeType() &&
+         !T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
+}
+
+void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
+                                          llvm::Function *F,
+                                          const llvm::FunctionType *FTy) {
+  unsigned FuncAttrs = 0;
+  if (FD->getAttr<NoThrowAttr>())
+    FuncAttrs |= llvm::ParamAttr::NoUnwind;
+  if (FD->getAttr<NoReturnAttr>())
+    FuncAttrs |= llvm::ParamAttr::NoReturn;
+
+  llvm::SmallVector<llvm::ParamAttrsWithIndex, 8> ParamAttrList;
+  if (FuncAttrs)
+    ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs));
+  // Note that there is parallel code in CodeGenFunction::EmitCallExpr
+  bool AggregateReturn = hasAggregateLLVMType(FD->getResultType());
+  if (AggregateReturn)
+    ParamAttrList.push_back(
+        llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet));
+  unsigned increment = AggregateReturn ? 2 : 1;
+  for (unsigned i = 0; i < FD->getNumParams(); i++) {
+    QualType ParamType = FD->getParamDecl(i)->getType();
+    unsigned ParamAttrs = 0;
+    if (ParamType->isRecordType())
+      ParamAttrs |= llvm::ParamAttr::ByVal;
+    if (ParamType->isSignedIntegerType() && ParamType->isPromotableIntegerType())
+      ParamAttrs |= llvm::ParamAttr::SExt;
+    if (ParamType->isUnsignedIntegerType() && ParamType->isPromotableIntegerType())
+      ParamAttrs |= llvm::ParamAttr::ZExt;
+    if (ParamAttrs)
+      ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(i + increment,
+                                                             ParamAttrs));
+  }
+  F->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
+                                        ParamAttrList.size()));
+
+  // Set the appropriate calling convention for the Function.
+  if (FD->getAttr<FastCallAttr>())
+    F->setCallingConv(llvm::CallingConv::Fast);
+
+  // TODO: Set up linkage and many other things.  Note, this is a simple 
+  // approximation of what we really want.
+  if (FD->getStorageClass() == FunctionDecl::Static)
+    F->setLinkage(llvm::Function::InternalLinkage);
+  else if (FD->getAttr<DLLImportAttr>())
+    F->setLinkage(llvm::Function::DLLImportLinkage);
+  else if (FD->getAttr<DLLExportAttr>())
+    F->setLinkage(llvm::Function::DLLExportLinkage);
+  else if (FD->getAttr<WeakAttr>() || FD->isInline())
+    F->setLinkage(llvm::Function::WeakLinkage);
+
+  if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>())
+    CodeGenModule::setVisibility(F, attr->getVisibility());
+  // FIXME: else handle -fvisibility
+}
+
+
 
 llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D,
                                                      bool isDefinition) {
@@ -202,9 +262,7 @@
     F = llvm::Function::Create(FTy, llvm::Function::ExternalLinkage,
                                D->getName(), &getModule());
 
-    // Set the appropriate calling convention for the Function.
-    if (D->getAttr<FastCallAttr>())
-      F->setCallingConv(llvm::CallingConv::Fast);
+    SetFunctionAttributes(D, F, FTy);
     return Entry = F;
   }
   
@@ -243,6 +301,7 @@
   assert(F->isDeclaration() && "Shouldn't replace non-declaration");
   F->eraseFromParent();
 
+  SetFunctionAttributes(D, NewFn, FTy);
   // Return the new function which has the right type.
   return Entry = NewFn;
 }

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=51839&r1=51838&r2=51839&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Sun Jun  1 10:54:49 2008
@@ -26,6 +26,7 @@
   class Function;
   class GlobalValue;
   class TargetData;
+  class FunctionType;
 }
 
 namespace clang {
@@ -149,6 +150,10 @@
   /// searches for any entries in GlobalDeclMap that point to OldVal, changing
   /// them to point to NewVal.  This is badbadbad, FIXME!
   void ReplaceMapValuesWith(llvm::Constant *OldVal, llvm::Constant *NewVal);
+
+  void SetFunctionAttributes(const FunctionDecl *FD,
+                             llvm::Function *F,
+                             const llvm::FunctionType *FTy);
   
 };
 }  // end namespace CodeGen





More information about the cfe-commits mailing list