Skip to content

Commit

Permalink
Merged master:7fb9de2c6f57 into amd-gfx:6eb6fff44da8
Browse files Browse the repository at this point in the history
Local branch amd-gfx 6eb6fff Merged master:f4ba7a100a56 into amd-gfx:365715cceaad
Remote branch master 7fb9de2 [StackSafety,NFC] Fix tests in debug
  • Loading branch information
Sw authored and Sw committed Aug 7, 2020
2 parents 6eb6fff + 7fb9de2 commit 25d7a92
Show file tree
Hide file tree
Showing 20 changed files with 735 additions and 245 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,13 @@ struct Bar {
template <class... Values>
struct Bar2 {
static_assert((... && (sizeof(Values) > 0)) == (... && (sizeof(Values) > 0)));
// CHECK-MESSAGES: :[[@LINE-1]]:47: warning: both sides of operator are equivalent [misc-redundant-expression]
// FIXME: It's not clear that we should be diagnosing this. The `&&` operator
// here is unresolved and could resolve to an overloaded operator that might
// have side-effects on its operands. For other constructs with the same
// property (eg, the `S2` cases above) we suppress this diagnostic. This
// started failing when Clang started properly modeling the fold-expression as
// containing an unresolved operator name.
// FIXME-MESSAGES: :[[@LINE-1]]:47: warning: both sides of operator are equivalent [misc-redundant-expression]
};

} // namespace no_crash
20 changes: 16 additions & 4 deletions flang/lib/Semantics/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2704,10 +2704,22 @@ void ArgumentAnalyzer::Analyze(const parser::Variable &x) {
actuals_.emplace_back(std::move(*expr));
return;
}
const Symbol *symbol{GetFirstSymbol(*expr)};
context_.Say(x.GetSource(),
"Assignment to constant '%s' is not allowed"_err_en_US,
symbol ? symbol->name() : x.GetSource());
const Symbol *symbol{GetLastSymbol(*expr)};
if (!symbol) {
context_.SayAt(x, "Assignment to constant '%s' is not allowed"_err_en_US,
x.GetSource());
} else if (auto *subp{symbol->detailsIf<semantics::SubprogramDetails>()}) {
auto *msg{context_.SayAt(x,
"Assignment to subprogram '%s' is not allowed"_err_en_US,
symbol->name())};
if (subp->isFunction()) {
const auto &result{subp->result().name()};
msg->Attach(result, "Function result is '%s'"_err_en_US, result);
}
} else {
context_.SayAt(x, "Assignment to constant '%s' is not allowed"_err_en_US,
symbol->name());
}
}
fatalErrors_ = true;
}
Expand Down
10 changes: 10 additions & 0 deletions flang/test/Semantics/assign04.f90
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,13 @@ subroutine s7
integer :: a(10), v(10)
a(v(:)) = 1 ! vector subscript is ok
end

subroutine s8
!ERROR: Assignment to subprogram 's8' is not allowed
s8 = 1.0
end

