Skip to content

Commit bf73c83

Browse files
committed
Reimplement most of the stuff and align with the upstream CodeGen structure
1 parent 35f7139 commit bf73c83

15 files changed

+1343
-52
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

+40
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,7 @@ def UnaryOpKind_Dec : I32EnumAttrCase<"Dec", 2, "dec">;
820820
def UnaryOpKind_Plus : I32EnumAttrCase<"Plus", 3, "plus">;
821821
def UnaryOpKind_Minus : I32EnumAttrCase<"Minus", 4, "minus">;
822822
def UnaryOpKind_Not : I32EnumAttrCase<"Not", 5, "not">;
823+
def UnaryOpKind_Conjugate : I32EnumAttrCase<"Conjugate", 6, "conjugate">;
823824

824825
def UnaryOpKind : I32EnumAttr<
825826
"UnaryOpKind",
@@ -829,6 +830,7 @@ def UnaryOpKind : I32EnumAttr<
829830
UnaryOpKind_Plus,
830831
UnaryOpKind_Minus,
831832
UnaryOpKind_Not,
833+
UnaryOpKind_Conjugate,
832834
]> {
833835
let cppNamespace = "::mlir::cir";
834836
}
@@ -992,6 +994,44 @@ def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
992994
let hasVerifier = 0;
993995
}
994996

997+
//===----------------------------------------------------------------------===//
998+
// ComplexCreateOp
999+
//===----------------------------------------------------------------------===//
1000+
1001+
def ComplexCreateOp : CIR_Op<"complex.create", [Pure, SameTypeOperands]> {
1002+
let summary = "Create a new complex value from its real and imaginary parts";
1003+
let description = [{
1004+
The `cir.complex.create` operation takes two operands of the same type and
1005+
returns a value of `!cir.complex` type. The real and imaginary part of the
1006+
returned complex value is specified by the operands.
1007+
1008+
The element type of the returned complex value is the same as the type of
1009+
the operand. The type of the two operands must be either an integer type or
1010+
a floating-point type.
1011+
1012+
Example:
1013+
1014+
```mlir
1015+
!u32i = !cir.int<u, 32>
1016+
!complex = !cir.complex<!u32i>
1017+
1018+
%0 = cir.const(#cir.int<1> : !u32i) : !u32i
1019+
%1 = cir.const(#cir.int<2> : !u32i) : !u32i
1020+
%2 = cir.complex.create(%0 : !u32i, %1) : !complex
1021+
```
1022+
}];
1023+
1024+
let results = (outs CIR_ComplexType:$result);
1025+
let arguments = (ins CIR_AnyType:$real, CIR_AnyType:$imag);
1026+
1027+
let assemblyFormat = [{
1028+
`(` $real `:` qualified(type($real)) `,` $imag `)`
1029+
`:` type($result) attr-dict
1030+
}];
1031+
1032+
let hasVerifier = 1;
1033+
}
1034+
9951035
//===----------------------------------------------------------------------===//
9961036
// ComplexRealOp and ComplexImagOp
9971037
//===----------------------------------------------------------------------===//

clang/lib/CIR/CodeGen/CIRGenBuilder.h

+15
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,12 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
720720
addr.getPointer());
721721
}
722722

723+
mlir::Value createVolatileLoad(mlir::Location loc, Address addr) {
724+
return create<mlir::cir::LoadOp>(loc, addr.getElementType(),
725+
addr.getPointer(), /*isDeref=*/false,
726+
/*is_volatile=*/true);
727+
}
728+
723729
mlir::Value createAlignedLoad(mlir::Location loc, mlir::Type ty,
724730
mlir::Value ptr,
725731
[[maybe_unused]] llvm::MaybeAlign align,
@@ -863,6 +869,15 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
863869
return createNot(createPtrToBoolCast(ptr));
864870
}
865871

872+
mlir::Value createComplexCreate(mlir::Location loc, mlir::Value real,
873+
mlir::Value imag) {
874+
assert(real.getType() == imag.getType() &&
875+
"operands to cir.complex.create must have the same type");
876+
877+
auto complexTy = mlir::cir::ComplexType::get(getContext(), real.getType());
878+
return create<mlir::cir::ComplexCreateOp>(loc, complexTy, real, imag);
879+
}
880+
866881
mlir::Value createComplexReal(mlir::Location loc, mlir::Value operand) {
867882
auto operandComplexTy = operand.getType().cast<mlir::cir::ComplexType>();
868883
auto resultTy = operandComplexTy.getElementTy();

clang/lib/CIR/CodeGen/CIRGenCXX.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ static void buildDeclInit(CIRGenFunction &CGF, const VarDecl *D,
201201
CGF.buildScalarInit(Init, CGF.getLoc(D->getLocation()), lv, false);
202202
return;
203203
case TEK_Complex:
204-
llvm_unreachable("complext evaluation NYI");
204+
CGF.buildComplexInit(Init, CGF.getLoc(D->getLocation()), lv);
205+
return;
205206
}
206207
}
207208

