[cfe-commits] r44394 - in /cfe/trunk: CodeGen/CGExpr.cpp CodeGen/CodeGenModule.cpp CodeGen/CodeGenModule.h CodeGen/ModuleBuilder.cpp Driver/ASTConsumers.cpp Driver/ASTConsumers.h Driver/clang.cpp include/clang/Basic/LangOptions.h include/clang/CodeGen/ModuleBuilder.h

Chris Lattner sabre at nondot.org
Tue Nov 27 21:34:05 PST 2007


Author: lattner
Date: Tue Nov 27 23:34:05 2007
New Revision: 44394

URL: http://llvm.org/viewvc/llvm-project?rev=44394&view=rev
Log:
Implement support for -fwritable-strings and make the code generator
merge string literals when it is not provided.

Modified:
    cfe/trunk/CodeGen/CGExpr.cpp
    cfe/trunk/CodeGen/CodeGenModule.cpp
    cfe/trunk/CodeGen/CodeGenModule.h
    cfe/trunk/CodeGen/ModuleBuilder.cpp
    cfe/trunk/Driver/ASTConsumers.cpp
    cfe/trunk/Driver/ASTConsumers.h
    cfe/trunk/Driver/clang.cpp
    cfe/trunk/include/clang/Basic/LangOptions.h
    cfe/trunk/include/clang/CodeGen/ModuleBuilder.h

Modified: cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExpr.cpp?rev=44394&r1=44393&r2=44394&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGExpr.cpp Tue Nov 27 23:34:05 2007
@@ -304,18 +304,8 @@
   assert(!E->isWide() && "FIXME: Wide strings not supported yet!");
   const char *StrData = E->getStrData();
   unsigned Len = E->getByteLength();
-  
-  // FIXME: Can cache/reuse these within the module.
-  llvm::Constant *C=llvm::ConstantArray::get(std::string(StrData, StrData+Len));
-  
-  // Create a global variable for this.
-  C = new llvm::GlobalVariable(C->getType(), true, 
-                               llvm::GlobalValue::InternalLinkage,
-                               C, ".str", CurFn->getParent());
-  llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
-  llvm::Constant *Zeros[] = { Zero, Zero };
-  C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
-  return LValue::MakeAddr(C);
+  std::string StringLiteral(StrData, StrData+Len);
+  return LValue::MakeAddr(CGM.GetAddrOfConstantString(StringLiteral));
 }
 
 LValue CodeGenFunction::EmitPreDefinedLValue(const PreDefinedExpr *E) {

Modified: cfe/trunk/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenModule.cpp?rev=44394&r1=44393&r2=44394&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenModule.cpp Tue Nov 27 23:34:05 2007
@@ -15,6 +15,7 @@
 #include "CodeGenFunction.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
@@ -24,9 +25,9 @@
 using namespace CodeGen;
 
 
-CodeGenModule::CodeGenModule(ASTContext &C, llvm::Module &M,
-                             const llvm::TargetData &TD)
-  : Context(C), TheModule(M), TheTargetData(TD),
+CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
+                             llvm::Module &M, const llvm::TargetData &TD)
+  : Context(C), Features(LO), TheModule(M), TheTargetData(TD),
     Types(C, M, TD), MemCpyFn(0), CFConstantStringClassRef(0) {}
 
 llvm::Constant *CodeGenModule::GetAddrOfGlobalDecl(const ValueDecl *D) {
@@ -155,27 +156,6 @@
   return 0;
 }
 
-/// GenerateStringLiteral -- returns a pointer to the first element of a 
-/// character array containing the literal.
-static llvm::Constant *GenerateStringLiteral(const StringLiteral* E, 
-                                            CodeGenModule& CGModule) {
-  assert(!E->isWide() && "FIXME: Wide strings not supported yet!");
-  const char *StrData = E->getStrData();
-  unsigned Len = E->getByteLength();
-
-  // FIXME: Can cache/reuse these within the module.
-  llvm::Constant *C=llvm::ConstantArray::get(std::string(StrData, StrData+Len));
-
-  // Create a global variable for this.
-  C = new llvm::GlobalVariable(C->getType(), true, 
-                               llvm::GlobalValue::InternalLinkage,
-                               C, ".str", &CGModule.getModule());
-  llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
-  llvm::Constant *Zeros[] = { Zero, Zero };
-  C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
-  return C;
-}
-
 /// GenerateAggregateInit - Generate a Constant initaliser for global array or
 /// struct typed variables.
 static llvm::Constant *GenerateAggregateInit(const InitListExpr *ILE, 
@@ -244,7 +224,10 @@
   // Generate constant for string literal values.
   case Stmt::StringLiteralClass: {
     const StringLiteral *SLiteral = cast<StringLiteral>(Expression);
-    return GenerateStringLiteral(SLiteral, CGModule);
+    const char *StrData = SLiteral->getStrData();
+    unsigned Len = SLiteral->getByteLength();
+    return CGModule.GetAddrOfConstantString(std::string(StrData, 
+                                                        StrData + Len));
   }
 
   // Elide parenthesis.
@@ -455,3 +438,39 @@
   Entry.setValue(GV);
   return GV;
 }
