63#define DEBUG_TYPE "ppc-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()) {
80 auto *CurrUser = dyn_cast<User>(Curr);
83 if (CurrUser && !isa<CallInst>(Curr) && !isa<Constant>(Curr))
84 for (
auto &
Op : CurrUser->operands())
94 "Expect an i1 value");
97 :
Type::getInt32Ty(
V->getContext());
99 if (
auto *
P = dyn_cast<PHINode>(V)) {
105 for (
unsigned i = 0; i <
P->getNumOperands(); ++i)
111 if (
auto *
I = dyn_cast<Instruction>(V))
112 IRB.SetInsertPoint(
I->getNextNode());
114 IRB.SetInsertPoint(&
Func->getEntryBlock(),
Func->getEntryBlock().begin());
115 return IRB.CreateZExt(V, IntTy);
128 static PHINodeSet getPromotablePHINodes(
const Function &
F) {
129 PHINodeSet Promotable;
133 if (
const auto *
P = dyn_cast<PHINode>(&
I))
134 if (
P->getType()->isIntegerTy(1))
138 for (
const PHINode *
P : Promotable) {
140 auto IsValidUser = [] (
const Value *
V) ->
bool {
141 return isa<ReturnInst>(V) || isa<CallInst>(V) || isa<PHINode>(V) ||
142 isa<DbgInfoIntrinsic>(V);
144 auto IsValidOperand = [] (
const Value *
V) ->
bool {
145 return isa<Constant>(V) || isa<Argument>(V) || isa<CallInst>(V) ||
148 const auto &
Users =
P->users();
156 auto IsPromotable = [&Promotable] (
const Value *
V) ->
bool {
157 const auto *
Phi = dyn_cast<PHINode>(V);
158 return !
Phi || Promotable.count(Phi);
162 Promotable.erase(
User);
165 for (
const PHINode *
P : Promotable) {
167 const auto &
Users =
P->users();
191 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
196 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) {
253 auto *
First = dyn_cast<User>(Pair.first);
254 auto *Second = dyn_cast<User>(Pair.second);
255 assert((!
First || Second) &&
"translated from user to non-user!?");
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());
267 new TruncInst(IntRetVal, Int1Ty,
"backToBool",
I->getIterator());
285char PPCBoolRetToInt::ID = 0;
287 "Convert i1 constants to i32/i64 if they are returned",
false,
ReachingDefAnalysis InstSet & ToRemove
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This defines the Use class.
iv Induction Variable Users
mir Rename Register Operands
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Target-Independent Code Generator Pass Configuration Options pass.
Represent the analysis usage information of a pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
Legacy analysis pass which computes a DominatorTree.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
Common code between 32-bit and 64-bit PowerPC targets.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt1Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
NodeAddr< PhiNode * > Phi
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
void initializePPCBoolRetToIntPass(PassRegistry &)
FunctionPass * createPPCBoolRetToIntPass()