10b57cec5SDimitry Andric //===- LowerWidenableCondition.cpp - Lower the guard intrinsic ---------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This pass lowers the llvm.widenable.condition intrinsic to default value 100b57cec5SDimitry Andric // which is i1 true. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/LowerWidenableCondition.h" 150b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 160b57cec5SDimitry Andric #include "llvm/IR/Function.h" 170b57cec5SDimitry Andric #include "llvm/IR/InstIterator.h" 180b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 190b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h" 200b57cec5SDimitry Andric #include "llvm/IR/Module.h" 210b57cec5SDimitry Andric #include "llvm/IR/PatternMatch.h" 220b57cec5SDimitry Andric #include "llvm/Transforms/Scalar.h" 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric using namespace llvm; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric static bool lowerWidenableCondition(Function &F) { 270b57cec5SDimitry Andric // Check if we can cheaply rule out the possibility of not having any work to 280b57cec5SDimitry Andric // do. 290b57cec5SDimitry Andric auto *WCDecl = F.getParent()->getFunction( 300b57cec5SDimitry Andric Intrinsic::getName(Intrinsic::experimental_widenable_condition)); 310b57cec5SDimitry Andric if (!WCDecl || WCDecl->use_empty()) 320b57cec5SDimitry Andric return false; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric using namespace llvm::PatternMatch; 350b57cec5SDimitry Andric SmallVector<CallInst *, 8> ToLower; 36*81ad6265SDimitry Andric // Traverse through the users of WCDecl. 37*81ad6265SDimitry Andric // This is presumably cheaper than traversing all instructions in the 38*81ad6265SDimitry Andric // function. 39*81ad6265SDimitry Andric for (auto *U : WCDecl->users()) 40*81ad6265SDimitry Andric if (auto *CI = dyn_cast<CallInst>(U)) 41*81ad6265SDimitry Andric if (CI->getFunction() == &F) 42*81ad6265SDimitry Andric ToLower.push_back(CI); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric if (ToLower.empty()) 450b57cec5SDimitry Andric return false; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric for (auto *CI : ToLower) { 480b57cec5SDimitry Andric CI->replaceAllUsesWith(ConstantInt::getTrue(CI->getContext())); 490b57cec5SDimitry Andric CI->eraseFromParent(); 500b57cec5SDimitry Andric } 510b57cec5SDimitry Andric return true; 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric PreservedAnalyses LowerWidenableConditionPass::run(Function &F, 550b57cec5SDimitry Andric FunctionAnalysisManager &AM) { 560b57cec5SDimitry Andric if (lowerWidenableCondition(F)) 570b57cec5SDimitry Andric return PreservedAnalyses::none(); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric return PreservedAnalyses::all(); 600b57cec5SDimitry Andric } 61