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

Daniel Dunbar daniel at zuster.org
Mon Sep 8 14:33:46 PDT 2008


Author: ddunbar
Date: Mon Sep  8 16:33:45 2008
New Revision: 55963

URL: http://llvm.org/viewvc/llvm-project?rev=55963&view=rev
Log:
Refactor parameter attribute handling:
  - Add CGCall.h for dealing with ABI issues related to calls.
  - Add CGFunctionInfo and CGCallInfo for capturing ABI relevant
    information about functions and calls.
  - Isolate LLVM parameter attribute handling inside CGCall.cpp

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

Added: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=55963&view=auto

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (added)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Mon Sep  8 16:33:45 2008
@@ -0,0 +1,117 @@
+//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes wrap the information about a call or function
+// definition used to handle ABI compliancy.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGCall.h"
+#include "CodeGenFunction.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "llvm/ParameterAttributes.h"
+using namespace clang;
+using namespace CodeGen;
+
+/***/
+
+static void 
+constructParamAttrListInternal(const Decl *TargetDecl,
+                               const llvm::SmallVector<QualType, 16> &ArgTypes,
+                               ParamAttrListType &PAL) {
+  unsigned FuncAttrs = 0;
+
+  if (TargetDecl) {
+    if (TargetDecl->getAttr<NoThrowAttr>())
+      FuncAttrs |= llvm::ParamAttr::NoUnwind;
+    if (TargetDecl->getAttr<NoReturnAttr>())
+      FuncAttrs |= llvm::ParamAttr::NoReturn;
+  }
+
+  unsigned Index = 1;
+  if (CodeGenFunction::hasAggregateLLVMType(ArgTypes[0])) {
+    PAL.push_back(llvm::ParamAttrsWithIndex::get(Index, 
+                                                 llvm::ParamAttr::StructRet));
+    ++Index;
+  } else if (ArgTypes[0]->isPromotableIntegerType()) {
+    if (ArgTypes[0]->isSignedIntegerType()) {
+      FuncAttrs |= llvm::ParamAttr::SExt;
+    } else if (ArgTypes[0]->isUnsignedIntegerType()) {
+      FuncAttrs |= llvm::ParamAttr::ZExt;
+    }
+  }
+  if (FuncAttrs)
+    PAL.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs));
+  for (llvm::SmallVector<QualType, 8>::const_iterator i = ArgTypes.begin() + 1,
+         e = ArgTypes.end(); i != e; ++i, ++Index) {
+    QualType ParamType = *i;
+    unsigned ParamAttrs = 0;
+    if (ParamType->isRecordType())
+      ParamAttrs |= llvm::ParamAttr::ByVal;
+    if (ParamType->isPromotableIntegerType()) {
+      if (ParamType->isSignedIntegerType()) {
+        ParamAttrs |= llvm::ParamAttr::SExt;
+      } else if (ParamType->isUnsignedIntegerType()) {
+        ParamAttrs |= llvm::ParamAttr::ZExt;
+      }
+    }
+    if (ParamAttrs)
+      PAL.push_back(llvm::ParamAttrsWithIndex::get(Index, ParamAttrs));
+  }
+}
+
+/***/
+
+// FIXME: Use iterator and sidestep silly type array creation.
+
+CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD)
+  : TheDecl(FD) 
+{
+  const FunctionType *FTy = FD->getType()->getAsFunctionType();
+  const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy);
+  
+  ArgTypes.push_back(FTy->getResultType());
+  if (FTP)
+    for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
+      ArgTypes.push_back(FTP->getArgType(i));
+}
+
+CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD,
+                               const ASTContext &Context)
+  : TheDecl(MD) 
+{
+  ArgTypes.push_back(MD->getResultType());
+  ArgTypes.push_back(MD->getSelfDecl()->getType());
+  ArgTypes.push_back(Context.getObjCSelType());
+  for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(),
+         e = MD->param_end(); i != e; ++i)
+    ArgTypes.push_back((*i)->getType());
+}
+
+void CGFunctionInfo::constructParamAttrList(ParamAttrListType &PAL) const {
+  constructParamAttrListInternal(TheDecl, ArgTypes, PAL);
+}
+
+/***/
+
+CGCallInfo::CGCallInfo(QualType _ResultType,
+                       const llvm::SmallVector<std::pair<llvm::Value*, QualType>, 16> &_Args) 
+  : ResultType(_ResultType),
+    Args(_Args) {
+  ArgTypes.push_back(ResultType);
+  for (CallArgList::const_iterator i = Args.begin(), e = Args.end(); i!=e; ++i)
+    ArgTypes.push_back(i->second);
+}
+
+void CGCallInfo::constructParamAttrList(ParamAttrListType &PAL) const {
+  // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set.
+  constructParamAttrListInternal(0, ArgTypes, PAL);
+}

