[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