diff options
Diffstat (limited to 'contrib/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp | 80 |
1 files changed, 49 insertions, 31 deletions
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp b/contrib/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp index bfb4d87..93c201d 100644 --- a/contrib/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp +++ b/contrib/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp @@ -1,4 +1,4 @@ -//===- PPCBoolRetToInt.cpp - Convert bool literals to i32 if they are returned ==// +//===- PPCBoolRetToInt.cpp ------------------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -33,15 +33,26 @@ //===----------------------------------------------------------------------===// #include "PPC.h" -#include "llvm/Transforms/Scalar.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/IR/Argument.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/IR/OperandTraits.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Use.h" +#include "llvm/IR/User.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" #include "llvm/Pass.h" +#include <cassert> using namespace llvm; @@ -57,7 +68,6 @@ STATISTIC(NumBoolToIntPromotion, "Total number of times a bool was promoted to an int"); class PPCBoolRetToInt : public FunctionPass { - static SmallPtrSet<Value *, 8> findAllDefs(Value *V) { SmallPtrSet<Value *, 8> Defs; SmallVector<Value *, 8> WorkList; @@ -66,7 +76,10 @@ class PPCBoolRetToInt : public FunctionPass { while (!WorkList.empty()) { Value *Curr = WorkList.back(); WorkList.pop_back(); - if (User *CurrUser = dyn_cast<User>(Curr)) + auto *CurrUser = dyn_cast<User>(Curr); + // Operands of CallInst are skipped because they may not be Bool type, + // and their positions are defined by ABI. + if (CurrUser && !isa<CallInst>(Curr)) for (auto &Op : CurrUser->operands()) if (Defs.insert(Op).second) WorkList.push_back(Op); @@ -77,9 +90,9 @@ class PPCBoolRetToInt : public FunctionPass { // Translate a i1 value to an equivalent i32 value: static Value *translate(Value *V) { Type *Int32Ty = Type::getInt32Ty(V->getContext()); - if (Constant *C = dyn_cast<Constant>(V)) + if (auto *C = dyn_cast<Constant>(V)) return ConstantExpr::getZExt(C, Int32Ty); - if (PHINode *P = dyn_cast<PHINode>(V)) { + if (auto *P = dyn_cast<PHINode>(V)) { // Temporarily set the operands to 0. We'll fix this later in // runOnUse. Value *Zero = Constant::getNullValue(Int32Ty); @@ -90,8 +103,8 @@ class PPCBoolRetToInt : public FunctionPass { return Q; } - Argument *A = dyn_cast<Argument>(V); - Instruction *I = dyn_cast<Instruction>(V); + auto *A = dyn_cast<Argument>(V); + auto *I = dyn_cast<Instruction>(V); assert((A || I) && "Unknown value type"); auto InstPt = @@ -114,7 +127,7 @@ class PPCBoolRetToInt : public FunctionPass { // Condition 1 for (auto &BB : F) for (auto &I : BB) - if (const PHINode *P = dyn_cast<PHINode>(&I)) + if (const auto *P = dyn_cast<PHINode>(&I)) if (P->getType()->isIntegerTy(1)) Promotable.insert(P); @@ -131,14 +144,14 @@ class PPCBoolRetToInt : public FunctionPass { }; const auto &Users = P->users(); const auto &Operands = P->operands(); - if (!std::all_of(Users.begin(), Users.end(), IsValidUser) || - !std::all_of(Operands.begin(), Operands.end(), IsValidOperand)) + if (!llvm::all_of(Users, IsValidUser) || + !llvm::all_of(Operands, IsValidOperand)) ToRemove.push_back(P); } // Iterate to convergence auto IsPromotable = [&Promotable] (const Value *V) -> bool { - const PHINode *Phi = dyn_cast<PHINode>(V); + const auto *Phi = dyn_cast<PHINode>(V); return !Phi || Promotable.count(Phi); }; while (!ToRemove.empty()) { @@ -150,8 +163,8 @@ class PPCBoolRetToInt : public FunctionPass { // Condition 4 and 5 const auto &Users = P->users(); const auto &Operands = P->operands(); - if (!std::all_of(Users.begin(), Users.end(), IsPromotable) || - !std::all_of(Operands.begin(), Operands.end(), IsPromotable)) + if (!llvm::all_of(Users, IsPromotable) || + !llvm::all_of(Operands, IsPromotable)) ToRemove.push_back(P); } } @@ -163,11 +176,12 @@ class PPCBoolRetToInt : public FunctionPass { public: static char ID; + PPCBoolRetToInt() : FunctionPass(ID) { initializePPCBoolRetToIntPass(*PassRegistry::getPassRegistry()); } - bool runOnFunction(Function &F) { + bool runOnFunction(Function &F) override { if (skipFunction(F)) return false; @@ -176,12 +190,12 @@ class PPCBoolRetToInt : public FunctionPass { bool Changed = false; for (auto &BB : F) { for (auto &I : BB) { - if (ReturnInst *R = dyn_cast<ReturnInst>(&I)) + if (auto *R = dyn_cast<ReturnInst>(&I)) if (F.getReturnType()->isIntegerTy(1)) Changed |= runOnUse(R->getOperandUse(0), PromotablePHINodes, Bool2IntMap); - if (CallInst *CI = dyn_cast<CallInst>(&I)) + if (auto *CI = dyn_cast<CallInst>(&I)) for (auto &U : CI->operands()) if (U->getType()->isIntegerTy(1)) Changed |= runOnUse(U, PromotablePHINodes, Bool2IntMap); @@ -196,18 +210,19 @@ class PPCBoolRetToInt : public FunctionPass { auto Defs = findAllDefs(U); // If the values are all Constants or Arguments, don't bother - if (!std::any_of(Defs.begin(), Defs.end(), isa<Instruction, Value *>)) + if (llvm::none_of(Defs, isa<Instruction, Value *>)) return false; - // Presently, we only know how to handle PHINode, Constant, and Arguments. - // Potentially, bitwise operations (AND, OR, XOR, NOT) and sign extension - // could also be handled in the future. + // Presently, we only know how to handle PHINode, Constant, Arguments and + // CallInst. Potentially, bitwise operations (AND, OR, XOR, NOT) and sign + // extension could also be handled in the future. for (Value *V : Defs) - if (!isa<PHINode>(V) && !isa<Constant>(V) && !isa<Argument>(V)) + if (!isa<PHINode>(V) && !isa<Constant>(V) && + !isa<Argument>(V) && !isa<CallInst>(V)) return false; for (Value *V : Defs) - if (const PHINode *P = dyn_cast<PHINode>(V)) + if (const auto *P = dyn_cast<PHINode>(V)) if (!PromotablePHINodes.count(P)) return false; @@ -221,32 +236,35 @@ class PPCBoolRetToInt : public FunctionPass { if (!BoolToIntMap.count(V)) BoolToIntMap[V] = translate(V); - // Replace the operands of the translated instructions. There were set to + // Replace the operands of the translated instructions. They were set to // zero in the translate function. for (auto &Pair : BoolToIntMap) { - User *First = dyn_cast<User>(Pair.first); - User *Second = dyn_cast<User>(Pair.second); + auto *First = dyn_cast<User>(Pair.first); + auto *Second = dyn_cast<User>(Pair.second); assert((!First || Second) && "translated from user to non-user!?"); - if (First) + // Operands of CallInst are skipped because they may not be Bool type, + // and their positions are defined by ABI. + if (First && !isa<CallInst>(First)) for (unsigned i = 0; i < First->getNumOperands(); ++i) Second->setOperand(i, BoolToIntMap[First->getOperand(i)]); } Value *IntRetVal = BoolToIntMap[U]; Type *Int1Ty = Type::getInt1Ty(U->getContext()); - Instruction *I = cast<Instruction>(U.getUser()); + auto *I = cast<Instruction>(U.getUser()); Value *BackToBool = new TruncInst(IntRetVal, Int1Ty, "backToBool", I); U.set(BackToBool); return true; } - void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addPreserved<DominatorTreeWrapperPass>(); FunctionPass::getAnalysisUsage(AU); } }; -} + +} // end anonymous namespace char PPCBoolRetToInt::ID = 0; INITIALIZE_PASS(PPCBoolRetToInt, "bool-ret-to-int", |