61#define DEBUG_TYPE "ppc-bool-ret-to-int"
64 "Number of times a bool feeding a RetInst was promoted to an int");
66 "Number of times a bool feeding a CallInst was promoted to an int");
68 "Total number of times a bool was promoted to an int");
76 while (!WorkList.
empty()) {
78 auto *CurrUser = dyn_cast<User>(Curr);
81 if (CurrUser && !isa<CallInst>(Curr) && !isa<Constant>(Curr))
82 for (
auto &
Op : CurrUser->operands())
92 "Expect an i1 value");
95 :
Type::getInt32Ty(
V->getContext());
97 if (
auto *
P = dyn_cast<PHINode>(V)) {
103 for (
unsigned i = 0; i <
P->getNumOperands(); ++i)
109 if (
auto *
I = dyn_cast<Instruction>(V))
110 IRB.SetInsertPoint(
I->getNextNode());
112 IRB.SetInsertPoint(&
Func->getEntryBlock(),
Func->getEntryBlock().begin());
113 return IRB.CreateZExt(V, IntTy);
126 static PHINodeSet getPromotablePHINodes(
const Function &
F) {
127 PHINodeSet Promotable;
131 if (
const auto *
P = dyn_cast<PHINode>(&
I))
132 if (
P->getType()->isIntegerTy(1))
136 for (
const PHINode *
P : Promotable) {
138 auto IsValidUser = [] (
const Value *
V) ->
bool {
139 return isa<ReturnInst>(V) || isa<CallInst>(V) || isa<PHINode>(V) ||
140 isa<DbgInfoIntrinsic>(V);
142 auto IsValidOperand = [] (
const Value *
V) ->
bool {
143 return isa<Constant>(V) || isa<Argument>(V) || isa<CallInst>(V) ||
146 const auto &
Users =
P->users();
154 auto IsPromotable = [&Promotable] (
const Value *
V) ->
bool {
155 const auto *
Phi = dyn_cast<PHINode>(V);
156 return !
Phi || Promotable.count(Phi);
160 Promotable.erase(
User);
163 for (
const PHINode *
P : Promotable) {
165 const auto &
Users =
P->users();
189 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
194 ST =
TM.getSubtargetImpl(
F);
197 PHINodeSet PromotablePHINodes = getPromotablePHINodes(
F);
199 bool Changed =
false;
202 if (
auto *R = dyn_cast<ReturnInst>(&
I))
203 if (
F.getReturnType()->isIntegerTy(1))
205 runOnUse(
R->getOperandUse(0), PromotablePHINodes, Bool2IntMap);
207 if (
auto *CI = dyn_cast<CallInst>(&
I))
208 for (
auto &U : CI->operands())
209 if (
U->getType()->isIntegerTy(1))
210 Changed |= runOnUse(U, PromotablePHINodes, Bool2IntMap);
217 bool runOnUse(
Use &U,
const PHINodeSet &PromotablePHINodes,
218 B2IMap &BoolToIntMap) {
219 auto Defs = findAllDefs(U);
228 for (
Value *V : Defs)
229 if (!isa<PHINode>(V) && !isa<Constant>(V) &&
230 !isa<Argument>(V) && !isa<CallInst>(V))
233 for (
Value *V : Defs)
234 if (
const auto *
P = dyn_cast<PHINode>(V))
235 if (!PromotablePHINodes.count(
P))
238 if (isa<ReturnInst>(
U.getUser()))
239 ++NumBoolRetPromotion;
240 if (isa<CallInst>(
U.getUser()))
241 ++NumBoolCallPromotion;
242 ++NumBoolToIntPromotion;
244 for (
Value *V : Defs)
245 if (!BoolToIntMap.count(V))
246 BoolToIntMap[V] = translate(V);
250 for (
auto &Pair : BoolToIntMap) {
251 auto *
First = dyn_cast<User>(Pair.first);
252 auto *Second = dyn_cast<User>(Pair.second);
253 assert((!
First || Second) &&
"translated from user to non-user!?");
257 for (
unsigned i = 0; i <
First->getNumOperands(); ++i)
258 Second->setOperand(i, BoolToIntMap[
First->getOperand(i)]);
261 Value *IntRetVal = BoolToIntMap[
U];
263 auto *
I = cast<Instruction>(
U.getUser());
265 new TruncInst(IntRetVal, Int1Ty,
"backToBool",
I->getIterator());
283char PPCBoolRetToInt::ID = 0;
285 "Convert i1 constants to i32/i64 if they are returned",
false,
ReachingDefAnalysis InstSet & ToRemove
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()