clang/lib/CIR/CodeGen/CIRGenClass.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ void CIRGenFunction::buildInitializerForField(FieldDecl *Field, LValue LHS,
805805
}
806806
break;
807807
case TEK_Complex:
808-
llvm_unreachable("NYI");
808+
buildComplexExprIntoLValue(Init, LHS, /*isInit*/ true);
809809
break;
810810
case TEK_Aggregate: {
811811
AggValueSlot Slot = AggValueSlot::forLValue(

clang/lib/CIR/CodeGen/CIRGenDecl.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,15 @@ void CIRGenFunction::buildScalarInit(const Expr *init, mlir::Location loc,
684684
return;
685685
}
686686

687+
void CIRGenFunction::buildComplexInit(const Expr *init, mlir::Location loc,
688+
LValue lvalue) {
689+
// TODO: this is where a lot of ObjC lifetime stuff would be done.
690+
SourceLocRAIIObject Loc{*this, loc};
691+
mlir::Value value = buildScalarExpr(init);
692+
buildStoreOfComplex(getLoc(init->getSourceRange()), value, lvalue);
693+
return;
694+
}
695+
687696
void CIRGenFunction::buildExprAsInit(const Expr *init, const ValueDecl *D,
688697
LValue lvalue, bool capturedByInit) {
689698
SourceLocRAIIObject Loc{*this, getLoc(init->getSourceRange())};
@@ -704,7 +713,10 @@ void CIRGenFunction::buildExprAsInit(const Expr *init, const ValueDecl *D,
704713
buildScalarInit(init, getLoc(D->getSourceRange()), lvalue);
705714
return;
706715
case TEK_Complex: {
707-
assert(0 && "not implemented");
716+
auto complex = buildComplexExpr(init);
717+
if (capturedByInit)
718+
llvm_unreachable("NYI");
719+
buildStoreOfComplex(getLoc(init->getSourceRange()), complex, lvalue);
708720
return;
709721
}
710722
case TEK_Aggregate:

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

+32-4
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,11 @@ void CIRGenFunction::buildStoreOfScalar(mlir::Value value, LValue lvalue,
613613
lvalue.isNontemporal());
614614
}
615615

616+
void CIRGenFunction::buildStoreOfComplex(mlir::Location loc, mlir::Value value,
617+
LValue lvalue) {
618+
builder.createStore(loc, value, lvalue.getAddress());
619+
}
620+
616621
/// Given an expression that represents a value lvalue, this
617622
/// method emits the address of the lvalue, then loads the result as an rvalue,
618623
/// returning the rvalue.
@@ -975,7 +980,8 @@ LValue CIRGenFunction::buildBinaryOperatorLValue(const BinaryOperator *E) {
975980
}
976981

977982
case TEK_Complex:
978-
assert(0 && "not implemented");
983+
return buildComplexAssignmentLValue(E);
984+
979985
case TEK_Aggregate:
980986
assert(0 && "not implemented");
981987
}
@@ -1066,7 +1072,7 @@ RValue CIRGenFunction::buildAnyExpr(const Expr *E, AggValueSlot aggSlot,
10661072
case TEK_Scalar:
10671073
return RValue::get(buildScalarExpr(E));
10681074
case TEK_Complex:
1069-
assert(0 && "not implemented");
1075+
return RValue::getComplex(buildComplexExpr(E));
10701076
case TEK_Aggregate: {
10711077
if (!ignoreResult && aggSlot.isIgnored())
10721078
aggSlot = CreateAggTemp(E->getType(), getLoc(E->getSourceRange()),
@@ -1855,7 +1861,8 @@ void CIRGenFunction::buildAnyExprToMem(const Expr *E, Address Location,
18551861
// FIXME: This function should take an LValue as an argument.
18561862
switch (getEvaluationKind(E->getType())) {
18571863
case TEK_Complex:
1858-
assert(0 && "NYI");
1864+
buildComplexExprIntoLValue(E, makeAddrLValue(Location, E->getType()),
1865+
/*isInit*/ false);
18591866
return;
18601867

18611868
case TEK_Aggregate: {
@@ -2307,7 +2314,7 @@ RValue CIRGenFunction::convertTempToRValue(Address addr, clang::QualType type,
23072314
LValue lvalue = makeAddrLValue(addr, type, AlignmentSource::Decl);
23082315
switch (getEvaluationKind(type)) {
23092316
case TEK_Complex:
2310-
llvm_unreachable("NYI");
2317+
return RValue::getComplex(buildLoadOfComplex(lvalue, loc));
23112318
case TEK_Aggregate:
23122319
llvm_unreachable("NYI");
23132320
case TEK_Scalar:
@@ -2870,3 +2877,24 @@ LValue CIRGenFunction::buildPredefinedLValue(const PredefinedExpr *E) {
28702877

28712878
return buildStringLiteralLValue(SL);
28722879
}
2880+
2881+
mlir::Value CIRGenFunction::buildComplexPrePostIncDec(const UnaryOperator *E,
2882+
LValue LV, bool isInc,
2883+
bool isPre) {
2884+
auto InVal = buildLoadOfComplex(LV, E->getExprLoc());
2885+
2886+
auto Loc = getLoc(E->getSourceRange());
2887+
mlir::Value IncDecVal;
2888+
if (isInc)
2889+
IncDecVal = builder.create<mlir::cir::UnaryOp>(
2890+
Loc, mlir::cir::UnaryOpKind::Inc, InVal);
2891+
else
2892+
IncDecVal = builder.create<mlir::cir::UnaryOp>(
2893+
Loc, mlir::cir::UnaryOpKind::Dec, InVal);
2894+
2895+
buildStoreOfComplex(Loc, IncDecVal, LV);
2896+
if (getLangOpts().OpenMP)
2897+
assert(!UnimplementedFeature::openMP());
2898+
2899+
return isPre ? IncDecVal : InVal;
2900+
}

0 commit comments

Comments
 (0)