Skip to content

Commit f963e75

Browse files
authored
merge main into amd-staging (#631)
2 parents 0d7728c + 13a0614 commit f963e75

File tree

88 files changed

+16402
-27076
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+16402
-27076
lines changed

clang/include/clang/Basic/TargetID.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ getConflictTargetIDCombination(const std::set<llvm::StringRef> &TargetIDs);
5656
/// Check whether the provided target ID is compatible with the requested
5757
/// target ID.
5858
bool isCompatibleTargetID(llvm::StringRef Provided, llvm::StringRef Requested);
59+
60+
/// Sanitize a target ID string for use in a file name.
61+
/// Replaces invalid characters (like ':') with safe characters (like '@').
62+
/// Currently only replaces ':' with '@' on Windows.
63+
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID);
5964
} // namespace clang
6065

6166
#endif

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

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,119 @@ def CIR_GlobalDtorAttr : CIR_GlobalCtorDtor<"Dtor", "dtor"> {
822822
}];
823823
}
824824

825+
//===----------------------------------------------------------------------===//
826+
// CXX SpecialMemberAttr
827+
//===----------------------------------------------------------------------===//
828+
829+
def CIR_CtorKind : CIR_I32EnumAttr<"CtorKind", "CXX Constructor Kind", [
830+
I32EnumAttrCase<"Custom", 0, "custom">,
831+
I32EnumAttrCase<"Default", 1, "default">,
832+
I32EnumAttrCase<"Copy", 2, "copy">,
833+
I32EnumAttrCase<"Move", 3, "move">,
834+
]> {
835+
let genSpecializedAttr = 0;
836+
}
837+
838+
def CIR_CXXCtorAttr : CIR_Attr<"CXXCtor", "cxx_ctor"> {
839+
let summary = "Marks a function as a C++ constructor";
840+
let description = [{
841+
This attribute identifies a C++ constructor and classifies its kind:
842+
843+
- `custom`: a user-defined constructor
844+
- `default`: a default constructor
845+
- `copy`: a copy constructor
846+
- `move`: a move constructor
847+
848+
Example:
849+
```mlir
850+
#cir.cxx_ctor<!rec_a, copy>
851+
#cir.cxx_ctor<!rec_b, default, trivial>
852+
```
853+
}];
854+
855+
let parameters = (ins
856+
"mlir::Type":$type,
857+
EnumParameter<CIR_CtorKind>:$ctor_kind,
858+
DefaultValuedParameter<"bool", "false">:$is_trivial
859+
);
860+
861+
let builders = [
862+
AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
863+
CArg<"CtorKind", "cir::CtorKind::Custom">:$ctorKind,
864+
CArg<"bool", "false">:$isTrivial), [{
865+
return $_get(type.getContext(), type, ctorKind, isTrivial);
866+
}]>,
867+
];
868+
869+
let assemblyFormat = [{
870+
`<` $type `,` $ctor_kind (`,` `trivial` $is_trivial^)? `>`
871+
}];
872+
}
873+
874+
def CIR_CXXDtorAttr : CIR_Attr<"CXXDtor", "cxx_dtor"> {
875+
let summary = "Marks a function as a CXX destructor";
876+
let description = [{
877+
This attribute identifies a C++ destructor.
878+
}];
879+
880+
let parameters = (ins
881+
"mlir::Type":$type,
882+
DefaultValuedParameter<"bool", "false">:$is_trivial
883+
);
884+
885+
let builders = [
886+
AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
887+
CArg<"bool", "false">:$isTrivial), [{
888+
return $_get(type.getContext(), type, isTrivial);
889+
}]>
890+
];
891+
892+
let assemblyFormat = [{
893+
`<` $type (`,` `trivial` $is_trivial^)? `>`
894+
}];
895+
}
896+
897+
def CIR_AssignKind : CIR_I32EnumAttr<"AssignKind", "CXX Assignment Operator Kind", [
898+
I32EnumAttrCase<"Copy", 0, "copy">,
899+
I32EnumAttrCase<"Move", 1, "move">,
900+
]> {
901+
let genSpecializedAttr = 0;
902+
}
903+
904+
def CIR_CXXAssignAttr : CIR_Attr<"CXXAssign", "cxx_assign"> {
905+
let summary = "Marks a function as a CXX assignment operator";
906+
let description = [{
907+
This attribute identifies a C++ assignment operator and classifies its kind:
908+
909+
- `copy`: a copy assignment
910+
- `move`: a move assignment
911+
}];
912+
913+
let parameters = (ins
914+
"mlir::Type":$type,
915+
EnumParameter<CIR_AssignKind>:$assign_kind,
916+
DefaultValuedParameter<"bool", "false">:$is_trivial
917+
);
918+
919+
let builders = [
920+
AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
921+
CArg<"AssignKind">:$assignKind,
922+
CArg<"bool", "false">:$isTrivial), [{
923+
return $_get(type.getContext(), type, assignKind, isTrivial);
924+
}]>
925+
];
926+
927+
let assemblyFormat = [{
928+
`<` $type `,` $assign_kind (`,` `trivial` $is_trivial^)? `>`
929+
}];
930+
}
931+
932+
def CIR_CXXSpecialMemberAttr : AnyAttrOf<[
933+
CIR_CXXCtorAttr,
934+
CIR_CXXDtorAttr,
935+
CIR_CXXAssignAttr
936+
]>;
937+
825938
//===----------------------------------------------------------------------===//
826939
// BitfieldInfoAttr
827940
//===----------------------------------------------------------------------===//

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

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2533,7 +2533,9 @@ def CIR_FuncOp : CIR_Op<"func", [
25332533
OptionalAttr<DictArrayAttr>:$res_attrs,
25342534
OptionalAttr<FlatSymbolRefAttr>:$aliasee,
25352535
CIR_OptionalPriorityAttr:$global_ctor_priority,
2536-
CIR_OptionalPriorityAttr:$global_dtor_priority);
2536+
CIR_OptionalPriorityAttr:$global_dtor_priority,
2537+
OptionalAttr<CIR_CXXSpecialMemberAttr>:$cxx_special_member
2538+
);
25372539

