forked from OSchip/llvm-project
Revert "[clang] Remove the DIFlagArgumentNotModified debug info flag"
This reverts commit rG1643734741d2 due to LLDB test failure.
This commit is contained in:
parent
71327707b0
commit
41d6ad6efd
|
@ -18,6 +18,7 @@
|
|||
#include "CodeGenFunction.h"
|
||||
#include "CodeGenModule.h"
|
||||
#include "ConstantEmitter.h"
|
||||
#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/DeclFriend.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
|
@ -3685,6 +3686,15 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc,
|
|||
if (HasDecl && isa<FunctionDecl>(D))
|
||||
DeclCache[D->getCanonicalDecl()].reset(SP);
|
||||
|
||||
// We use the SPDefCache only in the case when the debug entry values option
|
||||
// is set, in order to speed up parameters modification analysis.
|
||||
//
|
||||
// FIXME: Use AbstractCallee here to support ObjCMethodDecl.
|
||||
if (CGM.getCodeGenOpts().EnableDebugEntryValues && HasDecl)
|
||||
if (auto *FD = dyn_cast<FunctionDecl>(D))
|
||||
if (FD->hasBody() && !FD->param_empty())
|
||||
SPDefCache[FD].reset(SP);
|
||||
|
||||
// Push the function onto the lexical block stack.
|
||||
LexicalBlockStack.emplace_back(SP);
|
||||
|
||||
|
@ -4079,6 +4089,11 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
|
|||
llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
|
||||
Builder.GetInsertBlock());
|
||||
|
||||
if (CGM.getCodeGenOpts().EnableDebugEntryValues && ArgNo) {
|
||||
if (auto *PD = dyn_cast<ParmVarDecl>(VD))
|
||||
ParamCache[PD].reset(D);
|
||||
}
|
||||
|
||||
return D;
|
||||
}
|
||||
|
||||
|
@ -4694,6 +4709,29 @@ void CGDebugInfo::setDwoId(uint64_t Signature) {
|
|||
TheCU->setDWOId(Signature);
|
||||
}
|
||||
|
||||
/// Analyzes each function parameter to determine whether it is constant
|
||||
/// throughout the function body.
|
||||
static void analyzeParametersModification(
|
||||
ASTContext &Ctx,
|
||||
llvm::DenseMap<const FunctionDecl *, llvm::TrackingMDRef> &SPDefCache,
|
||||
llvm::DenseMap<const ParmVarDecl *, llvm::TrackingMDRef> &ParamCache) {
|
||||
for (auto &SP : SPDefCache) {
|
||||
auto *FD = SP.first;
|
||||
assert(FD->hasBody() && "Functions must have body here");
|
||||
const Stmt *FuncBody = (*FD).getBody();
|
||||
for (auto Parm : FD->parameters()) {
|
||||
ExprMutationAnalyzer FuncAnalyzer(*FuncBody, Ctx);
|
||||
if (FuncAnalyzer.isMutated(Parm))
|
||||
continue;
|
||||
|
||||
auto I = ParamCache.find(Parm);
|
||||
assert(I != ParamCache.end() && "Parameters should be already cached");
|
||||
auto *DIParm = cast<llvm::DILocalVariable>(I->second);
|
||||
DIParm->setIsNotModified();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGDebugInfo::finalize() {
|
||||
// Creating types might create further types - invalidating the current
|
||||
// element and the size(), so don't cache/reference them.
|
||||
|
@ -4766,6 +4804,10 @@ void CGDebugInfo::finalize() {
|
|||
if (auto MD = TypeCache[RT])
|
||||
DBuilder.retainType(cast<llvm::DIType>(MD));
|
||||
|
||||
if (CGM.getCodeGenOpts().EnableDebugEntryValues)
|
||||
// This will be used to emit debug entry values.
|
||||
analyzeParametersModification(CGM.getContext(), SPDefCache, ParamCache);
|
||||
|
||||
DBuilder.finalize();
|
||||
}
|
||||
|
||||
|
|
|
@ -146,6 +146,10 @@ class CGDebugInfo {
|
|||
|
||||
llvm::DenseMap<const char *, llvm::TrackingMDRef> DIFileCache;
|
||||
llvm::DenseMap<const FunctionDecl *, llvm::TrackingMDRef> SPCache;
|
||||
/// Cache function definitions relevant to use for parameters mutation
|
||||
/// analysis.
|
||||
llvm::DenseMap<const FunctionDecl *, llvm::TrackingMDRef> SPDefCache;
|
||||
llvm::DenseMap<const ParmVarDecl *, llvm::TrackingMDRef> ParamCache;
|
||||
/// Cache declarations relevant to DW_TAG_imported_declarations (C++
|
||||
/// using declarations) that aren't covered by other more specific caches.
|
||||
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> DeclCache;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// RUN: %clang -Xclang -femit-debug-entry-values -g -O2 -Xclang -disable-llvm-passes -S -target x86_64-none-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-ENTRY-VAL-OPT
|
||||
// RUN: %clang -Xclang -femit-debug-entry-values -g -O2 -Xclang -disable-llvm-passes -S -target arm-none-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-ENTRY-VAL-OPT
|
||||
// RUN: %clang -Xclang -femit-debug-entry-values -g -O2 -Xclang -disable-llvm-passes -S -target aarch64-none-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-ENTRY-VAL-OPT
|
||||
// RUN: %clang -Xclang -femit-debug-entry-values -g -O2 -Xclang -disable-llvm-passes -S -target armeb-none-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-ENTRY-VAL-OPT
|
||||
|
||||
// CHECK-ENTRY-VAL-OPT: !DILocalVariable(name: "a", arg: 1, scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}})
|
||||
// CHECK-ENTRY-VAL-OPT: !DILocalVariable(name: "b", arg: 2, scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}}, flags: DIFlagArgumentNotModified)
|
||||
//
|
||||
// For the os_log_helper:
|
||||
// CHECK-ENTRY-VAL-OPT: !DILocalVariable(name: "buffer", arg: 1, {{.*}}, flags: DIFlagArtificial)
|
||||
//
|
||||
// RUN: %clang -g -O2 -Xclang -disable-llvm-passes -target x86_64-none-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
// CHECK-NOT: !DILocalVariable(name: "b", arg: 2, scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}}, flags: DIFlagArgumentNotModified)
|
||||
//
|
||||
// For the os_log_helper:
|
||||
// CHECK: !DILocalVariable(name: "buffer", arg: 1, {{.*}}, flags: DIFlagArtificial)
|
||||
|
||||
int fn2 (int a, int b) {
|
||||
++a;
|
||||
return b;
|
||||
}
|
||||
|
||||
void test_builtin_os_log(void *buf, int i, const char *data) {
|
||||
__builtin_os_log_format(buf, "%d %{public}s %{private}.16P", i, data, data);
|
||||
}
|
Loading…
Reference in New Issue