diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.h | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 137 | ||||
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.h | 50 |
6 files changed, 175 insertions, 35 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index eb716b6ab18..5ecc30eb4ea 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -17,6 +17,7 @@ #include "CGCall.h" #include "CGObjCRuntime.h" #include "Mangle.h" +#include "TargetInfo.h" #include "clang/CodeGen/CodeGenOptions.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" @@ -42,8 +43,9 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, Diagnostic &diags) : BlockModule(C, M, TD, Types, *this), Context(C), Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M), - TheTargetData(TD), Diags(diags), Types(C, M, TD), MangleCtx(C), - VtableInfo(*this), Runtime(0), + TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags), + Types(C, M, TD, getTargetCodeGenInfo().getABIInfo()), + MangleCtx(C), VtableInfo(*this), Runtime(0), MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0), VMContext(M.getContext()) { @@ -376,6 +378,8 @@ void CodeGenModule::SetCommonAttributes(const Decl *D, if (const SectionAttr *SA = D->getAttr<SectionAttr>()) GV->setSection(SA->getName()); + + getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this); } void CodeGenModule::SetInternalFunctionAttributes(const Decl *D, diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 47d8c54cd98..c7aa7a47a83 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -43,6 +43,7 @@ namespace llvm { } namespace clang { + class TargetCodeGenInfo; class ASTContext; class FunctionDecl; class IdentifierInfo; @@ -85,6 +86,7 @@ class CodeGenModule : public BlockModule { const CodeGenOptions &CodeGenOpts; llvm::Module &TheModule; const llvm::TargetData &TheTargetData; + mutable const TargetCodeGenInfo *TheTargetCodeGenInfo; Diagnostic &Diags; CodeGenTypes Types; MangleContext MangleCtx; @@ -191,6 +193,7 @@ public: Diagnostic &getDiags() const { return Diags; } const llvm::TargetData &getTargetData() const { return TheTargetData; } llvm::LLVMContext &getLLVMContext() { return VMContext; } + const TargetCodeGenInfo &getTargetCodeGenInfo() const; /// getDeclVisibilityMode - Compute the visibility of the decl \arg D. LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const; diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index cd34e0c064e..bfea2367a92 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -28,9 +28,9 @@ using namespace clang; using namespace CodeGen; CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M, - const llvm::TargetData &TD) + const llvm::TargetData &TD, const ABIInfo &Info) : Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD), - TheABIInfo(0) { + TheABIInfo(Info) { } CodeGenTypes::~CodeGenTypes() { @@ -44,7 +44,6 @@ CodeGenTypes::~CodeGenTypes() { while (I != E) delete &*I++; } - delete TheABIInfo; } /// ConvertType - Convert the specified type to its LLVM form. diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 2ff602f900f..7e342526e84 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -85,7 +85,7 @@ class CodeGenTypes { const TargetInfo &Target; llvm::Module& TheModule; const llvm::TargetData& TheTargetData; - mutable const ABIInfo* TheABIInfo; + const ABIInfo& TheABIInfo; llvm::SmallVector<std::pair<QualType, llvm::OpaqueType *>, 8> PointersToResolve; @@ -140,13 +140,14 @@ private: /// interface to convert type T into a llvm::Type. const llvm::Type *ConvertNewType(QualType T); public: - CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD); + CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD, + const ABIInfo &Info); ~CodeGenTypes(); const llvm::TargetData &getTargetData() const { return TheTargetData; } const TargetInfo &getTarget() const { return Target; } ASTContext &getContext() const { return Context; } - const ABIInfo &getABIInfo() const; + const ABIInfo &getABIInfo() const { return TheABIInfo; } llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); } /// ConvertType - Convert type T into a llvm::Type. diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 863a297cc6a..e5fd47ec2d1 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -1,4 +1,4 @@ -//===---- TargetABIInfo.cpp - Encapsulate target ABI details ----*- C++ -*-===// +//===---- TargetInfo.cpp - Encapsulate target details -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,10 +12,12 @@ // //===----------------------------------------------------------------------===// +#include "TargetInfo.h" #include "ABIInfo.h" #include "CodeGenFunction.h" #include "clang/AST/RecordLayout.h" #include "llvm/Type.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -50,6 +52,8 @@ void ABIArgInfo::dump() const { OS << ")\n"; } +TargetCodeGenInfo::~TargetCodeGenInfo() { delete Info; } + static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays); /// isEmptyField - Return true iff a the field is "empty", that is it @@ -251,6 +255,27 @@ class DefaultABIInfo : public ABIInfo { CodeGenFunction &CGF) const; }; +class DefaultTargetCodeGenInfo : public TargetCodeGenInfo { +public: + DefaultTargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {}; +}; + +llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const { + return 0; +} + +ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty, + ASTContext &Context, + llvm::LLVMContext &VMContext) const { + if (CodeGenFunction::hasAggregateLLVMType(Ty)) { + return ABIArgInfo::getIndirect(0); + } else { + return (Ty->isPromotableIntegerType() ? + ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + } +} + /// X86_32ABIInfo - The X86-32 ABI information. class X86_32ABIInfo : public ABIInfo { ASTContext &Context; @@ -291,8 +316,14 @@ public: : ABIInfo(), Context(Context), IsDarwinVectorABI(d), IsSmallStructInRegABI(p) {} }; -} +class X86_32TargetCodeGenInfo : public TargetCodeGenInfo { +public: + X86_32TargetCodeGenInfo(ASTContext &Context, bool d, bool p) + :TargetCodeGenInfo(new X86_32ABIInfo(Context, d, p)) {}; +}; + +} /// shouldReturnTypeInRegister - Determine if the given type should be /// passed in a register (for the Darwin ABI). @@ -585,6 +616,12 @@ public: virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const; }; + +class X86_64TargetCodeGenInfo : public TargetCodeGenInfo { +public: + X86_64TargetCodeGenInfo():TargetCodeGenInfo(new X86_64ABIInfo()) {}; +}; + } X86_64ABIInfo::Class X86_64ABIInfo::merge(Class Accum, @@ -1389,6 +1426,11 @@ class PIC16ABIInfo : public ABIInfo { CodeGenFunction &CGF) const; }; +class PIC16TargetCodeGenInfo : public TargetCodeGenInfo { +public: + PIC16TargetCodeGenInfo():TargetCodeGenInfo(new PIC16ABIInfo()) {}; +}; + } ABIArgInfo PIC16ABIInfo::classifyReturnType(QualType RetTy, @@ -1448,6 +1490,12 @@ private: CodeGenFunction &CGF) const; }; +class ARMTargetCodeGenInfo : public TargetCodeGenInfo { +public: + ARMTargetCodeGenInfo(ARMABIInfo::ABIKind K) + :TargetCodeGenInfo(new ARMABIInfo(K)) {}; +}; + } void ARMABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context, @@ -1704,6 +1752,11 @@ class SystemZABIInfo : public ABIInfo { CodeGenFunction &CGF) const; }; +class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { +public: + SystemZTargetCodeGenInfo():TargetCodeGenInfo(new SystemZABIInfo()) {}; +}; + } bool SystemZABIInfo::isPromotableIntegerType(QualType Ty) const { @@ -1757,51 +1810,79 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty, } } -ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty, - ASTContext &Context, - llvm::LLVMContext &VMContext) const { - if (CodeGenFunction::hasAggregateLLVMType(Ty)) { - return ABIArgInfo::getIndirect(0); - } else { - return (Ty->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); - } +// MSP430 ABI Implementation + +namespace { + +class MSP430TargetCodeGenInfo : public TargetCodeGenInfo { +public: + MSP430TargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {}; + void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const; +}; + } -llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const { - return 0; +void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D, + llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const { + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + if (const MSP430InterruptAttr *attr = FD->getAttr<MSP430InterruptAttr>()) { + // Handle 'interrupt' attribute: + llvm::Function *F = cast<llvm::Function>(GV); + + // Step 1: Set ISR calling convention. + F->setCallingConv(llvm::CallingConv::MSP430_INTR); + + // Step 2: Add attributes goodness. + F->addFnAttr(llvm::Attribute::NoInline); + + // Step 3: Emit ISR vector alias. + unsigned Num = attr->getNumber() + 0xffe0; + new llvm::GlobalAlias(GV->getType(), llvm::Function::ExternalLinkage, + "vector_" + + llvm::LowercaseString(llvm::utohexstr(Num)), + GV, &M.getModule()); + } + } } -const ABIInfo &CodeGenTypes::getABIInfo() const { - if (TheABIInfo) - return *TheABIInfo; +const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() const { + if (TheTargetCodeGenInfo) + return *TheTargetCodeGenInfo; - // For now we just cache the ABIInfo in CodeGenTypes and don't free it. + // For now we just cache the TargetCodeGenInfo in CodeGenModule and don't + // free it. const llvm::Triple &Triple(getContext().Target.getTriple()); switch (Triple.getArch()) { default: - return *(TheABIInfo = new DefaultABIInfo); + return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo); case llvm::Triple::arm: case llvm::Triple::thumb: // FIXME: We want to know the float calling convention as well. if (strcmp(getContext().Target.getABI(), "apcs-gnu") == 0) - return *(TheABIInfo = new ARMABIInfo(ARMABIInfo::APCS)); + return *(TheTargetCodeGenInfo = + new ARMTargetCodeGenInfo(ARMABIInfo::APCS)); - return *(TheABIInfo = new ARMABIInfo(ARMABIInfo::AAPCS)); + return *(TheTargetCodeGenInfo = + new ARMTargetCodeGenInfo(ARMABIInfo::AAPCS)); case llvm::Triple::pic16: - return *(TheABIInfo = new PIC16ABIInfo()); + return *(TheTargetCodeGenInfo = new PIC16TargetCodeGenInfo()); case llvm::Triple::systemz: - return *(TheABIInfo = new SystemZABIInfo()); + return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo()); + + case llvm::Triple::msp430: + return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo()); case llvm::Triple::x86: switch (Triple.getOS()) { case llvm::Triple::Darwin: - return *(TheABIInfo = new X86_32ABIInfo(Context, true, true)); + return *(TheTargetCodeGenInfo = + new X86_32TargetCodeGenInfo(Context, true, true)); case llvm::Triple::Cygwin: case llvm::Triple::MinGW32: case llvm::Triple::MinGW64: @@ -1809,13 +1890,15 @@ const ABIInfo &CodeGenTypes::getABIInfo() const { case llvm::Triple::DragonFly: case llvm::Triple::FreeBSD: case llvm::Triple::OpenBSD: - return *(TheABIInfo = new X86_32ABIInfo(Context, false, true)); + return *(TheTargetCodeGenInfo = + new X86_32TargetCodeGenInfo(Context, false, true)); default: - return *(TheABIInfo = new X86_32ABIInfo(Context, false, false)); + return *(TheTargetCodeGenInfo = + new X86_32TargetCodeGenInfo(Context, false, false)); } case llvm::Triple::x86_64: - return *(TheABIInfo = new X86_64ABIInfo()); + return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo()); } } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h new file mode 100644 index 00000000000..495b22fc284 --- /dev/null +++ b/clang/lib/CodeGen/TargetInfo.h @@ -0,0 +1,50 @@ +//===---- TargetInfo.h - Encapsulate target 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_TARGETINFO_H +#define CLANG_CODEGEN_TARGETINFO_H + +namespace llvm { + class GlobalValue; +} + +namespace clang { + class ABIInfo; + class Decl; + + namespace CodeGen { + class CodeGenModule; + } + + /// TargetCodeGenInfo - This class organizes various target-specific + /// codegeneration issues, like target-specific attributes, builtins and so + /// on. + class TargetCodeGenInfo { + ABIInfo *Info; + public: + // WARNING: Acquires the ownership of ABIInfo. + TargetCodeGenInfo(ABIInfo *info = 0):Info(info) { }; + virtual ~TargetCodeGenInfo(); + + /// getABIInfo() - Returns ABI info helper for the target. + const ABIInfo& getABIInfo() const { return *Info; } + + /// SetTargetAttributes - Provides a convenient hook to handle extra + /// target-specific attributes for the given global. + virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const { }; + }; +} + +#endif // CLANG_CODEGEN_TARGETINFO_H |