Added: cfe/trunk/lib/CodeGen/CGCall.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.h?rev=55963&view=auto

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.h (added)
+++ cfe/trunk/lib/CodeGen/CGCall.h Mon Sep  8 16:33:45 2008
@@ -0,0 +1,76 @@
+//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes wrap the information about a call or function
+// definition used to handle ABI compliancy.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGCALL_H
+#define CLANG_CODEGEN_CGCALL_H
+
+#include "clang/AST/Type.h"
+
+namespace llvm {
+  class Function;
+  struct ParamAttrsWithIndex;
+  class Value;
+
+  template<typename T, unsigned> class SmallVector;
+}
+
+namespace clang {
+  class ASTContext;
+  class Decl;
+  class FunctionDecl;
+  class ObjCMethodDecl;
+
+namespace CodeGen {
+  typedef llvm::SmallVector<llvm::ParamAttrsWithIndex, 8> ParamAttrListType;
+
+  /// CallArgList - Type for representing both the value and type of
+  /// arguments in a call.
+  typedef llvm::SmallVector<std::pair<llvm::Value*, QualType>, 16> CallArgList;
+
+  /// CGFunctionInfo - Class to encapsulate the information about a
+  /// function definition.
+  class CGFunctionInfo {
+    /// TheDecl - The decl we are storing information for. This is
+    /// either a Function or ObjCMethod Decl.
+    const Decl *TheDecl;
+
+    llvm::SmallVector<QualType, 16> ArgTypes;
+
+  public:
+    CGFunctionInfo(const FunctionDecl *FD);
+    CGFunctionInfo(const ObjCMethodDecl *MD,
+                   const ASTContext &Context);
+
+    const Decl* getDecl() const { return TheDecl; }
+
+    void constructParamAttrList(ParamAttrListType &Args) const;
+  };
+
+  /// CGCallInfo - Class to encapsulate the arguments and clang types
+  /// used in a call.
+  class CGCallInfo {
+    QualType ResultType;
+    const CallArgList &Args;
+
+    llvm::SmallVector<QualType, 16> ArgTypes;
+
+  public:
+    CGCallInfo(QualType _ResultType, const CallArgList &Args);
+    
+    void constructParamAttrList(ParamAttrListType &Args) const;
+  };
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Sep  8 16:33:45 2008
@@ -13,6 +13,7 @@
 
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "CGCall.h"
 #include "CGObjCRuntime.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
@@ -884,11 +885,12 @@
 RValue CodeGenFunction::EmitCall(llvm::Value *Callee, 
                                  QualType ResultType, 
                                  const CallArgList &CallArgs) {
+  // FIXME: Factor out code to load from args into locals into target.
   llvm::SmallVector<llvm::Value*, 16> Args;
   llvm::Value *TempArg0 = 0;
 
-  // Handle struct-return functions by passing a pointer to the location that
-  // we would like to return into.
+  // Handle struct-return functions by passing a pointer to the
+  // location that we would like to return into.
   if (hasAggregateLLVMType(ResultType)) {
     // Create a temporary alloca to hold the result of the call. :(
     TempArg0 = CreateTempAlloca(ConvertType(ResultType));
@@ -900,35 +902,12 @@
     Args.push_back(I->first);
   
   llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
+  CGCallInfo CallInfo(ResultType, CallArgs);
 
-  // Note that there is parallel code in SetFunctionAttributes in CodeGenModule
-  llvm::SmallVector<llvm::ParamAttrsWithIndex, 8> ParamAttrList;
-  unsigned Index = 1;
-  if (TempArg0) {
-    ParamAttrList.push_back(
-        llvm::ParamAttrsWithIndex::get(Index, llvm::ParamAttr::StructRet));
-    ++Index;
-  }
-
-  for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end(); 
-       I != E; ++I, ++Index) {
-    QualType ParamType = I->second;
-    unsigned ParamAttrs = 0;
-    if (ParamType->isRecordType())
-      ParamAttrs |= llvm::ParamAttr::ByVal;
-    if (ParamType->isPromotableIntegerType()) {
-      if (ParamType->isSignedIntegerType()) {
-        ParamAttrs |= llvm::ParamAttr::SExt;
-      } else if (ParamType->isUnsignedIntegerType()) {
-        ParamAttrs |= llvm::ParamAttr::ZExt;
-      }
-    }
-    if (ParamAttrs)
-      ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(Index,
-                                                             ParamAttrs));
-  }
-  CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
-                                         ParamAttrList.size()));
+  CodeGen::ParamAttrListType ParamAttrList;
+  CallInfo.constructParamAttrList(ParamAttrList);
+  CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(), 
+                                         ParamAttrList.size()));  
 
   if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee))
     CI->setCallingConv(F->getCallingConv());

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Sep  8 16:33:45 2008
@@ -24,6 +24,7 @@
 #include <vector>
 #include <map>
 