+
+/// GenerateWritableString -- Creates storage for a string literal
+static llvm::Constant *GenerateStringLiteral(const std::string &str, 
+                                             bool constant,
+                                             CodeGenModule& CGModule) {
+  // Create Constant for this string literal
+  llvm::Constant *C=llvm::ConstantArray::get(str);
+  
+  // Create a global variable for this string
+  C = new llvm::GlobalVariable(C->getType(), constant, 
+                               llvm::GlobalValue::InternalLinkage,
+                               C, ".str", &CGModule.getModule());
+  llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
+  llvm::Constant *Zeros[] = { Zero, Zero };
+  C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
+  return C;
+}
+
+/// CodeGenModule::GetAddrOfConstantString -- returns a pointer to the first 
+/// element of a character array containing the literal.
+llvm::Constant *CodeGenModule::GetAddrOfConstantString(const std::string &str) {
+  // Don't share any string literals if writable-strings is turned on.
+  if (Features.WritableStrings)
+    return GenerateStringLiteral(str, false, *this);
+  
+  llvm::StringMapEntry<llvm::Constant *> &Entry = 
+  ConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
+
+  if (Entry.getValue())
+      return Entry.getValue();
+
+  // Create a global variable for this.
+  llvm::Constant *C = GenerateStringLiteral(str, true, *this);
+  Entry.setValue(C);
+  return C;
+}

Modified: cfe/trunk/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenModule.h?rev=44394&r1=44393&r2=44394&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/CodeGen/CodeGenModule.h Tue Nov 27 23:34:05 2007
@@ -32,6 +32,7 @@
   class Decl;
   class ValueDecl;
   class FileVarDecl;
