Skip to content

Commit

Permalink
merge main into amd-staging
Browse files Browse the repository at this point in the history
Revret: b7e4fba Cleanup x86_mmx after removing IR type  (llvm#100646) (Reason: dependent on dfeb399)
Change-Id: I8e9a9a897b4a44dd5f0a79dd7a630f0051a3f1ad
  • Loading branch information
ronlieb committed Jul 29, 2024
2 parents a87f347 + 102f322 commit d0957f9
Show file tree
Hide file tree
Showing 178 changed files with 10,316 additions and 2,733 deletions.
1 change: 0 additions & 1 deletion clang/include/clang/AST/ASTImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ class TypeSourceInfo;
FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);

void AddToLookupTable(Decl *ToD);
llvm::Error ImportAttrs(Decl *ToD, Decl *FromD);

protected:
/// Can be overwritten by subclasses to implement their own import logic.
Expand Down
4 changes: 0 additions & 4 deletions clang/include/clang/AST/DeclCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -1188,10 +1188,6 @@ class CXXRecordDecl : public RecordDecl {
///
/// \note This does NOT include a check for union-ness.
bool isEmpty() const { return data().Empty; }
/// Marks this record as empty. This is used by DWARFASTParserClang
/// when parsing records with empty fields having [[no_unique_address]]
/// attribute
void markEmpty() { data().Empty = true; }

void setInitMethod(bool Val) { data().HasInitMethod = Val; }
bool hasInitMethod() const { return data().HasInitMethod; }
Expand Down
35 changes: 31 additions & 4 deletions clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Stmt.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/ASTOps.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Error.h"
Expand All @@ -27,6 +28,24 @@
namespace clang {
namespace dataflow {

namespace internal {
class StmtToBlockMap {
public:
StmtToBlockMap(const CFG &Cfg);

const CFGBlock *lookup(const Stmt &S) const {
return StmtToBlock.lookup(&ignoreCFGOmittedNodes(S));
}

const llvm::DenseMap<const Stmt *, const CFGBlock *> &getMap() const {
return StmtToBlock;
}

private:
llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
};
} // namespace internal

/// Holds CFG with additional information derived from it that is needed to
/// perform dataflow analysis.
class AdornedCFG {
Expand All @@ -49,8 +68,17 @@ class AdornedCFG {
const CFG &getCFG() const { return *Cfg; }

/// Returns a mapping from statements to basic blocks that contain them.
/// Deprecated. Use `blockForStmt()` instead (which prevents the potential
/// error of forgetting to call `ignoreCFGOmittedNodes()` on the statement to
/// look up).
const llvm::DenseMap<const Stmt *, const CFGBlock *> &getStmtToBlock() const {
return StmtToBlock;
return StmtToBlock.getMap();
}

/// Returns the basic block that contains `S`, or null if no basic block
/// containing `S` is found.
const CFGBlock *blockForStmt(const Stmt &S) const {
return StmtToBlock.lookup(S);
}

/// Returns whether `B` is reachable from the entry block.
Expand All @@ -73,8 +101,7 @@ class AdornedCFG {
private:
AdornedCFG(
const Decl &D, std::unique_ptr<CFG> Cfg,
llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock,
llvm::BitVector BlockReachable,
internal::StmtToBlockMap StmtToBlock, llvm::BitVector BlockReachable,
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock)
: ContainingDecl(D), Cfg(std::move(Cfg)),
StmtToBlock(std::move(StmtToBlock)),
Expand All @@ -85,7 +112,7 @@ class AdornedCFG {
/// The `Decl` containing the statement used to construct the CFG.
const Decl &ContainingDecl;
std::unique_ptr<CFG> Cfg;
llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
internal::StmtToBlockMap StmtToBlock;
llvm::BitVector BlockReachable;
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock;
};
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticFrontendKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,9 @@ def err_function_needs_feature : Error<
let CategoryName = "Codegen ABI Check" in {
def err_function_always_inline_attribute_mismatch : Error<
"always_inline function %1 and its caller %0 have mismatching %2 attributes">;
def warn_function_always_inline_attribute_mismatch : Warning<
"always_inline function %1 and its caller %0 have mismatching %2 attributes, "
"inlining may change runtime behaviour">, InGroup<AArch64SMEAttributes>;
def err_function_always_inline_new_za : Error<
"always_inline function %0 has new za state">;

Expand Down
6 changes: 3 additions & 3 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -980,15 +980,15 @@ def Wsystem_headers_in_module_EQ : Joined<["-"], "Wsystem-headers-in-module=">,
HelpText<"Enable -Wsystem-headers when building <module>">,
MarshallingInfoStringVector<DiagnosticOpts<"SystemHeaderWarningsModules">>;
def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>,
Visibility<[ClangOption, CC1Option]>,
Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable warnings for deprecated constructs and define __DEPRECATED">;
def Wno_deprecated : Flag<["-"], "Wno-deprecated">, Group<W_Group>,
Visibility<[ClangOption, CC1Option]>;
defm invalid_constexpr : BoolWOption<"invalid-constexpr",
LangOpts<"CheckConstexprFunctionBodies">,
Default<!strconcat("!", cpp23.KeyPath)>,
NegFlag<SetFalse, [], [ClangOption, CC1Option], "Disable">,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
NegFlag<SetFalse, [HelpHidden], [ClangOption, CC1Option], "Disable">,
PosFlag<SetTrue, [HelpHidden], [ClangOption, CC1Option], "Enable">,
BothFlags<[], [ClangOption, CC1Option], " checking of constexpr function bodies for validity within a constant expression context">>;
def Wl_COMMA : CommaJoined<["-"], "Wl,">, Visibility<[ClangOption, FlangOption]>,
Flags<[LinkerInput, RenderAsInput]>,
Expand Down
30 changes: 9 additions & 21 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4179,12 +4179,6 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
D->getInClassInitStyle()))
return ToField;

// We need [[no_unqiue_address]] attributes to be added to FieldDecl, before
// we add fields in CXXRecordDecl::addedMember, otherwise record will be
// marked as having non-zero size.
Err = Importer.ImportAttrs(ToField, D);
if (Err)
return std::move(Err);
ToField->setAccess(D->getAccess());
ToField->setLexicalDeclContext(LexicalDC);
ToField->setImplicit(D->isImplicit());
Expand Down Expand Up @@ -9399,19 +9393,6 @@ TranslationUnitDecl *ASTImporter::GetFromTU(Decl *ToD) {
return FromDPos->second->getTranslationUnitDecl();
}

Error ASTImporter::ImportAttrs(Decl *ToD, Decl *FromD) {
if (!FromD->hasAttrs() || ToD->hasAttrs())
return Error::success();
for (const Attr *FromAttr : FromD->getAttrs()) {
auto ToAttrOrErr = Import(FromAttr);
if (ToAttrOrErr)
ToD->addAttr(*ToAttrOrErr);
else
return ToAttrOrErr.takeError();
}
return Error::success();
}

Expected<Decl *> ASTImporter::Import(Decl *FromD) {
if (!FromD)
return nullptr;
Expand Down Expand Up @@ -9545,8 +9526,15 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) {
}
// Make sure that ImportImpl registered the imported decl.
assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?");
if (auto Error = ImportAttrs(ToD, FromD))
return std::move(Error);

if (FromD->hasAttrs())
for (const Attr *FromAttr : FromD->getAttrs()) {
auto ToAttrOrErr = Import(FromAttr);
if (ToAttrOrErr)
ToD->addAttr(*ToAttrOrErr);
else
return ToAttrOrErr.takeError();
}

// Notify subclasses.
Imported(FromD, ToD);
Expand Down
16 changes: 11 additions & 5 deletions clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Stmt.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/ASTOps.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Error.h"
Expand Down Expand Up @@ -96,16 +97,15 @@ static llvm::BitVector findReachableBlocks(const CFG &Cfg) {

static llvm::DenseSet<const CFGBlock *>
buildContainsExprConsumedInDifferentBlock(
const CFG &Cfg,
const llvm::DenseMap<const Stmt *, const CFGBlock *> &StmtToBlock) {
const CFG &Cfg, const internal::StmtToBlockMap &StmtToBlock) {
llvm::DenseSet<const CFGBlock *> Result;

auto CheckChildExprs = [&Result, &StmtToBlock](const Stmt *S,
const CFGBlock *Block) {
for (const Stmt *Child : S->children()) {
if (!isa_and_nonnull<Expr>(Child))
continue;
const CFGBlock *ChildBlock = StmtToBlock.lookup(Child);
const CFGBlock *ChildBlock = StmtToBlock.lookup(*Child);
if (ChildBlock != Block)
Result.insert(ChildBlock);
}
Expand All @@ -126,6 +126,13 @@ buildContainsExprConsumedInDifferentBlock(
return Result;
}

namespace internal {

StmtToBlockMap::StmtToBlockMap(const CFG &Cfg)
: StmtToBlock(buildStmtToBasicBlockMap(Cfg)) {}

} // namespace internal

llvm::Expected<AdornedCFG> AdornedCFG::build(const FunctionDecl &Func) {
if (!Func.doesThisDeclarationHaveABody())
return llvm::createStringError(
Expand Down Expand Up @@ -166,8 +173,7 @@ llvm::Expected<AdornedCFG> AdornedCFG::build(const Decl &D, Stmt &S,
std::make_error_code(std::errc::invalid_argument),
"CFG::buildCFG failed");

llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock =
buildStmtToBasicBlockMap(*Cfg);
internal::StmtToBlockMap StmtToBlock(*Cfg);

llvm::BitVector BlockReachable = findReachableBlocks(*Cfg);

Expand Down
11 changes: 5 additions & 6 deletions clang/lib/Analysis/FlowSensitive/Transfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,16 @@ namespace clang {
namespace dataflow {

const Environment *StmtToEnvMap::getEnvironment(const Stmt &S) const {
auto BlockIt = ACFG.getStmtToBlock().find(&ignoreCFGOmittedNodes(S));
if (BlockIt == ACFG.getStmtToBlock().end()) {
const CFGBlock *Block = ACFG.blockForStmt(S);
if (Block == nullptr) {
assert(false);
// Return null to avoid dereferencing the end iterator in non-assert builds.
return nullptr;
}
if (!ACFG.isBlockReachable(*BlockIt->getSecond()))
if (!ACFG.isBlockReachable(*Block))
return nullptr;
if (BlockIt->getSecond()->getBlockID() == CurBlockID)
if (Block->getBlockID() == CurBlockID)
return &CurState.Env;
const auto &State = BlockToState[BlockIt->getSecond()->getBlockID()];
const auto &State = BlockToState[Block->getBlockID()];
if (!(State))
return nullptr;
return &State->Env;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,11 @@ computeBlockInputState(const CFGBlock &Block, AnalysisContext &AC) {
// See `NoreturnDestructorTest` for concrete examples.
if (Block.succ_begin()->getReachableBlock() != nullptr &&
Block.succ_begin()->getReachableBlock()->hasNoReturnElement()) {
auto &StmtToBlock = AC.ACFG.getStmtToBlock();
auto StmtBlock = StmtToBlock.find(Block.getTerminatorStmt());
assert(StmtBlock != StmtToBlock.end());
llvm::erase(Preds, StmtBlock->getSecond());
const CFGBlock *StmtBlock = nullptr;
if (const Stmt *Terminator = Block.getTerminatorStmt())
StmtBlock = AC.ACFG.blockForStmt(*Terminator);
assert(StmtBlock != nullptr);
llvm::erase(Preds, StmtBlock);
}
}

Expand Down
38 changes: 37 additions & 1 deletion clang/lib/Analysis/LiveVariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,22 @@ static void AddLiveExpr(llvm::ImmutableSet<const Expr *> &Set,
Set = F.add(Set, LookThroughExpr(E));
}

/// Add as a live expression all individual conditions in a logical expression.
/// For example, for the expression:
/// "(a < b) || (c && d && ((e || f) != (g && h)))"
/// the following expressions will be added as live:
/// "a < b", "c", "d", "((e || f) != (g && h))"
static void AddAllConditionalTerms(llvm::ImmutableSet<const Expr *> &Set,
llvm::ImmutableSet<const Expr *>::Factory &F,
const Expr *Cond) {
AddLiveExpr(Set, F, Cond);
if (auto const *BO = dyn_cast<BinaryOperator>(Cond->IgnoreParens());
BO && BO->isLogicalOp()) {
AddAllConditionalTerms(Set, F, BO->getLHS());
AddAllConditionalTerms(Set, F, BO->getRHS());
}
}

void TransferFunctions::Visit(Stmt *S) {
if (observer)
observer->observeStmt(S, currentBlock, val);
Expand Down Expand Up @@ -313,7 +329,27 @@ void TransferFunctions::Visit(Stmt *S) {
AddLiveExpr(val.liveExprs, LV.ESetFact, cast<ForStmt>(S)->getCond());
return;
}

case Stmt::ConditionalOperatorClass: {
// Keep not only direct children alive, but also all the short-circuited
// parts of the condition. Short-circuiting evaluation may cause the
// conditional operator evaluation to skip the evaluation of the entire
// condtion expression, so the value of the entire condition expression is
// never computed.
//
// This makes a difference when we compare exploded nodes coming from true
// and false expressions with no side effects: the only difference in the
// state is the value of (part of) the condition.
//
// BinaryConditionalOperatorClass ('x ?: y') is not affected because it
// explicitly calculates the value of the entire condition expression (to
// possibly use as a value for the "true expr") even if it is
// short-circuited.
auto const *CO = cast<ConditionalOperator>(S);
AddAllConditionalTerms(val.liveExprs, LV.ESetFact, CO->getCond());
AddLiveExpr(val.liveExprs, LV.ESetFact, CO->getTrueExpr());
AddLiveExpr(val.liveExprs, LV.ESetFact, CO->getFalseExpr());
return;
}
}

// HACK + FIXME: What is this? One could only guess that this is an attempt to
Expand Down
53 changes: 31 additions & 22 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1993,7 +1993,12 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
if (Method->isStatic())
return cast_or_null<llvm::DISubroutineType>(
getOrCreateType(QualType(Func, 0), Unit));
return getOrCreateInstanceMethodType(Method->getThisType(), Func, Unit);

QualType ThisType;
if (!Method->hasCXXExplicitFunctionObjectParameter())
ThisType = Method->getThisType();

return getOrCreateInstanceMethodType(ThisType, Func, Unit);
}

llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
Expand Down Expand Up @@ -2025,27 +2030,31 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
Elts.push_back(Args[0]);

// "this" pointer is always first argument.
const CXXRecordDecl *RD = ThisPtr->getPointeeCXXRecordDecl();
if (isa<ClassTemplateSpecializationDecl>(RD)) {
// Create pointer type directly in this case.
const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
uint64_t Size = CGM.getContext().getTypeSize(ThisPtrTy);
auto Align = getTypeAlignIfRequired(ThisPtrTy, CGM.getContext());
llvm::DIType *PointeeType =
getOrCreateType(ThisPtrTy->getPointeeType(), Unit);
llvm::DIType *ThisPtrType =
DBuilder.createPointerType(PointeeType, Size, Align);
TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
// TODO: This and the artificial type below are misleading, the
// types aren't artificial the argument is, but the current
// metadata doesn't represent that.
ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
Elts.push_back(ThisPtrType);
} else {
llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
Elts.push_back(ThisPtrType);
// ThisPtr may be null if the member function has an explicit 'this'
// parameter.
if (!ThisPtr.isNull()) {
const CXXRecordDecl *RD = ThisPtr->getPointeeCXXRecordDecl();
if (isa<ClassTemplateSpecializationDecl>(RD)) {
// Create pointer type directly in this case.
const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
uint64_t Size = CGM.getContext().getTypeSize(ThisPtrTy);
auto Align = getTypeAlignIfRequired(ThisPtrTy, CGM.getContext());
llvm::DIType *PointeeType =
getOrCreateType(ThisPtrTy->getPointeeType(), Unit);
llvm::DIType *ThisPtrType =
DBuilder.createPointerType(PointeeType, Size, Align);
TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
// TODO: This and the artificial type below are misleading, the
// types aren't artificial the argument is, but the current
// metadata doesn't represent that.
ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
Elts.push_back(ThisPtrType);
} else {
llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
Elts.push_back(ThisPtrType);
}
}

// Copy rest of the arguments.
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/CodeGen/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,8 +883,10 @@ void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming(

if (!CalleeIsStreamingCompatible &&
(CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible))
CGM.getDiags().Report(CallLoc,
diag::err_function_always_inline_attribute_mismatch)
CGM.getDiags().Report(
CallLoc, CalleeIsStreaming
? diag::err_function_always_inline_attribute_mismatch
: diag::warn_function_always_inline_attribute_mismatch)
<< Caller->getDeclName() << Callee->getDeclName() << "streaming";
if (auto *NewAttr = Callee->getAttr<ArmNewAttr>())
if (NewAttr->isNewZA())
Expand Down
Loading

0 comments on commit d0957f9

Please sign in to comment.