//===- 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 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(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(U) || isa(U); }); } void llvm::simpleSimplifyCFG(Function &F, ArrayRef 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 Visited(llvm::from_range, depth_first(&F.getEntryBlock())); SmallVector 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(); }