+  struct LangOptions;
     
 namespace CodeGen {
 
@@ -39,21 +40,25 @@
 /// while generating LLVM code.
 class CodeGenModule {
   ASTContext &Context;
+  const LangOptions &Features;
   llvm::Module &TheModule;
   const llvm::TargetData &TheTargetData;
   CodeGenTypes Types;
 
   llvm::Function *MemCpyFn;
   llvm::DenseMap<const Decl*, llvm::Constant*> GlobalDeclMap;
-  
+    
   llvm::StringMap<llvm::Constant*> CFConstantStringMap;
+  llvm::StringMap<llvm::Constant*> ConstantStringMap;
   llvm::Constant *CFConstantStringClassRef;
   
   std::vector<llvm::Function *> BuiltinFunctions;
 public:
-  CodeGenModule(ASTContext &C, llvm::Module &M, const llvm::TargetData &TD);
+  CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M, 
+                const llvm::TargetData &TD);
   
   ASTContext &getContext() const { return Context; }
+  const LangOptions &getLangOptions() const { return Features; }
   llvm::Module &getModule() const { return TheModule; }
   CodeGenTypes &getTypes() { return Types; }
   
@@ -64,6 +69,7 @@
   ///
   llvm::Function *getBuiltinLibFunction(unsigned BuiltinID);
   llvm::Constant *GetAddrOfConstantCFString(const std::string& str);
+  llvm::Constant *GetAddrOfConstantString(const std::string& str);
   llvm::Function *getMemCpyFn();
   
   

Modified: cfe/trunk/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/ModuleBuilder.cpp?rev=44394&r1=44393&r2=44394&view=diff

==============================================================================
--- cfe/trunk/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/CodeGen/ModuleBuilder.cpp Tue Nov 27 23:34:05 2007
@@ -18,9 +18,9 @@
 
 /// Init - Create an ModuleBuilder with the specified ASTContext.
 clang::CodeGen::CodeGenModule *
-clang::CodeGen::Init(ASTContext &Context, llvm::Module &M,
-                     const llvm::TargetData &TD) {
-  return new CodeGenModule(Context, M, TD);
+clang::CodeGen::Init(ASTContext &Context, const LangOptions &Features, 
+                     llvm::Module &M, const llvm::TargetData &TD) {
+  return new CodeGenModule(Context, Features, M, TD);
 }
 
 void clang::CodeGen::Terminate(CodeGenModule *B) {

Modified: cfe/trunk/Driver/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.cpp?rev=44394&r1=44393&r2=44394&view=diff

==============================================================================
--- cfe/trunk/Driver/ASTConsumers.cpp (original)
+++ cfe/trunk/Driver/ASTConsumers.cpp Tue Nov 27 23:34:05 2007
@@ -550,15 +550,18 @@
     llvm::Module *M;
     const llvm::TargetData *TD;
     ASTContext *Ctx;
+    const LangOptions &Features;
     CodeGen::CodeGenModule *Builder;
   public:
-    LLVMEmitter(Diagnostic &diags) : Diags(diags) {}
+    LLVMEmitter(Diagnostic &diags, const LangOptions &LO) 
+      : Diags(diags)
+      , Features(LO) {}
     virtual void Initialize(ASTContext &Context, unsigned MainFileID) {
       Ctx = &Context;
       M = new llvm::Module("foo");
       M->setTargetTriple(Ctx->Target.getTargetTriple());
       TD = new llvm::TargetData(Ctx->Target.getTargetDescription());
-      Builder = CodeGen::Init(Context, *M, *TD);
+      Builder = CodeGen::Init(Context, Features, *M, *TD);
     }
     
     virtual void HandleTopLevelDecl(Decl *D) {
@@ -588,7 +591,7 @@
   }; 
 } // end anonymous namespace
 
-ASTConsumer *clang::CreateLLVMEmitter(Diagnostic &Diags) {
-  return new LLVMEmitter(Diags);
+ASTConsumer *clang::CreateLLVMEmitter(Diagnostic &Diags, const LangOptions &Features) {
+  return new LLVMEmitter(Diags, Features);
 }
 

Modified: cfe/trunk/Driver/ASTConsumers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.h?rev=44394&r1=44393&r2=44394&view=diff

==============================================================================
--- cfe/trunk/Driver/ASTConsumers.h (original)
+++ cfe/trunk/Driver/ASTConsumers.h Tue Nov 27 23:34:05 2007
@@ -20,6 +20,7 @@
 
 class ASTConsumer;
 class Diagnostic;
+struct LangOptions;
 
 ASTConsumer *CreateASTPrinter(FILE* FP = NULL);
 ASTConsumer *CreateASTDumper();
@@ -28,7 +29,7 @@
 ASTConsumer *CreateLiveVarAnalyzer();
 ASTConsumer *CreateDeadStoreChecker(Diagnostic &Diags);
 ASTConsumer *CreateUnitValsChecker(Diagnostic &Diags);
-ASTConsumer *CreateLLVMEmitter(Diagnostic &Diags);
+ASTConsumer *CreateLLVMEmitter(Diagnostic &Diags, const LangOptions &Features);
 ASTConsumer *CreateCodeRewriterTest();
 ASTConsumer *CreateSerializationTest();
 

Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=44394&r1=44393&r2=44394&view=diff

==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Tue Nov 27 23:34:05 2007
@@ -278,6 +278,10 @@
 PascalStrings("fpascal-strings",
               llvm::cl::desc("Recognize and construct Pascal-style "
                              "string literals"));
+
+static llvm::cl::opt<bool>
+WritableStrings("fwritable-strings",
+              llvm::cl::desc("Store string literals as writable data."));
 // FIXME: add:
 //   -ansi
 //   -trigraphs
@@ -335,6 +339,7 @@
   Options.Trigraphs = 1; // -trigraphs or -ansi
   Options.DollarIdents = 1;  // FIXME: Really a target property.
   Options.PascalStrings = PascalStrings;
+  Options.WritableStrings = WritableStrings;
 }
 
 //===----------------------------------------------------------------------===//
@@ -820,7 +825,7 @@
     break;
       
   case EmitLLVM:
-    Consumer = CreateLLVMEmitter(PP.getDiagnostics());
+    Consumer = CreateLLVMEmitter(PP.getDiagnostics(), PP.getLangOptions());
     break;
     
   case RewriteTest:

Modified: cfe/trunk/include/clang/Basic/LangOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=44394&r1=44393&r2=44394&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.h (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.h Tue Nov 27 23:34:05 2007
@@ -36,12 +36,13 @@
   
   unsigned PascalStrings     : 1;  // Allow Pascal strings
   unsigned Boolean           : 1;  // Allow bool/true/false
+  unsigned WritableStrings   : 1;  // Allow writable strings
   
   LangOptions() {
     Trigraphs = BCPLComment = DollarIdents = Digraphs = HexFloats = 0;
     ObjC1 = ObjC2 = 0;
     C99 = Microsoft = CPlusPlus = CPlusPlus0x = NoExtensions = 0;
-    CXXOperatorNames = PascalStrings = Boolean = 0;
+    CXXOperatorNames = PascalStrings = Boolean = WritableStrings = 0;
   }
 };
 

Modified: cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=44394&r1=44393&r2=44394&view=diff

==============================================================================
--- cfe/trunk/include/clang/CodeGen/ModuleBuilder.h (original)
+++ cfe/trunk/include/clang/CodeGen/ModuleBuilder.h Tue Nov 27 23:34:05 2007
@@ -23,13 +23,14 @@
   class ASTContext;
   class FunctionDecl;
   class FileVarDecl;
+  struct LangOptions;
 
 namespace CodeGen {
   class CodeGenModule;
   
   /// Init - Create an ModuleBuilder with the specified ASTContext.
-  CodeGenModule *Init(ASTContext &Context, llvm::Module &M,
-                  const llvm::TargetData &TD);
+  CodeGenModule *Init(ASTContext &Context, const LangOptions &Features,
+                      llvm::Module &M, const llvm::TargetData &TD);
   
   /// CodeGenFunction - Convert the AST node for a FunctionDecl into LLVM.
   ///





More information about the cfe-commits mailing list