
Use splitBasicBlock and avoid directly dealing with the specific of how to trim the existing terminators. We just need to deal with unconditional branch to return.
83 lines
2.7 KiB
C++
83 lines
2.7 KiB
C++
//===- Utils.cpp - llvm-reduce utility functions --------------------------===//
|
|
//
|
|
// 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 contains some utility functions supporting llvm-reduce.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Utils.h"
|
|
#include "llvm/IR/Constants.h"
|
|
#include "llvm/IR/GlobalAlias.h"
|
|
#include "llvm/IR/GlobalIFunc.h"
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
|
#include "llvm/Transforms/Utils/Local.h"
|
|
|
|
using namespace llvm;
|
|
|
|
extern cl::OptionCategory LLVMReduceOptions;
|
|
|
|
cl::opt<bool> llvm::Verbose("verbose",
|
|
cl::desc("Print extra debugging information"),
|
|
cl::init(false), cl::cat(LLVMReduceOptions));
|
|
|
|
Value *llvm::getDefaultValue(Type *T) {
|
|
if (T->isVoidTy())
|
|
return PoisonValue::get(T);
|
|
|
|
if (auto *TET = dyn_cast<TargetExtType>(T)) {
|
|
if (TET->hasProperty(TargetExtType::HasZeroInit))
|
|
return ConstantTargetNone::get(TET);
|
|
return PoisonValue::get(TET);
|
|
}
|
|
|
|
return Constant::getNullValue(T);
|
|
}
|
|
|
|
bool llvm::hasAliasUse(Function &F) {
|
|
return any_of(F.users(), [](User *U) {
|
|
return isa<GlobalAlias>(U) || isa<GlobalIFunc>(U);
|
|
});
|
|
}
|
|
|
|
void llvm::simpleSimplifyCFG(Function &F, ArrayRef<BasicBlock *> BBs,
|
|
bool FoldBlockIntoPredecessor) {
|
|
|
|
for (BasicBlock *BB : BBs) {
|
|
ConstantFoldTerminator(BB);
|
|
if (FoldBlockIntoPredecessor)
|
|
MergeBlockIntoPredecessor(BB);
|
|
}
|
|
|
|
// Remove unreachable blocks
|
|
//
|
|
// removeUnreachableBlocks can't be used here, it will turn various undefined
|
|
// behavior into unreachables, but llvm-reduce was the thing that generated
|
|
// the undefined behavior, and we don't want it to kill the entire program.
|
|
SmallPtrSet<BasicBlock *, 16> Visited(llvm::from_range,
|
|
depth_first(&F.getEntryBlock()));
|
|
|
|
SmallVector<BasicBlock *, 16> Unreachable;
|
|
for (BasicBlock &BB : F) {
|
|
if (!Visited.count(&BB))
|
|
Unreachable.push_back(&BB);
|
|
}
|
|
|
|
// The dead BB's may be in a dead cycle or otherwise have references to each
|
|
// other. Because of this, we have to drop all references first, then delete
|
|
// them all at once.
|
|
for (BasicBlock *BB : Unreachable) {
|
|
for (BasicBlock *Successor : successors(&*BB))
|
|
if (Visited.count(Successor))
|
|
Successor->removePredecessor(&*BB, /*KeepOneInputPHIs=*/true);
|
|
BB->dropAllReferences();
|
|
}
|
|
|
|
for (BasicBlock *BB : Unreachable)
|
|
BB->eraseFromParent();
|
|
}
|