summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/TargetInfo.h11
-rw-r--r--clang/lib/Basic/TargetInfo.cpp1
-rw-r--r--clang/lib/Basic/Targets.cpp33
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp45
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h6
5 files changed, 80 insertions, 16 deletions
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index cd717594404..5a4f1c71d20 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/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/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 4ce32a9972f..675406edef3 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/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/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index c4ffa0d65e2..25bc6fbb4de 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/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<char> &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/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index df5882c2172..bd68288bba3 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/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<AnnotateAttr>()) {
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/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index d9e2820e8ef..a6caa379cc9 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/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
OpenPOWER on IntegriCloud