Skip to content

Commit 31138ec

Browse files
Merge from 'main' to 'sycl-web' (70 commits)
CONFLICT (content): Merge conflict in clang/lib/Driver/Driver.cpp
2 parents 6cd346b + d54c28b commit 31138ec

File tree

851 files changed

+10610
-72163
lines changed

Some content is hidden

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

851 files changed

+10610
-72163
lines changed

clang/include/clang/AST/OpenACCClause.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class OpenACCClause {
3838
OpenACCClauseKind getClauseKind() const { return Kind; }
3939
SourceLocation getBeginLoc() const { return Location.getBegin(); }
4040
SourceLocation getEndLoc() const { return Location.getEnd(); }
41+
SourceRange getSourceRange() const { return Location; }
4142

4243
static bool classof(const OpenACCClause *) { return true; }
4344

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ class SameFirstOperandAndResultType
6060
using BuilderCallbackRef =
6161
llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>;
6262

63+
namespace cir {
64+
void buildTerminatedBody(mlir::OpBuilder &builder, mlir::Location loc);
65+
} // namespace cir
66+
6367
// TableGen'erated files for MLIR dialects require that a macro be defined when
6468
// they are included. GET_OP_CLASSES tells the file to define the classes for
6569
// the operations of that dialect.

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

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,8 @@ def StoreOp : CIR_Op<"store", [
472472
// ReturnOp
473473
//===----------------------------------------------------------------------===//
474474

475-
def ReturnOp : CIR_Op<"return", [ParentOneOf<["FuncOp", "ScopeOp", "DoWhileOp",
476-
"WhileOp", "ForOp"]>,
475+
def ReturnOp : CIR_Op<"return", [ParentOneOf<["FuncOp", "ScopeOp", "IfOp",
476+
"DoWhileOp", "WhileOp", "ForOp"]>,
477477
Terminator]> {
478478
let summary = "Return from function";
479479
let description = [{
@@ -510,6 +510,58 @@ def ReturnOp : CIR_Op<"return", [ParentOneOf<["FuncOp", "ScopeOp", "DoWhileOp",
510510
let hasVerifier = 1;
511511
}
512512

513+
//===----------------------------------------------------------------------===//
514+
// IfOp
515+
//===----------------------------------------------------------------------===//
516+
517+
def IfOp : CIR_Op<"if",
518+
[DeclareOpInterfaceMethods<RegionBranchOpInterface>,
519+
RecursivelySpeculatable, AutomaticAllocationScope, NoRegionArguments]>{
520+
521+
let summary = "the if-then-else operation";
522+
let description = [{
523+
The `cir.if` operation represents an if-then-else construct for
524+
conditionally executing two regions of code. The operand is a `cir.bool`
525+
type.
526+
527+
Examples:
528+
529+
```mlir
530+
cir.if %cond {
531+
...
532+
} else {
533+
...
534+
}
535+
536+
cir.if %cond {
537+
...
538+
}
539+
540+
cir.if %cond {
541+
...
542+
cir.br ^a
543+
^a:
544+
cir.yield
545+
}
546+
```
547+
548+
`cir.if` defines no values and the 'else' can be omitted. The if/else
549+
regions must be terminated. If the region has only one block, the terminator
550+
can be left out, and `cir.yield` terminator will be inserted implictly.
551+
Otherwise, the region must be explicitly terminated.
552+
}];
553+
let arguments = (ins CIR_BoolType:$condition);
554+
let regions = (region AnyRegion:$thenRegion, AnyRegion:$elseRegion);
555+
let hasCustomAssemblyFormat=1;
556+
let hasVerifier=1;
557+
let skipDefaultBuilders=1;
558+
let builders = [
559+
OpBuilder<(ins "mlir::Value":$cond, "bool":$withElseRegion,
560+
CArg<"BuilderCallbackRef", "buildTerminatedBody">:$thenBuilder,
561+
CArg<"BuilderCallbackRef", "nullptr">:$elseBuilder)>
562+
];
563+
}
564+
513565
//===----------------------------------------------------------------------===//
514566
// ConditionOp
515567
//===----------------------------------------------------------------------===//
@@ -560,8 +612,8 @@ def ConditionOp : CIR_Op<"condition", [
560612
//===----------------------------------------------------------------------===//
561613

562614
def YieldOp : CIR_Op<"yield", [ReturnLike, Terminator,
563-
ParentOneOf<["ScopeOp", "WhileOp", "ForOp",
564-
"DoWhileOp"]>]> {
615+
ParentOneOf<["IfOp", "ScopeOp", "WhileOp",
616+
"ForOp", "DoWhileOp"]>]> {
565617
let summary = "Represents the default branching behaviour of a region";
566618
let description = [{
567619
The `cir.yield` operation terminates regions on different CIR operations,

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct MissingFeatures {
8080

8181
// Clang early optimizations or things defered to LLVM lowering.
8282
static bool mayHaveIntegerOverflow() { return false; }
83+
static bool shouldReverseUnaryCondOnBoolExpr() { return false; }
8384

8485
// Misc
8586
static bool cxxABI() { return false; }
@@ -110,6 +111,8 @@ struct MissingFeatures {
110111
static bool lvalueBaseInfo() { return false; }
111112
static bool alignCXXRecordDecl() { return false; }
112113
static bool setNonGC() { return false; }
114+
static bool incrementProfileCounter() { return false; }
115+
static bool insertBuiltinUnpredictable() { return false; }
113116

114117
// Missing types
115118
static bool dataMemberType() { return false; }

clang/include/clang/Serialization/ASTReader.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,18 @@ class ASTReaderListener {
237237
return true;
238238
}
239239

240+
/// Overloaded member function of \c visitInputFile that should
241+
/// be defined when there is a distinction between
242+
/// the file name and name-as-requested. For example, when deserializing input
243+
/// files from precompiled AST files.
244+
///
245+
/// \returns true to continue receiving the next input file, false to stop.
246+
virtual bool visitInputFile(StringRef FilenameAsRequested, StringRef Filename,
247+
bool isSystem, bool isOverridden,
248+
bool isExplicitModule) {
249+
return true;
250+
}
251+
240252
/// Returns true if this \c ASTReaderListener wants to receive the
241253
/// imports of the AST file via \c visitImport, false otherwise.
242254
virtual bool needsImportVisitation() const { return false; }

clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace dependencies {
3333

3434
class DependencyActionController;
3535
class DependencyConsumer;
36+
class PrebuiltModuleASTAttrs;
3637

3738
/// Modular dependency that has already been built prior to the dependency scan.
3839
struct PrebuiltModuleDep {
@@ -46,6 +47,47 @@ struct PrebuiltModuleDep {
4647
ModuleMapFile(M->PresumedModuleMapFile) {}
4748
};
4849

50+
/// Attributes loaded from AST files of prebuilt modules collected prior to
51+
/// ModuleDepCollector creation.
52+
using PrebuiltModulesAttrsMap = llvm::StringMap<PrebuiltModuleASTAttrs>;
53+
class PrebuiltModuleASTAttrs {
54+
public:
55+
/// When a module is discovered to not be in stable directories, traverse &
56+
/// update all modules that depend on it.
57+
void
58+
updateDependentsNotInStableDirs(PrebuiltModulesAttrsMap &PrebuiltModulesMap);
59+
60+
/// Read-only access to whether the module is made up of dependencies in
61+
/// stable directories.
62+
bool isInStableDir() const { return IsInStableDirs; }
63+
64+
/// Read-only access to vfs map files.
65+
const llvm::StringSet<> &getVFS() const { return VFSMap; }
66+
67+
/// Update the VFSMap to the one discovered from serializing the AST file.
68+
void setVFS(llvm::StringSet<> &&VFS) { VFSMap = std::move(VFS); }
69+
70+
/// Add a direct dependent module file, so it can be updated if the current
71+
/// module is from stable directores.
72+
void addDependent(StringRef ModuleFile) {
73+
ModuleFileDependents.insert(ModuleFile);
74+
}
75+
76+
/// Update whether the prebuilt module resolves entirely in a stable
77+
/// directories.
78+
void setInStableDir(bool V = false) {
79+
// Cannot reset attribute once it's false.
80+
if (!IsInStableDirs)
81+
return;
82+
IsInStableDirs = V;
83+
}
84+
85+
private:
86+
llvm::StringSet<> VFSMap;
87+
bool IsInStableDirs = true;
88+
std::set<StringRef> ModuleFileDependents;
89+
};
90+
4991
/// This is used to identify a specific module.
5092
struct ModuleID {
5193
/// The name of the module. This may include `:` for C++20 module partitions,
@@ -171,8 +213,6 @@ struct ModuleDeps {
171213
BuildInfo;
172214
};
173215

174-
using PrebuiltModuleVFSMapT = llvm::StringMap<llvm::StringSet<>>;
175-
176216
class ModuleDepCollector;
177217

178218
/// Callback that records textual includes and direct modular includes/imports
@@ -242,7 +282,7 @@ class ModuleDepCollector final : public DependencyCollector {
242282
CompilerInstance &ScanInstance, DependencyConsumer &C,
243283
DependencyActionController &Controller,
244284
CompilerInvocation OriginalCI,
245-
PrebuiltModuleVFSMapT PrebuiltModuleVFSMap);
285+
const PrebuiltModulesAttrsMap PrebuiltModulesASTMap);
246286

247287
void attachToPreprocessor(Preprocessor &PP) override;
248288
void attachToASTReader(ASTReader &R) override;
@@ -262,8 +302,9 @@ class ModuleDepCollector final : public DependencyCollector {
262302
DependencyConsumer &Consumer;
263303
/// Callbacks for computing dependency information.
264304
DependencyActionController &Controller;
265-
/// Mapping from prebuilt AST files to their sorted list of VFS overlay files.
266-
PrebuiltModuleVFSMapT PrebuiltModuleVFSMap;
305+
/// Mapping from prebuilt AST filepaths to their attributes referenced during
306+
/// dependency collecting.
307+
const PrebuiltModulesAttrsMap PrebuiltModulesASTMap;
267308
/// Path to the main source file.
268309
std::string MainFile;
269310
/// Hash identifying the compilation conditions of the current TU.
@@ -339,6 +380,14 @@ void resetBenignCodeGenOptions(frontend::ActionKind ProgramAction,
339380
bool isPathInStableDir(const ArrayRef<StringRef> Directories,
340381
const StringRef Input);
341382

383+
/// Determine if options collected from a module's
384+
/// compilation can safely be considered as stable.
385+
///
386+
/// \param Directories Paths known to be in a stable location. e.g. Sysroot.
387+
/// \param HSOpts Header search options derived from the compiler invocation.
388+
bool areOptionsInStableDir(const ArrayRef<StringRef> Directories,
389+
const HeaderSearchOptions &HSOpts);
390+
342391
} // end namespace dependencies
343392
} // end namespace tooling
344393
} // end namespace clang

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6823,7 +6823,7 @@ bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc,
68236823
return true;
68246824
}
68256825

6826-
if (size_t N = Desc->getNumElems()) {
6826+
if (unsigned N = Desc->getNumElems()) {
68276827
for (ssize_t I = N - 1; I >= 0; --I) {
68286828
if (!this->emitConstUint64(I, Loc))
68296829
return false;

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

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

@@ -474,6 +475,90 @@ void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
474475
emitLValue(e);
475476
}
476477

478+
/// Emit an `if` on a boolean condition, filling `then` and `else` into
479+
/// appropriated regions.
480+
mlir::LogicalResult CIRGenFunction::emitIfOnBoolExpr(const Expr *cond,
481+
const Stmt *thenS,
482+
const Stmt *elseS) {
483+
mlir::Location thenLoc = getLoc(thenS->getSourceRange());
484+
std::optional<mlir::Location> elseLoc;
485+
if (elseS)
486+
elseLoc = getLoc(elseS->getSourceRange());
487+
488+
mlir::LogicalResult resThen = mlir::success(), resElse = mlir::success();
489+
emitIfOnBoolExpr(
490+
cond, /*thenBuilder=*/
491+
[&](mlir::OpBuilder &, mlir::Location) {
492+
LexicalScope lexScope{*this, thenLoc, builder.getInsertionBlock()};
493+
resThen = emitStmt(thenS, /*useCurrentScope=*/true);
494+
},
495+
thenLoc,
496+
/*elseBuilder=*/
497+
[&](mlir::OpBuilder &, mlir::Location) {
498+
assert(elseLoc && "Invalid location for elseS.");
499+
LexicalScope lexScope{*this, *elseLoc, builder.getInsertionBlock()};
500+
resElse = emitStmt(elseS, /*useCurrentScope=*/true);
501+
},
502+
elseLoc);
503+
504+
return mlir::LogicalResult::success(resThen.succeeded() &&
505+
resElse.succeeded());
506+
}
507+
508+
/// Emit an `if` on a boolean condition, filling `then` and `else` into
509+
/// appropriated regions.
510+
cir::IfOp CIRGenFunction::emitIfOnBoolExpr(
511+
const clang::Expr *cond, BuilderCallbackRef thenBuilder,
512+
mlir::Location thenLoc, BuilderCallbackRef elseBuilder,
513+
std::optional<mlir::Location> elseLoc) {
514+
// Attempt to be as accurate as possible with IfOp location, generate
515+
// one fused location that has either 2 or 4 total locations, depending
516+
// on else's availability.
517+
SmallVector<mlir::Location, 2> ifLocs{thenLoc};
518+
if (elseLoc)
519+
ifLocs.push_back(*elseLoc);
520+
mlir::Location loc = mlir::FusedLoc::get(&getMLIRContext(), ifLocs);
521+
522+
// Emit the code with the fully general case.
523+
mlir::Value condV = emitOpOnBoolExpr(loc, cond);
524+
return builder.create<cir::IfOp>(loc, condV, elseLoc.has_value(),
525+
/*thenBuilder=*/thenBuilder,
526+
/*elseBuilder=*/elseBuilder);
527+
}
528+
529+
/// TODO(cir): see EmitBranchOnBoolExpr for extra ideas).
530+
mlir::Value CIRGenFunction::emitOpOnBoolExpr(mlir::Location loc,
531+
const Expr *cond) {
532+
assert(!cir::MissingFeatures::pgoUse());
533+
assert(!cir::MissingFeatures::generateDebugInfo());
534+
cond = cond->IgnoreParens();
535+
536+
// In LLVM the condition is reversed here for efficient codegen.
537+
// This should be done in CIR prior to LLVM lowering, if we do now
538+
// we can make CIR based diagnostics misleading.
539+
// cir.ternary(!x, t, f) -> cir.ternary(x, f, t)
540+
assert(!cir::MissingFeatures::shouldReverseUnaryCondOnBoolExpr());
541+
542+
if (isa<ConditionalOperator>(cond)) {
543+
cgm.errorNYI(cond->getExprLoc(), "Ternary NYI");
544+
assert(!cir::MissingFeatures::ternaryOp());
545+
return createDummyValue(loc, cond->getType());
546+
}
547+
548+
if (isa<CXXThrowExpr>(cond)) {
549+
cgm.errorNYI("NYI");
550+
return createDummyValue(loc, cond->getType());
551+
}
552+
553+
// If the branch has a condition wrapped by __builtin_unpredictable,
554+
// create metadata that specifies that the branch is unpredictable.
555+
// Don't bother if not optimizing because that metadata would not be used.
556+
assert(!cir::MissingFeatures::insertBuiltinUnpredictable());
557+
558+
// Emit the code with the fully general case.
559+
return evaluateExprAsBool(cond);
560+
}
561+
477562
mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
478563
mlir::Location loc, CharUnits alignment,
479564
bool insertIntoFnEntryBlock,

0 commit comments

Comments
 (0)