Skip to content

Commit 4c601c8

Browse files
author
z1.cciauto
committed
merge main into amd-staging
2 parents a0dd2dd + 4f107cd commit 4c601c8

File tree

193 files changed

+5448
-2957
lines changed

Some content is hidden

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

193 files changed

+5448
-2957
lines changed

clang/include/clang/AST/DeclTemplate.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -781,16 +781,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
781781
bool loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
782782
TemplateParameterList *TPL = nullptr) const;
783783

784-
template <class EntryType, typename ...ProfileArguments>
785-
typename SpecEntryTraits<EntryType>::DeclType*
784+
template <class EntryType, typename... ProfileArguments>
785+
typename SpecEntryTraits<EntryType>::DeclType *
786786
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
787-
void *&InsertPos, ProfileArguments &&...ProfileArgs);
787+
void *&InsertPos, ProfileArguments... ProfileArgs);
788788

789789
template <class EntryType, typename... ProfileArguments>
790790
typename SpecEntryTraits<EntryType>::DeclType *
791791
findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
792-
void *&InsertPos,
793-
ProfileArguments &&...ProfileArgs);
792+
void *&InsertPos, ProfileArguments... ProfileArgs);
794793

795794
template <class Derived, class EntryType>
796795
void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,

clang/include/clang/Basic/SourceManager.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,15 @@ class SourceManager : public RefCountedBase<SourceManager> {
15291529
return Filename == "<scratch space>";
15301530
}
15311531

