aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/CodeGen')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenAtomic.cpp20
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCall.cpp26
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCall.h2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExpr.cpp4
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp14
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp20
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenModule.cpp1
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenTypeCache.h7
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenTypes.cpp2
-rw-r--r--clang/lib/CIR/CodeGen/TargetInfo.h6
10 files changed, 74 insertions, 28 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index e943b02..0f4d6d2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -718,10 +718,26 @@ void CIRGenFunction::emitAtomicInit(Expr *init, LValue dest) {
return;
}
- case cir::TEK_Aggregate:
- cgm.errorNYI(init->getSourceRange(), "emitAtomicInit: aggregate type");
+ case cir::TEK_Aggregate: {
+ // Fix up the destination if the initializer isn't an expression
+ // of atomic type.
+ bool zeroed = false;
+ if (!init->getType()->isAtomicType()) {
+ zeroed = atomics.emitMemSetZeroIfNecessary();
+ dest = atomics.projectValue();
+ }
+
+ // Evaluate the expression directly into the destination.
+ assert(!cir::MissingFeatures::aggValueSlotGC());
+ AggValueSlot slot = AggValueSlot::forLValue(
+ dest, AggValueSlot::IsNotDestructed, AggValueSlot::IsNotAliased,
+ AggValueSlot::DoesNotOverlap,
+ zeroed ? AggValueSlot::IsZeroed : AggValueSlot::IsNotZeroed);
+
+ emitAggExpr(init, slot);
return;
}
+ }
llvm_unreachable("bad evaluation kind");
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 2970b36..61072f0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -522,7 +522,8 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
assert(!cir::MissingFeatures::opCallPaddingArgs());
mlir::Type argType = convertType(canQualArgType);
- if (!mlir::isa<cir::RecordType>(argType)) {
+ if (!mlir::isa<cir::RecordType>(argType) &&
+ !mlir::isa<cir::ComplexType>(argType)) {
mlir::Value v;
if (arg.isAggregate())
cgm.errorNYI(loc, "emitCall: aggregate call argument");
@@ -540,15 +541,16 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
cirCallArgs[argNo] = v;
} else {
Address src = Address::invalid();
- if (!arg.isAggregate())
- cgm.errorNYI(loc, "emitCall: non-aggregate call argument");
- else
+ if (!arg.isAggregate()) {
+ src = createMemTemp(arg.ty, loc, "coerce");
+ arg.copyInto(*this, src, loc);
+ } else {
src = arg.hasLValue() ? arg.getKnownLValue().getAddress()
: arg.getKnownRValue().getAggregateAddress();
+ }
// Fast-isel and the optimizer generally like scalar values better than
// FCAs, so we flatten them if this is safe to do for this argument.
- auto argRecordTy = cast<cir::RecordType>(argType);
mlir::Type srcTy = src.getElementType();
// FIXME(cir): get proper location for each argument.
mlir::Location argLoc = loc;
@@ -564,7 +566,7 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
// uint64_t DstSize = CGM.getDataLayout().getTypeAllocSize(STy);
// if (SrcSize < DstSize) {
assert(!cir::MissingFeatures::dataLayoutTypeAllocSize());
- if (srcTy != argRecordTy) {
+ if (srcTy != argType) {
cgm.errorNYI(loc, "emitCall: source type does not match argument type");
} else {
// FIXME(cir): this currently only runs when the types are exactly the
@@ -676,6 +678,18 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
llvm_unreachable("Invalid evaluation kind");
}
+void CallArg::copyInto(CIRGenFunction &cgf, Address addr,
+ mlir::Location loc) const {
+ LValue dst = cgf.makeAddrLValue(addr, ty);
+ if (!hasLV && rv.isScalar())
+ cgf.cgm.errorNYI(loc, "copyInto scalar value");
+ else if (!hasLV && rv.isComplex())
+ cgf.emitStoreOfComplex(loc, rv.getComplexValue(), dst, /*isInit=*/true);
+ else
+ cgf.cgm.errorNYI(loc, "copyInto hasLV");
+ isUsed = true;
+}
+
void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
clang::QualType argType) {
assert(argType->isReferenceType() == e->isGLValue() &&
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.h b/clang/lib/CIR/CodeGen/CIRGenCall.h
index 52d541f..55b3d97 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.h
@@ -224,6 +224,8 @@ public:
}
bool isAggregate() const { return hasLV || rv.isAggregate(); }
+
+ void copyInto(CIRGenFunction &cgf, Address addr, mlir::Location loc) const;
};
class CallArgList : public llvm::SmallVector<CallArg, 8> {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index b4c8924..be94890 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -2053,8 +2053,8 @@ mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
// CIR uses its own alloca address space rather than follow the target data
// layout like original CodeGen. The data layout awareness should be done in
// the lowering pass instead.
- assert(!cir::MissingFeatures::addressSpace());
- cir::PointerType localVarPtrTy = builder.getPointerTo(ty);
+ cir::PointerType localVarPtrTy =
+ builder.getPointerTo(ty, getCIRAllocaAddressSpace());
mlir::IntegerAttr alignIntAttr = cgm.getSize(alignment);
mlir::Value addr;
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 1e987f3..e51c3fc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -144,10 +144,7 @@ public:
void VisitUnaryCoawait(UnaryOperator *e) {
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitUnaryCoawait");
}
- void VisitUnaryExtension(UnaryOperator *e) {
- cgf.cgm.errorNYI(e->getSourceRange(),
- "AggExprEmitter: VisitUnaryExtension");
- }
+ void VisitUnaryExtension(UnaryOperator *e) { Visit(e->getSubExpr()); }
void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e) {
cgf.cgm.errorNYI(e->getSourceRange(),
"AggExprEmitter: VisitSubstNonTypeTemplateParmExpr");
@@ -184,7 +181,8 @@ public:
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitBinAssign");
}
void VisitBinComma(const BinaryOperator *e) {
- cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitBinComma");
+ cgf.emitIgnoredExpr(e->getLHS());
+ Visit(e->getRHS());
}
void VisitBinCmp(const BinaryOperator *e) {
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitBinCmp");
@@ -212,9 +210,11 @@ public:
}
void VisitChooseExpr(const ChooseExpr *e) { Visit(e->getChosenSubExpr()); }
void VisitCXXParenListInitExpr(CXXParenListInitExpr *e) {
- cgf.cgm.errorNYI(e->getSourceRange(),
- "AggExprEmitter: VisitCXXParenListInitExpr");
+ visitCXXParenListOrInitListExpr(e, e->getInitExprs(),
+ e->getInitializedFieldInUnion(),
+ e->getArrayFiller());
}
+
void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *e,
llvm::Value *outerBegin = nullptr) {
cgf.cgm.errorNYI(e->getSourceRange(),
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 500007f..768d75d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2159,16 +2159,16 @@ mlir::Value ScalarExprEmitter::VisitRealImag(const UnaryOperator *e,
// __imag on a scalar returns zero. Emit the subexpr to ensure side
// effects are evaluated, but not the actual value.
- if (op->isGLValue())
- cgf.emitLValue(op);
- else if (!promotionTy.isNull())
- cgf.emitPromotedScalarExpr(op, promotionTy);
- else
- cgf.emitScalarExpr(op);
-
- mlir::Type valueTy =
- cgf.convertType(promotionTy.isNull() ? e->getType() : promotionTy);
- return builder.getNullValue(valueTy, loc);
+ mlir::Value operand;
+ if (op->isGLValue()) {
+ operand = cgf.emitLValue(op).getPointer();
+ operand = cir::LoadOp::create(builder, loc, operand);
+ } else if (!promotionTy.isNull()) {
+ operand = cgf.emitPromotedScalarExpr(op, promotionTy);
+ } else {
+ operand = cgf.emitScalarExpr(op);
+ }
+ return builder.createComplexImag(loc, operand);
}
/// Return the size or alignment of the type of argument of the sizeof
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 8485564..910c8a9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -76,6 +76,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
SInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/true);
UInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/false);
UInt8PtrTy = cir::PointerType::get(UInt8Ty);
+ cirAllocaAddressSpace = getTargetCIRGenInfo().getCIRAllocaAddressSpace();
UInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/false);
UInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/false);
UInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/false);
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
index cc3ce09..273ec7f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
+++ b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
@@ -14,6 +14,7 @@
#define LLVM_CLANG_LIB_CIR_CIRGENTYPECACHE_H
#include "clang/AST/CharUnits.h"
+#include "clang/Basic/AddressSpaces.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
namespace clang::CIRGen {
@@ -73,6 +74,8 @@ struct CIRGenTypeCache {
/// The alignment of size_t.
unsigned char SizeAlignInBytes;
+ cir::TargetAddressSpaceAttr cirAllocaAddressSpace;
+
clang::CharUnits getSizeAlign() const {
return clang::CharUnits::fromQuantity(SizeAlignInBytes);
}
@@ -80,6 +83,10 @@ struct CIRGenTypeCache {
clang::CharUnits getPointerAlign() const {
return clang::CharUnits::fromQuantity(PointerAlignInBytes);
}
+
+ cir::TargetAddressSpaceAttr getCIRAllocaAddressSpace() const {
+ return cirAllocaAddressSpace;
+ }
};
} // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index bb24933..e65896a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -417,7 +417,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
mlir::Type pointeeType = convertType(elemTy);
- resultType = builder.getPointerTo(pointeeType);
+ resultType = builder.getPointerTo(pointeeType, elemTy.getAddressSpace());
break;
}
diff --git a/clang/lib/CIR/CodeGen/TargetInfo.h b/clang/lib/CIR/CodeGen/TargetInfo.h
index a5c548a..dbb0312 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.h
+++ b/clang/lib/CIR/CodeGen/TargetInfo.h
@@ -16,6 +16,7 @@
#include "ABIInfo.h"
#include "CIRGenTypes.h"
+#include "clang/Basic/AddressSpaces.h"
#include <memory>
#include <utility>
@@ -43,6 +44,11 @@ public:
/// Returns ABI info helper for the target.
const ABIInfo &getABIInfo() const { return *info; }
+ /// Get the address space for alloca.
+ virtual cir::TargetAddressSpaceAttr getCIRAllocaAddressSpace() const {
+ return {};
+ }
+
/// Determine whether a call to an unprototyped functions under
/// the given calling convention should use the variadic
/// convention or the non-variadic convention.