mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 15:36:09 +00:00

A large amount of complexity when it comes to shuffling DPValue objects around is pushed into BasicBlock::spliceDebugInfo, and it gets comprehensive testing there via the unit tests. It turns out that there's a corner case though: splicing instructions and debug-info to the end() iterator requires blocks of DPValues to be concatenated, but the DPValues don't behave normally as they're dangling at the end of a block. While this splicing-to-an-empty-block case is rare, and it's even rarer for it to contain debug-info, it does happen occasionally. Fix this by wrapping spliceDebugInfo with an outer layer that removes any dangling DPValues in the destination block -- that way the main splicing function (renamed to spliceDebugInfoImpl) doesn't need to worry about that scenario. See the diagram in the added function for more info.
1178 lines
40 KiB
C++
1178 lines
40 KiB
C++
//===-- BasicBlock.cpp - Implement BasicBlock related methods -------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the BasicBlock class for the IR library.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/IR/BasicBlock.h"
|
|
#include "SymbolTableListTraitsImpl.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include "llvm/ADT/Statistic.h"
|
|
#include "llvm/IR/CFG.h"
|
|
#include "llvm/IR/Constants.h"
|
|
#include "llvm/IR/DebugProgramInstruction.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/IR/IntrinsicInst.h"
|
|
#include "llvm/IR/LLVMContext.h"
|
|
#include "llvm/IR/Type.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
#include "LLVMContextImpl.h"
|
|
|
|
using namespace llvm;
|
|
|
|
#define DEBUG_TYPE "ir"
|
|
STATISTIC(NumInstrRenumberings, "Number of renumberings across all blocks");
|
|
|
|
cl::opt<bool>
|
|
UseNewDbgInfoFormat("experimental-debuginfo-iterators",
|
|
cl::desc("Enable communicating debuginfo positions "
|
|
"through iterators, eliminating intrinsics"),
|
|
cl::init(false));
|
|
|
|
DPMarker *BasicBlock::createMarker(Instruction *I) {
|
|
assert(IsNewDbgInfoFormat &&
|
|
"Tried to create a marker in a non new debug-info block!");
|
|
if (I->DbgMarker)
|
|
return I->DbgMarker;
|
|
DPMarker *Marker = new DPMarker();
|
|
Marker->MarkedInstr = I;
|
|
I->DbgMarker = Marker;
|
|
return Marker;
|
|
}
|
|
|
|
DPMarker *BasicBlock::createMarker(InstListType::iterator It) {
|
|
assert(IsNewDbgInfoFormat &&
|
|
"Tried to create a marker in a non new debug-info block!");
|
|
if (It != end())
|
|
return createMarker(&*It);
|
|
DPMarker *DPM = getTrailingDPValues();
|
|
if (DPM)
|
|
return DPM;
|
|
DPM = new DPMarker();
|
|
setTrailingDPValues(DPM);
|
|
return DPM;
|
|
}
|
|
|
|
void BasicBlock::convertToNewDbgValues() {
|
|
// Is the command line option set?
|
|
if (!UseNewDbgInfoFormat)
|
|
return;
|
|
|
|
IsNewDbgInfoFormat = true;
|
|
|
|
// Iterate over all instructions in the instruction list, collecting dbg.value
|
|
// instructions and converting them to DPValues. Once we find a "real"
|
|
// instruction, attach all those DPValues to a DPMarker in that instruction.
|
|
SmallVector<DPValue *, 4> DPVals;
|
|
for (Instruction &I : make_early_inc_range(InstList)) {
|
|
assert(!I.DbgMarker && "DbgMarker already set on old-format instrs?");
|
|
if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(&I)) {
|
|
// Convert this dbg.value to a DPValue.
|
|
DPValue *Value = new DPValue(DVI);
|
|
DPVals.push_back(Value);
|
|
DVI->eraseFromParent();
|
|
continue;
|
|
}
|
|
|
|
// Create a marker to store DPValues in. Technically we don't need to store
|
|
// one marker per instruction, but that's a future optimisation.
|
|
createMarker(&I);
|
|
DPMarker *Marker = I.DbgMarker;
|
|
|
|
for (DPValue *DPV : DPVals)
|
|
Marker->insertDPValue(DPV, false);
|
|
|
|
DPVals.clear();
|
|
}
|
|
}
|
|
|
|
void BasicBlock::convertFromNewDbgValues() {
|
|
invalidateOrders();
|
|
IsNewDbgInfoFormat = false;
|
|
|
|
// Iterate over the block, finding instructions annotated with DPMarkers.
|
|
// Convert any attached DPValues to dbg.values and insert ahead of the
|
|
// instruction.
|
|
for (auto &Inst : *this) {
|
|
if (!Inst.DbgMarker)
|
|
continue;
|
|
|
|
DPMarker &Marker = *Inst.DbgMarker;
|
|
for (DPValue &DPV : Marker.getDbgValueRange())
|
|
InstList.insert(Inst.getIterator(),
|
|
DPV.createDebugIntrinsic(getModule(), nullptr));
|
|
|
|
Marker.eraseFromParent();
|
|
};
|
|
|
|
// Assume no trailing DPValues: we could technically create them at the end
|
|
// of the block, after a terminator, but this would be non-cannonical and
|
|
// indicates that something else is broken somewhere.
|
|
assert(!getTrailingDPValues());
|
|
}
|
|
|
|
bool BasicBlock::validateDbgValues(bool Assert, bool Msg, raw_ostream *OS) {
|
|
bool RetVal = false;
|
|
if (!OS)
|
|
OS = &errs();
|
|
|
|
// Helper lambda for reporting failures: via assertion, printing, and return
|
|
// value.
|
|
auto TestFailure = [Assert, Msg, &RetVal, OS](bool Val, const char *Text) {
|
|
// Did the test fail?
|
|
if (Val)
|
|
return;
|
|
|
|
// If we're asserting, then fire off an assertion.
|
|
if (Assert)
|
|
llvm_unreachable(Text);
|
|
|
|
if (Msg)
|
|
*OS << Text << "\n";
|
|
RetVal = true;
|
|
};
|
|
|
|
// We should have the same debug-format as the parent function.
|
|
TestFailure(getParent()->IsNewDbgInfoFormat == IsNewDbgInfoFormat,
|
|
"Parent function doesn't have the same debug-info format");
|
|
|
|
// Only validate if we are using the new format.
|
|
if (!IsNewDbgInfoFormat)
|
|
return RetVal;
|
|
|
|
// Match every DPMarker to every Instruction and vice versa, and
|
|
// verify that there are no invalid DPValues.
|
|
for (auto It = begin(); It != end(); ++It) {
|
|
if (!It->DbgMarker)
|
|
continue;
|
|
|
|
// Validate DebugProgramMarkers.
|
|
DPMarker *CurrentDebugMarker = It->DbgMarker;
|
|
|
|
// If this is a marker, it should match the instruction and vice versa.
|
|
TestFailure(CurrentDebugMarker->MarkedInstr == &*It,
|
|
"Debug Marker points to incorrect instruction?");
|
|
|
|
// Now validate any DPValues in the marker.
|
|
for (DPValue &DPV : CurrentDebugMarker->getDbgValueRange()) {
|
|
// Validate DebugProgramValues.
|
|
TestFailure(DPV.getMarker() == CurrentDebugMarker,
|
|
"Not pointing at correct next marker!");
|
|
|
|
// Verify that no DbgValues appear prior to PHIs.
|
|
TestFailure(
|
|
!isa<PHINode>(It),
|
|
"DebugProgramValues must not appear before PHI nodes in a block!");
|
|
}
|
|
}
|
|
|
|
// Except transiently when removing + re-inserting the block terminator, there
|
|
// should be no trailing DPValues.
|
|
TestFailure(!getTrailingDPValues(), "Trailing DPValues in block");
|
|
return RetVal;
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
void BasicBlock::dumpDbgValues() const {
|
|
for (auto &Inst : *this) {
|
|
if (!Inst.DbgMarker)
|
|
continue;
|
|
|
|
dbgs() << "@ " << Inst.DbgMarker << " ";
|
|
Inst.DbgMarker->dump();
|
|
};
|
|
}
|
|
#endif
|
|
|
|
void BasicBlock::setIsNewDbgInfoFormat(bool NewFlag) {
|
|
if (NewFlag && !IsNewDbgInfoFormat)
|
|
convertToNewDbgValues();
|
|
else if (!NewFlag && IsNewDbgInfoFormat)
|
|
convertFromNewDbgValues();
|
|
}
|
|
|
|
ValueSymbolTable *BasicBlock::getValueSymbolTable() {
|
|
if (Function *F = getParent())
|
|
return F->getValueSymbolTable();
|
|
return nullptr;
|
|
}
|
|
|
|
LLVMContext &BasicBlock::getContext() const {
|
|
return getType()->getContext();
|
|
}
|
|
|
|
template <> void llvm::invalidateParentIListOrdering(BasicBlock *BB) {
|
|
BB->invalidateOrders();
|
|
}
|
|
|
|
// Explicit instantiation of SymbolTableListTraits since some of the methods
|
|
// are not in the public header file...
|
|
template class llvm::SymbolTableListTraits<Instruction,
|
|
ilist_iterator_bits<true>>;
|
|
|
|
BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
|
|
BasicBlock *InsertBefore)
|
|
: Value(Type::getLabelTy(C), Value::BasicBlockVal),
|
|
IsNewDbgInfoFormat(false), Parent(nullptr) {
|
|
|
|
if (NewParent)
|
|
insertInto(NewParent, InsertBefore);
|
|
else
|
|
assert(!InsertBefore &&
|
|
"Cannot insert block before another block with no function!");
|
|
|
|
setName(Name);
|
|
if (NewParent)
|
|
setIsNewDbgInfoFormat(NewParent->IsNewDbgInfoFormat);
|
|
}
|
|
|
|
void BasicBlock::insertInto(Function *NewParent, BasicBlock *InsertBefore) {
|
|
assert(NewParent && "Expected a parent");
|
|
assert(!Parent && "Already has a parent");
|
|
|
|
setIsNewDbgInfoFormat(NewParent->IsNewDbgInfoFormat);
|
|
|
|
if (InsertBefore)
|
|
NewParent->insert(InsertBefore->getIterator(), this);
|
|
else
|
|
NewParent->insert(NewParent->end(), this);
|
|
}
|
|
|
|
BasicBlock::~BasicBlock() {
|
|
validateInstrOrdering();
|
|
|
|
// If the address of the block is taken and it is being deleted (e.g. because
|
|
// it is dead), this means that there is either a dangling constant expr
|
|
// hanging off the block, or an undefined use of the block (source code
|
|
// expecting the address of a label to keep the block alive even though there
|
|
// is no indirect branch). Handle these cases by zapping the BlockAddress
|
|
// nodes. There are no other possible uses at this point.
|
|
if (hasAddressTaken()) {
|
|
assert(!use_empty() && "There should be at least one blockaddress!");
|
|
Constant *Replacement =
|
|
ConstantInt::get(llvm::Type::getInt32Ty(getContext()), 1);
|
|
while (!use_empty()) {
|
|
BlockAddress *BA = cast<BlockAddress>(user_back());
|
|
BA->replaceAllUsesWith(ConstantExpr::getIntToPtr(Replacement,
|
|
BA->getType()));
|
|
BA->destroyConstant();
|
|
}
|
|
}
|
|
|
|
assert(getParent() == nullptr && "BasicBlock still linked into the program!");
|
|
dropAllReferences();
|
|
for (auto &Inst : *this) {
|
|
if (!Inst.DbgMarker)
|
|
continue;
|
|
Inst.DbgMarker->eraseFromParent();
|
|
}
|
|
InstList.clear();
|
|
}
|
|
|
|
void BasicBlock::setParent(Function *parent) {
|
|
// Set Parent=parent, updating instruction symtab entries as appropriate.
|
|
InstList.setSymTabObject(&Parent, parent);
|
|
}
|
|
|
|
iterator_range<filter_iterator<BasicBlock::const_iterator,
|
|
std::function<bool(const Instruction &)>>>
|
|
BasicBlock::instructionsWithoutDebug(bool SkipPseudoOp) const {
|
|
std::function<bool(const Instruction &)> Fn = [=](const Instruction &I) {
|
|
return !isa<DbgInfoIntrinsic>(I) &&
|
|
!(SkipPseudoOp && isa<PseudoProbeInst>(I));
|
|
};
|
|
return make_filter_range(*this, Fn);
|
|
}
|
|
|
|
iterator_range<
|
|
filter_iterator<BasicBlock::iterator, std::function<bool(Instruction &)>>>
|
|
BasicBlock::instructionsWithoutDebug(bool SkipPseudoOp) {
|
|
std::function<bool(Instruction &)> Fn = [=](Instruction &I) {
|
|
return !isa<DbgInfoIntrinsic>(I) &&
|
|
!(SkipPseudoOp && isa<PseudoProbeInst>(I));
|
|
};
|
|
return make_filter_range(*this, Fn);
|
|
}
|
|
|
|
filter_iterator<BasicBlock::const_iterator,
|
|
std::function<bool(const Instruction &)>>::difference_type
|
|
BasicBlock::sizeWithoutDebug() const {
|
|
return std::distance(instructionsWithoutDebug().begin(),
|
|
instructionsWithoutDebug().end());
|
|
}
|
|
|
|
void BasicBlock::removeFromParent() {
|
|
getParent()->getBasicBlockList().remove(getIterator());
|
|
}
|
|
|
|
iplist<BasicBlock>::iterator BasicBlock::eraseFromParent() {
|
|
return getParent()->getBasicBlockList().erase(getIterator());
|
|
}
|
|
|
|
void BasicBlock::moveBefore(SymbolTableList<BasicBlock>::iterator MovePos) {
|
|
getParent()->splice(MovePos, getParent(), getIterator());
|
|
}
|
|
|
|
void BasicBlock::moveAfter(BasicBlock *MovePos) {
|
|
MovePos->getParent()->splice(++MovePos->getIterator(), getParent(),
|
|
getIterator());
|
|
}
|
|
|
|
const Module *BasicBlock::getModule() const {
|
|
return getParent()->getParent();
|
|
}
|
|
|
|
const CallInst *BasicBlock::getTerminatingMustTailCall() const {
|
|
if (InstList.empty())
|
|
return nullptr;
|
|
const ReturnInst *RI = dyn_cast<ReturnInst>(&InstList.back());
|
|
if (!RI || RI == &InstList.front())
|
|
return nullptr;
|
|
|
|
const Instruction *Prev = RI->getPrevNode();
|
|
if (!Prev)
|
|
return nullptr;
|
|
|
|
if (Value *RV = RI->getReturnValue()) {
|
|
if (RV != Prev)
|
|
return nullptr;
|
|
|
|
// Look through the optional bitcast.
|
|
if (auto *BI = dyn_cast<BitCastInst>(Prev)) {
|
|
RV = BI->getOperand(0);
|
|
Prev = BI->getPrevNode();
|
|
if (!Prev || RV != Prev)
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
if (auto *CI = dyn_cast<CallInst>(Prev)) {
|
|
if (CI->isMustTailCall())
|
|
return CI;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
const CallInst *BasicBlock::getTerminatingDeoptimizeCall() const {
|
|
if (InstList.empty())
|
|
return nullptr;
|
|
auto *RI = dyn_cast<ReturnInst>(&InstList.back());
|
|
if (!RI || RI == &InstList.front())
|
|
return nullptr;
|
|
|
|
if (auto *CI = dyn_cast_or_null<CallInst>(RI->getPrevNode()))
|
|
if (Function *F = CI->getCalledFunction())
|
|
if (F->getIntrinsicID() == Intrinsic::experimental_deoptimize)
|
|
return CI;
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
const CallInst *BasicBlock::getPostdominatingDeoptimizeCall() const {
|
|
const BasicBlock* BB = this;
|
|
SmallPtrSet<const BasicBlock *, 8> Visited;
|
|
Visited.insert(BB);
|
|
while (auto *Succ = BB->getUniqueSuccessor()) {
|
|
if (!Visited.insert(Succ).second)
|
|
return nullptr;
|
|
BB = Succ;
|
|
}
|
|
return BB->getTerminatingDeoptimizeCall();
|
|
}
|
|
|
|
const Instruction *BasicBlock::getFirstMayFaultInst() const {
|
|
if (InstList.empty())
|
|
return nullptr;
|
|
for (const Instruction &I : *this)
|
|
if (isa<LoadInst>(I) || isa<StoreInst>(I) || isa<CallBase>(I))
|
|
return &I;
|
|
return nullptr;
|
|
}
|
|
|
|
const Instruction* BasicBlock::getFirstNonPHI() const {
|
|
for (const Instruction &I : *this)
|
|
if (!isa<PHINode>(I))
|
|
return &I;
|
|
return nullptr;
|
|
}
|
|
|
|
BasicBlock::const_iterator BasicBlock::getFirstNonPHIIt() const {
|
|
const Instruction *I = getFirstNonPHI();
|
|
BasicBlock::const_iterator It = I->getIterator();
|
|
// Set the head-inclusive bit to indicate that this iterator includes
|
|
// any debug-info at the start of the block. This is a no-op unless the
|
|
// appropriate CMake flag is set.
|
|
It.setHeadBit(true);
|
|
return It;
|
|
}
|
|
|
|
const Instruction *BasicBlock::getFirstNonPHIOrDbg(bool SkipPseudoOp) const {
|
|
for (const Instruction &I : *this) {
|
|
if (isa<PHINode>(I) || isa<DbgInfoIntrinsic>(I))
|
|
continue;
|
|
|
|
if (SkipPseudoOp && isa<PseudoProbeInst>(I))
|
|
continue;
|
|
|
|
return &I;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
const Instruction *
|
|
BasicBlock::getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp) const {
|
|
for (const Instruction &I : *this) {
|
|
if (isa<PHINode>(I) || isa<DbgInfoIntrinsic>(I))
|
|
continue;
|
|
|
|
if (I.isLifetimeStartOrEnd())
|
|
continue;
|
|
|
|
if (SkipPseudoOp && isa<PseudoProbeInst>(I))
|
|
continue;
|
|
|
|
return &I;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
BasicBlock::const_iterator BasicBlock::getFirstInsertionPt() const {
|
|
const Instruction *FirstNonPHI = getFirstNonPHI();
|
|
if (!FirstNonPHI)
|
|
return end();
|
|
|
|
const_iterator InsertPt = FirstNonPHI->getIterator();
|
|
if (InsertPt->isEHPad()) ++InsertPt;
|
|
// Set the head-inclusive bit to indicate that this iterator includes
|
|
// any debug-info at the start of the block. This is a no-op unless the
|
|
// appropriate CMake flag is set.
|
|
InsertPt.setHeadBit(true);
|
|
return InsertPt;
|
|
}
|
|
|
|
BasicBlock::const_iterator BasicBlock::getFirstNonPHIOrDbgOrAlloca() const {
|
|
const Instruction *FirstNonPHI = getFirstNonPHI();
|
|
if (!FirstNonPHI)
|
|
return end();
|
|
|
|
const_iterator InsertPt = FirstNonPHI->getIterator();
|
|
if (InsertPt->isEHPad())
|
|
++InsertPt;
|
|
|
|
if (isEntryBlock()) {
|
|
const_iterator End = end();
|
|
while (InsertPt != End &&
|
|
(isa<AllocaInst>(*InsertPt) || isa<DbgInfoIntrinsic>(*InsertPt) ||
|
|
isa<PseudoProbeInst>(*InsertPt))) {
|
|
if (const AllocaInst *AI = dyn_cast<AllocaInst>(&*InsertPt)) {
|
|
if (!AI->isStaticAlloca())
|
|
break;
|
|
}
|
|
++InsertPt;
|
|
}
|
|
}
|
|
return InsertPt;
|
|
}
|
|
|
|
void BasicBlock::dropAllReferences() {
|
|
for (Instruction &I : *this)
|
|
I.dropAllReferences();
|
|
}
|
|
|
|
const BasicBlock *BasicBlock::getSinglePredecessor() const {
|
|
const_pred_iterator PI = pred_begin(this), E = pred_end(this);
|
|
if (PI == E) return nullptr; // No preds.
|
|
const BasicBlock *ThePred = *PI;
|
|
++PI;
|
|
return (PI == E) ? ThePred : nullptr /*multiple preds*/;
|
|
}
|
|
|
|
const BasicBlock *BasicBlock::getUniquePredecessor() const {
|
|
const_pred_iterator PI = pred_begin(this), E = pred_end(this);
|
|
if (PI == E) return nullptr; // No preds.
|
|
const BasicBlock *PredBB = *PI;
|
|
++PI;
|
|
for (;PI != E; ++PI) {
|
|
if (*PI != PredBB)
|
|
return nullptr;
|
|
// The same predecessor appears multiple times in the predecessor list.
|
|
// This is OK.
|
|
}
|
|
return PredBB;
|
|
}
|
|
|
|
bool BasicBlock::hasNPredecessors(unsigned N) const {
|
|
return hasNItems(pred_begin(this), pred_end(this), N);
|
|
}
|
|
|
|
bool BasicBlock::hasNPredecessorsOrMore(unsigned N) const {
|
|
return hasNItemsOrMore(pred_begin(this), pred_end(this), N);
|
|
}
|
|
|
|
const BasicBlock *BasicBlock::getSingleSuccessor() const {
|
|
const_succ_iterator SI = succ_begin(this), E = succ_end(this);
|
|
if (SI == E) return nullptr; // no successors
|
|
const BasicBlock *TheSucc = *SI;
|
|
++SI;
|
|
return (SI == E) ? TheSucc : nullptr /* multiple successors */;
|
|
}
|
|
|
|
const BasicBlock *BasicBlock::getUniqueSuccessor() const {
|
|
const_succ_iterator SI = succ_begin(this), E = succ_end(this);
|
|
if (SI == E) return nullptr; // No successors
|
|
const BasicBlock *SuccBB = *SI;
|
|
++SI;
|
|
for (;SI != E; ++SI) {
|
|
if (*SI != SuccBB)
|
|
return nullptr;
|
|
// The same successor appears multiple times in the successor list.
|
|
// This is OK.
|
|
}
|
|
return SuccBB;
|
|
}
|
|
|
|
iterator_range<BasicBlock::phi_iterator> BasicBlock::phis() {
|
|
PHINode *P = empty() ? nullptr : dyn_cast<PHINode>(&*begin());
|
|
return make_range<phi_iterator>(P, nullptr);
|
|
}
|
|
|
|
void BasicBlock::removePredecessor(BasicBlock *Pred,
|
|
bool KeepOneInputPHIs) {
|
|
// Use hasNUsesOrMore to bound the cost of this assertion for complex CFGs.
|
|
assert((hasNUsesOrMore(16) || llvm::is_contained(predecessors(this), Pred)) &&
|
|
"Pred is not a predecessor!");
|
|
|
|
// Return early if there are no PHI nodes to update.
|
|
if (empty() || !isa<PHINode>(begin()))
|
|
return;
|
|
|
|
unsigned NumPreds = cast<PHINode>(front()).getNumIncomingValues();
|
|
for (PHINode &Phi : make_early_inc_range(phis())) {
|
|
Phi.removeIncomingValue(Pred, !KeepOneInputPHIs);
|
|
if (KeepOneInputPHIs)
|
|
continue;
|
|
|
|
// If we have a single predecessor, removeIncomingValue may have erased the
|
|
// PHI node itself.
|
|
if (NumPreds == 1)
|
|
continue;
|
|
|
|
// Try to replace the PHI node with a constant value.
|
|
if (Value *PhiConstant = Phi.hasConstantValue()) {
|
|
Phi.replaceAllUsesWith(PhiConstant);
|
|
Phi.eraseFromParent();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool BasicBlock::canSplitPredecessors() const {
|
|
const Instruction *FirstNonPHI = getFirstNonPHI();
|
|
if (isa<LandingPadInst>(FirstNonPHI))
|
|
return true;
|
|
// This is perhaps a little conservative because constructs like
|
|
// CleanupBlockInst are pretty easy to split. However, SplitBlockPredecessors
|
|
// cannot handle such things just yet.
|
|
if (FirstNonPHI->isEHPad())
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
bool BasicBlock::isLegalToHoistInto() const {
|
|
auto *Term = getTerminator();
|
|
// No terminator means the block is under construction.
|
|
if (!Term)
|
|
return true;
|
|
|
|
// If the block has no successors, there can be no instructions to hoist.
|
|
assert(Term->getNumSuccessors() > 0);
|
|
|
|
// Instructions should not be hoisted across special terminators, which may
|
|
// have side effects or return values.
|
|
return !Term->isSpecialTerminator();
|
|
}
|
|
|
|
bool BasicBlock::isEntryBlock() const {
|
|
const Function *F = getParent();
|
|
assert(F && "Block must have a parent function to use this API");
|
|
return this == &F->getEntryBlock();
|
|
}
|
|
|
|
BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName,
|
|
bool Before) {
|
|
if (Before)
|
|
return splitBasicBlockBefore(I, BBName);
|
|
|
|
assert(getTerminator() && "Can't use splitBasicBlock on degenerate BB!");
|
|
assert(I != InstList.end() &&
|
|
"Trying to get me to create degenerate basic block!");
|
|
|
|
BasicBlock *New = BasicBlock::Create(getContext(), BBName, getParent(),
|
|
this->getNextNode());
|
|
|
|
// Save DebugLoc of split point before invalidating iterator.
|
|
DebugLoc Loc = I->getStableDebugLoc();
|
|
// Move all of the specified instructions from the original basic block into
|
|
// the new basic block.
|
|
New->splice(New->end(), this, I, end());
|
|
|
|
// Add a branch instruction to the newly formed basic block.
|
|
BranchInst *BI = BranchInst::Create(New, this);
|
|
BI->setDebugLoc(Loc);
|
|
|
|
// Now we must loop through all of the successors of the New block (which
|
|
// _were_ the successors of the 'this' block), and update any PHI nodes in
|
|
// successors. If there were PHI nodes in the successors, then they need to
|
|
// know that incoming branches will be from New, not from Old (this).
|
|
//
|
|
New->replaceSuccessorsPhiUsesWith(this, New);
|
|
return New;
|
|
}
|
|
|
|
BasicBlock *BasicBlock::splitBasicBlockBefore(iterator I, const Twine &BBName) {
|
|
assert(getTerminator() &&
|
|
"Can't use splitBasicBlockBefore on degenerate BB!");
|
|
assert(I != InstList.end() &&
|
|
"Trying to get me to create degenerate basic block!");
|
|
|
|
assert((!isa<PHINode>(*I) || getSinglePredecessor()) &&
|
|
"cannot split on multi incoming phis");
|
|
|
|
BasicBlock *New = BasicBlock::Create(getContext(), BBName, getParent(), this);
|
|
// Save DebugLoc of split point before invalidating iterator.
|
|
DebugLoc Loc = I->getDebugLoc();
|
|
// Move all of the specified instructions from the original basic block into
|
|
// the new basic block.
|
|
New->splice(New->end(), this, begin(), I);
|
|
|
|
// Loop through all of the predecessors of the 'this' block (which will be the
|
|
// predecessors of the New block), replace the specified successor 'this'
|
|
// block to point at the New block and update any PHI nodes in 'this' block.
|
|
// If there were PHI nodes in 'this' block, the PHI nodes are updated
|
|
// to reflect that the incoming branches will be from the New block and not
|
|
// from predecessors of the 'this' block.
|
|
// Save predecessors to separate vector before modifying them.
|
|
SmallVector<BasicBlock *, 4> Predecessors;
|
|
for (BasicBlock *Pred : predecessors(this))
|
|
Predecessors.push_back(Pred);
|
|
for (BasicBlock *Pred : Predecessors) {
|
|
Instruction *TI = Pred->getTerminator();
|
|
TI->replaceSuccessorWith(this, New);
|
|
this->replacePhiUsesWith(Pred, New);
|
|
}
|
|
// Add a branch instruction from "New" to "this" Block.
|
|
BranchInst *BI = BranchInst::Create(this, New);
|
|
BI->setDebugLoc(Loc);
|
|
|
|
return New;
|
|
}
|
|
|
|
BasicBlock::iterator BasicBlock::erase(BasicBlock::iterator FromIt,
|
|
BasicBlock::iterator ToIt) {
|
|
return InstList.erase(FromIt, ToIt);
|
|
}
|
|
|
|
void BasicBlock::replacePhiUsesWith(BasicBlock *Old, BasicBlock *New) {
|
|
// N.B. This might not be a complete BasicBlock, so don't assume
|
|
// that it ends with a non-phi instruction.
|
|
for (Instruction &I : *this) {
|
|
PHINode *PN = dyn_cast<PHINode>(&I);
|
|
if (!PN)
|
|
break;
|
|
PN->replaceIncomingBlockWith(Old, New);
|
|
}
|
|
}
|
|
|
|
void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *Old,
|
|
BasicBlock *New) {
|
|
Instruction *TI = getTerminator();
|
|
if (!TI)
|
|
// Cope with being called on a BasicBlock that doesn't have a terminator
|
|
// yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this.
|
|
return;
|
|
for (BasicBlock *Succ : successors(TI))
|
|
Succ->replacePhiUsesWith(Old, New);
|
|
}
|
|
|
|
void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) {
|
|
this->replaceSuccessorsPhiUsesWith(this, New);
|
|
}
|
|
|
|
bool BasicBlock::isLandingPad() const {
|
|
return isa<LandingPadInst>(getFirstNonPHI());
|
|
}
|
|
|
|
const LandingPadInst *BasicBlock::getLandingPadInst() const {
|
|
return dyn_cast<LandingPadInst>(getFirstNonPHI());
|
|
}
|
|
|
|
std::optional<uint64_t> BasicBlock::getIrrLoopHeaderWeight() const {
|
|
const Instruction *TI = getTerminator();
|
|
if (MDNode *MDIrrLoopHeader =
|
|
TI->getMetadata(LLVMContext::MD_irr_loop)) {
|
|
MDString *MDName = cast<MDString>(MDIrrLoopHeader->getOperand(0));
|
|
if (MDName->getString().equals("loop_header_weight")) {
|
|
auto *CI = mdconst::extract<ConstantInt>(MDIrrLoopHeader->getOperand(1));
|
|
return std::optional<uint64_t>(CI->getValue().getZExtValue());
|
|
}
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
BasicBlock::iterator llvm::skipDebugIntrinsics(BasicBlock::iterator It) {
|
|
while (isa<DbgInfoIntrinsic>(It))
|
|
++It;
|
|
return It;
|
|
}
|
|
|
|
void BasicBlock::renumberInstructions() {
|
|
unsigned Order = 0;
|
|
for (Instruction &I : *this)
|
|
I.Order = Order++;
|
|
|
|
// Set the bit to indicate that the instruction order valid and cached.
|
|
BasicBlockBits Bits = getBasicBlockBits();
|
|
Bits.InstrOrderValid = true;
|
|
setBasicBlockBits(Bits);
|
|
|
|
NumInstrRenumberings++;
|
|
}
|
|
|
|
void BasicBlock::flushTerminatorDbgValues() {
|
|
// If we erase the terminator in a block, any DPValues will sink and "fall
|
|
// off the end", existing after any terminator that gets inserted. With
|
|
// dbg.value intrinsics we would just insert the terminator at end() and
|
|
// the dbg.values would come before the terminator. With DPValues, we must
|
|
// do this manually.
|
|
// To get out of this unfortunate form, whenever we insert a terminator,
|
|
// check whether there's anything trailing at the end and move those DPValues
|
|
// in front of the terminator.
|
|
|
|
// Do nothing if we're not in new debug-info format.
|
|
if (!IsNewDbgInfoFormat)
|
|
return;
|
|
|
|
// If there's no terminator, there's nothing to do.
|
|
Instruction *Term = getTerminator();
|
|
if (!Term)
|
|
return;
|
|
|
|
// Are there any dangling DPValues?
|
|
DPMarker *TrailingDPValues = getTrailingDPValues();
|
|
if (!TrailingDPValues)
|
|
return;
|
|
|
|
// Transfer DPValues from the trailing position onto the terminator.
|
|
Term->DbgMarker->absorbDebugValues(*TrailingDPValues, false);
|
|
deleteTrailingDPValues();
|
|
}
|
|
|
|
void BasicBlock::spliceDebugInfoEmptyBlock(BasicBlock::iterator Dest,
|
|
BasicBlock *Src,
|
|
BasicBlock::iterator First,
|
|
BasicBlock::iterator Last) {
|
|
// Imagine the folowing:
|
|
//
|
|
// bb1:
|
|
// dbg.value(...
|
|
// ret i32 0
|
|
//
|
|
// If an optimisation pass attempts to splice the contents of the block from
|
|
// BB1->begin() to BB1->getTerminator(), then the dbg.value will be
|
|
// transferred to the destination.
|
|
// However, in the "new" DPValue format for debug-info, that range is empty:
|
|
// begin() returns an iterator to the terminator, as there will only be a
|
|
// single instruction in the block. We must piece together from the bits set
|
|
// in the iterators whether there was the intention to transfer any debug
|
|
// info.
|
|
|
|
// If we're not in "new" debug-info format, do nothing.
|
|
if (!IsNewDbgInfoFormat)
|
|
return;
|
|
|
|
assert(First == Last);
|
|
bool InsertAtHead = Dest.getHeadBit();
|
|
bool ReadFromHead = First.getHeadBit();
|
|
|
|
// If the source block is completely empty, including no terminator, then
|
|
// transfer any trailing DPValues that are still hanging around. This can
|
|
// occur when a block is optimised away and the terminator has been moved
|
|
// somewhere else.
|
|
if (Src->empty()) {
|
|
assert(Dest != end() &&
|
|
"Transferring trailing DPValues to another trailing position");
|
|
DPMarker *SrcTrailingDPValues = Src->getTrailingDPValues();
|
|
if (!SrcTrailingDPValues)
|
|
return;
|
|
|
|
DPMarker *M = Dest->DbgMarker;
|
|
M->absorbDebugValues(*SrcTrailingDPValues, InsertAtHead);
|
|
Src->deleteTrailingDPValues();
|
|
return;
|
|
}
|
|
|
|
// There are instructions in this block; if the First iterator was
|
|
// with begin() / getFirstInsertionPt() then the caller intended debug-info
|
|
// at the start of the block to be transferred.
|
|
if (!Src->empty() && First == Src->begin() && ReadFromHead)
|
|
Dest->DbgMarker->absorbDebugValues(*First->DbgMarker, InsertAtHead);
|
|
|
|
return;
|
|
}
|
|
|
|
void BasicBlock::spliceDebugInfo(BasicBlock::iterator Dest, BasicBlock *Src,
|
|
BasicBlock::iterator First,
|
|
BasicBlock::iterator Last) {
|
|
/* Do a quick normalisation before calling the real splice implementation. We
|
|
might be operating on a degenerate basic block that has no instructions
|
|
in it, a legitimate transient state. In that case, Dest will be end() and
|
|
any DPValues temporarily stored in the TrailingDPValues map in LLVMContext.
|
|
We might illustrate it thus:
|
|
|
|
Dest
|
|
|
|
|
this-block: ~~~~~~~~
|
|
Src-block: ++++B---B---B---B:::C
|
|
| |
|
|
First Last
|
|
|
|
However: does the caller expect the "~" DPValues to end up before or after
|
|
the spliced segment? This is communciated in the "Head" bit of Dest, which
|
|
signals whether the caller called begin() or end() on this block.
|
|
|
|
If the head bit is set, then all is well, we leave DPValues trailing just
|
|
like how dbg.value instructions would trail after instructions spliced to
|
|
the beginning of this block.
|
|
|
|
If the head bit isn't set, then try to jam the "~" DPValues onto the front
|
|
of the First instruction, then splice like normal, which joins the "~"
|
|
DPValues with the "+" DPValues. However if the "+" DPValues are supposed to
|
|
be left behind in Src, then:
|
|
* detach the "+" DPValues,
|
|
* move the "~" DPValues onto First,
|
|
* splice like normal,
|
|
* replace the "+" DPValues onto the Last position.
|
|
Complicated, but gets the job done. */
|
|
|
|
// If we're inserting at end(), and not in front of dangling DPValues, then
|
|
// move the DPValues onto "First". They'll then be moved naturally in the
|
|
// splice process.
|
|
DPMarker *MoreDanglingDPValues = nullptr;
|
|
DPMarker *OurTrailingDPValues = getTrailingDPValues();
|
|
if (Dest == end() && !Dest.getHeadBit() && OurTrailingDPValues) {
|
|
// Are the "+" DPValues not supposed to move? If so, detach them
|
|
// temporarily.
|
|
if (!First.getHeadBit() && First->hasDbgValues()) {
|
|
MoreDanglingDPValues = Src->getMarker(First);
|
|
MoreDanglingDPValues->removeFromParent();
|
|
}
|
|
|
|
if (First->hasDbgValues()) {
|
|
DPMarker *CurMarker = Src->getMarker(First);
|
|
// Place them at the front, it would look like this:
|
|
// Dest
|
|
// |
|
|
// this-block:
|
|
// Src-block: ~~~~~~~~++++B---B---B---B:::C
|
|
// | |
|
|
// First Last
|
|
CurMarker->absorbDebugValues(*OurTrailingDPValues, true);
|
|
OurTrailingDPValues->eraseFromParent();
|
|
} else {
|
|
// No current marker, create one and absorb in. (FIXME: we can avoid an
|
|
// allocation in the future).
|
|
DPMarker *CurMarker = Src->createMarker(&*First);
|
|
CurMarker->absorbDebugValues(*OurTrailingDPValues, false);
|
|
OurTrailingDPValues->eraseFromParent();
|
|
}
|
|
deleteTrailingDPValues();
|
|
First.setHeadBit(true);
|
|
}
|
|
|
|
// Call the main debug-info-splicing implementation.
|
|
spliceDebugInfoImpl(Dest, Src, First, Last);
|
|
|
|
// Do we have some "+" DPValues hanging around that weren't supposed to move,
|
|
// and we detached to make things easier?
|
|
if (!MoreDanglingDPValues)
|
|
return;
|
|
|
|
// FIXME: we could avoid an allocation here sometimes.
|
|
DPMarker *LastMarker = Src->createMarker(Last);
|
|
LastMarker->absorbDebugValues(*MoreDanglingDPValues, true);
|
|
MoreDanglingDPValues->eraseFromParent();
|
|
}
|
|
|
|
void BasicBlock::spliceDebugInfoImpl(BasicBlock::iterator Dest, BasicBlock *Src,
|
|
BasicBlock::iterator First,
|
|
BasicBlock::iterator Last) {
|
|
// Find out where to _place_ these dbg.values; if InsertAtHead is specified,
|
|
// this will be at the start of Dest's debug value range, otherwise this is
|
|
// just Dest's marker.
|
|
bool InsertAtHead = Dest.getHeadBit();
|
|
bool ReadFromHead = First.getHeadBit();
|
|
// Use this flag to signal the abnormal case, where we don't want to copy the
|
|
// DPValues ahead of the "Last" position.
|
|
bool ReadFromTail = !Last.getTailBit();
|
|
|
|
/*
|
|
Here's an illustration of what we're about to do. We have two blocks, this
|
|
and Src, and two segments of list. Each instruction is marked by a capital
|
|
while potential DPValue debug-info is marked out by "-" characters and a few
|
|
other special characters (+:=) where I want to highlight what's going on.
|
|
|
|
Dest
|
|
|
|
|
this-block: A----A----A ====A----A----A----A---A---A
|
|
Src-block ++++B---B---B---B:::C
|
|
| |
|
|
First Last
|
|
|
|
The splice method is going to take all the instructions from First up to
|
|
(but not including) Last and insert them in _front_ of Dest, forming one
|
|
long list. All the DPValues attached to instructions _between_ First and
|
|
Last need no maintenence. However, we have to do special things with the
|
|
DPValues marked with the +:= characters. We only have three positions:
|
|
should the "+" DPValues be transferred, and if so to where? Do we move the
|
|
":" DPValues? Would they go in front of the "=" DPValues, or should the "="
|
|
DPValues go before "+" DPValues?
|
|
|
|
We're told which way it should be by the bits carried in the iterators. The
|
|
"Head" bit indicates whether the specified position is supposed to be at the
|
|
front of the attached DPValues (true) or not (false). The Tail bit is true
|
|
on the other end of a range: is the range intended to include DPValues up to
|
|
the end (false) or not (true).
|
|
|
|
FIXME: the tail bit doesn't need to be distinct from the head bit, we could
|
|
combine them.
|
|
|
|
Here are some examples of different configurations:
|
|
|
|
Dest.Head = true, First.Head = true, Last.Tail = false
|
|
|
|
this-block: A----A----A++++B---B---B---B:::====A----A----A----A---A---A
|
|
| |
|
|
First Dest
|
|
|
|
Wheras if we didn't want to read from the Src list,
|
|
|
|
Dest.Head = true, First.Head = false, Last.Tail = false
|
|
|
|
this-block: A----A----AB---B---B---B:::====A----A----A----A---A---A
|
|
| |
|
|
First Dest
|
|
|
|
Or if we didn't want to insert at the head of Dest:
|
|
|
|
Dest.Head = false, First.Head = false, Last.Tail = false
|
|
|
|
this-block: A----A----A====B---B---B---B:::A----A----A----A---A---A
|
|
| |
|
|
First Dest
|
|
|
|
Tests for these various configurations can be found in the unit test file
|
|
BasicBlockDbgInfoTest.cpp.
|
|
|
|
*/
|
|
|
|
// Detach the marker at Dest -- this lets us move the "====" DPValues around.
|
|
DPMarker *DestMarker = nullptr;
|
|
if (Dest != end()) {
|
|
DestMarker = getMarker(Dest);
|
|
DestMarker->removeFromParent();
|
|
createMarker(&*Dest);
|
|
}
|
|
|
|
// If we're moving the tail range of DPValues (":::"), absorb them into the
|
|
// front of the DPValues at Dest.
|
|
if (ReadFromTail && Src->getMarker(Last)) {
|
|
DPMarker *OntoDest = getMarker(Dest);
|
|
DPMarker *FromLast = Src->getMarker(Last);
|
|
OntoDest->absorbDebugValues(*FromLast, true);
|
|
}
|
|
|
|
// If we're _not_ reading from the head of First, i.e. the "++++" DPValues,
|
|
// move their markers onto Last. They remain in the Src block. No action
|
|
// needed.
|
|
if (!ReadFromHead) {
|
|
DPMarker *OntoLast = Src->createMarker(Last);
|
|
DPMarker *FromFirst = Src->createMarker(First);
|
|
OntoLast->absorbDebugValues(*FromFirst,
|
|
true); // Always insert at head of it.
|
|
}
|
|
|
|
// Finally, do something with the "====" DPValues we detached.
|
|
if (DestMarker) {
|
|
if (InsertAtHead) {
|
|
// Insert them at the end of the DPValues at Dest. The "::::" DPValues
|
|
// might be in front of them.
|
|
DPMarker *NewDestMarker = getMarker(Dest);
|
|
NewDestMarker->absorbDebugValues(*DestMarker, false);
|
|
} else {
|
|
// Insert them right at the start of the range we moved, ahead of First
|
|
// and the "++++" DPValues.
|
|
DPMarker *FirstMarker = getMarker(First);
|
|
FirstMarker->absorbDebugValues(*DestMarker, true);
|
|
}
|
|
DestMarker->eraseFromParent();
|
|
} else if (Dest == end() && !InsertAtHead) {
|
|
// In the rare circumstance where we insert at end(), and we did not
|
|
// generate the iterator with begin() / getFirstInsertionPt(), it means
|
|
// any trailing debug-info at the end of the block would "normally" have
|
|
// been pushed in front of "First". Move it there now.
|
|
DPMarker *FirstMarker = getMarker(First);
|
|
DPMarker *TrailingDPValues = getTrailingDPValues();
|
|
if (TrailingDPValues) {
|
|
FirstMarker->absorbDebugValues(*TrailingDPValues, true);
|
|
deleteTrailingDPValues();
|
|
}
|
|
}
|
|
}
|
|
|
|
void BasicBlock::splice(iterator Dest, BasicBlock *Src, iterator First,
|
|
iterator Last) {
|
|
assert(Src->IsNewDbgInfoFormat == IsNewDbgInfoFormat);
|
|
|
|
#ifdef EXPENSIVE_CHECKS
|
|
// Check that First is before Last.
|
|
auto FromBBEnd = Src->end();
|
|
for (auto It = First; It != Last; ++It)
|
|
assert(It != FromBBEnd && "FromBeginIt not before FromEndIt!");
|
|
#endif // EXPENSIVE_CHECKS
|
|
|
|
// Lots of horrible special casing for empty transfers: the dbg.values between
|
|
// two positions could be spliced in dbg.value mode.
|
|
if (First == Last) {
|
|
spliceDebugInfoEmptyBlock(Dest, Src, First, Last);
|
|
return;
|
|
}
|
|
|
|
// Handle non-instr debug-info specific juggling.
|
|
if (IsNewDbgInfoFormat)
|
|
spliceDebugInfo(Dest, Src, First, Last);
|
|
|
|
// And move the instructions.
|
|
getInstList().splice(Dest, Src->getInstList(), First, Last);
|
|
|
|
flushTerminatorDbgValues();
|
|
}
|
|
|
|
void BasicBlock::insertDPValueAfter(DPValue *DPV, Instruction *I) {
|
|
assert(IsNewDbgInfoFormat);
|
|
assert(I->getParent() == this);
|
|
|
|
iterator NextIt = std::next(I->getIterator());
|
|
DPMarker *NextMarker = getMarker(NextIt);
|
|
if (!NextMarker)
|
|
NextMarker = createMarker(NextIt);
|
|
NextMarker->insertDPValue(DPV, true);
|
|
}
|
|
|
|
void BasicBlock::insertDPValueBefore(DPValue *DPV,
|
|
InstListType::iterator Where) {
|
|
// We should never directly insert at the end of the block, new DPValues
|
|
// shouldn't be generated at times when there's no terminator.
|
|
assert(Where != end());
|
|
assert(Where->getParent() == this);
|
|
bool InsertAtHead = Where.getHeadBit();
|
|
Where->DbgMarker->insertDPValue(DPV, InsertAtHead);
|
|
}
|
|
|
|
DPMarker *BasicBlock::getNextMarker(Instruction *I) {
|
|
return getMarker(std::next(I->getIterator()));
|
|
}
|
|
|
|
DPMarker *BasicBlock::getMarker(InstListType::iterator It) {
|
|
if (It == end()) {
|
|
DPMarker *DPM = getTrailingDPValues();
|
|
return DPM;
|
|
}
|
|
return It->DbgMarker;
|
|
}
|
|
|
|
void BasicBlock::reinsertInstInDPValues(
|
|
Instruction *I, std::optional<DPValue::self_iterator> Pos) {
|
|
// "I" was originally removed from a position where it was
|
|
// immediately in front of Pos. Any DPValues on that position then "fell down"
|
|
// onto Pos. "I" has been re-inserted at the front of that wedge of DPValues,
|
|
// shuffle them around to represent the original positioning. To illustrate:
|
|
//
|
|
// Instructions: I1---I---I0
|
|
// DPValues: DDD DDD
|
|
//
|
|
// Instruction "I" removed,
|
|
//
|
|
// Instructions: I1------I0
|
|
// DPValues: DDDDDD
|
|
// ^Pos
|
|
//
|
|
// Instruction "I" re-inserted (now):
|
|
//
|
|
// Instructions: I1---I------I0
|
|
// DPValues: DDDDDD
|
|
// ^Pos
|
|
//
|
|
// After this method completes:
|
|
//
|
|
// Instructions: I1---I---I0
|
|
// DPValues: DDD DDD
|
|
|
|
// This happens if there were no DPValues on I0. Are there now DPValues there?
|
|
if (!Pos) {
|
|
DPMarker *NextMarker = getNextMarker(I);
|
|
if (!NextMarker)
|
|
return;
|
|
if (NextMarker->StoredDPValues.empty())
|
|
return;
|
|
// There are DPMarkers there now -- they fell down from "I".
|
|
DPMarker *ThisMarker = createMarker(I);
|
|
ThisMarker->absorbDebugValues(*NextMarker, false);
|
|
return;
|
|
}
|
|
|
|
// Is there even a range of DPValues to move?
|
|
DPMarker *DPM = (*Pos)->getMarker();
|
|
auto Range = make_range(DPM->StoredDPValues.begin(), (*Pos));
|
|
if (Range.begin() == Range.end())
|
|
return;
|
|
|
|
// Otherwise: splice.
|
|
DPMarker *ThisMarker = createMarker(I);
|
|
assert(ThisMarker->StoredDPValues.empty());
|
|
ThisMarker->absorbDebugValues(Range, *DPM, true);
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
/// In asserts builds, this checks the numbering. In non-asserts builds, it
|
|
/// is defined as a no-op inline function in BasicBlock.h.
|
|
void BasicBlock::validateInstrOrdering() const {
|
|
if (!isInstrOrderValid())
|
|
return;
|
|
const Instruction *Prev = nullptr;
|
|
for (const Instruction &I : *this) {
|
|
assert((!Prev || Prev->comesBefore(&I)) &&
|
|
"cached instruction ordering is incorrect");
|
|
Prev = &I;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void BasicBlock::setTrailingDPValues(DPMarker *foo) {
|
|
getContext().pImpl->setTrailingDPValues(this, foo);
|
|
}
|
|
|
|
DPMarker *BasicBlock::getTrailingDPValues() {
|
|
return getContext().pImpl->getTrailingDPValues(this);
|
|
}
|
|
|
|
void BasicBlock::deleteTrailingDPValues() {
|
|
getContext().pImpl->deleteTrailingDPValues(this);
|
|
}
|
|
|