+#include "CGCall.h"
 #include "CGValue.h"
 
 namespace llvm {
@@ -307,10 +308,6 @@
   //                         Scalar Expression Emission
   //===--------------------------------------------------------------------===//
 
-  /// CallArgList - Type for representing both the value and type of
-  /// arguments in a call.
-  typedef llvm::SmallVector<std::pair<llvm::Value*, QualType>, 16> CallArgList;
-
   /// EmitCallArg - Emit the given expression and append the result
   /// onto the given Args list.
   void EmitCallArg(const Expr *E, CallArgList &Args);

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Sep  8 16:33:45 2008
@@ -14,6 +14,7 @@
 #include "CGDebugInfo.h"
 #include "CodeGenModule.h"
 #include "CodeGenFunction.h"
+#include "CGCall.h"
 #include "CGObjCRuntime.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
@@ -172,78 +173,43 @@
   gv->setSection("llvm.metadata");
 }
 
-void CodeGenModule::SetGlobalValueAttributes(const FunctionDecl *FD,
-                                             llvm::GlobalValue *GV) {
+static void SetGlobalValueAttributes(const Decl *D, 
+                                     bool IsInternal,
+                                     bool IsInline,
+                                     llvm::GlobalValue *GV) {
   // TODO: Set up linkage and many other things.  Note, this is a simple 
   // approximation of what we really want.
-  if (FD->getStorageClass() == FunctionDecl::Static)
+  if (IsInternal) {
     GV->setLinkage(llvm::Function::InternalLinkage);
-  else if (FD->getAttr<DLLImportAttr>())
-    GV->setLinkage(llvm::Function::DLLImportLinkage);
-  else if (FD->getAttr<DLLExportAttr>())
-    GV->setLinkage(llvm::Function::DLLExportLinkage);
-  else if (FD->getAttr<WeakAttr>() || FD->isInline())
-    GV->setLinkage(llvm::Function::WeakLinkage);
+  } else {
+    if (D->getAttr<DLLImportAttr>())
+      GV->setLinkage(llvm::Function::DLLImportLinkage);
+    else if (D->getAttr<DLLExportAttr>())
+      GV->setLinkage(llvm::Function::DLLExportLinkage);
+    else if (D->getAttr<WeakAttr>() || IsInline)
+      GV->setLinkage(llvm::Function::WeakLinkage);
+  }
 
-  if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>())
+  if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>())
     setGlobalVisibility(GV, attr->getVisibility());
   // FIXME: else handle -fvisibility
 
-  if (const AsmLabelAttr *ALA = FD->getAttr<AsmLabelAttr>()) {
+  if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
     // Prefaced with special LLVM marker to indicate that the name
     // should not be munged.
     GV->setName("\01" + ALA->getLabel());
   }
 }
 
