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
4 changes: 0 additions & 4 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,8 @@ struct MissingFeatures {
// RecordType
static bool skippedLayout() { return false; }
static bool astRecordDeclAttr() { return false; }
static bool cxxSupport() { return false; }
static bool recordZeroInit() { return false; }
static bool zeroSizeRecordMembers() { return false; }
static bool recordLayoutVirtualBases() { return false; }

// Various handling of deferred processing in CIRGenModule.
static bool cgmRelease() { return false; }
Expand All @@ -148,7 +146,6 @@ struct MissingFeatures {
static bool cxxabiUseARMMethodPtrABI() { return false; }
static bool cxxabiUseARMGuardVarABI() { return false; }
static bool cxxabiAppleARM64CXXABI() { return false; }
static bool cxxabiStructorImplicitParam() { return false; }
static bool isDiscreteBitFieldABI() { return false; }

// Address class
Expand Down Expand Up @@ -229,7 +226,6 @@ struct MissingFeatures {
static bool globalViewIndices() { return false; }
static bool globalViewIntLowering() { return false; }
static bool hip() { return false; }
static bool implicitConstructorArgs() { return false; }
static bool incrementProfileCounter() { return false; }
static bool innermostEHScope() { return false; }
static bool insertBuiltinUnpredictable() { return false; }
Expand Down
33 changes: 33 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
cir::ConstantOp getUInt32(uint32_t c, mlir::Location loc) {
return getConstantInt(loc, getUInt32Ty(), c);
}
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc) {
cir::IntType sInt64Ty = getSInt64Ty();
return create<cir::ConstantOp>(loc, cir::IntAttr::get(sInt64Ty, c));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return create<cir::ConstantOp>(loc, cir::IntAttr::get(sInt64Ty, c));
return cir::ConstantOp::create(*this, loc, cir::IntAttr::get(sInt64Ty, c));

}

// Creates constant nullptr for pointer type ty.
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) {
Expand Down Expand Up @@ -359,6 +363,18 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
return Address(baseAddr, destType, addr.getAlignment());
}

mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy,
mlir::Value addr, uint64_t offset) {
return cir::VTTAddrPointOp::create(*this, loc, retTy,
mlir::FlatSymbolRefAttr{}, addr, offset);
}

mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy,
mlir::FlatSymbolRefAttr sym, uint64_t offset) {
return cir::VTTAddrPointOp::create(*this, loc, retTy, sym, mlir::Value{},
offset);
}

/// Cast the element type of the given address to a different type,
/// preserving information like the alignment.
Address createElementBitCast(mlir::Location loc, Address addr,
Expand All @@ -379,6 +395,23 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
/*mem_order=*/cir::MemOrderAttr{});
}

cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty,
mlir::Value ptr, llvm::MaybeAlign align) {
if (ty != mlir::cast<cir::PointerType>(ptr.getType()).getPointee())
ptr = createPtrBitcast(ptr, ty);
uint64_t alignment = align ? align->value() : 0;
mlir::IntegerAttr alignAttr = getAlignmentAttr(alignment);
return create<cir::LoadOp>(loc, ptr, /*isDeref=*/false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return create<cir::LoadOp>(loc, ptr, /*isDeref=*/false,
return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false,

/*isVolatile=*/false, alignAttr,
/*mem_order=*/cir::MemOrderAttr{});
}

cir::LoadOp
createAlignedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr,
clang::CharUnits align = clang::CharUnits::One()) {
return createAlignedLoad(loc, ty, ptr, align.getAsAlign());
}

cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst,
bool isVolatile = false,
mlir::IntegerAttr align = {},
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ using namespace clang::CIRGen;

CIRGenCXXABI::~CIRGenCXXABI() {}

CIRGenCXXABI::AddedStructorArgCounts CIRGenCXXABI::addImplicitConstructorArgs(
CIRGenFunction &cgf, const CXXConstructorDecl *d, CXXCtorType type,
bool forVirtualBase, bool delegating, CallArgList &args) {
AddedStructorArgs addedArgs =
getImplicitConstructorArgs(cgf, d, type, forVirtualBase, delegating);
for (auto [idx, prefixArg] : llvm::enumerate(addedArgs.prefix))
args.insert(args.begin() + 1 + idx,
CallArg(RValue::get(prefixArg.value), prefixArg.type));
for (const auto &arg : addedArgs.suffix)
args.add(RValue::get(arg.value), arg.type);
return AddedStructorArgCounts(addedArgs.prefix.size(),
addedArgs.suffix.size());
}