1532+
/// Returns whether \p Loc is located in a built-in or command line source.
1533+
bool isInPredefinedFile(SourceLocation Loc) const {
1534+
PresumedLoc Presumed = getPresumedLoc(Loc);
1535+
if (Presumed.isInvalid())
1536+
return false;
1537+
StringRef Filename(Presumed.getFilename());
1538+
return Filename == "<built-in>" || Filename == "<command line>";
1539+
}
1540+
15321541
/// Returns if a SourceLocation is in a system header.
15331542
bool isInSystemHeader(SourceLocation Loc) const {
15341543
if (Loc.isInvalid())

clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,19 @@ ANALYZER_OPTION(
414414
"any target.",
415415
true)
416416

417+
ANALYZER_OPTION(
418+
bool, InlineFunctionsWithAmbiguousLoops, "inline-functions-with-ambiguous-loops",
419+
"If disabled (the default), the analyzer puts functions on a \"do not "
420+
"inline this\" list if it finds an execution path within that function "
421+
"that may potentially perform 'analyzer-max-loop' (= 4 by default) "
422+
"iterations in a loop. (Note that functions that _definitely_ reach the "
423+
"loop limit on some execution path are currently marked as \"do not "
424+
"inline\" even if this option is enabled.) Enabling this option "
425+
"eliminates this (somewhat arbitrary) restriction from the analysis "
426+
"scope, which increases the analysis runtime (on average by ~10%, but "
427+
"a few translation units may see much larger slowdowns).",
428+
false)
429+
417430
//===----------------------------------------------------------------------===//
418431
// Unsigned analyzer options.
419432
//===----------------------------------------------------------------------===//

clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ class FunctionSummariesTy {
8181
I->second.MayInline = 0;
8282
}
8383

84-
void markReachedMaxBlockCount(const Decl *D) {
85-
markShouldNotInline(D);
86-
}
87-
8884
std::optional<bool> mayInline(const Decl *D) {
8985
MapTy::const_iterator I = Map.find(D);
9086
if (I != Map.end() && I->second.InlineChecked)

clang/lib/AST/DeclTemplate.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -382,12 +382,11 @@ template <class EntryType, typename... ProfileArguments>
382382
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
383383
RedeclarableTemplateDecl::findSpecializationLocally(
384384
llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
385-
ProfileArguments &&...ProfileArgs) {
385+
ProfileArguments... ProfileArgs) {
386386
using SETraits = RedeclarableTemplateDecl::SpecEntryTraits<EntryType>;
387387

388388
llvm::FoldingSetNodeID ID;
389-
EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
390-
getASTContext());
389+
EntryType::Profile(ID, ProfileArgs..., getASTContext());
391390
EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
392391
return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
393392
}
@@ -396,18 +395,15 @@ template <class EntryType, typename... ProfileArguments>
396395
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
397396
RedeclarableTemplateDecl::findSpecializationImpl(
398397
llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
399-
ProfileArguments &&...ProfileArgs) {
398+
ProfileArguments... ProfileArgs) {
400399

401-
if (auto *Found = findSpecializationLocally(
402-
Specs, InsertPos, std::forward<ProfileArguments>(ProfileArgs)...))
400+
if (auto *Found = findSpecializationLocally(Specs, InsertPos, ProfileArgs...))
403401
return Found;
404402

405-
if (!loadLazySpecializationsImpl(
406-
std::forward<ProfileArguments>(ProfileArgs)...))
403+
if (!loadLazySpecializationsImpl(ProfileArgs...))
407404
return nullptr;
408405

409-
return findSpecializationLocally(
410-
Specs, InsertPos, std::forward<ProfileArguments>(ProfileArgs)...);
406+
return findSpecializationLocally(Specs, InsertPos, ProfileArgs...);
411407
}
412408

413409
template<class Derived, class EntryType>

clang/lib/Driver/Driver.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5646,19 +5646,20 @@ class ToolSelector final {
56465646
if (!BJ || !CJ)
56475647
return nullptr;
56485648

5649+
auto HasBitcodeInput = [](const JobActionInfo &AI) {
5650+
for (auto &Input : AI.JA->getInputs())
5651+
if (!types::isLLVMIR(Input->getType()))
5652+
return false;
5653+
return true;
5654+
};
5655+
56495656
// Check if the initial input (to the compile job or its predessor if one
56505657
// exists) is LLVM bitcode. In that case, no preprocessor step is required
56515658
// and we can still collapse the compile and backend jobs when we have
56525659
// -save-temps. I.e. there is no need for a separate compile job just to
56535660
// emit unoptimized bitcode.
5654-
bool InputIsBitcode = true;
5655-
for (size_t i = 1; i < ActionInfo.size(); i++)
5656-
if (ActionInfo[i].JA->getType() != types::TY_LLVM_BC &&
5657-
ActionInfo[i].JA->getType() != types::TY_LTO_BC) {
5658-
InputIsBitcode = false;
5659-
break;
5660-
}
5661-
if (!InputIsBitcode && !canCollapsePreprocessorAction())
5661+
bool InputIsBitcode = all_of(ActionInfo, HasBitcodeInput);
5662+
if (SaveTemps && !InputIsBitcode)
56625663
return nullptr;
56635664

56645665
// Get compiler tool.
@@ -5672,7 +5673,7 @@ class ToolSelector final {
56725673
if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR()))
56735674
return nullptr;
56745675

5675-
if (T->canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode))
5676+
if (T->canEmitIR() && EmbedBitcode)
56765677
return nullptr;
56775678

56785679
Inputs = CJ->getInputs();

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
549549