-static void 
-SetFunctionAttributesFromTypes(const Decl *FD,
-                               llvm::Function *F,
-                               const llvm::SmallVector<QualType, 16> &ArgTypes) {
-  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;
-  // Note that there is parallel code in CodeGenFunction::EmitCallExpr
-  unsigned increment = 1;
-  if (CodeGenFunction::hasAggregateLLVMType(ArgTypes[0])) {
-    ParamAttrList.push_back(
-        llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet));
-    ++increment;
-  } else if (ArgTypes[0]->isPromotableIntegerType()) {
-    if (ArgTypes[0]->isSignedIntegerType()) {
-      FuncAttrs |= llvm::ParamAttr::SExt;
-    } else if (ArgTypes[0]->isUnsignedIntegerType()) {
-      FuncAttrs |= llvm::ParamAttr::ZExt;
-    }
-  }
-  if (FuncAttrs)
-    ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs));
-  for (llvm::SmallVector<QualType, 8>::const_iterator i = ArgTypes.begin() + 1,
-         e = ArgTypes.end(); i != e; ++i, ++increment) {
-    QualType ParamType = *i;
-    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(increment,
-                                                             ParamAttrs));
-  }
+static void SetFunctionAttrs(const CGFunctionInfo &Info, llvm::Function *F) {
+  ParamAttrListType ParamAttrList;
+  Info.constructParamAttrList(ParamAttrList);
 
   F->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
                                         ParamAttrList.size()));
 
   // Set the appropriate calling convention for the Function.
-  if (FD->getAttr<FastCallAttr>())
+  if (Info.getDecl()->getAttr<FastCallAttr>())
     F->setCallingConv(llvm::CallingConv::Fast);
 }
 
@@ -256,36 +222,19 @@
 
 void CodeGenModule::SetMethodAttributes(const ObjCMethodDecl *MD,
                                         llvm::Function *F) {
-  llvm::SmallVector<QualType, 16> ArgTypes;
-  
-  ArgTypes.push_back(MD->getResultType());
-  ArgTypes.push_back(MD->getSelfDecl()->getType());
-  ArgTypes.push_back(Context.getObjCSelType());
-  for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(),
-         e = MD->param_end(); i != e; ++i)
-    ArgTypes.push_back((*i)->getType());
-
-  SetFunctionAttributesFromTypes(MD, F, ArgTypes);
+  SetFunctionAttrs(CGFunctionInfo(MD, Context), F);
   
   SetFunctionAttributesForDefinition(F);
 
-  // FIXME: set visibility
+  SetGlobalValueAttributes(MD, true, false, F);
 }
 
 void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
                                           llvm::Function *F) {
-  llvm::SmallVector<QualType, 16> ArgTypes;
-  const FunctionType *FTy = FD->getType()->getAsFunctionType();
-  const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy);
-  
-  ArgTypes.push_back(FTy->getResultType());
-  if (FTP)
-    for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
-      ArgTypes.push_back(FTP->getArgType(i));
-
-  SetFunctionAttributesFromTypes(FD, F, ArgTypes);
+  SetFunctionAttrs(CGFunctionInfo(FD), F);
 
-  SetGlobalValueAttributes(FD, F);
+  SetGlobalValueAttributes(FD, FD->getStorageClass() == FunctionDecl::Static, 
+                           FD->isInline(), F);
 }
 
 void CodeGenModule::EmitStatics() {
@@ -574,7 +523,8 @@
                                                      D->getName(),
                                                      aliasee,
                                                      &getModule());
-    SetGlobalValueAttributes(D, alias);
+    // Alias should never be internal
+    SetGlobalValueAttributes(D, false, false, alias);
     return alias;
   } else {
     const llvm::Type *Ty = getTypes().ConvertType(D->getType());

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Sep  8 16:33:45 2008
@@ -218,9 +218,6 @@
   void SetFunctionAttributes(const FunctionDecl *FD,
                              llvm::Function *F);
 
-  void SetGlobalValueAttributes(const FunctionDecl *FD,
-                                llvm::GlobalValue *GV);
-  
   /// EmitGlobal - Emit code for a singal global function or var
   /// decl. Forward declarations are emitted lazily.
   void EmitGlobal(const ValueDecl *D);





More information about the cfe-commits mailing list