#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/ProfileInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/DIBuilder.h"
#include "llvm/DebugInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Operator.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
const TargetLibraryInfo *TLI) {
TerminatorInst *T = BB->getTerminator();
IRBuilder<> Builder(T);
if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
if (BI->isUnconditional()) return false; BasicBlock *Dest1 = BI->getSuccessor(0);
BasicBlock *Dest2 = BI->getSuccessor(1);
if (ConstantInt *Cond = dyn_cast<ConstantInt>(BI->getCondition())) {
BasicBlock *Destination = Cond->getZExtValue() ? Dest1 : Dest2;
BasicBlock *OldDest = Cond->getZExtValue() ? Dest2 : Dest1;
OldDest->removePredecessor(BB);
Builder.CreateBr(Destination);
BI->eraseFromParent();
return true;
}
if (Dest2 == Dest1) {
assert(BI->getParent() && "Terminator not inserted in block!");
Dest1->removePredecessor(BI->getParent());
Builder.CreateBr(Dest1);
Value *Cond = BI->getCondition();
BI->eraseFromParent();
if (DeleteDeadConditions)
RecursivelyDeleteTriviallyDeadInstructions(Cond, TLI);
return true;
}
return false;
}
if (SwitchInst *SI = dyn_cast<SwitchInst>(T)) {
ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition());
BasicBlock *TheOnlyDest = SI->getDefaultDest();
BasicBlock *DefaultDest = TheOnlyDest;
for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
i != e; ++i) {
if (i.getCaseValue() == CI) {
TheOnlyDest = i.getCaseSuccessor();
break;
}
if (i.getCaseSuccessor() == DefaultDest) {
MDNode* MD = SI->getMetadata(LLVMContext::MD_prof);
if (MD && MD->getNumOperands() == 2 + SI->getNumCases()) {
SmallVector<uint32_t, 8> Weights;
for (unsigned MD_i = 1, MD_e = MD->getNumOperands(); MD_i < MD_e;
++MD_i) {
ConstantInt* CI = dyn_cast<ConstantInt>(MD->getOperand(MD_i));
assert(CI);
Weights.push_back(CI->getValue().getZExtValue());
}
unsigned idx = i.getCaseIndex();
Weights[0] += Weights[idx+1];
std::swap(Weights[idx+1], Weights.back());
Weights.pop_back();
SI->setMetadata(LLVMContext::MD_prof,
MDBuilder(BB->getContext()).
createBranchWeights(Weights));
}
DefaultDest->removePredecessor(SI->getParent());
SI->removeCase(i);
--i; --e;
continue;
}
if (i.getCaseSuccessor() != TheOnlyDest) TheOnlyDest = 0;
}
if (CI && !TheOnlyDest) {
TheOnlyDest = SI->getDefaultDest();
}
if (TheOnlyDest) {
Builder.CreateBr(TheOnlyDest);
BasicBlock *BB = SI->getParent();
for (unsigned i = 0, e = SI->getNumSuccessors(); i != e; ++i) {
BasicBlock *Succ = SI->getSuccessor(i);
if (Succ == TheOnlyDest)
TheOnlyDest = 0; else
Succ->removePredecessor(BB);
}
Value *Cond = SI->getCondition();
SI->eraseFromParent();
if (DeleteDeadConditions)
RecursivelyDeleteTriviallyDeadInstructions(Cond, TLI);
return true;
}
if (SI->getNumCases() == 1) {
SwitchInst::CaseIt FirstCase = SI->case_begin();
IntegersSubset& Case = FirstCase.getCaseValueEx();
if (Case.isSingleNumber()) {
Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
Case.getSingleNumber(0).toConstantInt(),
"cond");
BranchInst *NewBr = Builder.CreateCondBr(Cond,
FirstCase.getCaseSuccessor(),
SI->getDefaultDest());
MDNode* MD = SI->getMetadata(LLVMContext::MD_prof);
if (MD && MD->getNumOperands() == 3) {
ConstantInt *SICase = dyn_cast<ConstantInt>(MD->getOperand(2));
ConstantInt *SIDef = dyn_cast<ConstantInt>(MD->getOperand(1));
assert(SICase && SIDef);
NewBr->setMetadata(LLVMContext::MD_prof,
MDBuilder(BB->getContext()).
createBranchWeights(SICase->getValue().getZExtValue(),
SIDef->getValue().getZExtValue()));
}
SI->eraseFromParent();
return true;
}
}
return false;
}
if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(T)) {
if (BlockAddress *BA =
dyn_cast<BlockAddress>(IBI->getAddress()->stripPointerCasts())) {
BasicBlock *TheOnlyDest = BA->getBasicBlock();
Builder.CreateBr(TheOnlyDest);
for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; ++i) {
if (IBI->getDestination(i) == TheOnlyDest)
TheOnlyDest = 0;
else
IBI->getDestination(i)->removePredecessor(IBI->getParent());
}
Value *Address = IBI->getAddress();
IBI->eraseFromParent();
if (DeleteDeadConditions)
RecursivelyDeleteTriviallyDeadInstructions(Address, TLI);
if (TheOnlyDest) {
BB->getTerminator()->eraseFromParent();
new UnreachableInst(BB->getContext(), BB);
}
return true;
}
}
return false;
}
bool llvm::isInstructionTriviallyDead(Instruction *I,
const TargetLibraryInfo *TLI) {
if (!I->use_empty() || isa<TerminatorInst>(I)) return false;
if (isa<LandingPadInst>(I))
return false;
if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) {
if (DDI->getAddress())
return false;
return true;
}
if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) {
if (DVI->getValue())
return false;
return true;
}
if (!I->mayHaveSideEffects()) return true;
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
if (II->getIntrinsicID() == Intrinsic::stacksave)
return true;
if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end)
return isa<UndefValue>(II->getArgOperand(1));
}
if (isAllocLikeFn(I, TLI)) return true;
if (CallInst *CI = isFreeCall(I, TLI))
if (Constant *C = dyn_cast<Constant>(CI->getArgOperand(0)))
return C->isNullValue() || isa<UndefValue>(C);
return false;
}
bool
llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V,
const TargetLibraryInfo *TLI) {
Instruction *I = dyn_cast<Instruction>(V);
if (!I || !I->use_empty() || !isInstructionTriviallyDead(I, TLI))
return false;
SmallVector<Instruction*, 16> DeadInsts;
DeadInsts.push_back(I);
do {
I = DeadInsts.pop_back_val();
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
Value *OpV = I->getOperand(i);
I->setOperand(i, 0);
if (!OpV->use_empty()) continue;
if (Instruction *OpI = dyn_cast<Instruction>(OpV))
if (isInstructionTriviallyDead(OpI, TLI))
DeadInsts.push_back(OpI);
}
I->eraseFromParent();
} while (!DeadInsts.empty());
return true;
}
static bool areAllUsesEqual(Instruction *I) {
Value::use_iterator UI = I->use_begin();
Value::use_iterator UE = I->use_end();
if (UI == UE)
return true;
User *TheUse = *UI;
for (++UI; UI != UE; ++UI) {
if (*UI != TheUse)
return false;
}
return true;
}
bool llvm::RecursivelyDeleteDeadPHINode(PHINode *PN,
const TargetLibraryInfo *TLI) {
SmallPtrSet<Instruction*, 4> Visited;
for (Instruction *I = PN; areAllUsesEqual(I) && !I->mayHaveSideEffects();
I = cast<Instruction>(*I->use_begin())) {
if (I->use_empty())
return RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
if (!Visited.insert(I)) {
I->replaceAllUsesWith(UndefValue::get(I->getType()));
(void)RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
return true;
}
}
return false;
}
bool llvm::SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
bool MadeChange = false;
#ifndef NDEBUG
AssertingVH<Instruction> TerminatorVH(--BB->end());
#endif
for (BasicBlock::iterator BI = BB->begin(), E = --BB->end(); BI != E; ) {
assert(!BI->isTerminator());
Instruction *Inst = BI++;
WeakVH BIHandle(BI);
if (recursivelySimplifyInstruction(Inst, TD)) {
MadeChange = true;
if (BIHandle != BI)
BI = BB->begin();
continue;
}
MadeChange |= RecursivelyDeleteTriviallyDeadInstructions(Inst, TLI);
if (BIHandle != BI)
BI = BB->begin();
}
return MadeChange;
}
void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
DataLayout *TD) {
if (!isa<PHINode>(BB->begin()))
return;
BB->removePredecessor(Pred, true);
WeakVH PhiIt = &BB->front();
while (PHINode *PN = dyn_cast<PHINode>(PhiIt)) {
PhiIt = &*++BasicBlock::iterator(cast<Instruction>(PhiIt));
Value *OldPhiIt = PhiIt;
if (!recursivelySimplifyInstruction(PN, TD))
continue;
if (PhiIt != OldPhiIt) PhiIt = &BB->front();
}
}
void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, Pass *P) {
while (PHINode *PN = dyn_cast<PHINode>(DestBB->begin())) {
Value *NewVal = PN->getIncomingValue(0);
if (NewVal == PN) NewVal = UndefValue::get(PN->getType());
PN->replaceAllUsesWith(NewVal);
PN->eraseFromParent();
}
BasicBlock *PredBB = DestBB->getSinglePredecessor();
assert(PredBB && "Block doesn't have a single predecessor!");
if (DestBB->hasAddressTaken()) {
BlockAddress *BA = BlockAddress::get(DestBB);
Constant *Replacement =
ConstantInt::get(llvm::Type::getInt32Ty(BA->getContext()), 1);
BA->replaceAllUsesWith(ConstantExpr::getIntToPtr(Replacement,
BA->getType()));
BA->destroyConstant();
}
PredBB->replaceAllUsesWith(DestBB);
PredBB->getTerminator()->eraseFromParent();
DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList());
if (P) {
DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>();
if (DT) {
BasicBlock *PredBBIDom = DT->getNode(PredBB)->getIDom()->getBlock();
DT->changeImmediateDominator(DestBB, PredBBIDom);
DT->eraseNode(PredBB);
}
ProfileInfo *PI = P->getAnalysisIfAvailable<ProfileInfo>();
if (PI) {
PI->replaceAllUses(PredBB, DestBB);
PI->removeEdge(ProfileInfo::getEdge(PredBB, DestBB));
}
}
PredBB->eraseFromParent();
}
static bool CanPropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
assert(*succ_begin(BB) == Succ && "Succ is not successor of BB!");
DEBUG(dbgs() << "Looking to fold " << BB->getName() << " into "
<< Succ->getName() << "\n");
if (Succ->getSinglePredecessor()) return true;
SmallPtrSet<BasicBlock*, 16> BBPreds(pred_begin(BB), pred_end(BB));
for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) {
PHINode *PN = cast<PHINode>(I);
PHINode *BBPN = dyn_cast<PHINode>(PN->getIncomingValueForBlock(BB));
if (BBPN && BBPN->getParent() == BB) {
for (unsigned PI = 0, PE = PN->getNumIncomingValues(); PI != PE; ++PI) {
BasicBlock *IBB = PN->getIncomingBlock(PI);
if (BBPreds.count(IBB) &&
BBPN->getIncomingValueForBlock(IBB) != PN->getIncomingValue(PI)) {
DEBUG(dbgs() << "Can't fold, phi node " << PN->getName() << " in "
<< Succ->getName() << " is conflicting with "
<< BBPN->getName() << " with regard to common predecessor "
<< IBB->getName() << "\n");
return false;
}
}
} else {
Value* Val = PN->getIncomingValueForBlock(BB);
for (unsigned PI = 0, PE = PN->getNumIncomingValues(); PI != PE; ++PI) {
BasicBlock *IBB = PN->getIncomingBlock(PI);
if (BBPreds.count(IBB) && Val != PN->getIncomingValue(PI)) {
DEBUG(dbgs() << "Can't fold, phi node " << PN->getName() << " in "
<< Succ->getName() << " is conflicting with regard to common "
<< "predecessor " << IBB->getName() << "\n");
return false;
}
}
}
}
return true;
}
bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB) {
assert(BB != &BB->getParent()->getEntryBlock() &&
"TryToSimplifyUncondBranchFromEmptyBlock called on entry block!");
BasicBlock *Succ = cast<BranchInst>(BB->getTerminator())->getSuccessor(0);
if (BB == Succ) return false;
if (!CanPropagatePredecessorsForPHIs(BB, Succ)) return false;
if (!Succ->getSinglePredecessor()) {
BasicBlock::iterator BBI = BB->begin();
while (isa<PHINode>(*BBI)) {
for (Value::use_iterator UI = BBI->use_begin(), E = BBI->use_end();
UI != E; ++UI) {
if (PHINode* PN = dyn_cast<PHINode>(*UI)) {
if (PN->getIncomingBlock(UI) != BB)
return false;
} else {
return false;
}
}
++BBI;
}
}
DEBUG(dbgs() << "Killing Trivial BB: \n" << *BB);
if (isa<PHINode>(Succ->begin())) {
const SmallVector<BasicBlock*, 16> BBPreds(pred_begin(BB), pred_end(BB));
for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) {
PHINode *PN = cast<PHINode>(I);
Value *OldVal = PN->removeIncomingValue(BB, false);
assert(OldVal && "No entry in PHI for Pred BB!");
if (isa<PHINode>(OldVal) && cast<PHINode>(OldVal)->getParent() == BB) {
PHINode *OldValPN = cast<PHINode>(OldVal);
for (unsigned i = 0, e = OldValPN->getNumIncomingValues(); i != e; ++i)
PN->addIncoming(OldValPN->getIncomingValue(i),
OldValPN->getIncomingBlock(i));
} else {
for (unsigned i = 0, e = BBPreds.size(); i != e; ++i)
PN->addIncoming(OldVal, BBPreds[i]);
}
}
}
if (Succ->getSinglePredecessor()) {
BB->getTerminator()->eraseFromParent();
Succ->getInstList().splice(Succ->getFirstNonPHI(), BB->getInstList());
} else {
while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {
assert(PN->use_empty() && "There shouldn't be any uses here!");
PN->eraseFromParent();
}
}
BB->replaceAllUsesWith(Succ);
if (!Succ->hasName()) Succ->takeName(BB);
BB->eraseFromParent(); return true;
}
bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
bool Changed = false;
DenseMap<uintptr_t, PHINode *> HashMap;
DenseMap<PHINode *, PHINode *> CollisionMap;
for (BasicBlock::iterator I = BB->begin();
PHINode *PN = dyn_cast<PHINode>(I++); ) {
uintptr_t Hash = 0;
for (User::op_iterator I = PN->op_begin(), E = PN->op_end(); I != E; ++I) {
Hash ^= reinterpret_cast<uintptr_t>(static_cast<Value *>(*I));
Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7));
}
for (PHINode::block_iterator I = PN->block_begin(), E = PN->block_end();
I != E; ++I) {
Hash ^= reinterpret_cast<uintptr_t>(static_cast<BasicBlock *>(*I));
Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7));
}
Hash >>= 1;
std::pair<DenseMap<uintptr_t, PHINode *>::iterator, bool> Pair =
HashMap.insert(std::make_pair(Hash, PN));
if (Pair.second) continue;
for (PHINode *OtherPN = Pair.first->second; ; ) {
if (OtherPN->isIdenticalTo(PN)) {
PN->replaceAllUsesWith(OtherPN);
PN->eraseFromParent();
Changed = true;
break;
}
DenseMap<PHINode *, PHINode *>::iterator I = CollisionMap.find(OtherPN);
if (I == CollisionMap.end()) {
PHINode *Old = Pair.first->second;
Pair.first->second = PN;
CollisionMap[PN] = Old;
break;
}
OtherPN = I->second;
}
}
return Changed;
}
static unsigned enforceKnownAlignment(Value *V, unsigned Align,
unsigned PrefAlign, const DataLayout *TD) {
V = V->stripPointerCasts();
if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
if (TD && TD->exceedsNaturalStackAlignment(PrefAlign))
return Align;
if (AI->getAlignment() >= PrefAlign)
return AI->getAlignment();
AI->setAlignment(PrefAlign);
return PrefAlign;
}
if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
if (GV->isDeclaration()) return Align;
if (GV->isWeakForLinker()) return Align;
if (GV->getAlignment() >= PrefAlign)
return GV->getAlignment();
if (!GV->hasSection() || GV->getAlignment() == 0)
GV->setAlignment(PrefAlign);
return GV->getAlignment();
}
return Align;
}
unsigned llvm::getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
const DataLayout *TD) {
assert(V->getType()->isPointerTy() &&
"getOrEnforceKnownAlignment expects a pointer!");
unsigned BitWidth = TD ? TD->getPointerSizeInBits() : 64;
APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
ComputeMaskedBits(V, KnownZero, KnownOne, TD);
unsigned TrailZ = KnownZero.countTrailingOnes();
TrailZ = std::min(TrailZ, unsigned(sizeof(unsigned) * CHAR_BIT - 1));
unsigned Align = 1u << std::min(BitWidth - 1, TrailZ);
Align = std::min(Align, +Value::MaximumAlignment);
if (PrefAlign > Align)
Align = enforceKnownAlignment(V, Align, PrefAlign, TD);
return Align;
}
static bool LdStHasDebugValue(DIVariable &DIVar, Instruction *I) {
llvm::BasicBlock::InstListType::iterator PrevI(I);
if (PrevI != I->getParent()->getInstList().begin()) {
--PrevI;
if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(PrevI))
if (DVI->getValue() == I->getOperand(0) &&
DVI->getOffset() == 0 &&
DVI->getVariable() == DIVar)
return true;
}
return false;
}
bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
StoreInst *SI, DIBuilder &Builder) {
DIVariable DIVar(DDI->getVariable());
if (!DIVar.Verify())
return false;
if (LdStHasDebugValue(DIVar, SI))
return true;
Instruction *DbgVal = NULL;
Argument *ExtendedArg = NULL;
if (ZExtInst *ZExt = dyn_cast<ZExtInst>(SI->getOperand(0)))
ExtendedArg = dyn_cast<Argument>(ZExt->getOperand(0));
if (SExtInst *SExt = dyn_cast<SExtInst>(SI->getOperand(0)))
ExtendedArg = dyn_cast<Argument>(SExt->getOperand(0));
if (ExtendedArg)
DbgVal = Builder.insertDbgValueIntrinsic(ExtendedArg, 0, DIVar, SI);
else
DbgVal = Builder.insertDbgValueIntrinsic(SI->getOperand(0), 0, DIVar, SI);
DebugLoc SIDL = SI->getDebugLoc();
if (!SIDL.isUnknown())
DbgVal->setDebugLoc(SIDL);
else
DbgVal->setDebugLoc(DDI->getDebugLoc());
return true;
}
bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
LoadInst *LI, DIBuilder &Builder) {
DIVariable DIVar(DDI->getVariable());
if (!DIVar.Verify())
return false;
if (LdStHasDebugValue(DIVar, LI))
return true;
Instruction *DbgVal =
Builder.insertDbgValueIntrinsic(LI->getOperand(0), 0,
DIVar, LI);
DebugLoc LIDL = LI->getDebugLoc();
if (!LIDL.isUnknown())
DbgVal->setDebugLoc(LIDL);
else
DbgVal->setDebugLoc(DDI->getDebugLoc());
return true;
}
bool llvm::LowerDbgDeclare(Function &F) {
DIBuilder DIB(*F.getParent());
SmallVector<DbgDeclareInst *, 4> Dbgs;
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) {
if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
Dbgs.push_back(DDI);
}
if (Dbgs.empty())
return false;
for (SmallVector<DbgDeclareInst *, 4>::iterator I = Dbgs.begin(),
E = Dbgs.end(); I != E; ++I) {
DbgDeclareInst *DDI = *I;
if (AllocaInst *AI = dyn_cast_or_null<AllocaInst>(DDI->getAddress())) {
bool RemoveDDI = true;
for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end();
UI != E; ++UI)
if (StoreInst *SI = dyn_cast<StoreInst>(*UI))
ConvertDebugDeclareToDebugValue(DDI, SI, DIB);
else if (LoadInst *LI = dyn_cast<LoadInst>(*UI))
ConvertDebugDeclareToDebugValue(DDI, LI, DIB);
else
RemoveDDI = false;
if (RemoveDDI)
DDI->eraseFromParent();
}
}
return true;
}
DbgDeclareInst *llvm::FindAllocaDbgDeclare(Value *V) {
if (MDNode *DebugNode = MDNode::getIfExists(V->getContext(), V))
for (Value::use_iterator UI = DebugNode->use_begin(),
E = DebugNode->use_end(); UI != E; ++UI)
if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(*UI))
return DDI;
return 0;
}
bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
DIBuilder &Builder) {
DbgDeclareInst *DDI = FindAllocaDbgDeclare(AI);
if (!DDI)
return false;
DIVariable DIVar(DDI->getVariable());
if (!DIVar.Verify())
return false;
Type *Int64Ty = Type::getInt64Ty(AI->getContext());
SmallVector<Value*, 4> NewDIVarAddress;
if (DIVar.hasComplexAddress()) {
for (unsigned i = 0, n = DIVar.getNumAddrElements(); i < n; ++i) {
NewDIVarAddress.push_back(
ConstantInt::get(Int64Ty, DIVar.getAddrElement(i)));
}
}
NewDIVarAddress.push_back(ConstantInt::get(Int64Ty, DIBuilder::OpDeref));
DIVariable NewDIVar = Builder.createComplexVariable(
DIVar.getTag(), DIVar.getContext(), DIVar.getName(),
DIVar.getFile(), DIVar.getLineNumber(), DIVar.getType(),
NewDIVarAddress, DIVar.getArgNumber());
BasicBlock *BB = AI->getParent();
Builder.insertDeclare(NewAllocaAddress, NewDIVar, BB);
DDI->eraseFromParent();
return true;
}
bool llvm::removeUnreachableBlocks(Function &F) {
SmallPtrSet<BasicBlock*, 16> Reachable;
SmallVector<BasicBlock*, 128> Worklist;
Worklist.push_back(&F.getEntryBlock());
Reachable.insert(&F.getEntryBlock());
do {
BasicBlock *BB = Worklist.pop_back_val();
for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
if (Reachable.insert(*SI))
Worklist.push_back(*SI);
} while (!Worklist.empty());
if (Reachable.size() == F.size())
return false;
assert(Reachable.size() < F.size());
for (Function::iterator I = llvm::next(F.begin()), E = F.end(); I != E; ++I) {
if (Reachable.count(I))
continue;
for (succ_iterator SI = succ_begin(I), SE = succ_end(I); SI != SE; ++SI)
if (Reachable.count(*SI))
(*SI)->removePredecessor(I);
while (!I->empty()) {
Instruction &Inst = I->back();
if (!Inst.use_empty())
Inst.replaceAllUsesWith(UndefValue::get(Inst.getType()));
I->getInstList().pop_back();
}
--I;
llvm::next(I)->eraseFromParent();
}
return true;
}