Skip to content

Commit

Permalink
Merge "merge main into amd-staging" into amd-staging
Browse files Browse the repository at this point in the history
  • Loading branch information
nicebert committed Apr 26, 2024
2 parents 066a0b2 + 21a8061 commit 44b076c
Show file tree
Hide file tree
Showing 356 changed files with 12,666 additions and 3,174 deletions.
1 change: 0 additions & 1 deletion .ci/monolithic-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \
-D LLVM_LIT_ARGS="-v --xunit-xml-output ${BUILD_DIR}/test-results.xml --timeout=1200 --time-tests" \
-D LLVM_ENABLE_LLD=ON \
-D CMAKE_CXX_FLAGS=-gmlt \
-D BOLT_CLANG_EXE=/usr/bin/clang \
-D LLVM_CCACHE_BUILD=ON \
-D MLIR_ENABLE_BINDINGS_PYTHON=ON

Expand Down
4 changes: 4 additions & 0 deletions .github/new-prs-labeler.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
BOLT:
- bolt/**/*

ClangIR:
- clang/include/clang/CIR/**/*
- clang/lib/CIR/**/*
Expand Down Expand Up @@ -467,6 +470,7 @@ backend:m68k:

libc++:
- libcxx/**
- .github/workflows/libcxx-*

libc++abi:
- libcxxabi/**
Expand Down
3 changes: 1 addition & 2 deletions bolt/include/bolt/Passes/BinaryPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,7 @@ class PrintProfileStats : public BinaryFunctionPass {
/// dyno stats categories.
class PrintProgramStats : public BinaryFunctionPass {
public:
explicit PrintProgramStats(const cl::opt<bool> &PrintPass)
: BinaryFunctionPass(PrintPass) {}
explicit PrintProgramStats() : BinaryFunctionPass(false) {}

const char *getName() const override { return "print-stats"; }
bool shouldPrint(const BinaryFunction &) const override { return false; }
Expand Down
2 changes: 2 additions & 0 deletions bolt/lib/Profile/DataAggregator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "bolt/Profile/DataAggregator.h"
#include "bolt/Core/BinaryContext.h"
#include "bolt/Core/BinaryFunction.h"
#include "bolt/Passes/BinaryPasses.h"
#include "bolt/Profile/BoltAddressTranslation.h"
#include "bolt/Profile/Heatmap.h"
#include "bolt/Profile/YAMLProfileWriter.h"
Expand Down Expand Up @@ -611,6 +612,7 @@ Error DataAggregator::readProfile(BinaryContext &BC) {
if (std::error_code EC = writeBATYAML(BC, opts::SaveProfile))
report_error("cannot create output data file", EC);
}
BC.logBOLTErrorsAndQuitOnFatal(PrintProgramStats().runOnFunctions(BC));
}

return Error::success();
Expand Down
2 changes: 1 addition & 1 deletion bolt/lib/Rewrite/BinaryPassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
// order they're registered.

// Run this pass first to use stats for the original functions.
Manager.registerPass(std::make_unique<PrintProgramStats>(NeverPrint));
Manager.registerPass(std::make_unique<PrintProgramStats>());

if (opts::PrintProfileStats)
Manager.registerPass(std::make_unique<PrintProfileStats>(NeverPrint));
Expand Down
2 changes: 1 addition & 1 deletion bolt/lib/Rewrite/BoltDiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ class RewriteInstanceDiff {
}
}
}
PrintProgramStats PPS(opts::NeverPrint);
PrintProgramStats PPS;
outs() << "* BOLT-DIFF: Starting print program stats pass for binary 1\n";
RI1.BC->logBOLTErrorsAndQuitOnFatal(PPS.runOnFunctions(*RI1.BC));
outs() << "* BOLT-DIFF: Starting print program stats pass for binary 2\n";
Expand Down
6 changes: 0 additions & 6 deletions bolt/lib/Rewrite/RewriteInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1725,12 +1725,6 @@ void RewriteInstance::adjustFunctionBoundaries() {
if (!Function.isSymbolValidInScope(Symbol, SymbolSize))
break;

// Ignore unnamed symbols. Used, for example, by debugging info on RISC-V.
if (BC->isRISCV() && cantFail(Symbol.getName()).empty()) {
++NextSymRefI;
continue;
}

// Skip basic block labels. This happens on RISC-V with linker relaxation
// enabled because every branch needs a relocation and corresponding
// symbol. We don't want to add such symbols as entry points.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

// RUN: %clang %cflags -g -Wl,-q -o %t %s

/// Verify that the binary indeed contains an unnamed symbol at _start
/// Verify that the binary indeed contains a fake label ".L0 " at _start.
// RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=CHECK-ELF
// CHECK-ELF-DAG: [[#%x,START:]] {{.*}} FUNC GLOBAL DEFAULT [[#%d,SECTION:]] _start{{$}}
// CHECK-ELF-DAG: [[#%x,START]] {{.*}} NOTYPE LOCAL DEFAULT [[#SECTION]] .L0 {{$}}

/// Verify that BOLT did not create an extra entry point for the unnamed symbol
/// Verify that BOLT did not create an extra entry point for the fake label.
// RUN: llvm-bolt -o %t.bolt %t --print-cfg | FileCheck %s
// CHECK: Binary Function "_start" after building cfg {
// CHECK: IsMultiEntry: 0
Expand Down
9 changes: 8 additions & 1 deletion bolt/test/X86/pre-aggregated-perf.test
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ REQUIRES: system-linux

RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe
RUN: perf2bolt %t.exe -o %t --pa -p %p/Inputs/pre-aggregated.txt -w %t.new \
RUN: --profile-use-dfs
RUN: --profile-use-dfs | FileCheck %s

RUN: llvm-bolt %t.exe -data %t -o %t.null | FileCheck %s
RUN: llvm-bolt %t.exe -data %t.new -o %t.null | FileCheck %s
RUN: llvm-bolt %t.exe -p %p/Inputs/pre-aggregated.txt --pa -o %t.null | FileCheck %s

CHECK: BOLT-INFO: 4 out of 7 functions in the binary (57.1%) have non-empty execution profile

RUN: cat %t | sort | FileCheck %s -check-prefix=PERF2BOLT
RUN: cat %t.new | FileCheck %s -check-prefix=NEWFORMAT

Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ add_clang_library(clangTidyModernizeModule
MakeSharedCheck.cpp
MakeSmartPtrCheck.cpp
MakeUniqueCheck.cpp
MinMaxUseInitializerListCheck.cpp
ModernizeTidyModule.cpp
PassByValueCheck.cpp
RawStringLiteralCheck.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
//===--- MinMaxUseInitializerListCheck.cpp - clang-tidy -------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "MinMaxUseInitializerListCheck.h"
#include "../utils/ASTUtils.h"
#include "../utils/LexerUtils.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Lexer.h"

using namespace clang;

namespace {

struct FindArgsResult {
const Expr *First;
const Expr *Last;
const Expr *Compare;
SmallVector<const clang::Expr *, 2> Args;
};

} // anonymous namespace

using namespace clang::ast_matchers;

namespace clang::tidy::modernize {

static FindArgsResult findArgs(const CallExpr *Call) {
FindArgsResult Result;
Result.First = nullptr;
Result.Last = nullptr;
Result.Compare = nullptr;

// check if the function has initializer list argument
if (Call->getNumArgs() < 3) {
auto ArgIterator = Call->arguments().begin();

const auto *InitListExpr =
dyn_cast<CXXStdInitializerListExpr>(*ArgIterator);
const auto *InitList =
InitListExpr != nullptr
? dyn_cast<clang::InitListExpr>(
InitListExpr->getSubExpr()->IgnoreImplicit())
: nullptr;

if (InitList) {
Result.Args.append(InitList->inits().begin(), InitList->inits().end());
Result.First = *ArgIterator;
Result.Last = *ArgIterator;

// check if there is a comparison argument
std::advance(ArgIterator, 1);
if (ArgIterator != Call->arguments().end())
Result.Compare = *ArgIterator;

return Result;
}
Result.Args = SmallVector<const Expr *>(Call->arguments());
} else {
// if it has 3 arguments then the last will be the comparison
Result.Compare = *(std::next(Call->arguments().begin(), 2));
Result.Args = SmallVector<const Expr *>(llvm::drop_end(Call->arguments()));
}
Result.First = Result.Args.front();
Result.Last = Result.Args.back();

return Result;
}

static SmallVector<FixItHint>
generateReplacements(const MatchFinder::MatchResult &Match,
const CallExpr *TopCall, const FindArgsResult &Result,
const bool IgnoreNonTrivialTypes,
const std::uint64_t IgnoreTrivialTypesOfSizeAbove) {
SmallVector<FixItHint> FixItHints;
const SourceManager &SourceMngr = *Match.SourceManager;
const LangOptions &LanguageOpts = Match.Context->getLangOpts();

const QualType ResultType = TopCall->getDirectCallee()
->getReturnType()
.getCanonicalType()
.getNonReferenceType()
.getUnqualifiedType();

// check if the type is trivial
const bool IsResultTypeTrivial = ResultType.isTrivialType(*Match.Context);

if ((!IsResultTypeTrivial && IgnoreNonTrivialTypes))
return FixItHints;

if (IsResultTypeTrivial &&
static_cast<std::uint64_t>(
Match.Context->getTypeSizeInChars(ResultType).getQuantity()) >
IgnoreTrivialTypesOfSizeAbove)
return FixItHints;

for (const Expr *Arg : Result.Args) {
const auto *InnerCall = dyn_cast<CallExpr>(Arg->IgnoreParenImpCasts());

// If the argument is not a nested call
if (!InnerCall) {
// check if typecast is required
const QualType ArgType = Arg->IgnoreParenImpCasts()
->getType()
.getCanonicalType()
.getUnqualifiedType();

if (ArgType == ResultType)
continue;

const StringRef ArgText = Lexer::getSourceText(
CharSourceRange::getTokenRange(Arg->getSourceRange()), SourceMngr,
LanguageOpts);

const auto Replacement = Twine("static_cast<")
.concat(ResultType.getAsString(LanguageOpts))
.concat(">(")
.concat(ArgText)
.concat(")")
.str();

FixItHints.push_back(
FixItHint::CreateReplacement(Arg->getSourceRange(), Replacement));
continue;
}

const FindArgsResult InnerResult = findArgs(InnerCall);

// if the nested call doesn't have arguments skip it
if (!InnerResult.First || !InnerResult.Last)
continue;

// if the nested call is not the same as the top call
if (InnerCall->getDirectCallee()->getQualifiedNameAsString() !=
TopCall->getDirectCallee()->getQualifiedNameAsString())
continue;

// if the nested call doesn't have the same compare function
if ((Result.Compare || InnerResult.Compare) &&
!utils::areStatementsIdentical(Result.Compare, InnerResult.Compare,
*Match.Context))
continue;

// remove the function call
FixItHints.push_back(
FixItHint::CreateRemoval(InnerCall->getCallee()->getSourceRange()));

// remove the parentheses
const auto LParen = utils::lexer::findNextTokenSkippingComments(
InnerCall->getCallee()->getEndLoc(), SourceMngr, LanguageOpts);
if (LParen.has_value() && LParen->is(tok::l_paren))
FixItHints.push_back(
FixItHint::CreateRemoval(SourceRange(LParen->getLocation())));
FixItHints.push_back(
FixItHint::CreateRemoval(SourceRange(InnerCall->getRParenLoc())));

// if the inner call has an initializer list arg
if (InnerResult.First == InnerResult.Last) {
// remove the initializer list braces
FixItHints.push_back(FixItHint::CreateRemoval(
CharSourceRange::getTokenRange(InnerResult.First->getBeginLoc())));
FixItHints.push_back(FixItHint::CreateRemoval(
CharSourceRange::getTokenRange(InnerResult.First->getEndLoc())));
}

const SmallVector<FixItHint> InnerReplacements = generateReplacements(
Match, InnerCall, InnerResult, IgnoreNonTrivialTypes,
IgnoreTrivialTypesOfSizeAbove);

FixItHints.append(InnerReplacements);

if (InnerResult.Compare) {
// find the comma after the value arguments
const auto Comma = utils::lexer::findNextTokenSkippingComments(
InnerResult.Last->getEndLoc(), SourceMngr, LanguageOpts);

// remove the comma and the comparison
if (Comma.has_value() && Comma->is(tok::comma))
FixItHints.push_back(
FixItHint::CreateRemoval(SourceRange(Comma->getLocation())));

FixItHints.push_back(
FixItHint::CreateRemoval(InnerResult.Compare->getSourceRange()));
}
}

return FixItHints;
}

MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IgnoreNonTrivialTypes(Options.get("IgnoreNonTrivialTypes", true)),
IgnoreTrivialTypesOfSizeAbove(
Options.get("IgnoreTrivialTypesOfSizeAbove", 32L)),
Inserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
areDiagsSelfContained()) {}

void MinMaxUseInitializerListCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IgnoreNonTrivialTypes", IgnoreNonTrivialTypes);
Options.store(Opts, "IgnoreTrivialTypesOfSizeAbove",
IgnoreTrivialTypesOfSizeAbove);
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
}

void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) {
auto CreateMatcher = [](const StringRef FunctionName) {
auto FuncDecl = functionDecl(hasName(FunctionName));
auto Expression = callExpr(callee(FuncDecl));

return callExpr(callee(FuncDecl),
anyOf(hasArgument(0, Expression),
hasArgument(1, Expression),
hasArgument(0, cxxStdInitializerListExpr())),
unless(hasParent(Expression)))
.bind("topCall");
};

Finder->addMatcher(CreateMatcher("::std::max"), this);
Finder->addMatcher(CreateMatcher("::std::min"), this);
}

void MinMaxUseInitializerListCheck::registerPPCallbacks(
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
Inserter.registerPreprocessor(PP);
}

void MinMaxUseInitializerListCheck::check(
const MatchFinder::MatchResult &Match) {

const auto *TopCall = Match.Nodes.getNodeAs<CallExpr>("topCall");

const FindArgsResult Result = findArgs(TopCall);
const SmallVector<FixItHint> Replacements =
generateReplacements(Match, TopCall, Result, IgnoreNonTrivialTypes,
IgnoreTrivialTypesOfSizeAbove);

if (Replacements.empty())
return;

const DiagnosticBuilder Diagnostic =
diag(TopCall->getBeginLoc(),
"do not use nested 'std::%0' calls, use an initializer list instead")
<< TopCall->getDirectCallee()->getName()
<< Inserter.createIncludeInsertion(
Match.SourceManager->getFileID(TopCall->getBeginLoc()),
"<algorithm>");

// if the top call doesn't have an initializer list argument
if (Result.First != Result.Last) {
// add { and } insertions
Diagnostic << FixItHint::CreateInsertion(Result.First->getBeginLoc(), "{");

Diagnostic << FixItHint::CreateInsertion(
Lexer::getLocForEndOfToken(Result.Last->getEndLoc(), 0,
*Match.SourceManager,
Match.Context->getLangOpts()),
"}");
}

Diagnostic << Replacements;
}

} // namespace clang::tidy::modernize
Loading

0 comments on commit 44b076c

Please sign in to comment.