62#define DEBUG_TYPE "ppc-bool-ret-to-int"
65 "Number of times a bool feeding a RetInst was promoted to an int");
67 "Number of times a bool feeding a CallInst was promoted to an int");
69 "Total number of times a bool was promoted to an int");
77 while (!WorkList.
empty()) {
79 auto *CurrUser = dyn_cast<User>(Curr);
82 if (CurrUser && !isa<CallInst>(Curr) && !isa<Constant>(Curr))
83 for (
auto &Op : CurrUser->operands())
84 if (Defs.
insert(Op).second)
93 "Expect an i1 value");
96 :
Type::getInt32Ty(
V->getContext());
98 if (
auto *
C = dyn_cast<Constant>(V))
100 if (
auto *
P = dyn_cast<PHINode>(V)) {
106 for (
unsigned i = 0; i <
P->getNumOperands(); ++i)
111 auto *
A = dyn_cast<Argument>(V);
112 auto *
I = dyn_cast<Instruction>(V);
113 assert((
A ||
I) &&
"Unknown value type");
116 A ? &*
A->getParent()->getEntryBlock().begin() :
I->getNextNode();
117 return new ZExtInst(V, IntTy,
"", InstPt);
130 static PHINodeSet getPromotablePHINodes(
const Function &
F) {
131 PHINodeSet Promotable;
135 if (
const auto *
P = dyn_cast<PHINode>(&
I))
136 if (
P->getType()->isIntegerTy(1))
140 for (
const PHINode *
P : Promotable) {
142 auto IsValidUser = [] (
const Value *
V) ->
bool {
143 return isa<ReturnInst>(V) || isa<CallInst>(V) || isa<PHINode>(V) ||
144 isa<DbgInfoIntrinsic>(V);
146 auto IsValidOperand = [] (
const Value *
V) ->
bool {
147 return isa<Constant>(V) || isa<Argument>(V) || isa<CallInst>(V) ||
150 const auto &
Users =
P->users();
158 auto IsPromotable = [&Promotable] (
const Value *
V) ->
bool {
159 const auto *Phi = dyn_cast<PHINode>(V);
160 return !Phi || Promotable.count(Phi);
164 Promotable.erase(
User);
167 for (
const PHINode *
P : Promotable) {
169 const auto &
Users =
P->users();
193 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
198 ST =
TM.getSubtargetImpl(
F);
200 PHINodeSet PromotablePHINodes = getPromotablePHINodes(
F);
202 bool Changed =
false;
205 if (
auto *R = dyn_cast<ReturnInst>(&
I))
206 if (
F.getReturnType()->isIntegerTy(1))
208 runOnUse(
R->getOperandUse(0), PromotablePHINodes, Bool2IntMap);
210 if (
auto *CI = dyn_cast<CallInst>(&
I))
211 for (
auto &U : CI->operands())
212 if (
U->getType()->isIntegerTy(1))
213 Changed |= runOnUse(U, PromotablePHINodes, Bool2IntMap);
220 bool runOnUse(
Use &U,
const PHINodeSet &PromotablePHINodes,
221 B2IMap &BoolToIntMap) {
222 auto Defs = findAllDefs(U);
231 for (
Value *V : Defs)
232 if (!isa<PHINode>(V) && !isa<Constant>(V) &&
233 !isa<Argument>(V) && !isa<CallInst>(V))
236 for (
Value *V : Defs)
237 if (
const auto *
P = dyn_cast<PHINode>(V))
238 if (!PromotablePHINodes.count(
P))
241 if (isa<ReturnInst>(
U.getUser()))
242 ++NumBoolRetPromotion;
243 if (isa<CallInst>(
U.getUser()))
244 ++NumBoolCallPromotion;
245 ++NumBoolToIntPromotion;
247 for (
Value *V : Defs)
248 if (!BoolToIntMap.count(V))
249 BoolToIntMap[V] = translate(V);
253 for (
auto &Pair : BoolToIntMap) {
254 auto *
First = dyn_cast<User>(Pair.first);
255 auto *Second = dyn_cast<User>(Pair.second);
256 assert((!First || Second) &&
"translated from user to non-user!?");
259 if (First && !isa<CallInst>(First) && !isa<Constant>(First))
260 for (
unsigned i = 0; i <
First->getNumOperands(); ++i)
261 Second->setOperand(i, BoolToIntMap[
First->getOperand(i)]);
264 Value *IntRetVal = BoolToIntMap[
U];
266 auto *
I = cast<Instruction>(
U.getUser());
284char PPCBoolRetToInt::ID = 0;
286 "Convert i1 constants to i32/i64 if they are returned",
false,
ReachingDefAnalysis InstSet & ToRemove
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
iv Induction Variable Users
mir Rename Register Operands
const char LLVMTargetMachineRef TM
#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.
This defines the Use class.
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 * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
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.
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="", Instruction *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.
This class represents zero extension of integer types.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
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.
void initializePPCBoolRetToIntPass(PassRegistry &)
FunctionPass * createPPCBoolRetToIntPass()