summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2019-01-27 16:42:12 +0000
committerpatrick <patrick@openbsd.org>2019-01-27 16:42:12 +0000
commitb773203fb58f3ef282fb69c832d8710cab5bc82d (patch)
treee75913f147570fbd75169647b144df85b88a038c /gnu/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
parenttweak errno in previous (diff)
downloadwireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz
wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp')
-rw-r--r--gnu/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp112
1 files changed, 53 insertions, 59 deletions
diff --git a/gnu/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/gnu/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
index c44edbed8ed..0de2bc72b52 100644
--- a/gnu/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
+++ b/gnu/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
@@ -28,6 +28,7 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
@@ -64,7 +65,6 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include <algorithm>
#include <cassert>
@@ -401,7 +401,7 @@ namespace {
/// defining value. The 'base defining value' for 'Def' is the transitive
/// closure of this relation stopping at the first instruction which has no
/// immediate base defining value. The b.d.v. might itself be a base pointer,
-/// but it can also be an arbitrary derived pointer.
+/// but it can also be an arbitrary derived pointer.
struct BaseDefiningValueResult {
/// Contains the value which is the base defining value.
Value * const BDV;
@@ -427,13 +427,13 @@ static BaseDefiningValueResult findBaseDefiningValue(Value *I);
/// Return a base defining value for the 'Index' element of the given vector
/// instruction 'I'. If Index is null, returns a BDV for the entire vector
-/// 'I'. As an optimization, this method will try to determine when the
+/// 'I'. As an optimization, this method will try to determine when the
/// element is known to already be a base pointer. If this can be established,
/// the second value in the returned pair will be true. Note that either a
/// vector or a pointer typed value can be returned. For the former, the
/// vector returned is a BDV (and possibly a base) of the entire vector 'I'.
/// If the later, the return pointer is a BDV (or possibly a base) for the
-/// particular element in 'I'.
+/// particular element in 'I'.
static BaseDefiningValueResult
findBaseDefiningValueOfVector(Value *I) {
// Each case parallels findBaseDefiningValue below, see that code for
@@ -444,7 +444,7 @@ findBaseDefiningValueOfVector(Value *I) {
return BaseDefiningValueResult(I, true);
if (isa<Constant>(I))
- // Base of constant vector consists only of constant null pointers.
+ // Base of constant vector consists only of constant null pointers.
// For reasoning see similar case inside 'findBaseDefiningValue' function.
return BaseDefiningValueResult(ConstantAggregateZero::get(I->getType()),
true);
@@ -476,6 +476,12 @@ findBaseDefiningValueOfVector(Value *I) {
if (auto *BC = dyn_cast<BitCastInst>(I))
return findBaseDefiningValue(BC->getOperand(0));
+ // We assume that functions in the source language only return base
+ // pointers. This should probably be generalized via attributes to support
+ // both source language and internal functions.
+ if (isa<CallInst>(I) || isa<InvokeInst>(I))
+ return BaseDefiningValueResult(I, true);
+
// A PHI or Select is a base defining value. The outer findBasePointer
// algorithm is responsible for constructing a base value for this BDV.
assert((isa<SelectInst>(I) || isa<PHINode>(I)) &&
@@ -502,11 +508,11 @@ static BaseDefiningValueResult findBaseDefiningValue(Value *I) {
if (isa<Constant>(I)) {
// We assume that objects with a constant base (e.g. a global) can't move
// and don't need to be reported to the collector because they are always
- // live. Besides global references, all kinds of constants (e.g. undef,
+ // live. Besides global references, all kinds of constants (e.g. undef,
// constant expressions, null pointers) can be introduced by the inliner or
// the optimizer, especially on dynamically dead paths.
// Here we treat all of them as having single null base. By doing this we
- // trying to avoid problems reporting various conflicts in a form of
+ // trying to avoid problems reporting various conflicts in a form of
// "phi (const1, const2)" or "phi (const, regular gc ptr)".
// See constant.ll file for relevant test cases.
@@ -610,8 +616,8 @@ static Value *findBaseDefiningValueCached(Value *I, DefiningValueMapTy &Cache) {
Value *&Cached = Cache[I];
if (!Cached) {
Cached = findBaseDefiningValue(I).BDV;
- DEBUG(dbgs() << "fBDV-cached: " << I->getName() << " -> "
- << Cached->getName() << "\n");
+ LLVM_DEBUG(dbgs() << "fBDV-cached: " << I->getName() << " -> "
+ << Cached->getName() << "\n");
}
assert(Cache[I] != nullptr);
return Cached;
@@ -842,9 +848,9 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache) {
}
#ifndef NDEBUG
- DEBUG(dbgs() << "States after initialization:\n");
+ LLVM_DEBUG(dbgs() << "States after initialization:\n");
for (auto Pair : States) {
- DEBUG(dbgs() << " " << Pair.second << " for " << *Pair.first << "\n");
+ LLVM_DEBUG(dbgs() << " " << Pair.second << " for " << *Pair.first << "\n");
}
#endif
@@ -917,9 +923,9 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache) {
}
#ifndef NDEBUG
- DEBUG(dbgs() << "States after meet iteration:\n");
+ LLVM_DEBUG(dbgs() << "States after meet iteration:\n");
for (auto Pair : States) {
- DEBUG(dbgs() << " " << Pair.second << " for " << *Pair.first << "\n");
+ LLVM_DEBUG(dbgs() << " " << Pair.second << " for " << *Pair.first << "\n");
}
#endif
@@ -960,7 +966,7 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache) {
auto MakeBaseInstPlaceholder = [](Instruction *I) -> Instruction* {
if (isa<PHINode>(I)) {
BasicBlock *BB = I->getParent();
- int NumPreds = std::distance(pred_begin(BB), pred_end(BB));
+ int NumPreds = pred_size(BB);
assert(NumPreds > 0 && "how did we reach here");
std::string Name = suffixed_name_or(I, ".base", "base_phi");
return PHINode::Create(I->getType(), NumPreds, Name, I);
@@ -1118,10 +1124,11 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache) {
assert(BDV && Base);
assert(!isKnownBaseResult(BDV) && "why did it get added?");
- DEBUG(dbgs() << "Updating base value cache"
- << " for: " << BDV->getName() << " from: "
- << (Cache.count(BDV) ? Cache[BDV]->getName().str() : "none")
- << " to: " << Base->getName() << "\n");
+ LLVM_DEBUG(
+ dbgs() << "Updating base value cache"
+ << " for: " << BDV->getName() << " from: "
+ << (Cache.count(BDV) ? Cache[BDV]->getName().str() : "none")
+ << " to: " << Base->getName() << "\n");
if (Cache.count(BDV)) {
assert(isKnownBaseResult(Base) &&
@@ -1278,14 +1285,14 @@ static void CreateGCRelocates(ArrayRef<Value *> LiveVariables,
return Index;
};
Module *M = StatepointToken->getModule();
-
+
// All gc_relocate are generated as i8 addrspace(1)* (or a vector type whose
// element type is i8 addrspace(1)*). We originally generated unique
// declarations for each pointer type, but this proved problematic because
// the intrinsic mangling code is incomplete and fragile. Since we're moving
// towards a single unified pointer type anyways, we can just cast everything
// to an i8* of the right address space. A bitcast is added later to convert
- // gc_relocate to the actual value's type.
+ // gc_relocate to the actual value's type.
auto getGCRelocateDecl = [&] (Type *Ty) {
assert(isHandledGCPointerType(Ty));
auto AS = Ty->getScalarType()->getPointerAddressSpace();
@@ -1369,7 +1376,7 @@ public:
assert(OldI != NewI && "Disallowed at construction?!");
assert((!IsDeoptimize || !New) &&
- "Deoptimize instrinsics are not replaced!");
+ "Deoptimize intrinsics are not replaced!");
Old = nullptr;
New = nullptr;
@@ -1379,7 +1386,7 @@ public:
if (IsDeoptimize) {
// Note: we've inserted instructions, so the call to llvm.deoptimize may
- // not necessarilly be followed by the matching return.
+ // not necessarily be followed by the matching return.
auto *RI = cast<ReturnInst>(OldI->getParent()->getTerminator());
new UnreachableInst(RI->getContext(), RI);
RI->eraseFromParent();
@@ -1406,7 +1413,7 @@ static StringRef getDeoptLowering(CallSite CS) {
}
return "live-through";
}
-
+
static void
makeStatepointExplicitImpl(const CallSite CS, /* to replace */
const SmallVectorImpl<Value *> &BasePtrs,
@@ -1805,7 +1812,7 @@ static void relocationViaAlloca(
SmallVector<Instruction *, 20> Uses;
// PERF: trade a linear scan for repeated reallocation
- Uses.reserve(std::distance(Def->user_begin(), Def->user_end()));
+ Uses.reserve(Def->getNumUses());
for (User *U : Def->users()) {
if (!isa<ConstantExpr>(U)) {
// If the def has a ConstantExpr use, then the def is either a
@@ -1817,7 +1824,7 @@ static void relocationViaAlloca(
}
}
- std::sort(Uses.begin(), Uses.end());
+ llvm::sort(Uses.begin(), Uses.end());
auto Last = std::unique(Uses.begin(), Uses.end());
Uses.erase(Last, Uses.end());
@@ -1977,7 +1984,7 @@ chainToBasePointerCost(SmallVectorImpl<Instruction*> &Chain,
Cost += 2;
} else {
- llvm_unreachable("unsupported instruciton type during rematerialization");
+ llvm_unreachable("unsupported instruction type during rematerialization");
}
}
@@ -2024,7 +2031,7 @@ static void rematerializeLiveValues(CallSite CS,
SmallVector<Value *, 32> LiveValuesToBeDeleted;
for (Value *LiveValue: Info.LiveSet) {
- // For each live pointer find it's defining chain
+ // For each live pointer find its defining chain
SmallVector<Instruction *, 3> ChainToBase;
assert(Info.PointerToBase.count(LiveValue));
Value *RootOfChain =
@@ -2461,22 +2468,8 @@ static void stripNonValidDataFromBody(Function &F) {
continue;
}
- if (const MDNode *MD = I.getMetadata(LLVMContext::MD_tbaa)) {
- assert(MD->getNumOperands() < 5 && "unrecognized metadata shape!");
- bool IsImmutableTBAA =
- MD->getNumOperands() == 4 &&
- mdconst::extract<ConstantInt>(MD->getOperand(3))->getValue() == 1;
-
- if (!IsImmutableTBAA)
- continue; // no work to do, MD_tbaa is already marked mutable
-
- MDNode *Base = cast<MDNode>(MD->getOperand(0));
- MDNode *Access = cast<MDNode>(MD->getOperand(1));
- uint64_t Offset =
- mdconst::extract<ConstantInt>(MD->getOperand(2))->getZExtValue();
-
- MDNode *MutableTBAA =
- Builder.createTBAAStructTagNode(Base, Access, Offset);
+ if (MDNode *Tag = I.getMetadata(LLVMContext::MD_tbaa)) {
+ MDNode *MutableTBAA = Builder.createMutableTBAAAccessTag(Tag);
I.setMetadata(LLVMContext::MD_tbaa, MutableTBAA);
}
@@ -2537,30 +2530,31 @@ bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT,
return false;
};
+
+ // Delete any unreachable statepoints so that we don't have unrewritten
+ // statepoints surviving this pass. This makes testing easier and the
+ // resulting IR less confusing to human readers.
+ DeferredDominance DD(DT);
+ bool MadeChange = removeUnreachableBlocks(F, nullptr, &DD);
+ DD.flush();
+
// Gather all the statepoints which need rewritten. Be careful to only
// consider those in reachable code since we need to ask dominance queries
// when rewriting. We'll delete the unreachable ones in a moment.
SmallVector<CallSite, 64> ParsePointNeeded;
- bool HasUnreachableStatepoint = false;
for (Instruction &I : instructions(F)) {
// TODO: only the ones with the flag set!
if (NeedsRewrite(I)) {
- if (DT.isReachableFromEntry(I.getParent()))
- ParsePointNeeded.push_back(CallSite(&I));
- else
- HasUnreachableStatepoint = true;
+ // NOTE removeUnreachableBlocks() is stronger than
+ // DominatorTree::isReachableFromEntry(). In other words
+ // removeUnreachableBlocks can remove some blocks for which
+ // isReachableFromEntry() returns true.
+ assert(DT.isReachableFromEntry(I.getParent()) &&
+ "no unreachable blocks expected");
+ ParsePointNeeded.push_back(CallSite(&I));
}
}
- bool MadeChange = false;
-
- // Delete any unreachable statepoints so that we don't have unrewritten
- // statepoints surviving this pass. This makes testing easier and the
- // resulting IR less confusing to human readers. Rather than be fancy, we
- // just reuse a utility function which removes the unreachable blocks.
- if (HasUnreachableStatepoint)
- MadeChange |= removeUnreachableBlocks(F);
-
// Return early if no work to do.
if (ParsePointNeeded.empty())
return MadeChange;
@@ -2576,7 +2570,7 @@ bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT,
}
// Before we start introducing relocations, we want to tweak the IR a bit to
- // avoid unfortunate code generation effects. The main example is that we
+ // avoid unfortunate code generation effects. The main example is that we
// want to try to make sure the comparison feeding a branch is after any
// safepoints. Otherwise, we end up with a comparison of pre-relocation
// values feeding a branch after relocation. This is semantically correct,
@@ -2599,7 +2593,7 @@ bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT,
TerminatorInst *TI = BB.getTerminator();
if (auto *Cond = getConditionInst(TI))
// TODO: Handle more than just ICmps here. We should be able to move
- // most instructions without side effects or memory access.
+ // most instructions without side effects or memory access.
if (isa<ICmpInst>(Cond) && Cond->hasOneUse()) {
MadeChange = true;
Cond->moveBefore(TI);