1 //===- LowerWidenableCondition.cpp - Lower the guard intrinsic ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass lowers the llvm.widenable.condition intrinsic to default value
10 // which is i1 true.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Transforms/Scalar/LowerWidenableCondition.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/InstIterator.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/IR/Module.h"
21 #include "llvm/IR/PatternMatch.h"
22 #include "llvm/InitializePasses.h"
23 #include "llvm/Pass.h"
24 #include "llvm/Transforms/Scalar.h"
25 
26 using namespace llvm;
27 
28 namespace {
29 struct LowerWidenableConditionLegacyPass : public FunctionPass {
30   static char ID;
31   LowerWidenableConditionLegacyPass() : FunctionPass(ID) {
32     initializeLowerWidenableConditionLegacyPassPass(
33         *PassRegistry::getPassRegistry());
34   }
35 
36   bool runOnFunction(Function &F) override;
37 };
38 }
39 
40 static bool lowerWidenableCondition(Function &F) {
41   // Check if we can cheaply rule out the possibility of not having any work to
42   // do.
43   auto *WCDecl = F.getParent()->getFunction(
44       Intrinsic::getName(Intrinsic::experimental_widenable_condition));
45   if (!WCDecl || WCDecl->use_empty())
46     return false;
47 
48   using namespace llvm::PatternMatch;
49   SmallVector<CallInst *, 8> ToLower;
50   // Traverse through the users of WCDecl.
51   // This is presumably cheaper than traversing all instructions in the
52   // function.
53   for (auto *U : WCDecl->users())
54     if (auto *CI = dyn_cast<CallInst>(U))
55       if (CI->getFunction() == &F)
56         ToLower.push_back(CI);
57 
58   if (ToLower.empty())
59     return false;
60 
61   for (auto *CI : ToLower) {
62     CI->replaceAllUsesWith(ConstantInt::getTrue(CI->getContext()));
63     CI->eraseFromParent();
64   }
65   return true;
66 }
67 
68 bool LowerWidenableConditionLegacyPass::runOnFunction(Function &F) {
69   return lowerWidenableCondition(F);
70 }
71 
72 char LowerWidenableConditionLegacyPass::ID = 0;
73 INITIALIZE_PASS(LowerWidenableConditionLegacyPass, "lower-widenable-condition",
74                 "Lower the widenable condition to default true value", false,
75                 false)
76 
77 Pass *llvm::createLowerWidenableConditionPass() {
78   return new LowerWidenableConditionLegacyPass();
79 }
80 
81 PreservedAnalyses LowerWidenableConditionPass::run(Function &F,
82                                                FunctionAnalysisManager &AM) {
83   if (lowerWidenableCondition(F))
84     return PreservedAnalyses::none();
85 
86   return PreservedAnalyses::all();
87 }
88