25382540
let regions = (region AnyRegion:$body);
25392541

@@ -2572,7 +2574,32 @@ def CIR_FuncOp : CIR_Op<"func", [
25722574
//===------------------------------------------------------------------===//
25732575

25742576
bool isDeclaration();
2575-
}];
2577+
2578+
//===------------------------------------------------------------------===//
2579+
// C++ Special Member Functions
2580+
//===------------------------------------------------------------------===//
2581+
2582+
/// Returns true if this function is a C++ special member function.
2583+
bool isCXXSpecialMemberFunction();
2584+
2585+
bool isCxxConstructor();
2586+
bool isCxxDestructor();
2587+
2588+
/// Returns true if this function is a copy or move assignment operator.
2589+
bool isCxxSpecialAssignment();
2590+
2591+
/// Returns the kind of constructor this function represents, if any.
2592+
std::optional<CtorKind> getCxxConstructorKind();
2593+
2594+
/// Returns the kind of assignment operator (move, copy) this function
2595+
/// represents, if any.
2596+
std::optional<AssignKind> getCxxSpecialAssignKind();
2597+
2598+
/// Returns true if the function is a trivial C++ member functions such as
2599+
/// trivial default constructor, copy/move constructor, copy/move assignment,
2600+
/// or destructor.
2601+
bool isCxxTrivialMemberFunction();
2602+
}];
25762603