real function f9() result(r)
!ERROR: Assignment to subprogram 'f9' is not allowed
f9 = 1.0
end
2 changes: 2 additions & 0 deletions llvm/include/llvm/Analysis/StackLifetime.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ class StackLifetime {
DenseMap<const BasicBlock *, SmallVector<std::pair<unsigned, Marker>, 4>>
BBMarkers;

bool HasUnknownLifetimeStartOrEnd = false;

void dumpAllocas() const;
void dumpBlockLiveness() const;
void dumpLiveRanges() const;
Expand Down
7 changes: 7 additions & 0 deletions llvm/include/llvm/IR/ModuleSummaryIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,9 @@ class ModuleSummaryIndex {
// some were not. Set when the combined index is created during the thin link.
bool PartiallySplitLTOUnits = false;

/// True if some of the FunctionSummary contains a ParamAccess.
bool HasParamAccess = false;

std::set<std::string> CfiFunctionDefs;
std::set<std::string> CfiFunctionDecls;

Expand Down Expand Up @@ -1213,6 +1216,8 @@ class ModuleSummaryIndex {
bool partiallySplitLTOUnits() const { return PartiallySplitLTOUnits; }
void setPartiallySplitLTOUnits() { PartiallySplitLTOUnits = true; }

bool hasParamAccess() const { return HasParamAccess; }

bool isGlobalValueLive(const GlobalValueSummary *GVS) const {
return !WithGlobalValueDeadStripping || GVS->isLive();
}
Expand Down Expand Up @@ -1284,6 +1289,8 @@ class ModuleSummaryIndex {
/// Add a global value summary for the given ValueInfo.
void addGlobalValueSummary(ValueInfo VI,
std::unique_ptr<GlobalValueSummary> Summary) {
if (const FunctionSummary *FS = dyn_cast<FunctionSummary>(Summary.get()))
HasParamAccess |= !FS->paramAccesses().empty();
addOriginalName(VI.getGUID(), Summary->getOriginalName());
// Here we have a notionally const VI, but the value it points to is owned
// by the non-const *this.
Expand Down
11 changes: 11 additions & 0 deletions llvm/include/llvm/IR/PassInstrumentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class PassInstrumentationCallbacks {
// IRUnits in a safe way, and we might pursue that as soon as there is a
// useful instrumentation that needs it.
using BeforePassFunc = bool(StringRef, Any);
using BeforeSkippedPassFunc = void(StringRef, Any);
using BeforeNonSkippedPassFunc = void(StringRef, Any);
using AfterPassFunc = void(StringRef, Any);
using AfterPassInvalidatedFunc = void(StringRef);
Expand All @@ -91,6 +92,11 @@ class PassInstrumentationCallbacks {
BeforePassCallbacks.emplace_back(std::move(C));
}

template <typename CallableT>
void registerBeforeSkippedPassCallback(CallableT C) {
BeforeSkippedPassCallbacks.emplace_back(std::move(C));
}

template <typename CallableT>
void registerBeforeNonSkippedPassCallback(CallableT C) {
BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
Expand Down Expand Up @@ -119,6 +125,8 @@ class PassInstrumentationCallbacks {
friend class PassInstrumentation;

SmallVector<llvm::unique_function<BeforePassFunc>, 4> BeforePassCallbacks;
SmallVector<llvm::unique_function<BeforeSkippedPassFunc>, 4>
BeforeSkippedPassCallbacks;
SmallVector<llvm::unique_function<BeforeNonSkippedPassFunc>, 4>
BeforeNonSkippedPassCallbacks;
SmallVector<llvm::unique_function<AfterPassFunc>, 4> AfterPassCallbacks;
Expand Down Expand Up @@ -179,6 +187,9 @@ class PassInstrumentation {
if (ShouldRun) {
for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)
C(Pass.name(), llvm::Any(&IR));
} else {
for (auto &C : Callbacks->BeforeSkippedPassCallbacks)
C(Pass.name(), llvm::Any(&IR));
}

return ShouldRun;
Expand Down
58 changes: 29 additions & 29 deletions llvm/lib/Analysis/StackLifetime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/BasicBlock.h"
Expand Down Expand Up @@ -63,42 +64,27 @@ bool StackLifetime::isAliveAfter(const AllocaInst *AI,
return getLiveRange(AI).test(InstNum);
}

static bool readMarker(const Instruction *I, bool *IsStart) {
if (!I->isLifetimeStartOrEnd())
return false;

auto *II = cast<IntrinsicInst>(I);
*IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start;
return true;
}

void StackLifetime::collectMarkers() {
InterestingAllocas.resize(NumAllocas);
DenseMap<const BasicBlock *, SmallDenseMap<const IntrinsicInst *, Marker>>
BBMarkerSet;

// Compute the set of start/end markers per basic block.
for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) {
const AllocaInst *AI = Allocas[AllocaNo];
SmallVector<const Instruction *, 8> WorkList;
WorkList.push_back(AI);
while (!WorkList.empty()) {
const Instruction *I = WorkList.pop_back_val();
for (const User *U : I->users()) {
if (auto *BI = dyn_cast<BitCastInst>(U)) {
WorkList.push_back(BI);
continue;
}
auto *UI = dyn_cast<IntrinsicInst>(U);
if (!UI)
continue;
bool IsStart;
if (!readMarker(UI, &IsStart))
continue;
if (IsStart)
InterestingAllocas.set(AllocaNo);
BBMarkerSet[UI->getParent()][UI] = {AllocaNo, IsStart};
for (const BasicBlock *BB : depth_first(&F)) {
for (const Instruction &I : *BB) {
const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
if (!II || !II->isLifetimeStartOrEnd())
continue;
const AllocaInst *AI = llvm::findAllocaForValue(II->getArgOperand(1));
if (!AI) {
HasUnknownLifetimeStartOrEnd = true;
continue;
}
bool IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start;
unsigned AllocaNo = AllocaNumbering[AI];
if (IsStart)
InterestingAllocas.set(AllocaNo);
BBMarkerSet[BB][II] = {AllocaNo, IsStart};
}
}

Expand Down Expand Up @@ -304,6 +290,20 @@ StackLifetime::StackLifetime(const Function &F,
}

void StackLifetime::run() {
if (HasUnknownLifetimeStartOrEnd) {
// There is marker which we can't assign to a specific alloca, so we
// fallback to the most conservative results for the type.
switch (Type) {
case LivenessType::May:
LiveRanges.resize(NumAllocas, getFullLiveRange());
break;
case LivenessType::Must:
LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
break;
}
return;
}

LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
for (unsigned I = 0; I < NumAllocas; ++I)
if (!InterestingAllocas.test(I))
Expand Down
20 changes: 18 additions & 2 deletions llvm/lib/Analysis/StackSafetyAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ using namespace llvm;
STATISTIC(NumAllocaStackSafe, "Number of safe allocas");
STATISTIC(NumAllocaTotal, "Number of total allocas");

STATISTIC(NumCombinedCalleeLookupTotal,
"Number of total callee lookups on combined index.");
STATISTIC(NumCombinedCalleeLookupFailed,
"Number of failed callee lookups on combined index.");
STATISTIC(NumModuleCalleeLookupTotal,
"Number of total callee lookups on module index.");
STATISTIC(NumModuleCalleeLookupFailed,
"Number of failed callee lookups on module index.");

static cl::opt<int> StackSafetyMaxIterations("stack-safety-max-iterations",
cl::init(20), cl::Hidden);

Expand Down Expand Up @@ -174,6 +183,7 @@ template <typename CalleeTy> struct FunctionInfo {
} else {
assert(Allocas.empty());
}
O << "\n";
}
};

Expand Down Expand Up @@ -607,7 +617,6 @@ GlobalValueSummary *getGlobalValueSummary(const ModuleSummaryIndex *Index,
auto VI = Index->getValueInfo(ValueGUID);
if (!VI || VI.getSummaryList().empty())
return nullptr;
assert(VI.getSummaryList().size() == 1);
auto &Summary = VI.getSummaryList()[0];
return Summary.get();
}
Expand Down Expand Up @@ -637,8 +646,11 @@ void resolveAllCalls(UseInfo<GlobalValue> &Use,
GlobalValueSummary *GVS = getGlobalValueSummary(Index, C.Callee->getGUID());

FunctionSummary *FS = resolveCallee(GVS);
if (!FS)
++NumModuleCalleeLookupTotal;
if (!FS) {
++NumModuleCalleeLookupFailed;
return Use.updateRange(FullSet);
}
const ConstantRange *Found = findParamAccess(*FS, C.ParamNo);
if (!Found)
return Use.updateRange(FullSet);
Expand Down Expand Up @@ -921,6 +933,8 @@ bool llvm::needsParamAccessSummary(const Module &M) {
}

void llvm::generateParamAccessSummary(ModuleSummaryIndex &Index) {
if (!Index.hasParamAccess())
return;
const ConstantRange FullSet(FunctionSummary::ParamAccess::RangeWidth, true);
std::map<const FunctionSummary *, FunctionInfo<FunctionSummary>> Functions;

Expand All @@ -942,7 +956,9 @@ void llvm::generateParamAccessSummary(ModuleSummaryIndex &Index) {
assert(!Call.Offsets.isFullSet());
FunctionSummary *S = resolveCallee(
Index.findSummaryInModule(Call.Callee, FS->modulePath()));
++NumCombinedCalleeLookupTotal;
if (!S) {
++NumCombinedCalleeLookupFailed;
US.Range = FullSet;
US.Calls.clear();
break;
Expand Down
Loading

0 comments on commit 25d7a92

Please sign in to comment.