Skip to content

Commit

Permalink
[CIR][CIRGen] Add codegen for some comp-literal exprs
Browse files Browse the repository at this point in the history
  • Loading branch information
YazZz1k committed Feb 8, 2024
1 parent 00b21e0 commit 34c256d
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 4 deletions.
7 changes: 7 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenCstEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,14 @@ class ConstantEmitter {
/// Is the current emission context abstract?
bool isAbstract() const { return Abstract; }

bool isInConstantContext() const { return InConstantContext; }
void setInConstantContext(bool var) { InConstantContext = var; }

/// Try to emit the initiaizer of the given declaration as an abstract
/// constant. If this succeeds, the emission must be finalized.
mlir::Attribute tryEmitForInitializer(const VarDecl &D);
mlir::Attribute tryEmitForInitializer(const Expr *E, LangAS destAddrSpace,
QualType destType);

void finalize(mlir::cir::GlobalOp global);

Expand Down Expand Up @@ -106,6 +111,8 @@ class ConstantEmitter {
mlir::Attribute emitAbstract(SourceLocation loc, const APValue &value,
QualType T);

mlir::Attribute tryEmitConstantExpr(const ConstantExpr *CE);

// These are private helper routines of the constant emitter that
// can't actually be private because things are split out into helper
// functions and classes.
Expand Down
56 changes: 52 additions & 4 deletions clang/lib/CIR/CodeGen/CIRGenExprConst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,8 +674,9 @@ class ConstExprEmitter
mlir::Attribute VisitStmt(Stmt *S, QualType T) { return nullptr; }

mlir::Attribute VisitConstantExpr(ConstantExpr *CE, QualType T) {
assert(0 && "unimplemented");
return {};
if (mlir::Attribute Result = Emitter.tryEmitConstantExpr(CE))
return Result;
return Visit(CE->getSubExpr(), T);
}

mlir::Attribute VisitParenExpr(ParenExpr *PE, QualType T) {
Expand Down Expand Up @@ -1190,15 +1191,44 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
return Visit(base.get<const Expr *>());
}

static ConstantLValue
tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter,
const CompoundLiteralExpr *E) {
CIRGenModule &CGM = emitter.CGM;

LangAS addressSpace = E->getType().getAddressSpace();
mlir::Attribute C = emitter.tryEmitForInitializer(E->getInitializer(),
addressSpace, E->getType());
if (!C) {
assert(!E->isFileScope() &&
"file-scope compound literal did not have constant initializer!");
return nullptr;
}

auto GV = CIRGenModule::createGlobalOp(
CGM, CGM.getLoc(E->getSourceRange()),
CGM.createGlobalCompoundLiteralName(),
CGM.getTypes().convertTypeForMem(E->getType()),
E->getType().isConstantStorage(CGM.getASTContext(), false, false));
GV.setInitialValueAttr(C);
GV.setLinkage(mlir::cir::GlobalLinkageKind::InternalLinkage);
CharUnits Align = CGM.getASTContext().getTypeAlignInChars(E->getType());
GV.setAlignment(Align.getAsAlign().value());

emitter.finalize(GV);
return CGM.getBuilder().getGlobalViewAttr(GV);
}

ConstantLValue ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *E) {
assert(0 && "NYI");
return Visit(E->getSubExpr());
}

ConstantLValue
ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
assert(0 && "NYI");
return nullptr;
ConstantEmitter CompoundLiteralEmitter(CGM, Emitter.CGF);
CompoundLiteralEmitter.setInConstantContext(Emitter.isInConstantContext());
return tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter, E);
}

ConstantLValue
Expand Down Expand Up @@ -1279,6 +1309,13 @@ mlir::Attribute ConstantEmitter::tryEmitForInitializer(const VarDecl &D) {
return markIfFailed(tryEmitPrivateForVarInit(D));
}

mlir::Attribute ConstantEmitter::tryEmitForInitializer(const Expr *E,
LangAS destAddrSpace,
QualType destType) {
initializeNonAbstract(destAddrSpace);
return markIfFailed(tryEmitPrivateForMemory(E, destType));
}

void ConstantEmitter::finalize(mlir::cir::GlobalOp global) {
assert(InitializedNonAbstract &&
"finalizing emitter that was used for abstract emission?");
Expand Down Expand Up @@ -1371,6 +1408,17 @@ mlir::Attribute ConstantEmitter::tryEmitAbstract(const APValue &value,
return validateAndPopAbstract(C, state);
}

mlir::Attribute ConstantEmitter::tryEmitConstantExpr(const ConstantExpr *CE) {
if (!CE->hasAPValueResult())
return nullptr;

QualType RetType = CE->getType();
if (CE->isGLValue())
RetType = CGM.getASTContext().getLValueReferenceType(RetType);

return emitAbstract(CE->getBeginLoc(), CE->getAPValueResult(), RetType);
}

mlir::Attribute ConstantEmitter::tryEmitAbstractForMemory(const Expr *E,
QualType destType) {
auto nonMemoryDestType = getNonMemoryType(CGM, destType);
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,12 @@ class CIRGenModule : public CIRGenTypeCache {
StringRef Name = ".str");
unsigned StringLiteralCnt = 0;

unsigned CompoundLitaralCnt = 0;
/// Return the unique name for global compound literal
std::string createGlobalCompoundLiteralName() {
return (Twine(".compoundLiteral.") + Twine(CompoundLitaralCnt++)).str();
}

/// Return the AST address space of constant literal, which is used to emit
/// the constant literal as global variable in LLVM IR.
/// Note: This is not necessarily the address space of the constant literal
Expand Down
29 changes: 29 additions & 0 deletions clang/test/CIR/CodeGen/compound-literal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -S -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM


typedef struct {
int *arr;
} S;

S a = {
.arr = (int[]){}
};

// CIR: cir.global "private" internal @".compoundLiteral.0" = #cir.zero : !cir.array<!s32i x 0> {alignment = 4 : i64}
// CIR: cir.global external @a = #cir.const_struct<{#cir.global_view<@".compoundLiteral.0"> : !cir.ptr<!s32i>}> : !ty_22S22

// LLVM: @.compoundLiteral.0 = internal global [0 x i32] zeroinitializer
// LLVM: @a = global %struct.S { ptr @.compoundLiteral.0 }

S b = {
.arr = (int[]){1}
};

// CIR: cir.global "private" internal @".compoundLiteral.1" = #cir.const_array<[#cir.int<1> : !s32i]> : !cir.array<!s32i x 1> {alignment = 4 : i64}
// CIR: cir.global external @b = #cir.const_struct<{#cir.global_view<@".compoundLiteral.1"> : !cir.ptr<!s32i>}> : !ty_22S22

// LLVM: @.compoundLiteral.1 = internal global [1 x i32] [i32 1]
// LLVM: @b = global %struct.S { ptr @.compoundLiteral.1 }

0 comments on commit 34c256d

Please sign in to comment.