25772604
let hasCustomAssemblyFormat = 1;
25782605
let hasVerifier = 1;
@@ -4362,7 +4389,7 @@ def CIR_ObjSizeOp : CIR_Op<"objsize", [Pure]> {
43624389
When the `min` attribute is present, the operation returns the minimum
43634390
guaranteed accessible size. When absent (max mode), it returns the maximum
43644391
possible object size. Corresponds to `llvm.objectsize`'s `min` argument.
4365-
4392+
43664393
The `dynamic` attribute determines if the value should be evaluated at
43674394
runtime. Corresponds to `llvm.objectsize`'s `dynamic` argument.
43684395

clang/lib/Basic/TargetID.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
#include "clang/Basic/TargetID.h"
1010
#include "llvm/ADT/STLExtras.h"
1111
#include "llvm/ADT/SmallSet.h"
12+
#include "llvm/ADT/SmallVector.h"
13+
#include "llvm/Support/Path.h"
1214
#include "llvm/TargetParser/TargetParser.h"
1315
#include "llvm/TargetParser/Triple.h"
1416
#include <map>
1517
#include <optional>
18+
#include <string>
1619

1720
namespace clang {
1821

@@ -183,4 +186,11 @@ bool isCompatibleTargetID(llvm::StringRef Provided, llvm::StringRef Requested) {
183186
return true;
184187
}
185188

189+
std::string sanitizeTargetIDInFileName(llvm::StringRef TargetID) {
190+
std::string FileName = TargetID.str();
191+
if (llvm::sys::path::is_style_windows(llvm::sys::path::Style::native))
192+
llvm::replace(FileName, ':', '@');
193+
return FileName;
194+
}
195+
186196
} // namespace clang

clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,26 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
121121
return emitIntrinsicCallOp(*this, expr, "x86.sse.sfence", voidTy);
122122
case X86::BI_mm_prefetch:
123123
case X86::BI__rdtsc:
124-
case X86::BI__builtin_ia32_rdtscp:
124+
case X86::BI__builtin_ia32_rdtscp: {
125+
cgm.errorNYI(expr->getSourceRange(),
126+
std::string("unimplemented X86 builtin call: ") +
127+
getContext().BuiltinInfo.getName(builtinID));
128+
return {};
129+
}
125130
case X86::BI__builtin_ia32_lzcnt_u16:
126131
case X86::BI__builtin_ia32_lzcnt_u32:
127-
case X86::BI__builtin_ia32_lzcnt_u64:
132+
case X86::BI__builtin_ia32_lzcnt_u64: {
133+
mlir::Value isZeroPoison = builder.getFalse(getLoc(expr->getExprLoc()));
134+
return emitIntrinsicCallOp(*this, expr, "ctlz", ops[0].getType(),
135+
mlir::ValueRange{ops[0], isZeroPoison});
136+
}
128137
case X86::BI__builtin_ia32_tzcnt_u16:
129138
case X86::BI__builtin_ia32_tzcnt_u32:
130-
case X86::BI__builtin_ia32_tzcnt_u64:
139+
case X86::BI__builtin_ia32_tzcnt_u64: {
140+
mlir::Value isZeroPoison = builder.getFalse(getLoc(expr->getExprLoc()));
141+
return emitIntrinsicCallOp(*this, expr, "cttz", ops[0].getType(),
142+
mlir::ValueRange{ops[0], isZeroPoison});
143+
}
131144
case X86::BI__builtin_ia32_undef128:
132145
case X86::BI__builtin_ia32_undef256:
133146
case X86::BI__builtin_ia32_undef512:

clang/lib/CIR/CodeGen/CIRGenClass.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/AST/ExprCXX.h"
1919
#include "clang/AST/RecordLayout.h"
2020
#include "clang/AST/Type.h"
21+
#include "clang/CIR/Dialect/IR/CIRDialect.h"
2122
#include "clang/CIR/MissingFeatures.h"
2223

2324
using namespace clang;
@@ -786,6 +787,8 @@ void CIRGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &args) {
786787
"Body of an implicit assignment operator should be compound stmt.");
787788
const auto *rootCS = cast<CompoundStmt>(rootS);
788789

790+
cgm.setCXXSpecialMemberAttr(cast<cir::FuncOp>(curFn), assignOp);
791+
789792
assert(!cir::MissingFeatures::incrementProfileCounter());
790793
assert(!cir::MissingFeatures::runCleanupsScope());
791794

clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ emitSuspendExpression(CIRGenFunction &cgf, CGCoroData &coro,
292292
AggValueSlot aggSlot, bool ignoreResult,
293293
mlir::Block *scopeParentBlock,
294294
mlir::Value &tmpResumeRValAddr, bool forLValue) {
295-
mlir::LogicalResult awaitBuild = mlir::success();
295+
[[maybe_unused]] mlir::LogicalResult awaitBuild = mlir::success();
296296
LValueOrRValue awaitRes;
297297

298298
CIRGenFunction::OpaqueValueMapping binder =

clang/lib/CIR/CodeGen/CIRGenException.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ void CIRGenFunction::exitCXXTryStmt(const CXXTryStmt &s, bool isFnTryBlock) {
425425
assert(!cir::MissingFeatures::incrementProfileCounter());
426426

427427
// Perform the body of the catch.
428-
mlir::LogicalResult emitResult =
428+
[[maybe_unused]] mlir::LogicalResult emitResult =
429429
emitStmt(catchStmt->getHandlerBlock(), /*useCurrentScope=*/true);
430430
assert(emitResult.succeeded() && "failed to emit catch handler block");
431431

clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e,
426426
const llvm::APInt &count =
427427
mlir::cast<cir::IntAttr>(constNumElements).getValue();
428428

429-
unsigned numElementsWidth = count.getBitWidth();
429+
[[maybe_unused]] unsigned numElementsWidth = count.getBitWidth();
430430
bool hasAnyOverflow = false;
431431

432432
// The equivalent code in CodeGen/CGExprCXX.cpp handles these cases as

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ static void eraseEmptyAndUnusedBlocks(cir::FuncOp func) {
570570

571571
cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
572572
cir::FuncType funcType) {
573-
const auto funcDecl = cast<FunctionDecl>(gd.getDecl());
573+
const auto *funcDecl = cast<FunctionDecl>(gd.getDecl());
574574
curGD = gd;
575575

576576
if (funcDecl->isInlineBuiltinDeclaration()) {
@@ -640,6 +640,7 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
640640
{
641641
LexicalScope lexScope(*this, fusedLoc, entryBB);
642642

643+
// Emit the standard function prologue.
643644
startFunction(gd, retTy, fn, funcType, args, loc, bodyRange.getBegin());
644645

645646
// Save parameters for coroutine function.
@@ -666,6 +667,7 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
666667
// copy-constructors.
667668
emitImplicitAssignmentOperatorBody(args);
668669
} else if (body) {
670+
// Emit standard function body.
669671
if (mlir::failed(emitFunctionBody(body))) {
670672
return nullptr;
671673
}
@@ -693,6 +695,8 @@ void CIRGenFunction::emitConstructorBody(FunctionArgList &args) {
693695
ctorType == Ctor_Complete) &&
694696
"can only generate complete ctor for this ABI");
695697

698+
cgm.setCXXSpecialMemberAttr(cast<cir::FuncOp>(curFn), ctor);
699+
696700
if (ctorType == Ctor_Complete && isConstructorDelegationValid(ctor) &&
697701
cgm.getTarget().getCXXABI().hasConstructorVariants()) {
698702
emitDelegateCXXConstructorCall(ctor, Ctor_Base, args, ctor->getEndLoc());
@@ -731,6 +735,8 @@ void CIRGenFunction::emitDestructorBody(FunctionArgList &args) {
731735
const CXXDestructorDecl *dtor = cast<CXXDestructorDecl>(curGD.getDecl());
732736
CXXDtorType dtorType = curGD.getDtorType();
733737

738+
cgm.setCXXSpecialMemberAttr(cast<cir::FuncOp>(curFn), dtor);
739+
734740
// For an abstract class, non-base destructors are never used (and can't
735741
// be emitted in general, because vbase dtors may not have been validated
736742
// by Sema), but the Itanium ABI doesn't make them optional and Clang may

0 commit comments

Comments
 (0)