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/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index df5882c..bd68288 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::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 @@
 
   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 @@
   
 /// 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 @@
   }
 }
 
-/// 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 @@
   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);