Skip to content

Commit e1fe8e1

Browse files
authored
[CIR][ABI][NFC] Follow-up to struct unpacking (#791)
This patch fixes a bunch of pending review comments in #784: - Remove data layout attribute from address space testing - Remove incoherent comment - Rename abi_or_pref to abiOrPref - Make comments impersonal - Implement feature guard for ARM's CMSE secure call feature - Track volatile return times feature in CC lowering - Track missing features in the Itanium record builder - Remove incoherent fix me - Clarify comment regarding CIR record layout getter - Track missing cache for record layout getter - Remove unnecessary todo's
1 parent 548458f commit e1fe8e1

File tree

11 files changed

+41
-56
lines changed

11 files changed

+41
-56
lines changed

clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class CIRDataLayout {
5555
const StructLayout *getStructLayout(mlir::cir::StructType Ty) const;
5656

5757
/// Internal helper method that returns requested alignment for type.
58-
llvm::Align getAlignment(mlir::Type Ty, bool abi_or_pref) const;
58+
llvm::Align getAlignment(mlir::Type Ty, bool abiOrPref) const;
5959

6060
llvm::Align getABITypeAlign(mlir::Type ty) const {
6161
return getAlignment(ty, true);
@@ -93,8 +93,6 @@ class CIRDataLayout {
9393
return layout.getTypeSizeInBits(Ty);
9494
}
9595

96-
// The implementation of this method is provided inline as it is particularly
97-
// well suited to constant folding when called on a specific Type subclass.
9896
llvm::TypeSize getTypeSizeInBits(mlir::Type Ty) const;
9997

10098
mlir::Type getIntPtrType(mlir::Type Ty) const {

clang/include/clang/CIR/MissingFeatures.h

+7
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ struct MissingFeatures {
135135
static bool syncScopeID() { return false; }
136136

137137
// Misc
138+
static bool cacheRecordLayouts() { return false; }
138139
static bool capturedByInit() { return false; }
139140
static bool tryEmitAsConstant() { return false; }
140141
static bool incrementProfileCounter() { return false; }
@@ -282,6 +283,9 @@ struct MissingFeatures {
282283
// up argument registers), but we do not yet track such cases.
283284
static bool chainCall() { return false; }
284285

286+
// ARM-specific feature that can be specified as a function attribute in C.
287+
static bool cmseNonSecureCallAttr() { return false; }
288+
285289
// ABI-lowering has special handling for regcall calling convention (tries to
286290
// pass every argument in regs). We don't support it just yet.
287291
static bool regCall() { return false; }
@@ -326,6 +330,9 @@ struct MissingFeatures {
326330
// CIR modules parsed from text form may not carry the triple or data layout
327331
// specs. We should make it always present.
328332
static bool makeTripleAlwaysPresent() { return false; }
333+
334+
// This Itanium bit is currently being skipped in cir.
335+
static bool itaniumRecordLayoutBuilderFinishLayout() { return false; }
329336
};
330337

331338
} // namespace cir

clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -156,25 +156,25 @@ CIRDataLayout::getStructLayout(mlir::cir::StructType Ty) const {
156156
}
157157

158158
/*!
159-
\param abi_or_pref Flag that determines which alignment is returned. true
159+
\param abiOrPref Flag that determines which alignment is returned. true
160160
returns the ABI alignment, false returns the preferred alignment.
161161
\param Ty The underlying type for which alignment is determined.
162162
163-
Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref
163+
Get the ABI (\a abiOrPref == true) or preferred alignment (\a abiOrPref
164164
== false) for the requested type \a Ty.
165165
*/
166-
llvm::Align CIRDataLayout::getAlignment(mlir::Type Ty, bool abi_or_pref) const {
166+
llvm::Align CIRDataLayout::getAlignment(mlir::Type Ty, bool abiOrPref) const {
167167

168168
if (llvm::isa<mlir::cir::StructType>(Ty)) {
169169
// Packed structure types always have an ABI alignment of one.
170-
if (::cir::MissingFeatures::recordDeclIsPacked() && abi_or_pref)
170+
if (::cir::MissingFeatures::recordDeclIsPacked() && abiOrPref)
171171
llvm_unreachable("NYI");
172172

173173
// Get the layout annotation... which is lazily created on demand.
174174
const StructLayout *Layout =
175175
getStructLayout(llvm::cast<mlir::cir::StructType>(Ty));
176176
const llvm::Align Align =
177-
abi_or_pref ? StructAlignment.ABIAlign : StructAlignment.PrefAlign;
177+
abiOrPref ? StructAlignment.ABIAlign : StructAlignment.PrefAlign;
178178
return std::max(Align, Layout->getAlignment());
179179
}
180180

@@ -183,7 +183,7 @@ llvm::Align CIRDataLayout::getAlignment(mlir::Type Ty, bool abi_or_pref) const {
183183
assert(!::cir::MissingFeatures::addressSpace());
184184

185185
// Fetch type alignment from MLIR's data layout.
186-
unsigned align = abi_or_pref ? layout.getTypeABIAlignment(Ty)
186+
unsigned align = abiOrPref ? layout.getTypeABIAlignment(Ty)
187187
: layout.getTypePreferredAlignment(Ty);
188188
return llvm::Align(align);
189189
}

clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRLowerContext.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ clang::TypeInfo CIRLowerContext::getTypeInfoImpl(const Type T) const {
6161
// FIXME(cir): Here we fetch the width and alignment of a type considering the
6262
// current target. We can likely improve this using MLIR's data layout, or
6363
// some other interface, to abstract this away (e.g. type.getWidth() &
64-
// type.getAlign()). I'm not sure if data layoot suffices because this would
65-
// involve some other types such as vectors and complex numbers.
64+
// type.getAlign()). Verify if data layout suffices because this would involve
65+
// some other types such as vectors and complex numbers.
6666
// FIXME(cir): In the original codegen, this receives an AST type, meaning it
6767
// differs chars from integers, something that is not possible with the
6868
// current level of CIR.

clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRRecordLayout.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "CIRRecordLayout.h"
15+
#include "clang/CIR/MissingFeatures.h"
1516

1617
namespace mlir {
1718
namespace cir {
@@ -45,10 +46,8 @@ CIRRecordLayout::CIRRecordLayout(
4546
CXXInfo->NonVirtualAlignment = nonvirtualalignment;
4647
CXXInfo->PreferredNVAlignment = preferrednvalignment;
4748
CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
48-
// FIXME(cir): I'm assuming that since we are not dealing with inherited
49-
// classes yet, removing the following lines will be ok.
50-
// CXXInfo->BaseOffsets = BaseOffsets;
51-
// CXXInfo->VBaseOffsets = VBaseOffsets;
49+
// FIXME(cir): Initialize base classes offsets.
50+
assert(!::cir::MissingFeatures::getCXXRecordBases());
5251
CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
5352
CXXInfo->VBPtrOffset = vbptroffset;
5453
CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;

clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerCall.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ arrangeFreeFunctionLikeCall(LowerTypes &LT, LowerModule &LM,
4242
}
4343

4444
// TODO(cir): There's some CC stuff related to no-proto functions here, but
45-
// I'm skipping it since it requires CodeGen info. Maybe we can embbed this
46-
// information in the FuncOp during CIRGen.
45+
// its skipped here since it requires CodeGen info. Maybe this information
46+
// could be embbed in the FuncOp during CIRGen.
4747

4848
assert(!::cir::MissingFeatures::chainCall() && !chainCall && "NYI");
4949
FnInfoOpts opts = chainCall ? FnInfoOpts::IsChainCall : FnInfoOpts::None;
@@ -120,8 +120,8 @@ void LowerModule::constructAttributeList(StringRef Name,
120120
// }
121121

122122
// NOTE(cir): The original code adds default and no-builtin attributes here as
123-
// well. AFAIK, these are ABI/Target-agnostic, so it would be better handled
124-
// in CIRGen. Regardless, I'm leaving this comment here as a heads up.
123+
// well. These are ABI/Target-agnostic, so it would be better handled in
124+
// CIRGen.
125125

126126
// Override some default IR attributes based on declaration-specific
127127
// information.

clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp

+6-12
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,7 @@ LogicalResult LowerFunction::buildFunctionEpilog(const LowerFunctionInfo &FI) {
434434

435435
// If there is a dominating store to ReturnValue, we can elide
436436
// the load, zap the store, and usually zap the alloca.
437-
// NOTE(cir): This seems like a premature optimization case, so I'm
438-
// skipping it.
437+
// NOTE(cir): This seems like a premature optimization case. Skipping it.
439438
if (::cir::MissingFeatures::returnValueDominatingStoreOptmiization()) {
440439
llvm_unreachable("NYI");
441440
}
@@ -453,12 +452,6 @@ LogicalResult LowerFunction::buildFunctionEpilog(const LowerFunctionInfo &FI) {
453452
mlir::PatternRewriter::InsertionGuard guard(rewriter);
454453
NewFn->walk([&](ReturnOp returnOp) {
455454
rewriter.setInsertionPoint(returnOp);
456-
457-
// TODO(cir): I'm not sure if we need this offset here or in CIRGen.
458-
// Perhaps both? For now I'm just ignoring it.
459-
// Value V = emitAddressAtOffset(*this, getResultAlloca(returnOp),
460-
// RetAI);
461-
462455
RV = castReturnValue(returnOp->getOperand(0), RetAI.getCoerceToType(),
463456
*this);
464457
rewriter.replaceOpWithNewOp<ReturnOp>(returnOp, RV);
@@ -655,7 +648,7 @@ Value LowerFunction::rewriteCallOp(const LowerFunctionInfo &CallInfo,
655648

656649
FuncType IRFuncTy = LM.getTypes().getFunctionType(CallInfo);
657650

658-
// NOTE(cir): Some target/ABI related checks happen here. I'm skipping them
651+
// NOTE(cir): Some target/ABI related checks happen here. They are skipped
659652
// under the assumption that they are handled in CIRGen.
660653

661654
// 1. Set up the arguments.
@@ -737,7 +730,7 @@ Value LowerFunction::rewriteCallOp(const LowerFunctionInfo &CallInfo,
737730
if (!isa<StructType>(I->getType())) {
738731
llvm_unreachable("NYI");
739732
} else {
740-
// NOTE(cir): I'm leaving L/RValue stuff for CIRGen to handle.
733+
// NOTE(cir): L/RValue stuff are left for CIRGen to handle.
741734
Src = *I;
742735
}
743736

@@ -756,6 +749,7 @@ Value LowerFunction::rewriteCallOp(const LowerFunctionInfo &CallInfo,
756749
Value Load = createCoercedValue(Src, ArgInfo.getCoerceToType(), *this);
757750

758751
// FIXME(cir): We should probably handle CMSE non-secure calls here
752+
assert(!::cir::MissingFeatures::cmseNonSecureCallAttr());
759753

760754
// since they are a ARM-specific feature.
761755
if (::cir::MissingFeatures::undef())
@@ -856,22 +850,22 @@ Value LowerFunction::rewriteCallOp(const LowerFunctionInfo &CallInfo,
856850
// FIXME(cir): Use return value slot here.
857851
Value RetVal = callOp.getResult();
858852
// TODO(cir): Check for volatile return values.
853+
assert(!::cir::MissingFeatures::volatileTypes());
859854

860855
// NOTE(cir): If the function returns, there should always be a valid
861856
// return value present. Instead of setting the return value here, we
862857
// should have the ReturnValueSlot object set it beforehand.
863858
if (!RetVal) {
864859
RetVal = callOp.getResult();
865860
// TODO(cir): Check for volatile return values.
861+
assert(::cir::MissingFeatures::volatileTypes());
866862
}
867863

868864
// An empty record can overlap other data (if declared with
869865
// no_unique_address); omit the store for such types - as there is no
870866
// actual data to store.
871867
if (dyn_cast<StructType>(RetTy) &&
872868
cast<StructType>(RetTy).getNumElements() != 0) {
873-
// NOTE(cir): I'm assuming we don't need to change any offsets here.
874-
// Value StorePtr = emitAddressAtOffset(*this, RetVal, RetAI);
875869
RetVal =
876870
createCoercedValue(newCallOp.getResult(), RetVal.getType(), *this);
877871
}

clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerTypes.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ mlir::Type LowerTypes::convertType(Type T) {
108108
/// LLVM IR representation for a given AST type. When a the ABI-specific
109109
/// function info sets a nullptr for a return or argument type, the default
110110
/// type given by this method is used. In CIR's case, its types are already
111-
/// supposed to be ABI-specific, so this method is not really useful here. I'm
112-
/// keeping it here for parity's sake.
111+
/// supposed to be ABI-specific, so this method is not really useful here.
112+
/// It's kept here for codegen parity's sake.
113113

114114
// Certain CIR types are already ABI-specific, so we just return them.
115115
if (isa<BoolType, IntType, SingleType, DoubleType>(T)) {

clang/lib/CIR/Dialect/Transforms/TargetLowering/RecordLayoutBuilder.cpp

+7-18
Original file line numberDiff line numberDiff line change
@@ -239,18 +239,10 @@ void ItaniumRecordLayoutBuilder::layout(const StructType RT) {
239239

240240
layoutFields(RT);
241241

242-
// NonVirtualSize = Context.toCharUnitsFromBits(
243-
// llvm::alignTo(getSizeInBits(),
244-
// Context.getTargetInfo().getCharAlign()));
245-
// NonVirtualAlignment = Alignment;
246-
// PreferredNVAlignment = PreferredAlignment;
247-
248-
// // Lay out the virtual bases and add the primary virtual base offsets.
249-
// LayoutVirtualBases(RD, RD);
250-
251-
// // Finally, round the size of the total struct up to the alignment
252-
// // of the struct itself.
253-
// FinishLayout(RD);
242+
// FIXME(cir): Handle virtual-related layouts.
243+
assert(!::cir::MissingFeatures::getCXXRecordBases());
244+
245+
assert(!::cir::MissingFeatures::itaniumRecordLayoutBuilderFinishLayout());
254246
}
255247

256248
void ItaniumRecordLayoutBuilder::initializeLayout(const mlir::Type Ty) {
@@ -558,10 +550,6 @@ static bool mustSkipTailPadding(clang::TargetCXXABI ABI, const StructType RD) {
558550
return false;
559551

560552
case clang::TargetCXXABI::UseTailPaddingUnlessPOD03:
561-
// FIXME: To the extent that this is meant to cover the Itanium ABI
562-
// rules, we should implement the restrictions about over-sized
563-
// bitfields:
564-
//
565553
// http://itanium-cxx-abi.github.io/cxx-abi/abi.html#POD :
566554
// In general, a type is considered a POD for the purposes of
567555
// layout if it is a POD type (in the sense of ISO C++
@@ -605,7 +593,8 @@ const CIRRecordLayout &CIRLowerContext::getCIRRecordLayout(const Type D) const {
605593

606594
assert(RT.isComplete() && "Cannot get layout of forward declarations!");
607595

608-
// FIXME(cir): Cache the layout. Also, use a more MLIR-based approach.
596+
// FIXME(cir): Use a more MLIR-based approach by using it's buitin data layout
597+
// features, such as interfaces, cacheing, and the DLTI dialect.
609598

610599
const CIRRecordLayout *NewEntry = nullptr;
611600

@@ -642,8 +631,8 @@ const CIRRecordLayout &CIRLowerContext::getCIRRecordLayout(const Type D) const {
642631
Builder.PrimaryBaseIsVirtual, nullptr, false, false);
643632
}
644633

645-
// TODO(cir): Cache the layout.
646634
// TODO(cir): Add option to dump the layouts.
635+
assert(!::cir::MissingFeatures::cacheRecordLayouts());
647636

648637
return *NewEntry;
649638
}

clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/X86.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,8 @@ void X86_64ABIInfo::classify(Type Ty, uint64_t OffsetBase, Class &Lo, Class &Hi,
235235
} else if (isa<IntType>(Ty)) {
236236

237237
// FIXME(cir): Clang's BuiltinType::Kind allow comparisons (GT, LT, etc).
238-
// We should implement this in CIR to simplify the conditions below. BTW,
239-
// I'm not sure if the comparisons below are truly equivalent to the ones
240-
// in Clang.
238+
// We should implement this in CIR to simplify the conditions below. Hence,
239+
// Comparisons below might not be truly equivalent to the ones in Clang.
241240
if (isa<IntType>(Ty)) {
242241
Current = Class::Integer;
243242
}

clang/test/CIR/Lowering/address-space.cir

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55

66
module attributes {
77
cir.triple = "spirv64-unknown-unknown",
8-
llvm.data_layout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1",
9-
dlti.dl_spec = #dlti.dl_spec<> // Avoid assert errors.
8+
llvm.data_layout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
109
} {
1110
cir.global external addrspace(offload_global) @addrspace1 = #cir.int<1> : !s32i
1211
// LLVM: @addrspace1 = addrspace(1) global i32

0 commit comments

Comments
 (0)