550550
CmdArgs.push_back("-x");
551551
if (Args.hasArg(options::OPT_rewrite_objc))
552-
CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
552+
CmdArgs.push_back(types::getTypeName(types::TY_ObjCXX));
553553
else {
554554
// Map the driver type to the frontend type. This is mostly an identity
555555
// mapping, except that the distinction between module interface units

clang/lib/ExtractAPI/ExtractAPIConsumer.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,7 @@ class MacroCallback : public PPCallbacks {
305305

306306
auto DefLoc = MI->getDefinitionLoc();
307307

308-
if (SM.isWrittenInBuiltinFile(DefLoc) ||
309-
SM.isWrittenInCommandLineFile(DefLoc))
308+
if (SM.isInPredefinedFile(DefLoc))
310309
continue;
311310

312311
auto AssociatedModuleMacros = MD.getModuleMacros();

clang/lib/Frontend/PrintPreprocessedOutput.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,8 +569,7 @@ void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
569569
SourceLocation DefLoc = MI->getDefinitionLoc();
570570
if (DirectivesOnly && !MI->isUsed()) {
571571
SourceManager &SM = PP.getSourceManager();
572-
if (SM.isWrittenInBuiltinFile(DefLoc) ||
573-
SM.isWrittenInCommandLineFile(DefLoc))
572+
if (SM.isInPredefinedFile(DefLoc))
574573
return;
575574
}
576575
MoveToLine(DefLoc, /*RequireStartOfLine=*/true);

clang/lib/Lex/PPDirectives.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,8 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
374374
// Macro names with reserved identifiers are accepted if built-in or passed
375375
// through the command line (the later may be present if -dD was used to
376376
// generate the preprocessed file).
377-
bool IsBuiltinOrCmd = SourceMgr.isWrittenInBuiltinFile(MacroNameLoc) ||
378-
SourceMgr.isWrittenInCommandLineFile(MacroNameLoc);
379-
if (!IsBuiltinOrCmd && !SourceMgr.isInSystemHeader(MacroNameLoc)) {
377+
if (!SourceMgr.isInPredefinedFile(MacroNameLoc) &&
378+
!SourceMgr.isInSystemHeader(MacroNameLoc)) {
380379
MacroDiag D = MD_NoWarn;
381380
if (isDefineUndef == MU_Define) {
382381
D = shouldWarnOnMacroDef(*this, II);
@@ -1706,8 +1705,7 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
17061705
// If a filename was present, read any flags that are present.
17071706
if (ReadLineMarkerFlags(IsFileEntry, IsFileExit, FileKind, *this))
17081707
return;
1709-
if (!SourceMgr.isWrittenInBuiltinFile(DigitTok.getLocation()) &&
1710-
!SourceMgr.isWrittenInCommandLineFile(DigitTok.getLocation()))
1708+
if (!SourceMgr.isInPredefinedFile(DigitTok.getLocation()))
17111709
Diag(StrTok, diag::ext_pp_gnu_line_directive);
17121710

17131711
// Exiting to an empty string means pop to the including file, so leave

clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2523,6 +2523,20 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N,
25232523
return true;
25242524
}
25252525

2526+
/// Return the innermost location context which is inlined at `Node`, unless
2527+
/// it's the top-level (entry point) location context.
2528+
static const LocationContext *getInlinedLocationContext(ExplodedNode *Node,
2529+
ExplodedGraph &G) {
2530+
const LocationContext *CalleeLC = Node->getLocation().getLocationContext();
2531+
const LocationContext *RootLC =
2532+
(*G.roots_begin())->getLocation().getLocationContext();
2533+
2534+
if (CalleeLC->getStackFrame() == RootLC->getStackFrame())
2535+
return nullptr;
2536+
2537+
return CalleeLC;
2538+
}
2539+
25262540
/// Block entrance. (Update counters).
25272541
void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
25282542
NodeBuilderWithSinks &nodeBuilder,
@@ -2570,21 +2584,24 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
25702584
const ExplodedNode *Sink =
25712585
nodeBuilder.generateSink(Pred->getState(), Pred, &tag);
25722586

2573-
// Check if we stopped at the top level function or not.
2574-
// Root node should have the location context of the top most function.
2575-
const LocationContext *CalleeLC = Pred->getLocation().getLocationContext();
2576-
const LocationContext *CalleeSF = CalleeLC->getStackFrame();
2577-
const LocationContext *RootLC =
2578-
(*G.roots_begin())->getLocation().getLocationContext();
2579-
if (RootLC->getStackFrame() != CalleeSF) {
2580-
Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl());
2587+
if (const LocationContext *LC = getInlinedLocationContext(Pred, G)) {
2588+
// FIXME: This will unconditionally prevent inlining this function (even
2589+
// from other entry points), which is not a reasonable heuristic: even if
2590+
// we reached max block count on this particular execution path, there
2591+
// may be other execution paths (especially with other parametrizations)
2592+
// where the analyzer can reach the end of the function (so there is no
2593+
// natural reason to avoid inlining it). However, disabling this would
2594+
// significantly increase the analysis time (because more entry points
2595+
// would exhaust their allocated budget), so it must be compensated by a
2596+
// different (more reasonable) reduction of analysis scope.
2597+
Engine.FunctionSummaries->markShouldNotInline(
2598+
LC->getStackFrame()->getDecl());
25812599

25822600
// Re-run the call evaluation without inlining it, by storing the
25832601
// no-inlining policy in the state and enqueuing the new work item on
25842602
// the list. Replay should almost never fail. Use the stats to catch it
25852603
// if it does.
2586-
if ((!AMgr.options.NoRetryExhausted &&
2587-
replayWithoutInlining(Pred, CalleeLC)))
2604+
if ((!AMgr.options.NoRetryExhausted && replayWithoutInlining(Pred, LC)))
25882605
return;
25892606
NumMaxBlockCountReachedInInlined++;
25902607
} else
@@ -2856,8 +2873,29 @@ void ExprEngine::processBranch(
28562873
// conflicts with the widen-loop analysis option (which is off by
28572874
// default). If we intend to support and stabilize the loop widening,
28582875
// we must ensure that it 'plays nicely' with this logic.
2859-
if (!SkipTrueBranch || AMgr.options.ShouldWidenLoops)
2876+
if (!SkipTrueBranch || AMgr.options.ShouldWidenLoops) {
28602877
Builder.generateNode(StTrue, true, PredN);
2878+
} else if (!AMgr.options.InlineFunctionsWithAmbiguousLoops) {
2879+
// FIXME: There is an ancient and arbitrary heuristic in
2880+
// `ExprEngine::processCFGBlockEntrance` which prevents all further
2881+
// inlining of a function if it finds an execution path within that
2882+
// function which reaches the `MaxBlockVisitOnPath` limit (a/k/a
2883+
// `analyzer-max-loop`, by default four iterations in a loop). Adding
2884+
// this "don't assume third iteration" logic significantly increased
2885+
// the analysis runtime on some inputs because less functions were
2886+
// arbitrarily excluded from being inlined, so more entry points used
2887+
// up their full allocated budget. As a hacky compensation for this,
2888+
// here we apply the "should not inline" mark in cases when the loop
2889+
// could potentially reach the `MaxBlockVisitOnPath` limit without the
2890+
// "don't assume third iteration" logic. This slightly overcompensates
2891+
// (activates if the third iteration can be entered, and will not
2892+
// recognize cases where the fourth iteration would't be completed), but
2893+
// should be good enough for practical purposes.
2894+
if (const LocationContext *LC = getInlinedLocationContext(Pred, G)) {
2895+
Engine.FunctionSummaries->markShouldNotInline(
2896+
LC->getStackFrame()->getDecl());
2897+
}
2898+
}
28612899
}
28622900

28632901
if (StFalse) {

clang/test/Analysis/analyzer-config.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
// CHECK-NEXT: graph-trim-interval = 1000
9090
// CHECK-NEXT: ignore-bison-generated-files = true
9191
// CHECK-NEXT: ignore-flex-generated-files = true
92+
// CHECK-NEXT: inline-functions-with-ambiguous-loops = false
9293
// CHECK-NEXT: inline-lambdas = true
9394
// CHECK-NEXT: ipa = dynamic-bifurcate
9495
// CHECK-NEXT: ipa-always-inline-size = 3

0 commit comments

Comments
 (0)