From: Chris Lattner Date: Thu, 1 Oct 2009 02:18:36 +0000 (+0000) Subject: remove the GVNPRE pass. It has been subsumed by the GVN pass. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=99be299edb6531cad64785196d65414b888e7453;p=oota-llvm.git remove the GVNPRE pass. It has been subsumed by the GVN pass. Ok'd by Owen. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83193 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index f5017116de0..5854fc0eab0 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -71,7 +71,6 @@ namespace { (void) llvm::createGlobalDCEPass(); (void) llvm::createGlobalOptimizerPass(); (void) llvm::createGlobalsModRefPass(); - (void) llvm::createGVNPREPass(); (void) llvm::createIPConstantPropagationPass(); (void) llvm::createIPSCCPPass(); (void) llvm::createIndVarSimplifyPass(); diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index d5d2e49a955..012f69b1615 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -283,13 +283,6 @@ extern const PassInfo *const LCSSAID; // FunctionPass *createPredicateSimplifierPass(); -//===----------------------------------------------------------------------===// -// -// GVN-PRE - This pass performs global value numbering and partial redundancy -// elimination. -// -FunctionPass *createGVNPREPass(); - //===----------------------------------------------------------------------===// // // GVN - This pass performs global value numbering and redundant load diff --git a/lib/Transforms/Scalar/GVNPRE.cpp b/lib/Transforms/Scalar/GVNPRE.cpp deleted file mode 100644 index b7462f2ac21..00000000000 --- a/lib/Transforms/Scalar/GVNPRE.cpp +++ /dev/null @@ -1,1893 +0,0 @@ -//===- GVNPRE.cpp - Eliminate redundant values and expressions ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass performs a hybrid of global value numbering and partial redundancy -// elimination, known as GVN-PRE. It performs partial redundancy elimination on -// values, rather than lexical expressions, allowing a more comprehensive view -// the optimization. It replaces redundant values with uses of earlier -// occurences of the same value. While this is beneficial in that it eliminates -// unneeded computation, it also increases register pressure by creating large -// live ranges, and should be used with caution on platforms that are very -// sensitive to register pressure. -// -// Note that this pass does the value numbering itself, it does not use the -// ValueNumbering analysis passes. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "gvnpre" -#include "llvm/Value.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Instructions.h" -#include "llvm/Function.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Analysis/Dominators.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DepthFirstIterator.h" -#include "llvm/ADT/PostOrderIterator.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" -#include "llvm/Support/CFG.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" -#include -#include -#include -using namespace llvm; - -//===----------------------------------------------------------------------===// -// ValueTable Class -//===----------------------------------------------------------------------===// - -namespace { - -/// This class holds the mapping between values and value numbers. It is used -/// as an efficient mechanism to determine the expression-wise equivalence of -/// two values. - -struct Expression { - enum ExpressionOpcode { ADD, FADD, SUB, FSUB, MUL, FMUL, - UDIV, SDIV, FDIV, UREM, SREM, - FREM, SHL, LSHR, ASHR, AND, OR, XOR, ICMPEQ, - ICMPNE, ICMPUGT, ICMPUGE, ICMPULT, ICMPULE, - ICMPSGT, ICMPSGE, ICMPSLT, ICMPSLE, FCMPOEQ, - FCMPOGT, FCMPOGE, FCMPOLT, FCMPOLE, FCMPONE, - FCMPORD, FCMPUNO, FCMPUEQ, FCMPUGT, FCMPUGE, - FCMPULT, FCMPULE, FCMPUNE, EXTRACT, INSERT, - SHUFFLE, SELECT, TRUNC, ZEXT, SEXT, FPTOUI, - FPTOSI, UITOFP, SITOFP, FPTRUNC, FPEXT, - PTRTOINT, INTTOPTR, BITCAST, GEP, EMPTY, - TOMBSTONE }; - - ExpressionOpcode opcode; - const Type* type; - uint32_t firstVN; - uint32_t secondVN; - uint32_t thirdVN; - SmallVector varargs; - - Expression() { } - explicit Expression(ExpressionOpcode o) : opcode(o) { } - - bool operator==(const Expression &other) const { - if (opcode != other.opcode) - return false; - else if (opcode == EMPTY || opcode == TOMBSTONE) - return true; - else if (type != other.type) - return false; - else if (firstVN != other.firstVN) - return false; - else if (secondVN != other.secondVN) - return false; - else if (thirdVN != other.thirdVN) - return false; - else { - if (varargs.size() != other.varargs.size()) - return false; - - for (size_t i = 0; i < varargs.size(); ++i) - if (varargs[i] != other.varargs[i]) - return false; - - return true; - } - } - - bool operator!=(const Expression &other) const { - if (opcode != other.opcode) - return true; - else if (opcode == EMPTY || opcode == TOMBSTONE) - return false; - else if (type != other.type) - return true; - else if (firstVN != other.firstVN) - return true; - else if (secondVN != other.secondVN) - return true; - else if (thirdVN != other.thirdVN) - return true; - else { - if (varargs.size() != other.varargs.size()) - return true; - - for (size_t i = 0; i < varargs.size(); ++i) - if (varargs[i] != other.varargs[i]) - return true; - - return false; - } - } -}; - -} - -namespace { - class ValueTable { - private: - DenseMap valueNumbering; - DenseMap expressionNumbering; - - uint32_t nextValueNumber; - - Expression::ExpressionOpcode getOpcode(BinaryOperator* BO); - Expression::ExpressionOpcode getOpcode(CmpInst* C); - Expression::ExpressionOpcode getOpcode(CastInst* C); - Expression create_expression(BinaryOperator* BO); - Expression create_expression(CmpInst* C); - Expression create_expression(ShuffleVectorInst* V); - Expression create_expression(ExtractElementInst* C); - Expression create_expression(InsertElementInst* V); - Expression create_expression(SelectInst* V); - Expression create_expression(CastInst* C); - Expression create_expression(GetElementPtrInst* G); - public: - ValueTable() { nextValueNumber = 1; } - uint32_t lookup_or_add(Value* V); - uint32_t lookup(Value* V) const; - void add(Value* V, uint32_t num); - void clear(); - void erase(Value* v); - unsigned size(); - }; -} - -namespace llvm { -template <> struct DenseMapInfo { - static inline Expression getEmptyKey() { - return Expression(Expression::EMPTY); - } - - static inline Expression getTombstoneKey() { - return Expression(Expression::TOMBSTONE); - } - - static unsigned getHashValue(const Expression e) { - unsigned hash = e.opcode; - - hash = e.firstVN + hash * 37; - hash = e.secondVN + hash * 37; - hash = e.thirdVN + hash * 37; - - hash = ((unsigned)((uintptr_t)e.type >> 4) ^ - (unsigned)((uintptr_t)e.type >> 9)) + - hash * 37; - - for (SmallVector::const_iterator I = e.varargs.begin(), - E = e.varargs.end(); I != E; ++I) - hash = *I + hash * 37; - - return hash; - } - static bool isEqual(const Expression &LHS, const Expression &RHS) { - return LHS == RHS; - } - static bool isPod() { return true; } -}; -} - -//===----------------------------------------------------------------------===// -// ValueTable Internal Functions -//===----------------------------------------------------------------------===// -Expression::ExpressionOpcode - ValueTable::getOpcode(BinaryOperator* BO) { - switch(BO->getOpcode()) { - case Instruction::Add: - return Expression::ADD; - case Instruction::FAdd: - return Expression::FADD; - case Instruction::Sub: - return Expression::SUB; - case Instruction::FSub: - return Expression::FSUB; - case Instruction::Mul: - return Expression::MUL; - case Instruction::FMul: - return Expression::FMUL; - case Instruction::UDiv: - return Expression::UDIV; - case Instruction::SDiv: - return Expression::SDIV; - case Instruction::FDiv: - return Expression::FDIV; - case Instruction::URem: - return Expression::UREM; - case Instruction::SRem: - return Expression::SREM; - case Instruction::FRem: - return Expression::FREM; - case Instruction::Shl: - return Expression::SHL; - case Instruction::LShr: - return Expression::LSHR; - case Instruction::AShr: - return Expression::ASHR; - case Instruction::And: - return Expression::AND; - case Instruction::Or: - return Expression::OR; - case Instruction::Xor: - return Expression::XOR; - - // THIS SHOULD NEVER HAPPEN - default: - llvm_unreachable("Binary operator with unknown opcode?"); - return Expression::ADD; - } -} - -Expression::ExpressionOpcode ValueTable::getOpcode(CmpInst* C) { - if (C->getOpcode() == Instruction::ICmp) { - switch (C->getPredicate()) { - case ICmpInst::ICMP_EQ: - return Expression::ICMPEQ; - case ICmpInst::ICMP_NE: - return Expression::ICMPNE; - case ICmpInst::ICMP_UGT: - return Expression::ICMPUGT; - case ICmpInst::ICMP_UGE: - return Expression::ICMPUGE; - case ICmpInst::ICMP_ULT: - return Expression::ICMPULT; - case ICmpInst::ICMP_ULE: - return Expression::ICMPULE; - case ICmpInst::ICMP_SGT: - return Expression::ICMPSGT; - case ICmpInst::ICMP_SGE: - return Expression::ICMPSGE; - case ICmpInst::ICMP_SLT: - return Expression::ICMPSLT; - case ICmpInst::ICMP_SLE: - return Expression::ICMPSLE; - - // THIS SHOULD NEVER HAPPEN - default: - llvm_unreachable("Comparison with unknown predicate?"); - return Expression::ICMPEQ; - } - } else { - switch (C->getPredicate()) { - case FCmpInst::FCMP_OEQ: - return Expression::FCMPOEQ; - case FCmpInst::FCMP_OGT: - return Expression::FCMPOGT; - case FCmpInst::FCMP_OGE: - return Expression::FCMPOGE; - case FCmpInst::FCMP_OLT: - return Expression::FCMPOLT; - case FCmpInst::FCMP_OLE: - return Expression::FCMPOLE; - case FCmpInst::FCMP_ONE: - return Expression::FCMPONE; - case FCmpInst::FCMP_ORD: - return Expression::FCMPORD; - case FCmpInst::FCMP_UNO: - return Expression::FCMPUNO; - case FCmpInst::FCMP_UEQ: - return Expression::FCMPUEQ; - case FCmpInst::FCMP_UGT: - return Expression::FCMPUGT; - case FCmpInst::FCMP_UGE: - return Expression::FCMPUGE; - case FCmpInst::FCMP_ULT: - return Expression::FCMPULT; - case FCmpInst::FCMP_ULE: - return Expression::FCMPULE; - case FCmpInst::FCMP_UNE: - return Expression::FCMPUNE; - - // THIS SHOULD NEVER HAPPEN - default: - llvm_unreachable("Comparison with unknown predicate?"); - return Expression::FCMPOEQ; - } - } -} - -Expression::ExpressionOpcode - ValueTable::getOpcode(CastInst* C) { - switch(C->getOpcode()) { - case Instruction::Trunc: - return Expression::TRUNC; - case Instruction::ZExt: - return Expression::ZEXT; - case Instruction::SExt: - return Expression::SEXT; - case Instruction::FPToUI: - return Expression::FPTOUI; - case Instruction::FPToSI: - return Expression::FPTOSI; - case Instruction::UIToFP: - return Expression::UITOFP; - case Instruction::SIToFP: - return Expression::SITOFP; - case Instruction::FPTrunc: - return Expression::FPTRUNC; - case Instruction::FPExt: - return Expression::FPEXT; - case Instruction::PtrToInt: - return Expression::PTRTOINT; - case Instruction::IntToPtr: - return Expression::INTTOPTR; - case Instruction::BitCast: - return Expression::BITCAST; - - // THIS SHOULD NEVER HAPPEN - default: - llvm_unreachable("Cast operator with unknown opcode?"); - return Expression::BITCAST; - } -} - -Expression ValueTable::create_expression(BinaryOperator* BO) { - Expression e; - - e.firstVN = lookup_or_add(BO->getOperand(0)); - e.secondVN = lookup_or_add(BO->getOperand(1)); - e.thirdVN = 0; - e.type = BO->getType(); - e.opcode = getOpcode(BO); - - return e; -} - -Expression ValueTable::create_expression(CmpInst* C) { - Expression e; - - e.firstVN = lookup_or_add(C->getOperand(0)); - e.secondVN = lookup_or_add(C->getOperand(1)); - e.thirdVN = 0; - e.type = C->getType(); - e.opcode = getOpcode(C); - - return e; -} - -Expression ValueTable::create_expression(CastInst* C) { - Expression e; - - e.firstVN = lookup_or_add(C->getOperand(0)); - e.secondVN = 0; - e.thirdVN = 0; - e.type = C->getType(); - e.opcode = getOpcode(C); - - return e; -} - -Expression ValueTable::create_expression(ShuffleVectorInst* S) { - Expression e; - - e.firstVN = lookup_or_add(S->getOperand(0)); - e.secondVN = lookup_or_add(S->getOperand(1)); - e.thirdVN = lookup_or_add(S->getOperand(2)); - e.type = S->getType(); - e.opcode = Expression::SHUFFLE; - - return e; -} - -Expression ValueTable::create_expression(ExtractElementInst* E) { - Expression e; - - e.firstVN = lookup_or_add(E->getOperand(0)); - e.secondVN = lookup_or_add(E->getOperand(1)); - e.thirdVN = 0; - e.type = E->getType(); - e.opcode = Expression::EXTRACT; - - return e; -} - -Expression ValueTable::create_expression(InsertElementInst* I) { - Expression e; - - e.firstVN = lookup_or_add(I->getOperand(0)); - e.secondVN = lookup_or_add(I->getOperand(1)); - e.thirdVN = lookup_or_add(I->getOperand(2)); - e.type = I->getType(); - e.opcode = Expression::INSERT; - - return e; -} - -Expression ValueTable::create_expression(SelectInst* I) { - Expression e; - - e.firstVN = lookup_or_add(I->getCondition()); - e.secondVN = lookup_or_add(I->getTrueValue()); - e.thirdVN = lookup_or_add(I->getFalseValue()); - e.type = I->getType(); - e.opcode = Expression::SELECT; - - return e; -} - -Expression ValueTable::create_expression(GetElementPtrInst* G) { - Expression e; - - e.firstVN = lookup_or_add(G->getPointerOperand()); - e.secondVN = 0; - e.thirdVN = 0; - e.type = G->getType(); - e.opcode = Expression::GEP; - - for (GetElementPtrInst::op_iterator I = G->idx_begin(), E = G->idx_end(); - I != E; ++I) - e.varargs.push_back(lookup_or_add(*I)); - - return e; -} - -//===----------------------------------------------------------------------===// -// ValueTable External Functions -//===----------------------------------------------------------------------===// - -/// lookup_or_add - Returns the value number for the specified value, assigning -/// it a new number if it did not have one before. -uint32_t ValueTable::lookup_or_add(Value* V) { - DenseMap::iterator VI = valueNumbering.find(V); - if (VI != valueNumbering.end()) - return VI->second; - - - if (BinaryOperator* BO = dyn_cast(V)) { - Expression e = create_expression(BO); - - DenseMap::iterator EI = expressionNumbering.find(e); - if (EI != expressionNumbering.end()) { - valueNumbering.insert(std::make_pair(V, EI->second)); - return EI->second; - } else { - expressionNumbering.insert(std::make_pair(e, nextValueNumber)); - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - - return nextValueNumber++; - } - } else if (CmpInst* C = dyn_cast(V)) { - Expression e = create_expression(C); - - DenseMap::iterator EI = expressionNumbering.find(e); - if (EI != expressionNumbering.end()) { - valueNumbering.insert(std::make_pair(V, EI->second)); - return EI->second; - } else { - expressionNumbering.insert(std::make_pair(e, nextValueNumber)); - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - - return nextValueNumber++; - } - } else if (ShuffleVectorInst* U = dyn_cast(V)) { - Expression e = create_expression(U); - - DenseMap::iterator EI = expressionNumbering.find(e); - if (EI != expressionNumbering.end()) { - valueNumbering.insert(std::make_pair(V, EI->second)); - return EI->second; - } else { - expressionNumbering.insert(std::make_pair(e, nextValueNumber)); - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - - return nextValueNumber++; - } - } else if (ExtractElementInst* U = dyn_cast(V)) { - Expression e = create_expression(U); - - DenseMap::iterator EI = expressionNumbering.find(e); - if (EI != expressionNumbering.end()) { - valueNumbering.insert(std::make_pair(V, EI->second)); - return EI->second; - } else { - expressionNumbering.insert(std::make_pair(e, nextValueNumber)); - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - - return nextValueNumber++; - } - } else if (InsertElementInst* U = dyn_cast(V)) { - Expression e = create_expression(U); - - DenseMap::iterator EI = expressionNumbering.find(e); - if (EI != expressionNumbering.end()) { - valueNumbering.insert(std::make_pair(V, EI->second)); - return EI->second; - } else { - expressionNumbering.insert(std::make_pair(e, nextValueNumber)); - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - - return nextValueNumber++; - } - } else if (SelectInst* U = dyn_cast(V)) { - Expression e = create_expression(U); - - DenseMap::iterator EI = expressionNumbering.find(e); - if (EI != expressionNumbering.end()) { - valueNumbering.insert(std::make_pair(V, EI->second)); - return EI->second; - } else { - expressionNumbering.insert(std::make_pair(e, nextValueNumber)); - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - - return nextValueNumber++; - } - } else if (CastInst* U = dyn_cast(V)) { - Expression e = create_expression(U); - - DenseMap::iterator EI = expressionNumbering.find(e); - if (EI != expressionNumbering.end()) { - valueNumbering.insert(std::make_pair(V, EI->second)); - return EI->second; - } else { - expressionNumbering.insert(std::make_pair(e, nextValueNumber)); - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - - return nextValueNumber++; - } - } else if (GetElementPtrInst* U = dyn_cast(V)) { - Expression e = create_expression(U); - - DenseMap::iterator EI = expressionNumbering.find(e); - if (EI != expressionNumbering.end()) { - valueNumbering.insert(std::make_pair(V, EI->second)); - return EI->second; - } else { - expressionNumbering.insert(std::make_pair(e, nextValueNumber)); - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - - return nextValueNumber++; - } - } else { - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - return nextValueNumber++; - } -} - -/// lookup - Returns the value number of the specified value. Fails if -/// the value has not yet been numbered. -uint32_t ValueTable::lookup(Value* V) const { - DenseMap::iterator VI = valueNumbering.find(V); - if (VI != valueNumbering.end()) - return VI->second; - else - llvm_unreachable("Value not numbered?"); - - return 0; -} - -/// add - Add the specified value with the given value number, removing -/// its old number, if any -void ValueTable::add(Value* V, uint32_t num) { - DenseMap::iterator VI = valueNumbering.find(V); - if (VI != valueNumbering.end()) - valueNumbering.erase(VI); - valueNumbering.insert(std::make_pair(V, num)); -} - -/// clear - Remove all entries from the ValueTable -void ValueTable::clear() { - valueNumbering.clear(); - expressionNumbering.clear(); - nextValueNumber = 1; -} - -/// erase - Remove a value from the value numbering -void ValueTable::erase(Value* V) { - valueNumbering.erase(V); -} - -/// size - Return the number of assigned value numbers -unsigned ValueTable::size() { - // NOTE: zero is never assigned - return nextValueNumber; -} - -namespace { - -//===----------------------------------------------------------------------===// -// ValueNumberedSet Class -//===----------------------------------------------------------------------===// - -class ValueNumberedSet { - private: - SmallPtrSet contents; - BitVector numbers; - public: - ValueNumberedSet() { numbers.resize(1); } - ValueNumberedSet(const ValueNumberedSet& other) { - numbers = other.numbers; - contents = other.contents; - } - - typedef SmallPtrSet::iterator iterator; - - iterator begin() { return contents.begin(); } - iterator end() { return contents.end(); } - - bool insert(Value* v) { return contents.insert(v); } - void insert(iterator I, iterator E) { contents.insert(I, E); } - void erase(Value* v) { contents.erase(v); } - unsigned count(Value* v) { return contents.count(v); } - size_t size() { return contents.size(); } - - void set(unsigned i) { - if (i >= numbers.size()) - numbers.resize(i+1); - - numbers.set(i); - } - - void operator=(const ValueNumberedSet& other) { - contents = other.contents; - numbers = other.numbers; - } - - void reset(unsigned i) { - if (i < numbers.size()) - numbers.reset(i); - } - - bool test(unsigned i) { - if (i >= numbers.size()) - return false; - - return numbers.test(i); - } - - void clear() { - contents.clear(); - numbers.clear(); - } -}; - -} - -//===----------------------------------------------------------------------===// -// GVNPRE Pass -//===----------------------------------------------------------------------===// - -namespace { - class GVNPRE : public FunctionPass { - bool runOnFunction(Function &F); - public: - static char ID; // Pass identification, replacement for typeid - GVNPRE() : FunctionPass(&ID) {} - - private: - ValueTable VN; - SmallVector createdExpressions; - - DenseMap availableOut; - DenseMap anticipatedIn; - DenseMap generatedPhis; - - // This transformation requires dominator postdominator info - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); - AU.addRequiredID(BreakCriticalEdgesID); - AU.addRequired(); - AU.addRequired(); - } - - // Helper fuctions - // FIXME: eliminate or document these better - void dump(ValueNumberedSet& s) const ; - void clean(ValueNumberedSet& set) ; - Value* find_leader(ValueNumberedSet& vals, uint32_t v) ; - Value* phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ) ; - void phi_translate_set(ValueNumberedSet& anticIn, BasicBlock* pred, - BasicBlock* succ, ValueNumberedSet& out) ; - - void topo_sort(ValueNumberedSet& set, - SmallVector& vec) ; - - void cleanup() ; - bool elimination() ; - - void val_insert(ValueNumberedSet& s, Value* v) ; - void val_replace(ValueNumberedSet& s, Value* v) ; - bool dependsOnInvoke(Value* V) ; - void buildsets_availout(BasicBlock::iterator I, - ValueNumberedSet& currAvail, - ValueNumberedSet& currPhis, - ValueNumberedSet& currExps, - SmallPtrSet& currTemps); - bool buildsets_anticout(BasicBlock* BB, - ValueNumberedSet& anticOut, - SmallPtrSet& visited); - unsigned buildsets_anticin(BasicBlock* BB, - ValueNumberedSet& anticOut, - ValueNumberedSet& currExps, - SmallPtrSet& currTemps, - SmallPtrSet& visited); - void buildsets(Function& F) ; - - void insertion_pre(Value* e, BasicBlock* BB, - DenseMap& avail, - std::map& new_set); - unsigned insertion_mergepoint(SmallVector& workList, - df_iterator& D, - std::map& new_set); - bool insertion(Function& F) ; - - }; - - char GVNPRE::ID = 0; - -} - -// createGVNPREPass - The public interface to this file... -FunctionPass *llvm::createGVNPREPass() { return new GVNPRE(); } - -static RegisterPass X("gvnpre", - "Global Value Numbering/Partial Redundancy Elimination"); - - -STATISTIC(NumInsertedVals, "Number of values inserted"); -STATISTIC(NumInsertedPhis, "Number of PHI nodes inserted"); -STATISTIC(NumEliminated, "Number of redundant instructions eliminated"); - -/// find_leader - Given a set and a value number, return the first -/// element of the set with that value number, or 0 if no such element -/// is present -Value* GVNPRE::find_leader(ValueNumberedSet& vals, uint32_t v) { - if (!vals.test(v)) - return 0; - - for (ValueNumberedSet::iterator I = vals.begin(), E = vals.end(); - I != E; ++I) - if (v == VN.lookup(*I)) - return *I; - - llvm_unreachable("No leader found, but present bit is set?"); - return 0; -} - -/// val_insert - Insert a value into a set only if there is not a value -/// with the same value number already in the set -void GVNPRE::val_insert(ValueNumberedSet& s, Value* v) { - uint32_t num = VN.lookup(v); - if (!s.test(num)) - s.insert(v); -} - -/// val_replace - Insert a value into a set, replacing any values already in -/// the set that have the same value number -void GVNPRE::val_replace(ValueNumberedSet& s, Value* v) { - if (s.count(v)) return; - - uint32_t num = VN.lookup(v); - Value* leader = find_leader(s, num); - if (leader != 0) - s.erase(leader); - s.insert(v); - s.set(num); -} - -/// phi_translate - Given a value, its parent block, and a predecessor of its -/// parent, translate the value into legal for the predecessor block. This -/// means translating its operands (and recursively, their operands) through -/// any phi nodes in the parent into values available in the predecessor -Value* GVNPRE::phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ) { - if (V == 0) - return 0; - - // Unary Operations - if (CastInst* U = dyn_cast(V)) { - Value* newOp1 = 0; - if (isa(U->getOperand(0))) - newOp1 = phi_translate(U->getOperand(0), pred, succ); - else - newOp1 = U->getOperand(0); - - if (newOp1 == 0) - return 0; - - if (newOp1 != U->getOperand(0)) { - Instruction* newVal = 0; - if (CastInst* C = dyn_cast(U)) - newVal = CastInst::Create(C->getOpcode(), - newOp1, C->getType(), - C->getName()+".expr"); - - uint32_t v = VN.lookup_or_add(newVal); - - Value* leader = find_leader(availableOut[pred], v); - if (leader == 0) { - createdExpressions.push_back(newVal); - return newVal; - } else { - VN.erase(newVal); - delete newVal; - return leader; - } - } - - // Binary Operations - } if (isa(V) || isa(V) || - isa(V)) { - User* U = cast(V); - - Value* newOp1 = 0; - if (isa(U->getOperand(0))) - newOp1 = phi_translate(U->getOperand(0), pred, succ); - else - newOp1 = U->getOperand(0); - - if (newOp1 == 0) - return 0; - - Value* newOp2 = 0; - if (isa(U->getOperand(1))) - newOp2 = phi_translate(U->getOperand(1), pred, succ); - else - newOp2 = U->getOperand(1); - - if (newOp2 == 0) - return 0; - - if (newOp1 != U->getOperand(0) || newOp2 != U->getOperand(1)) { - Instruction* newVal = 0; - if (BinaryOperator* BO = dyn_cast(U)) - newVal = BinaryOperator::Create(BO->getOpcode(), - newOp1, newOp2, - BO->getName()+".expr"); - else if (CmpInst* C = dyn_cast(U)) - newVal = CmpInst::Create(C->getOpcode(), - C->getPredicate(), - newOp1, newOp2, - C->getName()+".expr"); - else if (ExtractElementInst* E = dyn_cast(U)) - newVal = ExtractElementInst::Create(newOp1, newOp2, - E->getName()+".expr"); - - uint32_t v = VN.lookup_or_add(newVal); - - Value* leader = find_leader(availableOut[pred], v); - if (leader == 0) { - createdExpressions.push_back(newVal); - return newVal; - } else { - VN.erase(newVal); - delete newVal; - return leader; - } - } - - // Ternary Operations - } else if (isa(V) || isa(V) || - isa(V)) { - User* U = cast(V); - - Value* newOp1 = 0; - if (isa(U->getOperand(0))) - newOp1 = phi_translate(U->getOperand(0), pred, succ); - else - newOp1 = U->getOperand(0); - - if (newOp1 == 0) - return 0; - - Value* newOp2 = 0; - if (isa(U->getOperand(1))) - newOp2 = phi_translate(U->getOperand(1), pred, succ); - else - newOp2 = U->getOperand(1); - - if (newOp2 == 0) - return 0; - - Value* newOp3 = 0; - if (isa(U->getOperand(2))) - newOp3 = phi_translate(U->getOperand(2), pred, succ); - else - newOp3 = U->getOperand(2); - - if (newOp3 == 0) - return 0; - - if (newOp1 != U->getOperand(0) || - newOp2 != U->getOperand(1) || - newOp3 != U->getOperand(2)) { - Instruction* newVal = 0; - if (ShuffleVectorInst* S = dyn_cast(U)) - newVal = new ShuffleVectorInst(newOp1, newOp2, newOp3, - S->getName() + ".expr"); - else if (InsertElementInst* I = dyn_cast(U)) - newVal = InsertElementInst::Create(newOp1, newOp2, newOp3, - I->getName() + ".expr"); - else if (SelectInst* I = dyn_cast(U)) - newVal = SelectInst::Create(newOp1, newOp2, newOp3, - I->getName() + ".expr"); - - uint32_t v = VN.lookup_or_add(newVal); - - Value* leader = find_leader(availableOut[pred], v); - if (leader == 0) { - createdExpressions.push_back(newVal); - return newVal; - } else { - VN.erase(newVal); - delete newVal; - return leader; - } - } - - // Varargs operators - } else if (GetElementPtrInst* U = dyn_cast(V)) { - Value* newOp1 = 0; - if (isa(U->getPointerOperand())) - newOp1 = phi_translate(U->getPointerOperand(), pred, succ); - else - newOp1 = U->getPointerOperand(); - - if (newOp1 == 0) - return 0; - - bool changed_idx = false; - SmallVector newIdx; - for (GetElementPtrInst::op_iterator I = U->idx_begin(), E = U->idx_end(); - I != E; ++I) - if (isa(*I)) { - Value* newVal = phi_translate(*I, pred, succ); - newIdx.push_back(newVal); - if (newVal != *I) - changed_idx = true; - } else { - newIdx.push_back(*I); - } - - if (newOp1 != U->getPointerOperand() || changed_idx) { - Instruction* newVal = - GetElementPtrInst::Create(newOp1, - newIdx.begin(), newIdx.end(), - U->getName()+".expr"); - - uint32_t v = VN.lookup_or_add(newVal); - - Value* leader = find_leader(availableOut[pred], v); - if (leader == 0) { - createdExpressions.push_back(newVal); - return newVal; - } else { - VN.erase(newVal); - delete newVal; - return leader; - } - } - - // PHI Nodes - } else if (PHINode* P = dyn_cast(V)) { - if (P->getParent() == succ) - return P->getIncomingValueForBlock(pred); - } - - return V; -} - -/// phi_translate_set - Perform phi translation on every element of a set -void GVNPRE::phi_translate_set(ValueNumberedSet& anticIn, - BasicBlock* pred, BasicBlock* succ, - ValueNumberedSet& out) { - for (ValueNumberedSet::iterator I = anticIn.begin(), - E = anticIn.end(); I != E; ++I) { - Value* V = phi_translate(*I, pred, succ); - if (V != 0 && !out.test(VN.lookup_or_add(V))) { - out.insert(V); - out.set(VN.lookup(V)); - } - } -} - -/// dependsOnInvoke - Test if a value has an phi node as an operand, any of -/// whose inputs is an invoke instruction. If this is true, we cannot safely -/// PRE the instruction or anything that depends on it. -bool GVNPRE::dependsOnInvoke(Value* V) { - if (PHINode* p = dyn_cast(V)) { - for (PHINode::op_iterator I = p->op_begin(), E = p->op_end(); I != E; ++I) - if (isa(*I)) - return true; - return false; - } else { - return false; - } -} - -/// clean - Remove all non-opaque values from the set whose operands are not -/// themselves in the set, as well as all values that depend on invokes (see -/// above) -void GVNPRE::clean(ValueNumberedSet& set) { - SmallVector worklist; - worklist.reserve(set.size()); - topo_sort(set, worklist); - - for (unsigned i = 0; i < worklist.size(); ++i) { - Value* v = worklist[i]; - - // Handle unary ops - if (CastInst* U = dyn_cast(v)) { - bool lhsValid = !isa(U->getOperand(0)); - lhsValid |= set.test(VN.lookup(U->getOperand(0))); - if (lhsValid) - lhsValid = !dependsOnInvoke(U->getOperand(0)); - - if (!lhsValid) { - set.erase(U); - set.reset(VN.lookup(U)); - } - - // Handle binary ops - } else if (isa(v) || isa(v) || - isa(v)) { - User* U = cast(v); - - bool lhsValid = !isa(U->getOperand(0)); - lhsValid |= set.test(VN.lookup(U->getOperand(0))); - if (lhsValid) - lhsValid = !dependsOnInvoke(U->getOperand(0)); - - bool rhsValid = !isa(U->getOperand(1)); - rhsValid |= set.test(VN.lookup(U->getOperand(1))); - if (rhsValid) - rhsValid = !dependsOnInvoke(U->getOperand(1)); - - if (!lhsValid || !rhsValid) { - set.erase(U); - set.reset(VN.lookup(U)); - } - - // Handle ternary ops - } else if (isa(v) || isa(v) || - isa(v)) { - User* U = cast(v); - - bool lhsValid = !isa(U->getOperand(0)); - lhsValid |= set.test(VN.lookup(U->getOperand(0))); - if (lhsValid) - lhsValid = !dependsOnInvoke(U->getOperand(0)); - - bool rhsValid = !isa(U->getOperand(1)); - rhsValid |= set.test(VN.lookup(U->getOperand(1))); - if (rhsValid) - rhsValid = !dependsOnInvoke(U->getOperand(1)); - - bool thirdValid = !isa(U->getOperand(2)); - thirdValid |= set.test(VN.lookup(U->getOperand(2))); - if (thirdValid) - thirdValid = !dependsOnInvoke(U->getOperand(2)); - - if (!lhsValid || !rhsValid || !thirdValid) { - set.erase(U); - set.reset(VN.lookup(U)); - } - - // Handle varargs ops - } else if (GetElementPtrInst* U = dyn_cast(v)) { - bool ptrValid = !isa(U->getPointerOperand()); - ptrValid |= set.test(VN.lookup(U->getPointerOperand())); - if (ptrValid) - ptrValid = !dependsOnInvoke(U->getPointerOperand()); - - bool varValid = true; - for (GetElementPtrInst::op_iterator I = U->idx_begin(), E = U->idx_end(); - I != E; ++I) - if (varValid) { - varValid &= !isa(*I) || set.test(VN.lookup(*I)); - varValid &= !dependsOnInvoke(*I); - } - - if (!ptrValid || !varValid) { - set.erase(U); - set.reset(VN.lookup(U)); - } - } - } -} - -/// topo_sort - Given a set of values, sort them by topological -/// order into the provided vector. -void GVNPRE::topo_sort(ValueNumberedSet& set, SmallVector& vec) { - SmallPtrSet visited; - SmallVector stack; - for (ValueNumberedSet::iterator I = set.begin(), E = set.end(); - I != E; ++I) { - if (visited.count(*I) == 0) - stack.push_back(*I); - - while (!stack.empty()) { - Value* e = stack.back(); - - // Handle unary ops - if (CastInst* U = dyn_cast(e)) { - Value* l = find_leader(set, VN.lookup(U->getOperand(0))); - - if (l != 0 && isa(l) && - visited.count(l) == 0) - stack.push_back(l); - else { - vec.push_back(e); - visited.insert(e); - stack.pop_back(); - } - - // Handle binary ops - } else if (isa(e) || isa(e) || - isa(e)) { - User* U = cast(e); - Value* l = find_leader(set, VN.lookup(U->getOperand(0))); - Value* r = find_leader(set, VN.lookup(U->getOperand(1))); - - if (l != 0 && isa(l) && - visited.count(l) == 0) - stack.push_back(l); - else if (r != 0 && isa(r) && - visited.count(r) == 0) - stack.push_back(r); - else { - vec.push_back(e); - visited.insert(e); - stack.pop_back(); - } - - // Handle ternary ops - } else if (isa(e) || isa(e) || - isa(e)) { - User* U = cast(e); - Value* l = find_leader(set, VN.lookup(U->getOperand(0))); - Value* r = find_leader(set, VN.lookup(U->getOperand(1))); - Value* m = find_leader(set, VN.lookup(U->getOperand(2))); - - if (l != 0 && isa(l) && - visited.count(l) == 0) - stack.push_back(l); - else if (r != 0 && isa(r) && - visited.count(r) == 0) - stack.push_back(r); - else if (m != 0 && isa(m) && - visited.count(m) == 0) - stack.push_back(m); - else { - vec.push_back(e); - visited.insert(e); - stack.pop_back(); - } - - // Handle vararg ops - } else if (GetElementPtrInst* U = dyn_cast(e)) { - Value* p = find_leader(set, VN.lookup(U->getPointerOperand())); - - if (p != 0 && isa(p) && - visited.count(p) == 0) - stack.push_back(p); - else { - bool push_va = false; - for (GetElementPtrInst::op_iterator I = U->idx_begin(), - E = U->idx_end(); I != E; ++I) { - Value * v = find_leader(set, VN.lookup(*I)); - if (v != 0 && isa(v) && visited.count(v) == 0) { - stack.push_back(v); - push_va = true; - } - } - - if (!push_va) { - vec.push_back(e); - visited.insert(e); - stack.pop_back(); - } - } - - // Handle opaque ops - } else { - visited.insert(e); - vec.push_back(e); - stack.pop_back(); - } - } - - stack.clear(); - } -} - -/// dump - Dump a set of values to standard error -void GVNPRE::dump(ValueNumberedSet& s) const { - DEBUG(errs() << "{ "); - for (ValueNumberedSet::iterator I = s.begin(), E = s.end(); - I != E; ++I) { - DEBUG(errs() << "" << VN.lookup(*I) << ": "); - DEBUG((*I)->dump()); - } - DEBUG(errs() << "}\n\n"); -} - -/// elimination - Phase 3 of the main algorithm. Perform full redundancy -/// elimination by walking the dominator tree and removing any instruction that -/// is dominated by another instruction with the same value number. -bool GVNPRE::elimination() { - bool changed_function = false; - - SmallVector, 8> replace; - SmallVector erase; - - DominatorTree& DT = getAnalysis(); - - for (df_iterator DI = df_begin(DT.getRootNode()), - E = df_end(DT.getRootNode()); DI != E; ++DI) { - BasicBlock* BB = DI->getBlock(); - - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); - BI != BE; ++BI) { - - if (isa(BI) || isa(BI) || - isa(BI) || isa(BI) || - isa(BI) || isa(BI) || - isa(BI) || isa(BI)) { - - if (availableOut[BB].test(VN.lookup(BI)) && - !availableOut[BB].count(BI)) { - Value *leader = find_leader(availableOut[BB], VN.lookup(BI)); - if (Instruction* Instr = dyn_cast(leader)) - if (Instr->getParent() != 0 && Instr != BI) { - replace.push_back(std::make_pair(BI, leader)); - erase.push_back(BI); - ++NumEliminated; - } - } - } - } - } - - while (!replace.empty()) { - std::pair rep = replace.back(); - replace.pop_back(); - rep.first->replaceAllUsesWith(rep.second); - changed_function = true; - } - - for (SmallVector::iterator I = erase.begin(), - E = erase.end(); I != E; ++I) - (*I)->eraseFromParent(); - - return changed_function; -} - -/// cleanup - Delete any extraneous values that were created to represent -/// expressions without leaders. -void GVNPRE::cleanup() { - while (!createdExpressions.empty()) { - Instruction* I = createdExpressions.back(); - createdExpressions.pop_back(); - - delete I; - } -} - -/// buildsets_availout - When calculating availability, handle an instruction -/// by inserting it into the appropriate sets -void GVNPRE::buildsets_availout(BasicBlock::iterator I, - ValueNumberedSet& currAvail, - ValueNumberedSet& currPhis, - ValueNumberedSet& currExps, - SmallPtrSet& currTemps) { - // Handle PHI nodes - if (PHINode* p = dyn_cast(I)) { - unsigned num = VN.lookup_or_add(p); - - currPhis.insert(p); - currPhis.set(num); - - // Handle unary ops - } else if (CastInst* U = dyn_cast(I)) { - Value* leftValue = U->getOperand(0); - - unsigned num = VN.lookup_or_add(U); - - if (isa(leftValue)) - if (!currExps.test(VN.lookup(leftValue))) { - currExps.insert(leftValue); - currExps.set(VN.lookup(leftValue)); - } - - if (!currExps.test(num)) { - currExps.insert(U); - currExps.set(num); - } - - // Handle binary ops - } else if (isa(I) || isa(I) || - isa(I)) { - User* U = cast(I); - Value* leftValue = U->getOperand(0); - Value* rightValue = U->getOperand(1); - - unsigned num = VN.lookup_or_add(U); - - if (isa(leftValue)) - if (!currExps.test(VN.lookup(leftValue))) { - currExps.insert(leftValue); - currExps.set(VN.lookup(leftValue)); - } - - if (isa(rightValue)) - if (!currExps.test(VN.lookup(rightValue))) { - currExps.insert(rightValue); - currExps.set(VN.lookup(rightValue)); - } - - if (!currExps.test(num)) { - currExps.insert(U); - currExps.set(num); - } - - // Handle ternary ops - } else if (isa(I) || isa(I) || - isa(I)) { - User* U = cast(I); - Value* leftValue = U->getOperand(0); - Value* rightValue = U->getOperand(1); - Value* thirdValue = U->getOperand(2); - - VN.lookup_or_add(U); - - unsigned num = VN.lookup_or_add(U); - - if (isa(leftValue)) - if (!currExps.test(VN.lookup(leftValue))) { - currExps.insert(leftValue); - currExps.set(VN.lookup(leftValue)); - } - if (isa(rightValue)) - if (!currExps.test(VN.lookup(rightValue))) { - currExps.insert(rightValue); - currExps.set(VN.lookup(rightValue)); - } - if (isa(thirdValue)) - if (!currExps.test(VN.lookup(thirdValue))) { - currExps.insert(thirdValue); - currExps.set(VN.lookup(thirdValue)); - } - - if (!currExps.test(num)) { - currExps.insert(U); - currExps.set(num); - } - - // Handle vararg ops - } else if (GetElementPtrInst* U = dyn_cast(I)) { - Value* ptrValue = U->getPointerOperand(); - - VN.lookup_or_add(U); - - unsigned num = VN.lookup_or_add(U); - - if (isa(ptrValue)) - if (!currExps.test(VN.lookup(ptrValue))) { - currExps.insert(ptrValue); - currExps.set(VN.lookup(ptrValue)); - } - - for (GetElementPtrInst::op_iterator OI = U->idx_begin(), OE = U->idx_end(); - OI != OE; ++OI) - if (isa(*OI) && !currExps.test(VN.lookup(*OI))) { - currExps.insert(*OI); - currExps.set(VN.lookup(*OI)); - } - - if (!currExps.test(VN.lookup(U))) { - currExps.insert(U); - currExps.set(num); - } - - // Handle opaque ops - } else if (!I->isTerminator()){ - VN.lookup_or_add(I); - - currTemps.insert(I); - } - - if (!I->isTerminator()) - if (!currAvail.test(VN.lookup(I))) { - currAvail.insert(I); - currAvail.set(VN.lookup(I)); - } -} - -/// buildsets_anticout - When walking the postdom tree, calculate the ANTIC_OUT -/// set as a function of the ANTIC_IN set of the block's predecessors -bool GVNPRE::buildsets_anticout(BasicBlock* BB, - ValueNumberedSet& anticOut, - SmallPtrSet& visited) { - if (BB->getTerminator()->getNumSuccessors() == 1) { - if (BB->getTerminator()->getSuccessor(0) != BB && - visited.count(BB->getTerminator()->getSuccessor(0)) == 0) { - return true; - } - else { - phi_translate_set(anticipatedIn[BB->getTerminator()->getSuccessor(0)], - BB, BB->getTerminator()->getSuccessor(0), anticOut); - } - } else if (BB->getTerminator()->getNumSuccessors() > 1) { - BasicBlock* first = BB->getTerminator()->getSuccessor(0); - for (ValueNumberedSet::iterator I = anticipatedIn[first].begin(), - E = anticipatedIn[first].end(); I != E; ++I) { - anticOut.insert(*I); - anticOut.set(VN.lookup(*I)); - } - - for (unsigned i = 1; i < BB->getTerminator()->getNumSuccessors(); ++i) { - BasicBlock* currSucc = BB->getTerminator()->getSuccessor(i); - ValueNumberedSet& succAnticIn = anticipatedIn[currSucc]; - - SmallVector temp; - - for (ValueNumberedSet::iterator I = anticOut.begin(), - E = anticOut.end(); I != E; ++I) - if (!succAnticIn.test(VN.lookup(*I))) - temp.push_back(*I); - - for (SmallVector::iterator I = temp.begin(), E = temp.end(); - I != E; ++I) { - anticOut.erase(*I); - anticOut.reset(VN.lookup(*I)); - } - } - } - - return false; -} - -/// buildsets_anticin - Walk the postdom tree, calculating ANTIC_OUT for -/// each block. ANTIC_IN is then a function of ANTIC_OUT and the GEN -/// sets populated in buildsets_availout -unsigned GVNPRE::buildsets_anticin(BasicBlock* BB, - ValueNumberedSet& anticOut, - ValueNumberedSet& currExps, - SmallPtrSet& currTemps, - SmallPtrSet& visited) { - ValueNumberedSet& anticIn = anticipatedIn[BB]; - unsigned old = anticIn.size(); - - bool defer = buildsets_anticout(BB, anticOut, visited); - if (defer) - return 0; - - anticIn.clear(); - - for (ValueNumberedSet::iterator I = anticOut.begin(), - E = anticOut.end(); I != E; ++I) { - anticIn.insert(*I); - anticIn.set(VN.lookup(*I)); - } - for (ValueNumberedSet::iterator I = currExps.begin(), - E = currExps.end(); I != E; ++I) { - if (!anticIn.test(VN.lookup(*I))) { - anticIn.insert(*I); - anticIn.set(VN.lookup(*I)); - } - } - - for (SmallPtrSet::iterator I = currTemps.begin(), - E = currTemps.end(); I != E; ++I) { - anticIn.erase(*I); - anticIn.reset(VN.lookup(*I)); - } - - clean(anticIn); - anticOut.clear(); - - if (old != anticIn.size()) - return 2; - else - return 1; -} - -/// buildsets - Phase 1 of the main algorithm. Construct the AVAIL_OUT -/// and the ANTIC_IN sets. -void GVNPRE::buildsets(Function& F) { - DenseMap generatedExpressions; - DenseMap > generatedTemporaries; - - DominatorTree &DT = getAnalysis(); - - // Phase 1, Part 1: calculate AVAIL_OUT - - // Top-down walk of the dominator tree - for (df_iterator DI = df_begin(DT.getRootNode()), - E = df_end(DT.getRootNode()); DI != E; ++DI) { - - // Get the sets to update for this block - ValueNumberedSet& currExps = generatedExpressions[DI->getBlock()]; - ValueNumberedSet& currPhis = generatedPhis[DI->getBlock()]; - SmallPtrSet& currTemps = generatedTemporaries[DI->getBlock()]; - ValueNumberedSet& currAvail = availableOut[DI->getBlock()]; - - BasicBlock* BB = DI->getBlock(); - - // A block inherits AVAIL_OUT from its dominator - if (DI->getIDom() != 0) - currAvail = availableOut[DI->getIDom()->getBlock()]; - - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); - BI != BE; ++BI) - buildsets_availout(BI, currAvail, currPhis, currExps, - currTemps); - - } - - // Phase 1, Part 2: calculate ANTIC_IN - - SmallPtrSet visited; - SmallPtrSet block_changed; - for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) - block_changed.insert(FI); - - bool changed = true; - unsigned iterations = 0; - - while (changed) { - changed = false; - ValueNumberedSet anticOut; - - // Postorder walk of the CFG - for (po_iterator BBI = po_begin(&F.getEntryBlock()), - BBE = po_end(&F.getEntryBlock()); BBI != BBE; ++BBI) { - BasicBlock* BB = *BBI; - - if (block_changed.count(BB) != 0) { - unsigned ret = buildsets_anticin(BB, anticOut,generatedExpressions[BB], - generatedTemporaries[BB], visited); - - if (ret == 0) { - changed = true; - continue; - } else { - visited.insert(BB); - - if (ret == 2) - for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); - PI != PE; ++PI) { - block_changed.insert(*PI); - } - else - block_changed.erase(BB); - - changed |= (ret == 2); - } - } - } - - iterations++; - } -} - -/// insertion_pre - When a partial redundancy has been identified, eliminate it -/// by inserting appropriate values into the predecessors and a phi node in -/// the main block -void GVNPRE::insertion_pre(Value* e, BasicBlock* BB, - DenseMap& avail, - std::map& new_sets) { - for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) { - Value* e2 = avail[*PI]; - if (!availableOut[*PI].test(VN.lookup(e2))) { - User* U = cast(e2); - - Value* s1 = 0; - if (isa(U->getOperand(0)) || - isa(U->getOperand(0)) || - isa(U->getOperand(0)) || - isa(U->getOperand(0)) || - isa(U->getOperand(0)) || - isa(U->getOperand(0)) || - isa(U->getOperand(0)) || - isa(U->getOperand(0))) - s1 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(0))); - else - s1 = U->getOperand(0); - - Value* s2 = 0; - - if (isa(U) || - isa(U) || - isa(U) || - isa(U) || - isa(U) || - isa(U)) { - if (isa(U->getOperand(1)) || - isa(U->getOperand(1)) || - isa(U->getOperand(1)) || - isa(U->getOperand(1)) || - isa(U->getOperand(1)) || - isa(U->getOperand(1)) || - isa(U->getOperand(1)) || - isa(U->getOperand(1))) { - s2 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(1))); - } else { - s2 = U->getOperand(1); - } - } - - // Ternary Operators - Value* s3 = 0; - if (isa(U) || - isa(U) || - isa(U)) { - if (isa(U->getOperand(2)) || - isa(U->getOperand(2)) || - isa(U->getOperand(2)) || - isa(U->getOperand(2)) || - isa(U->getOperand(2)) || - isa(U->getOperand(2)) || - isa(U->getOperand(2)) || - isa(U->getOperand(2))) { - s3 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(2))); - } else { - s3 = U->getOperand(2); - } - } - - // Vararg operators - SmallVector sVarargs; - if (GetElementPtrInst* G = dyn_cast(U)) { - for (GetElementPtrInst::op_iterator OI = G->idx_begin(), - OE = G->idx_end(); OI != OE; ++OI) { - if (isa(*OI) || - isa(*OI) || - isa(*OI) || - isa(*OI) || - isa(*OI) || - isa(*OI) || - isa(*OI) || - isa(*OI)) { - sVarargs.push_back(find_leader(availableOut[*PI], - VN.lookup(*OI))); - } else { - sVarargs.push_back(*OI); - } - } - } - - Value* newVal = 0; - if (BinaryOperator* BO = dyn_cast(U)) - newVal = BinaryOperator::Create(BO->getOpcode(), s1, s2, - BO->getName()+".gvnpre", - (*PI)->getTerminator()); - else if (CmpInst* C = dyn_cast(U)) - newVal = CmpInst::Create(C->getOpcode(), - C->getPredicate(), s1, s2, - C->getName()+".gvnpre", - (*PI)->getTerminator()); - else if (ShuffleVectorInst* S = dyn_cast(U)) - newVal = new ShuffleVectorInst(s1, s2, s3, S->getName()+".gvnpre", - (*PI)->getTerminator()); - else if (InsertElementInst* S = dyn_cast(U)) - newVal = InsertElementInst::Create(s1, s2, s3, S->getName()+".gvnpre", - (*PI)->getTerminator()); - else if (ExtractElementInst* S = dyn_cast(U)) - newVal = ExtractElementInst::Create(s1, s2, S->getName()+".gvnpre", - (*PI)->getTerminator()); - else if (SelectInst* S = dyn_cast(U)) - newVal = SelectInst::Create(s1, s2, s3, S->getName()+".gvnpre", - (*PI)->getTerminator()); - else if (CastInst* C = dyn_cast(U)) - newVal = CastInst::Create(C->getOpcode(), s1, C->getType(), - C->getName()+".gvnpre", - (*PI)->getTerminator()); - else if (GetElementPtrInst* G = dyn_cast(U)) - newVal = GetElementPtrInst::Create(s1, sVarargs.begin(), sVarargs.end(), - G->getName()+".gvnpre", - (*PI)->getTerminator()); - - VN.add(newVal, VN.lookup(U)); - - ValueNumberedSet& predAvail = availableOut[*PI]; - val_replace(predAvail, newVal); - val_replace(new_sets[*PI], newVal); - predAvail.set(VN.lookup(newVal)); - - DenseMap::iterator av = avail.find(*PI); - if (av != avail.end()) - avail.erase(av); - avail.insert(std::make_pair(*PI, newVal)); - - ++NumInsertedVals; - } - } - - PHINode* p = 0; - - for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) { - if (p == 0) - p = PHINode::Create(avail[*PI]->getType(), "gvnpre-join", BB->begin()); - - p->addIncoming(avail[*PI], *PI); - } - - VN.add(p, VN.lookup(e)); - val_replace(availableOut[BB], p); - availableOut[BB].set(VN.lookup(e)); - generatedPhis[BB].insert(p); - generatedPhis[BB].set(VN.lookup(e)); - new_sets[BB].insert(p); - new_sets[BB].set(VN.lookup(e)); - - ++NumInsertedPhis; -} - -/// insertion_mergepoint - When walking the dom tree, check at each merge -/// block for the possibility of a partial redundancy. If present, eliminate it -unsigned GVNPRE::insertion_mergepoint(SmallVector& workList, - df_iterator& D, - std::map& new_sets) { - bool changed_function = false; - bool new_stuff = false; - - BasicBlock* BB = D->getBlock(); - for (unsigned i = 0; i < workList.size(); ++i) { - Value* e = workList[i]; - - if (isa(e) || isa(e) || - isa(e) || isa(e) || - isa(e) || isa(e) || isa(e) || - isa(e)) { - if (availableOut[D->getIDom()->getBlock()].test(VN.lookup(e))) - continue; - - DenseMap avail; - bool by_some = false; - bool all_same = true; - Value * first_s = 0; - - for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; - ++PI) { - Value *e2 = phi_translate(e, *PI, BB); - Value *e3 = find_leader(availableOut[*PI], VN.lookup(e2)); - - if (e3 == 0) { - DenseMap::iterator av = avail.find(*PI); - if (av != avail.end()) - avail.erase(av); - avail.insert(std::make_pair(*PI, e2)); - all_same = false; - } else { - DenseMap::iterator av = avail.find(*PI); - if (av != avail.end()) - avail.erase(av); - avail.insert(std::make_pair(*PI, e3)); - - by_some = true; - if (first_s == 0) - first_s = e3; - else if (first_s != e3) - all_same = false; - } - } - - if (by_some && !all_same && - !generatedPhis[BB].test(VN.lookup(e))) { - insertion_pre(e, BB, avail, new_sets); - - changed_function = true; - new_stuff = true; - } - } - } - - unsigned retval = 0; - if (changed_function) - retval += 1; - if (new_stuff) - retval += 2; - - return retval; -} - -/// insert - Phase 2 of the main algorithm. Walk the dominator tree looking for -/// merge points. When one is found, check for a partial redundancy. If one is -/// present, eliminate it. Repeat this walk until no changes are made. -bool GVNPRE::insertion(Function& F) { - bool changed_function = false; - - DominatorTree &DT = getAnalysis(); - - std::map new_sets; - bool new_stuff = true; - while (new_stuff) { - new_stuff = false; - for (df_iterator DI = df_begin(DT.getRootNode()), - E = df_end(DT.getRootNode()); DI != E; ++DI) { - BasicBlock* BB = DI->getBlock(); - - if (BB == 0) - continue; - - ValueNumberedSet& availOut = availableOut[BB]; - ValueNumberedSet& anticIn = anticipatedIn[BB]; - - // Replace leaders with leaders inherited from dominator - if (DI->getIDom() != 0) { - ValueNumberedSet& dom_set = new_sets[DI->getIDom()->getBlock()]; - for (ValueNumberedSet::iterator I = dom_set.begin(), - E = dom_set.end(); I != E; ++I) { - val_replace(new_sets[BB], *I); - val_replace(availOut, *I); - } - } - - // If there is more than one predecessor... - if (pred_begin(BB) != pred_end(BB) && ++pred_begin(BB) != pred_end(BB)) { - SmallVector workList; - workList.reserve(anticIn.size()); - topo_sort(anticIn, workList); - - unsigned result = insertion_mergepoint(workList, DI, new_sets); - if (result & 1) - changed_function = true; - if (result & 2) - new_stuff = true; - } - } - } - - return changed_function; -} - -// GVNPRE::runOnFunction - This is the main transformation entry point for a -// function. -// -bool GVNPRE::runOnFunction(Function &F) { - // Clean out global sets from any previous functions - VN.clear(); - createdExpressions.clear(); - availableOut.clear(); - anticipatedIn.clear(); - generatedPhis.clear(); - - bool changed_function = false; - - // Phase 1: BuildSets - // This phase calculates the AVAIL_OUT and ANTIC_IN sets - buildsets(F); - - // Phase 2: Insert - // This phase inserts values to make partially redundant values - // fully redundant - changed_function |= insertion(F); - - // Phase 3: Eliminate - // This phase performs trivial full redundancy elimination - changed_function |= elimination(); - - // Phase 4: Cleanup - // This phase cleans up values that were created solely - // as leaders for expressions - cleanup(); - - return changed_function; -} diff --git a/test/Transforms/GVNPRE/2007-06-12-NoExit.ll b/test/Transforms/GVNPRE/2007-06-12-NoExit.ll deleted file mode 100644 index 49234600262..00000000000 --- a/test/Transforms/GVNPRE/2007-06-12-NoExit.ll +++ /dev/null @@ -1,9 +0,0 @@ -; RUN: opt < %s -gvnpre | llvm-dis - -define void @_Z4sortI3Lit16LessThan_defaultIS0_EEvPT_iT0_() { -entry: - br label %cond_false - -cond_false: ; preds = %cond_false, %entry - br label %cond_false -} diff --git a/test/Transforms/GVNPRE/2007-06-12-PhiTranslate.ll b/test/Transforms/GVNPRE/2007-06-12-PhiTranslate.ll deleted file mode 100644 index 9bc74215c89..00000000000 --- a/test/Transforms/GVNPRE/2007-06-12-PhiTranslate.ll +++ /dev/null @@ -1,19 +0,0 @@ -; RUN: opt < %s -gvnpre | llvm-dis - -define void @strength_test5(i32* %data) { -entry: - br i1 false, label %cond_next16.preheader, label %cond_true - -cond_true: ; preds = %entry - %tmp12 = icmp sgt i32 0, 0 ; [#uses=1] - br i1 %tmp12, label %return, label %cond_next16.preheader - -cond_next16.preheader: ; preds = %cond_true, %entry - %i.01.1.ph = phi i32 [ 1, %entry ], [ 1, %cond_true ] ; [#uses=1] - %i.01.1 = add i32 0, %i.01.1.ph ; [#uses=0] - %indvar.next = add i32 0, 1 ; [#uses=0] - ret void - -return: ; preds = %cond_true - ret void -} diff --git a/test/Transforms/GVNPRE/2007-06-15-InvokeInst.ll b/test/Transforms/GVNPRE/2007-06-15-InvokeInst.ll deleted file mode 100644 index 0f68b7865cb..00000000000 --- a/test/Transforms/GVNPRE/2007-06-15-InvokeInst.ll +++ /dev/null @@ -1,70 +0,0 @@ -; RUN: opt < %s -gvnpre | llvm-dis - -@.str1 = external constant [4 x i8] ; <[4 x i8]*> [#uses=1] -@.str2 = external constant [5 x i8] ; <[5 x i8]*> [#uses=1] - -define i32 @main(i32 %argc, i8** %argv) { -entry: - br i1 false, label %cond_next, label %cond_true - -cond_true: ; preds = %entry - ret i32 0 - -cond_next: ; preds = %entry - %tmp10 = invoke i16 @_ZN12token_stream4openEPKc( i8* null, i8* null ) signext - to label %invcont unwind label %cleanup690 ; [#uses=0] - -invcont: ; preds = %cond_next - %tmp15 = invoke i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0) ) - to label %invcont14 unwind label %cleanup685 ; [#uses=0] - -invcont14: ; preds = %invcont - %tmp17 = invoke i8* @_ZN24lambda_expression_parser10expressionEPP11arglst_node( i8* null, i8** null ) - to label %cond_true22 unwind label %cleanup685 - -cond_true22: ; preds = %invcont14 - %tmp35 = invoke i32 null( i8* null ) - to label %cond_next56 unwind label %cleanup685 ; [#uses=0] - -cond_next56: ; preds = %cond_true22 - %tmp59 = invoke i32 (i8*, ...)* @printf( i8* getelementptr ([5 x i8]* @.str2, i32 0, i32 0) ) - to label %invcont58 unwind label %cleanup685 ; [#uses=0] - -invcont58: ; preds = %cond_next56 - invoke void null( i8* null, i8* null, i32 0 ) - to label %invcont72 unwind label %cleanup685 - -invcont72: ; preds = %invcont58 - %tmp143 = invoke i32 null( i8* null ) - to label %invcont142 unwind label %cleanup685 ; [#uses=0] - -invcont142: ; preds = %invcont72 - br i1 false, label %cond_false407, label %cond_true150 - -cond_true150: ; preds = %invcont142 - ret i32 0 - -cond_false407: ; preds = %invcont142 - %tmp431 = invoke i8* null( i8* null, i8* null, i32 0, i32* null ) - to label %bb432 unwind label %cleanup685 - -bb432: ; preds = %bb432, %cond_false407 - %rexp413.7 = phi i8* [ %tmp431, %cond_false407 ], [ %rexp413.7, %bb432 ] - %tmp434 = icmp eq i8* %rexp413.7, null ; [#uses=1] - br i1 %tmp434, label %bb432, label %cond_true437 - -cond_true437: ; preds = %bb432 - ret i32 0 - -cleanup685: ; preds = %cond_false407, %invcont72, %invcont58, %cond_next56, %cond_true22, %invcont14, %invcont - ret i32 0 - -cleanup690: ; preds = %cond_next - ret i32 0 -} - -declare i16 @_ZN12token_stream4openEPKc(i8*, i8*) signext - -declare i32 @printf(i8*, ...) - -declare i8* @_ZN24lambda_expression_parser10expressionEPP11arglst_node(i8*, i8**) diff --git a/test/Transforms/GVNPRE/2007-06-15-Looping.ll b/test/Transforms/GVNPRE/2007-06-15-Looping.ll deleted file mode 100644 index 36fa8afbe38..00000000000 --- a/test/Transforms/GVNPRE/2007-06-15-Looping.ll +++ /dev/null @@ -1,22 +0,0 @@ -; RUN: opt < %s -gvnpre | llvm-dis - -define fastcc void @compute_max_score_1() { -entry: - %tmp7 = sub i32 0, 0 ; [#uses=0] - br label %bb - -bb: ; preds = %bb212, %entry - %indvar29 = phi i32 [ 0, %entry ], [ %indvar.next30, %bb212 ] ; [#uses=2] - %j.01.0 = sub i32 %indvar29, 0 ; [#uses=0] - br label %cond_next166 - -cond_next166: ; preds = %cond_next166, %bb - br i1 false, label %bb212, label %cond_next166 - -bb212: ; preds = %cond_next166 - %indvar.next30 = add i32 %indvar29, 1 ; [#uses=1] - br i1 false, label %return, label %bb - -return: ; preds = %bb212 - ret void -} diff --git a/test/Transforms/GVNPRE/2007-06-18-ConstantInPhi.ll b/test/Transforms/GVNPRE/2007-06-18-ConstantInPhi.ll deleted file mode 100644 index 980c4e91e91..00000000000 --- a/test/Transforms/GVNPRE/2007-06-18-ConstantInPhi.ll +++ /dev/null @@ -1,22 +0,0 @@ -; RUN: opt < %s -gvnpre | llvm-dis - -define void @vorbis_lsp_to_curve() { -entry: - br i1 false, label %bb.nph, label %return - -bb.nph: ; preds = %entry - br label %bb34 - -bb34: ; preds = %bb34, %bb.nph - %p.1 = phi float [ 0x3FE6A09E60000000, %bb.nph ], [ %tmp48, %bb34 ] ; [#uses=1] - %tmp44 = load float* null ; [#uses=1] - %tmp46 = fsub float %tmp44, 0.000000e+00 ; [#uses=1] - %tmp48 = fmul float %tmp46, %p.1 ; [#uses=1] - br i1 false, label %bb57, label %bb34 - -bb57: ; preds = %bb34 - ret void - -return: ; preds = %entry - ret void -} diff --git a/test/Transforms/GVNPRE/2007-06-18-EraseNumbering.ll b/test/Transforms/GVNPRE/2007-06-18-EraseNumbering.ll deleted file mode 100644 index 753575caebe..00000000000 --- a/test/Transforms/GVNPRE/2007-06-18-EraseNumbering.ll +++ /dev/null @@ -1,26 +0,0 @@ -; RUN: opt < %s -gvnpre | llvm-dis - -define i32 @TreeCCStreamFlush(i8* %stream) { -entry: - br i1 false, label %bb55.preheader, label %cond_true - -cond_true: ; preds = %entry - ret i32 0 - -bb55.preheader: ; preds = %entry - %tmp57 = icmp eq i8* null, null ; [#uses=0] - br i1 false, label %cond_next106, label %bb124 - -cond_next106: ; preds = %bb55.preheader - %tmp109 = load i8** null - br i1 false, label %bb124, label %bb116 - -bb116: ; preds = %cond_next106 - ret i32 0 - -bb124: ; preds = %cond_next106, %bb55.preheader - %buffer.4 = phi i8* [ null, %bb55.preheader ], [ %tmp109, %cond_next106 ] - %tmp131 = icmp eq i8* %buffer.4, null - %bothcond = or i1 %tmp131, false - ret i32 0 -} diff --git a/test/Transforms/GVNPRE/2007-07-03-PhiTranslateGEP.ll b/test/Transforms/GVNPRE/2007-07-03-PhiTranslateGEP.ll deleted file mode 100644 index 52cd18f0d07..00000000000 --- a/test/Transforms/GVNPRE/2007-07-03-PhiTranslateGEP.ll +++ /dev/null @@ -1,14 +0,0 @@ -; RUN: opt < %s -gvnpre | llvm-dis - -define i64 @foo({ i32, i32 }** %__v) { -entry: - br label %bb - -bb: ; preds = %bb, %entry - %__x.066.0 = phi { i32, i32 }* [ null, %entry ], [ null, %bb ] - %tmp2.i.i63 = getelementptr { i32, i32 }* %__x.066.0, i32 0, i32 1 - br i1 false, label %bb, label %cond_true - -cond_true: ; preds = %bb - ret i64 0 -} diff --git a/test/Transforms/GVNPRE/2007-07-04-CleanSelect.ll b/test/Transforms/GVNPRE/2007-07-04-CleanSelect.ll deleted file mode 100644 index 40e5a0b022f..00000000000 --- a/test/Transforms/GVNPRE/2007-07-04-CleanSelect.ll +++ /dev/null @@ -1,9 +0,0 @@ -; RUN: opt < %s -gvnpre | llvm-dis - -define i32* @_ZN6Solver9propagateEv(i32* %this) { -entry: - %tmp15.i48 = load i8* null ; [#uses=2] - %tmp64.i.i51 = sub i8 0, %tmp15.i48 ; [#uses=1] - %tmp231.i52 = select i1 false, i8 %tmp15.i48, i8 %tmp64.i.i51 ; [#uses=0] - ret i32* null -} diff --git a/test/Transforms/GVNPRE/2007-07-04-SelectInst.ll b/test/Transforms/GVNPRE/2007-07-04-SelectInst.ll deleted file mode 100644 index 495ded55c4c..00000000000 --- a/test/Transforms/GVNPRE/2007-07-04-SelectInst.ll +++ /dev/null @@ -1,18 +0,0 @@ -; RUN: opt < %s -gvnpre | llvm-dis - -define void @set_depth_values(i32 %level) { -cond_true90: ; preds = %cond_next84 - br i1 false, label %cond_true105, label %cond_true151 - -cond_true105: ; preds = %cond_true90 - %tmp132 = add i32 %level, -3 ; [#uses=2] - %tmp133 = icmp sgt i32 %tmp132, 0 ; [#uses=1] - %max134 = select i1 %tmp133, i32 %tmp132, i32 1 ; [#uses=0] - br label %cond_true151 - -cond_true151: ; preds = %cond_true140, %cond_true105 - %tmp153 = add i32 %level, -3 ; [#uses=2] - %tmp154 = icmp sgt i32 %tmp153, 0 ; [#uses=1] - %max155 = select i1 %tmp154, i32 %tmp153, i32 1 ; [#uses=0] - ret void -} diff --git a/test/Transforms/GVNPRE/2007-07-05-AvailabilityUpdating.ll b/test/Transforms/GVNPRE/2007-07-05-AvailabilityUpdating.ll deleted file mode 100644 index a173d4b77cd..00000000000 --- a/test/Transforms/GVNPRE/2007-07-05-AvailabilityUpdating.ll +++ /dev/null @@ -1,54 +0,0 @@ -; RUN: opt < %s -gvnpre -S | grep tmp114115.gvnpre - - %struct.AV = type { %struct.XPVAV*, i32, i32 } - %struct.CLONE_PARAMS = type { %struct.AV*, i32, %struct.PerlInterpreter* } - %struct.HE = type { %struct.HE*, %struct.HEK*, %struct.SV* } - %struct.HEK = type { i32, i32, [1 x i8] } - %struct.HV = type { %struct.XPVHV*, i32, i32 } - %struct.MAGIC = type { %struct.MAGIC*, %struct.MGVTBL*, i16, i8, i8, %struct.SV*, i8*, i32 } - %struct.MGVTBL = type { i32 (%struct.SV*, %struct.MAGIC*)*, i32 (%struct.SV*, %struct.MAGIC*)*, i32 (%struct.SV*, %struct.MAGIC*)*, i32 (%struct.SV*, %struct.MAGIC*)*, i32 (%struct.SV*, %struct.MAGIC*)*, i32 (%struct.SV*, %struct.MAGIC*, %struct.SV*, i8*, i32)*, i32 (%struct.MAGIC*, %struct.CLONE_PARAMS*)* } - %struct.OP = type { %struct.OP*, %struct.OP*, %struct.OP* ()*, i32, i16, i16, i8, i8 } - %struct.PMOP = type { %struct.OP*, %struct.OP*, %struct.OP* ()*, i32, i16, i16, i8, i8, %struct.OP*, %struct.OP*, %struct.OP*, %struct.OP*, %struct.PMOP*, %struct.REGEXP*, i32, i32, i8, %struct.HV* } - %struct.PerlInterpreter = type { i8 } - %struct.REGEXP = type { i32*, i32*, %struct.regnode*, %struct.reg_substr_data*, i8*, %struct.reg_data*, i8*, i32*, i32, i32, i32, i32, i32, i32, i32, i32, [1 x %struct.regnode] } - %struct.SV = type { i8*, i32, i32 } - %struct.XPVAV = type { i8*, i32, i32, i32, double, %struct.MAGIC*, %struct.HV*, %struct.SV**, %struct.SV*, i8 } - %struct.XPVHV = type { i8*, i32, i32, i32, double, %struct.MAGIC*, %struct.HV*, i32, %struct.HE*, %struct.PMOP*, i8* } - %struct.reg_data = type { i32, i8*, [1 x i8*] } - %struct.reg_substr_data = type { [3 x %struct.reg_substr_datum] } - %struct.reg_substr_datum = type { i32, i32, %struct.SV*, %struct.SV* } - %struct.regnode = type { i8, i8, i16 } - -define void @Perl_op_clear(%struct.OP* %o) { -entry: - switch i32 0, label %bb106 [ - i32 13, label %bb106 - i32 31, label %clear_pmop - i32 32, label %clear_pmop - i32 33, label %bb101 - ] - -bb101: ; preds = %entry - %tmp102103 = bitcast %struct.OP* %o to %struct.PMOP* ; <%struct.PMOP*> [#uses=1] - %tmp104 = getelementptr %struct.PMOP* %tmp102103, i32 0, i32 10 ; <%struct.OP**> [#uses=0] - br i1 false, label %cond_next174, label %cond_true122 - -bb106: ; preds = %entry, %entry - %tmp107108 = bitcast %struct.OP* %o to %struct.PMOP* ; <%struct.PMOP*> [#uses=0] - br label %clear_pmop - -clear_pmop: ; preds = %bb106, %entry, %entry - %tmp114115 = bitcast %struct.OP* %o to %struct.PMOP* ; <%struct.PMOP*> [#uses=0] - br label %cond_true122 - -cond_true122: ; preds = %clear_pmop, %bb101 - br i1 false, label %cond_next174, label %cond_true129 - -cond_true129: ; preds = %cond_true122 - ret void - -cond_next174: ; preds = %cond_true122, %bb101 - %tmp175176 = bitcast %struct.OP* %o to %struct.PMOP* ; <%struct.PMOP*> [#uses=1] - %tmp177 = getelementptr %struct.PMOP* %tmp175176, i32 0, i32 10 ; <%struct.OP**> [#uses=0] - ret void -} diff --git a/test/Transforms/GVNPRE/2007-07-07-AnticOutUnique.ll b/test/Transforms/GVNPRE/2007-07-07-AnticOutUnique.ll deleted file mode 100644 index 9c170388dcb..00000000000 --- a/test/Transforms/GVNPRE/2007-07-07-AnticOutUnique.ll +++ /dev/null @@ -1,14 +0,0 @@ -; RUN: opt < %s -gvnpre | llvm-dis - %"struct.ObjectArena" = type { i32, i32, %"struct.ResizeArray", i8*, i8* } - %"struct.ResizeArray" = type { i32 (...)**, %"struct.ResizeArrayRaw"* } - %"struct.ResizeArrayRaw" = type { i8**, i8*, i32, i32, i32, float, i32 } - -define void @_ZN11ObjectArenaIcED1Ev(%"struct.ObjectArena"* %this) { -entry: - br label %cond_true21 - -cond_true21: ; preds = %cond_true21, %entry - %tmp215.0 = phi %"struct.ResizeArray"* [ null, %entry ], [ null, %cond_true21 ] ; <%"struct.ResizeArray"*> [#uses=1] - %tmp2.i2 = getelementptr %"struct.ResizeArray"* %tmp215.0, i32 0, i32 1 ; <%"struct.ResizeArrayRaw"**> [#uses=0] - br label %cond_true21 -} diff --git a/test/Transforms/GVNPRE/basic.ll b/test/Transforms/GVNPRE/basic.ll deleted file mode 100644 index c7c3f106780..00000000000 --- a/test/Transforms/GVNPRE/basic.ll +++ /dev/null @@ -1,38 +0,0 @@ -; RUN: opt < %s -gvnpre -S | not grep {%z3 =} -; RUN: opt < %s -gvnpre -S | not grep {%z9 =} - -define i32 @main() { -block1: - %z1 = bitcast i32 0 to i32 ; [#uses=5] - br label %block2 - -block2: ; preds = %block6, %block1 - %z2 = phi i32 [ %z1, %block1 ], [ %z3, %block6 ] ; [#uses=3] - %z3 = add i32 %z2, 1 ; [#uses=5] - br i1 false, label %block3, label %block7 - -block3: ; preds = %block2 - br i1 true, label %block4, label %block5 - -block4: ; preds = %block3 - %z4 = add i32 %z2, %z3 ; [#uses=1] - %z5 = bitcast i32 %z4 to i32 ; [#uses=1] - %z6 = add i32 %z1, %z5 ; [#uses=0] - br label %block6 - -block5: ; preds = %block3 - %z7 = add i32 %z3, 1 ; [#uses=1] - br label %block6 - -block6: ; preds = %block5, %block4 - %z8 = phi i32 [ %z1, %block4 ], [ %z7, %block5 ] ; [#uses=1] - %z9 = add i32 %z2, %z3 ; [#uses=2] - %z10 = add i32 %z9, %z8 ; [#uses=0] - %z11 = bitcast i32 12 to i32 ; [#uses=1] - %z12 = add i32 %z9, %z11 ; [#uses=1] - %z13 = add i32 %z12, %z3 ; [#uses=0] - br label %block2 - -block7: ; preds = %block2 - ret i32 %z1 -} diff --git a/test/Transforms/GVNPRE/cast.ll b/test/Transforms/GVNPRE/cast.ll deleted file mode 100644 index e53e9930db8..00000000000 --- a/test/Transforms/GVNPRE/cast.ll +++ /dev/null @@ -1,17 +0,0 @@ -; RUN: opt < %s -gvnpre -S | grep b.gvnpre - -define i32 @extract() { -entry: ; preds = %cond_false, %entry - br i1 true, label %cond_true, label %cond_false - -cond_true: - br label %end - -cond_false: - %a = sext i16 0 to i32 - br label %end - -end: - %b = sext i16 0 to i32 - ret i32 %b -} diff --git a/test/Transforms/GVNPRE/dg.exp b/test/Transforms/GVNPRE/dg.exp deleted file mode 100644 index f2005891a59..00000000000 --- a/test/Transforms/GVNPRE/dg.exp +++ /dev/null @@ -1,3 +0,0 @@ -load_lib llvm.exp - -RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] diff --git a/test/Transforms/GVNPRE/extractelement.ll b/test/Transforms/GVNPRE/extractelement.ll deleted file mode 100644 index cc66545d5c8..00000000000 --- a/test/Transforms/GVNPRE/extractelement.ll +++ /dev/null @@ -1,18 +0,0 @@ -; RUN: opt < %s -gvnpre -S | grep b.gvnpre - -define i32 @extract() { -entry: ; preds = %cond_false, %entry - %foo = add <2 x i32> < i32 1, i32 1 >, < i32 1, i32 1 > - br i1 true, label %cond_true, label %cond_false - -cond_true: - br label %end - -cond_false: - %a = extractelement <2 x i32> %foo, i32 0 - br label %end - -end: - %b = extractelement <2 x i32> %foo, i32 0 - ret i32 %b -} diff --git a/test/Transforms/GVNPRE/gep.ll b/test/Transforms/GVNPRE/gep.ll deleted file mode 100644 index 677f4383f6c..00000000000 --- a/test/Transforms/GVNPRE/gep.ll +++ /dev/null @@ -1,17 +0,0 @@ -; RUN: opt < %s -gvnpre -S | grep b.gvnpre - -define i32 @extract({ i32 }* %P) { -entry: ; preds = %cond_false, %entry - br i1 true, label %cond_true, label %cond_false - -cond_true: - br label %end - -cond_false: - %a = getelementptr { i32 }* %P, i32 0, i32 0 - br label %end - -end: - %b = getelementptr { i32 }* %P, i32 0, i32 0 - ret i32 0 -} diff --git a/test/Transforms/GVNPRE/insertelement.ll b/test/Transforms/GVNPRE/insertelement.ll deleted file mode 100644 index b798978b738..00000000000 --- a/test/Transforms/GVNPRE/insertelement.ll +++ /dev/null @@ -1,18 +0,0 @@ -; RUN: opt < %s -gvnpre -S | grep b.gvnpre - -define i32 @extract() { -entry: ; preds = %cond_false, %entry - %foo = add <2 x i32> < i32 1, i32 1 >, < i32 1, i32 1 > - br i1 true, label %cond_true, label %cond_false - -cond_true: - br label %end - -cond_false: - %a = insertelement <2 x i32> %foo, i32 0, i32 3 - br label %end - -end: - %b = insertelement <2 x i32> %foo, i32 0, i32 3 - ret i32 0 -} diff --git a/test/Transforms/GVNPRE/select.ll b/test/Transforms/GVNPRE/select.ll deleted file mode 100644 index de73ed5c91d..00000000000 --- a/test/Transforms/GVNPRE/select.ll +++ /dev/null @@ -1,17 +0,0 @@ -; RUN: opt < %s -gvnpre -S | grep b.gvnpre - -define i32 @extract() { -entry: ; preds = %cond_false, %entry - br i1 true, label %cond_true, label %cond_false - -cond_true: - br label %end - -cond_false: - %a = select i1 true, i32 0, i32 1 - br label %end - -end: - %b = select i1 true, i32 0, i32 1 - ret i32 %b -} diff --git a/test/Transforms/GVNPRE/shufflevector.ll b/test/Transforms/GVNPRE/shufflevector.ll deleted file mode 100644 index 0862e706fce..00000000000 --- a/test/Transforms/GVNPRE/shufflevector.ll +++ /dev/null @@ -1,18 +0,0 @@ -; RUN: opt < %s -gvnpre -S | grep b.gvnpre - -define i32 @extract() { -entry: ; preds = %cond_false, %entry - %foo = add <2 x i32> < i32 1, i32 1 >, < i32 1, i32 1 > - br i1 true, label %cond_true, label %cond_false - -cond_true: - br label %end - -cond_false: - %a = shufflevector <2 x i32> %foo, <2 x i32> undef, <2 x i32> < i32 0, i32 1 > - br label %end - -end: - %b = shufflevector <2 x i32> %foo, <2 x i32> undef, <2 x i32> < i32 0, i32 1 > - ret i32 0 -}