void CIRGenCXXABI::buildThisParam(CIRGenFunction &cgf,
FunctionArgList &params) {
const auto *md = cast<CXXMethodDecl>(cgf.curGD.getDecl());
Expand Down
79 changes: 79 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenCXXABI.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,67 @@ class CIRGenCXXABI {
/// constructor/destructor Decl.
virtual void emitCXXStructor(clang::GlobalDecl gd) = 0;

virtual mlir::Value
getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
Address thisAddr, const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) = 0;

public:
/// Similar to AddedStructorArgs, but only notes the number of additional
/// arguments.
struct AddedStructorArgCounts {
unsigned prefix = 0;
unsigned suffix = 0;
AddedStructorArgCounts() = default;
AddedStructorArgCounts(unsigned p, unsigned s) : prefix(p), suffix(s) {}
static AddedStructorArgCounts withPrefix(unsigned n) { return {n, 0}; }
static AddedStructorArgCounts withSuffix(unsigned n) { return {0, n}; }
};

/// Additional implicit arguments to add to the beginning (Prefix) and end
/// (Suffix) of a constructor / destructor arg list.
///
/// Note that Prefix should actually be inserted *after* the first existing
/// arg; `this` arguments always come first.
struct AddedStructorArgs {
struct Arg {
mlir::Value value;
QualType type;
};
llvm::SmallVector<Arg, 1> prefix;
llvm::SmallVector<Arg, 1> suffix;
AddedStructorArgs() = default;
AddedStructorArgs(llvm::SmallVector<Arg, 1> p, llvm::SmallVector<Arg, 1> s)
: prefix(std::move(p)), suffix(std::move(s)) {}
static AddedStructorArgs withPrefix(llvm::SmallVector<Arg, 1> args) {
return {std::move(args), {}};
}
static AddedStructorArgs withSuffix(llvm::SmallVector<Arg, 1> args) {
return {{}, std::move(args)};
}
};

/// Build the signature of the given constructor or destructor vairant by
/// adding any required parameters. For convenience, ArgTys has been
/// initialized with the type of 'this'.
virtual AddedStructorArgCounts
buildStructorSignature(GlobalDecl gd,
llvm::SmallVectorImpl<CanQualType> &argTys) = 0;

AddedStructorArgCounts
addImplicitConstructorArgs(CIRGenFunction &cgf, const CXXConstructorDecl *d,
CXXCtorType type, bool forVirtualBase,
bool delegating, CallArgList &args);

clang::ImplicitParamDecl *getThisDecl(CIRGenFunction &cgf) {
return cgf.cxxabiThisDecl;
}

virtual AddedStructorArgs
getImplicitConstructorArgs(CIRGenFunction &cgf, const CXXConstructorDecl *d,
CXXCtorType type, bool forVirtualBase,
bool delegating) = 0;

/// Emit the ABI-specific prolog for the function
virtual void emitInstanceFunctionProlog(SourceLocation loc,
CIRGenFunction &cgf) = 0;
Expand Down Expand Up @@ -144,6 +200,17 @@ class CIRGenCXXABI {
CIRGenFunction &cgf, const CXXRecordDecl *vtableClass, BaseSubobject base,
const CXXRecordDecl *nearestVBase) = 0;

/// Insert any ABI-specific implicit parameters into the parameter list for a
/// function. This generally involves extra data for constructors and
/// destructors.
///
/// ABIs may also choose to override the return type, which has been
/// initialized with the type of 'this' if HasThisReturn(CGF.CurGD) is true or
/// the formal return type of the function otherwise.
virtual void addImplicitStructorParams(CIRGenFunction &cgf,
clang::QualType &resTy,
FunctionArgList &params) = 0;

/// Checks if ABI requires to initialize vptrs for given dynamic class.
virtual bool
doStructorsInitializeVPtrs(const clang::CXXRecordDecl *vtableClass) = 0;
Expand All @@ -162,6 +229,18 @@ class CIRGenCXXABI {

/// Gets the mangle context.
clang::MangleContext &getMangleContext() { return *mangleContext; }

clang::ImplicitParamDecl *&getStructorImplicitParamDecl(CIRGenFunction &cgf) {
return cgf.cxxStructorImplicitParamDecl;
}

mlir::Value getStructorImplicitParamValue(CIRGenFunction &cgf) {
return cgf.cxxStructorImplicitParamValue;
}

void setStructorImplicitParamValue(CIRGenFunction &cgf, mlir::Value val) {
cgf.cxxStructorImplicitParamValue = val;
}
};

/// Creates and Itanium-family ABI
Expand Down
20 changes: 12 additions & 8 deletions clang/lib/CIR/CodeGen/CIRGenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,10 @@ CIRGenTypes::arrangeCXXStructorDeclaration(GlobalDecl gd) {
if (passParams)
appendParameterTypes(*this, argTypes, fpt);

assert(!cir::MissingFeatures::implicitConstructorArgs());
// The structor signature may include implicit parameters.
[[maybe_unused]] CIRGenCXXABI::AddedStructorArgCounts addedArgs =
theCXXABI.buildStructorSignature(gd, argTypes);
assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());

RequiredArgs required =
(passParams && md->isVariadic() ? RequiredArgs(argTypes.size())
Expand Down Expand Up @@ -324,26 +327,27 @@ arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,

/// Arrange a call to a C++ method, passing the given arguments.
///
/// extraPrefixArgs is the number of ABI-specific args passed after the `this`
/// parameter.
/// passProtoArgs indicates whether `args` has args for the parameters in the
/// given CXXConstructorDecl.
const CIRGenFunctionInfo &CIRGenTypes::arrangeCXXConstructorCall(
const CallArgList &args, const CXXConstructorDecl *d, CXXCtorType ctorKind,
bool passProtoArgs) {
unsigned extraPrefixArgs, unsigned extraSuffixArgs, bool passProtoArgs) {

// FIXME: Kill copy.
llvm::SmallVector<CanQualType, 16> argTypes;
for (const auto &arg : args)
argTypes.push_back(astContext.getCanonicalParamType(arg.ty));

assert(!cir::MissingFeatures::implicitConstructorArgs());
// +1 for implicit this, which should always be args[0]
unsigned totalPrefixArgs = 1;
unsigned totalPrefixArgs = 1 + extraPrefixArgs;

CanQual<FunctionProtoType> fpt = getFormalType(d);
RequiredArgs required =
passProtoArgs
? RequiredArgs::getFromProtoWithExtraSlots(fpt, totalPrefixArgs)
: RequiredArgs::All;
RequiredArgs required = passProtoArgs
? RequiredArgs::getFromProtoWithExtraSlots(
fpt, totalPrefixArgs + extraSuffixArgs)
: RequiredArgs::All;

GlobalDecl gd(d, ctorKind);
if (theCXXABI.hasThisReturn(gd))
Expand Down
Loading
Loading