[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