63 #define DEBUG_TYPE "bool-ret-to-int" 66 "Number of times a bool feeding a RetInst was promoted to an int");
68 "Number of times a bool feeding a CallInst was promoted to an int");
70 "Total number of times a bool was promoted to an int");
78 while (!WorkList.
empty()) {
84 if (CurrUser && !isa<CallInst>(Curr))
85 for (
auto &
Op : CurrUser->operands())
97 if (
auto *
C = dyn_cast<Constant>(V))
99 if (
auto *
P = dyn_cast<PHINode>(V)) {
105 for (
unsigned i = 0; i <
P->getNumOperands(); ++i)
112 assert((A || I) &&
"Unknown value type");
115 A ? &*A->getParent()->getEntryBlock().begin() : I->getNextNode();
116 return new ZExtInst(V, IntTy,
"", InstPt);
129 static PHINodeSet getPromotablePHINodes(
const Function &
F) {
130 PHINodeSet Promotable;
134 if (
const auto *
P = dyn_cast<PHINode>(&I))
135 if (
P->getType()->isIntegerTy(1))
139 for (
const PHINode *
P : Promotable) {
141 auto IsValidUser = [] (
const Value *V) ->
bool {
142 return isa<ReturnInst>(V) || isa<CallInst>(V) || isa<PHINode>(V) ||
143 isa<DbgInfoIntrinsic>(V);
145 auto IsValidOperand = [] (
const Value *V) ->
bool {
146 return isa<Constant>(V) || isa<Argument>(V) || isa<CallInst>(V) ||
149 const auto &
Users =
P->users();
150 const auto &Operands =
P->operands();
157 auto IsPromotable = [&Promotable] (
const Value *V) ->
bool {
159 return !Phi || Promotable.count(Phi);
161 while (!ToRemove.
empty()) {
162 for (
auto &
User : ToRemove)
163 Promotable.erase(
User);
166 for (
const PHINode *
P : Promotable) {
168 const auto &
Users =
P->users();
169 const auto &Operands =
P->operands();
172 ToRemove.push_back(
P);
192 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
197 ST =
TM.getSubtargetImpl(F);
199 PHINodeSet PromotablePHINodes = getPromotablePHINodes(F);
201 bool Changed =
false;
204 if (
auto *R = dyn_cast<ReturnInst>(&I))
205 if (F.getReturnType()->isIntegerTy(1))
207 runOnUse(R->getOperandUse(0), PromotablePHINodes, Bool2IntMap);
209 if (
auto *CI = dyn_cast<CallInst>(&I))
210 for (
auto &U : CI->operands())
211 if (U->getType()->isIntegerTy(1))
212 Changed |= runOnUse(U, PromotablePHINodes, Bool2IntMap);
219 bool runOnUse(
Use &U,
const PHINodeSet &PromotablePHINodes,
220 B2IMap &BoolToIntMap) {
221 auto Defs = findAllDefs(U);
230 for (
Value *V : Defs)
231 if (!isa<PHINode>(V) && !isa<Constant>(V) &&
232 !isa<Argument>(V) && !isa<CallInst>(V))
235 for (
Value *V : Defs)
236 if (
const auto *
P = dyn_cast<PHINode>(V))
237 if (!PromotablePHINodes.count(
P))
240 if (isa<ReturnInst>(U.
getUser()))
241 ++NumBoolRetPromotion;
242 if (isa<CallInst>(U.
getUser()))
243 ++NumBoolCallPromotion;
244 ++NumBoolToIntPromotion;
246 for (
Value *V : Defs)
247 if (!BoolToIntMap.count(V))
248 BoolToIntMap[V] = translate(V);
252 for (
auto &Pair : BoolToIntMap) {
255 assert((!First || Second) &&
"translated from user to non-user!?");
258 if (First && !isa<CallInst>(First))
259 for (
unsigned i = 0; i < First->getNumOperands(); ++i)
260 Second->setOperand(i, BoolToIntMap[First->getOperand(i)]);
263 Value *IntRetVal = BoolToIntMap[U];
265 auto *I = cast<Instruction>(U.
getUser());
266 Value *BackToBool =
new TruncInst(IntRetVal, Int1Ty,
"backToBool", I);
285 "Convert i1 constants to i32/i64 if they are returned",
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static IntegerType * getInt1Ty(LLVMContext &C)
INITIALIZE_PASS(PPCBoolRetToInt, "bool-ret-to-int", "Convert i1 constants to i32/i64 if they are returned", false, false) FunctionPass *llvm
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents an incoming formal argument to a Function.
This class represents lattice values for constants.
This class represents zero extension of integer types.
void push_back(const T &Elt)
LLVMContext & getContext() const
All values hold a context through their type.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
STATISTIC(NumFunctions, "Total number of functions")
static IntegerType * getInt64Ty(LLVMContext &C)
iv Induction Variable Users
This defines the Use class.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A Use represents the edge between a Value definition and its users.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly...
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
FunctionPass * createPPCBoolRetToIntPass()
This class represents a truncation of integer types.
void initializePPCBoolRetToIntPass(PassRegistry &)
static bool runOnFunction(Function &F, bool PostInlining)
The instances of the Type class are immutable: once they are created, they are never changed...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Common code between 32-bit and 64-bit PowerPC targets.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static IntegerType * getInt32Ty(LLVMContext &C)
LLVM_NODISCARD bool empty() const
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Legacy analysis pass which computes a DominatorTree.