Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions clang/lib/CIR/CodeGen/CIRGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1885,14 +1885,7 @@ LValue CIRGenFunction::emitArraySubscriptExpr(const ArraySubscriptExpr *E,
}

LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral *E) {
auto sym = CGM.getAddrOfConstantStringFromLiteral(E).getSymbol();

auto cstGlobal = mlir::SymbolTable::lookupSymbolIn(CGM.getModule(), sym);
assert(cstGlobal && "Expected global");

auto g = dyn_cast<cir::GlobalOp>(cstGlobal);
assert(g && "unaware of other symbol providers");

auto g = CGM.getGlobalForStringLiteral(E);
assert(g.getAlignment() && "expected alignment for string literal");
auto align = *g.getAlignment();
auto addr = builder.createGetGlobal(getLoc(E->getSourceRange()), g);
Expand Down
51 changes: 38 additions & 13 deletions clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1783,10 +1783,32 @@ generateStringLiteral(mlir::Location loc, mlir::TypedAttr c,
return gv;
}

/// Return a pointer to a constant array for the given string literal.
cir::GlobalViewAttr
CIRGenModule::getAddrOfConstantStringFromLiteral(const StringLiteral *s,
StringRef name) {
// LLVM IR automatically uniques names when new llvm::GlobalVariables are
// created. This is handy, for example, when creating globals for string
// literals. Since we don't do that when creating cir::GlobalOp's, we need
// a mechanism to generate a unique name in advance.
//
// For now, this mechanism is only used in cases where we know that the
// name is compiler-generated, so we don't use the MLIR symbol table for
// the lookup.
std::string CIRGenModule::getUniqueGlobalName(const std::string &baseName) {
// If this is the first time we've generated a name for this basename, use
// it as is and start a counter for this base name.
auto it = cgGlobalNames.find(baseName);
if (it == cgGlobalNames.end()) {
cgGlobalNames[baseName] = 1;
return baseName;
}

std::string result =
baseName + "." + std::to_string(cgGlobalNames[baseName]++);
// There should not be any symbol with this name in the module.
assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
return result;
}

cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
StringRef name) {
CharUnits alignment =
astContext.getAlignOfGlobalVarInChars(s->getType(), /*VD=*/nullptr);

Expand All @@ -1800,13 +1822,6 @@ CIRGenModule::getAddrOfConstantStringFromLiteral(const StringLiteral *s,
uint64_t(alignment.getQuantity()) > *gv.getAlignment())
gv.setAlignmentAttr(getSize(alignment));
} else {
SmallString<256> stringNameBuffer = name;
llvm::raw_svector_ostream out(stringNameBuffer);
if (StringLiteralCnt)
out << '.' << StringLiteralCnt;
name = out.str();
StringLiteralCnt++;

SmallString<256> mangledNameBuffer;
StringRef globalVariableName;
auto lt = cir::GlobalLinkageKind::ExternalLinkage;
Expand All @@ -1822,18 +1837,28 @@ CIRGenModule::getAddrOfConstantStringFromLiteral(const StringLiteral *s,
globalVariableName = name;
}

// Unlike LLVM IR, CIR doesn't automatically unique names for globals, so
// we need to do that explicitly.
std::string uniqueName = getUniqueGlobalName(globalVariableName.str());
auto loc = getLoc(s->getSourceRange());
auto typedC = llvm::dyn_cast<mlir::TypedAttr>(c);
if (!typedC)
llvm_unreachable("this should never be untyped at this point");
gv = generateStringLiteral(loc, typedC, lt, *this, globalVariableName,
alignment);
gv = generateStringLiteral(loc, typedC, lt, *this, uniqueName, alignment);
setDSOLocal(static_cast<mlir::Operation *>(gv));
ConstantStringMap[c] = gv;

assert(!cir::MissingFeatures::reportGlobalToASan() && "NYI");
}

return gv;
}

/// Return a pointer to a constant array for the given string literal.
cir::GlobalViewAttr
CIRGenModule::getAddrOfConstantStringFromLiteral(const StringLiteral *s,
StringRef name) {
auto gv = getGlobalForStringLiteral(s, name);
auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
assert(arrayTy && "String literal must be array");
auto ptrTy = getBuilder().getPointerTo(arrayTy.getElementType(),
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,9 @@ class CIRGenModule : public CIRGenTypeCache {
return !getLangOpts().CPlusPlus;
}

llvm::StringMap<unsigned> cgGlobalNames;
std::string getUniqueGlobalName(const std::string &baseName);

/// Return the mlir::Value for the address of the given global variable.
/// If Ty is non-null and if the global doesn't exist, then it will be created
/// with the specified type instead of whatever the normal requested type
Expand Down Expand Up @@ -444,12 +447,15 @@ class CIRGenModule : public CIRGenTypeCache {
/// Return a constant array for the given string.
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *E);

/// Return a global op for the given string literal.
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *S,
llvm::StringRef Name = ".str");

/// Return a global symbol reference to a constant array for the given string
/// literal.
cir::GlobalViewAttr
getAddrOfConstantStringFromLiteral(const StringLiteral *S,
llvm::StringRef Name = ".str");
unsigned StringLiteralCnt = 0;

unsigned CompoundLitaralCnt = 0;
/// Return the unique name for global compound literal
Expand Down
Loading