From: Chris Lattner Date: Thu, 8 May 2008 05:58:21 +0000 (+0000) Subject: Add basic support for the pic-* target triples and add support for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2621fd1d6d3c5eadcae246859f62738645df7540;p=clang Add basic support for the pic-* target triples and add support for targets that do not support recursion (and thus codegen stack variables as globals). Patch contributed by Alireza Moshtaghi! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50844 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index cd71759440..5a4f1c71d2 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -36,6 +36,7 @@ protected: // values are specified by the TargetInfo constructor. bool CharIsSigned; unsigned WCharWidth, WCharAlign; + unsigned IntWidth, IntAlign; unsigned DoubleWidth, DoubleAlign; const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat; @@ -59,8 +60,8 @@ public: /// getPointerWidth - Return the width of pointers on this target, for the /// specified address space. FIXME: implement correctly. - uint64_t getPointerWidth(unsigned AddrSpace) const { return 32; } - uint64_t getPointerAlign(unsigned AddrSpace) const { return 32; } + virtual uint64_t getPointerWidth(unsigned AddrSpace) const { return 32; } + virtual uint64_t getPointerAlign(unsigned AddrSpace) const { return 32; } /// getBoolWidth/Align - Return the size of '_Bool' and C++ 'bool' for this /// target, in bits. @@ -81,8 +82,8 @@ public: /// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for /// this target, in bits. - unsigned getIntWidth() const { return 32; } // FIXME - unsigned getIntAlign() const { return 32; } // FIXME + unsigned getIntWidth() const { return IntWidth; } + unsigned getIntAlign() const { return IntAlign; } /// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' /// for this target, in bits. @@ -191,6 +192,8 @@ public: const char * const Aliases[5]; const char * const Register; }; + + virtual bool useGlobalsForAutomaticVariables() const {return false;} protected: virtual void getGCCRegNames(const char * const *&Names, diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 4ce32a9972..675406edef 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -24,6 +24,7 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) { // Set defaults. These should be overridden by concrete targets as needed. CharIsSigned = true; WCharWidth = WCharAlign = 32; + IntWidth = IntAlign = 32; DoubleWidth = 64; DoubleAlign = 32; FloatFormat = &llvm::APFloat::IEEEsingle; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index c4ffa0d65e..25bc6fbb4d 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -863,6 +863,36 @@ public: } // end anonymous namespace. +namespace { + class PIC16TargetInfo : public TargetInfo{ + public: + PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) { + IntWidth = IntAlign = 16; + } + virtual uint64_t getPointerWidth(unsigned AddrSpace) const { return 16; } + virtual uint64_t getPointerAlign(unsigned AddrSpace) const { return 8; } + virtual unsigned getIntWidth() const { return 16; } + virtual unsigned getIntAlign() const { return 8; } + virtual void getTargetDefines(std::vector &Defines) const { + Define(Defines, "__pic16"); + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const {} + virtual const char *getVAListDeclaration() const { return "";} + virtual const char *getClobbers() const {return "";} + virtual const char *getTargetPrefix() const {return "";} + virtual void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const {} + virtual bool validateAsmConstraint(char c, + TargetInfo::ConstraintInfo &info) const { + return true; + } + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const {} + virtual bool useGlobalsForAutomaticVariables() const {return true;} + }; +} + //===----------------------------------------------------------------------===// // Driver code //===----------------------------------------------------------------------===// @@ -890,6 +920,9 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) { if (T.find("x86_64-") == 0) return new DarwinX86_64TargetInfo(T); + if (T.find("pic16-") == 0) + return new PIC16TargetInfo(T); + if (IsX86(T)) return new DarwinI386TargetInfo(T); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index df5882c217..bd68288bba 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -15,6 +15,7 @@ #include "CodeGenModule.h" #include "clang/AST/AST.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/TargetInfo.h" #include "llvm/GlobalVariable.h" #include "llvm/Type.h" using namespace clang; @@ -67,16 +68,16 @@ void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) { } } -void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) { +llvm::GlobalValue * +CodeGenFunction::GenerateStaticBlockVarDecl(const VarDecl &D, + bool NoInit, + const char *Separator) { QualType Ty = D.getType(); assert(Ty->isConstantSizeType() && "VLAs can't be static"); - llvm::Value *&DMEntry = LocalDeclMap[&D]; - assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); - const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty); llvm::Constant *Init = 0; - if (D.getInit() == 0) { + if ((D.getInit() == 0) || NoInit) { Init = llvm::Constant::getNullValue(LTy); } else { Init = CGM.EmitConstantExpr(D.getInit(), this); @@ -92,9 +93,19 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) { llvm::GlobalValue *GV = new llvm::GlobalVariable(LTy, false, llvm::GlobalValue::InternalLinkage, - Init, ContextName + "." + D.getName(), + Init, ContextName + Separator + D.getName(), &CGM.getModule(), 0, Ty.getAddressSpace()); + return GV; +} + +void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) { + + llvm::Value *&DMEntry = LocalDeclMap[&D]; + assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); + + llvm::GlobalValue *GV = GenerateStaticBlockVarDecl(D, false, "."); + if (const AnnotateAttr *AA = D.getAttr()) { SourceManager &SM = CGM.getContext().getSourceManager(); llvm::Constant *Ann = @@ -107,16 +118,23 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) { /// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a /// variable declaration with auto, register, or no storage class specifier. -/// These turn into simple stack objects. +/// These turn into simple stack objects, or GlobalValues depending on target. void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { QualType Ty = D.getType(); llvm::Value *DeclPtr; if (Ty->isConstantSizeType()) { - // A normal fixed sized variable becomes an alloca in the entry block. - const llvm::Type *LTy = ConvertType(Ty); - // TODO: Alignment - DeclPtr = CreateTempAlloca(LTy, D.getName()); + if (!Target.useGlobalsForAutomaticVariables()) { + // A normal fixed sized variable becomes an alloca in the entry block. + const llvm::Type *LTy = ConvertType(Ty); + // TODO: Alignment + DeclPtr = CreateTempAlloca(LTy, D.getName()); + } else { + // Targets that don't support recursion emit locals as globals. + const char *Class = + D.getStorageClass() == VarDecl::Register ? ".reg." : ".auto."; + DeclPtr = GenerateStaticBlockVarDecl(D, true, Class); + } } else { // TODO: Create a dynamic alloca. assert(0 && "FIXME: Local VLAs not implemented yet"); @@ -139,7 +157,8 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { } } -/// Emit an alloca for the specified parameter and set up LocalDeclMap. +/// Emit an alloca (or GlobalValue depending on target) +/// for the specified parameter and set up LocalDeclMap. void CodeGenFunction::EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg) { QualType Ty = D.getType(); @@ -147,6 +166,8 @@ void CodeGenFunction::EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg) { if (!Ty->isConstantSizeType()) { // Variable sized values always are passed by-reference. DeclPtr = Arg; + } else if (Target.useGlobalsForAutomaticVariables()) { + DeclPtr = GenerateStaticBlockVarDecl(D, true, ".arg."); } else { // A fixed sized first class variable becomes an alloca in the entry block. const llvm::Type *LTy = ConvertType(Ty); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index d9e2820e8e..a6caa379cc 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -488,6 +488,12 @@ public: bool DestIsVolatile); /// LoadComplexFromAddr - Load a complex number from the specified address. ComplexPairTy LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile); + + /// GenerateStaticBlockVarDecl - return the the static + /// declaration of local variable. + llvm::GlobalValue *GenerateStaticBlockVarDecl(const VarDecl &D, + bool NoInit, + const char *Separator); }; } // end namespace CodeGen } // end namespace clang