From 94cf3b1c67017cfefcdb81bc8ce705297efc4dfb Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 29 Apr 2002 20:18:00 +0000 Subject: [PATCH] Remove unused files: This is the old induction varaible cannonicalization pass built on top of interval analysis git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2411 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/Transforms/Scalar/InductionVars.h | 27 -- lib/Transforms/Scalar/InductionVars.cpp | 408 ------------------ 2 files changed, 435 deletions(-) delete mode 100644 include/llvm/Transforms/Scalar/InductionVars.h delete mode 100644 lib/Transforms/Scalar/InductionVars.cpp diff --git a/include/llvm/Transforms/Scalar/InductionVars.h b/include/llvm/Transforms/Scalar/InductionVars.h deleted file mode 100644 index 704617c594b..00000000000 --- a/include/llvm/Transforms/Scalar/InductionVars.h +++ /dev/null @@ -1,27 +0,0 @@ -//===-- InductionVars.h - Induction Variable Recognition ---------*- C++ -*--=// -// -// This family of functions is useful for Induction variable recognition, -// removal and optimizations. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_OPT_INDUCTION_VARS_H -#define LLVM_OPT_INDUCTION_VARS_H - -#include "llvm/Pass.h" -class IntervalPartition; - -struct InductionVariableCannonicalize : public FunctionPass { - const char *getPassName() const { return "**OLD IndVars ***"; } - - // doInductionVariableCannonicalize - Simplify induction variables in loops - // - static bool doIt(Function *F, IntervalPartition &IP); - - virtual bool runOnFunction(Function *F); - - // getAnalysisUsage - Declare that we need IntervalPartitions - void getAnalysisUsage(AnalysisUsage &AU) const; -}; - -#endif diff --git a/lib/Transforms/Scalar/InductionVars.cpp b/lib/Transforms/Scalar/InductionVars.cpp deleted file mode 100644 index b4a440f4ccc..00000000000 --- a/lib/Transforms/Scalar/InductionVars.cpp +++ /dev/null @@ -1,408 +0,0 @@ -//===- InductionVars.cpp - Induction Variable Cannonicalization code --------=// -// -// This file implements induction variable cannonicalization of loops. -// -// Specifically, after this executes, the following is true: -// - There is a single induction variable for each loop (at least loops that -// used to contain at least one induction variable) -// * This induction variable starts at 0 and steps by 1 per iteration -// * This induction variable is represented by the first PHI node in the -// Header block, allowing it to be found easily. -// - All other preexisting induction variables are adjusted to operate in -// terms of this primary induction variable -// - Induction variables with a step size of 0 have been eliminated. -// -// This code assumes the following is true to perform its full job: -// - The CFG has been simplified to not have multiple entrances into an -// interval header. Interval headers should only have two predecessors, -// one from inside of the loop and one from outside of the loop. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Transforms/Scalar/InductionVars.h" -#include "llvm/Constants.h" -#include "llvm/iPHINode.h" -#include "llvm/Type.h" -#include "llvm/Support/CFG.h" -#include "llvm/Analysis/IntervalPartition.h" -#include "Support/STLExtras.h" -#include -#include -using std::cerr; - -// isLoopInvariant - Return true if the specified value/basic block source is -// an interval invariant computation. -// -static bool isLoopInvariant(Interval *Int, Value *V) { - assert(isa(V) || isa(V) || isa(V)); - - if (!isa(V)) - return true; // Constants and arguments are always loop invariant - - BasicBlock *ValueBlock = cast(V)->getParent(); - assert(ValueBlock && "Instruction not embedded in basic block!"); - - // For now, only consider values from outside of the interval, regardless of - // whether the expression could be lifted out of the loop by some LICM. - // - // TODO: invoke LICM library if we find out it would be useful. - // - return !Int->contains(ValueBlock); -} - - -// isLinearInductionVariableH - Return isLIV if the expression V is a linear -// expression defined in terms of loop invariant computations, and a single -// instance of the PHI node PN. Return isLIC if the expression V is a loop -// invariant computation. Return isNLIV if the expression is a negated linear -// induction variable. Return isOther if it is neither. -// -// Currently allowed operators are: ADD, SUB, NEG -// TODO: This should allow casts! -// -enum LIVType { isLIV, isLIC, isNLIV, isOther }; -// -// neg - Negate the sign of a LIV expression. -inline LIVType neg(LIVType T) { - assert(T == isLIV || T == isNLIV && "Negate Only works on LIV expressions"); - return T == isLIV ? isNLIV : isLIV; -} -// -static LIVType isLinearInductionVariableH(Interval *Int, Value *V, - PHINode *PN) { - if (V == PN) { return isLIV; } // PHI node references are (0+PHI) - if (isLoopInvariant(Int, V)) return isLIC; - - // loop variant computations must be instructions! - Instruction *I = cast(V); - switch (I->getOpcode()) { // Handle each instruction seperately - case Instruction::Add: - case Instruction::Sub: { - Value *SubV1 = cast(I)->getOperand(0); - Value *SubV2 = cast(I)->getOperand(1); - LIVType SubLIVType1 = isLinearInductionVariableH(Int, SubV1, PN); - if (SubLIVType1 == isOther) return isOther; // Early bailout - LIVType SubLIVType2 = isLinearInductionVariableH(Int, SubV2, PN); - - switch (SubLIVType2) { - case isOther: return isOther; // Unknown subexpression type - case isLIC: return SubLIVType1; // Constant offset, return type #1 - case isLIV: - case isNLIV: - // So now we know that we have a linear induction variable on the RHS of - // the ADD or SUB instruction. SubLIVType1 cannot be isOther, so it is - // either a Loop Invariant computation, or a LIV type. - if (SubLIVType1 == isLIC) { - // Loop invariant computation, we know this is a LIV then. - return (I->getOpcode() == Instruction::Add) ? - SubLIVType2 : neg(SubLIVType2); - } - - // If the LHS is also a LIV Expression, we cannot add two LIVs together - if (I->getOpcode() == Instruction::Add) return isOther; - - // We can only subtract two LIVs if they are the same type, which yields - // a LIC, because the LIVs cancel each other out. - return (SubLIVType1 == SubLIVType2) ? isLIC : isOther; - } - // NOT REACHED - } - - default: // Any other instruction is not a LINEAR induction var - return isOther; - } -} - -// isLinearInductionVariable - Return true if the specified expression is a -// "linear induction variable", which is an expression involving a single -// instance of the PHI node and a loop invariant value that is added or -// subtracted to the PHI node. This is calculated by walking the SSA graph -// -static inline bool isLinearInductionVariable(Interval *Int, Value *V, - PHINode *PN) { - return isLinearInductionVariableH(Int, V, PN) == isLIV; -} - - -// isSimpleInductionVar - Return true iff the cannonical induction variable PN -// has an initializer of the constant value 0, and has a step size of constant -// 1. -static inline bool isSimpleInductionVar(PHINode *PN) { - assert(PN->getNumIncomingValues() == 2 && "Must have cannonical PHI node!"); - Value *Initializer = PN->getIncomingValue(0); - if (!isa(Initializer)) return false; - - if (Initializer->getType()->isSigned()) { // Signed constant value... - if (((ConstantSInt*)Initializer)->getValue() != 0) return false; - } else if (Initializer->getType()->isUnsigned()) { // Unsigned constant value - if (((ConstantUInt*)Initializer)->getValue() != 0) return false; - } else { - return false; // Not signed or unsigned? Must be FP type or something - } - - Value *StepExpr = PN->getIncomingValue(1); - if (!isa(StepExpr) || - cast(StepExpr)->getOpcode() != Instruction::Add) - return false; - - BinaryOperator *I = cast(StepExpr); - assert(isa(I->getOperand(0)) && - "PHI node should be first operand of ADD instruction!"); - - // Get the right hand side of the ADD node. See if it is a constant 1. - Value *StepSize = I->getOperand(1); - if (!isa(StepSize)) return false; - - if (StepSize->getType()->isSigned()) { // Signed constant value... - if (((ConstantSInt*)StepSize)->getValue() != 1) return false; - } else if (StepSize->getType()->isUnsigned()) { // Unsigned constant value - if (((ConstantUInt*)StepSize)->getValue() != 1) return false; - } else { - return false; // Not signed or unsigned? Must be FP type or something - } - - // At this point, we know the initializer is a constant value 0 and the step - // size is a constant value 1. This is our simple induction variable! - return true; -} - -// InjectSimpleInductionVariable - Insert a cannonical induction variable into -// the interval header Header. This assumes that the flow graph is in -// simplified form (so we know that the header block has exactly 2 predecessors) -// -// TODO: This should inherit the largest type that is being used by the already -// present induction variables (instead of always using uint) -// -static PHINode *InjectSimpleInductionVariable(Interval *Int) { - std::string PHIName, AddName; - - BasicBlock *Header = Int->getHeaderNode(); - Function *M = Header->getParent(); - - if (M->hasSymbolTable()) { - // Only name the induction variable if the function isn't stripped. - PHIName = "ind_var"; - AddName = "ind_var_next"; - } - - // Create the neccesary instructions... - PHINode *PN = new PHINode(Type::UIntTy, PHIName); - Constant *One = ConstantUInt::get(Type::UIntTy, 1); - Constant *Zero = ConstantUInt::get(Type::UIntTy, 0); - BinaryOperator *AddNode = BinaryOperator::create(Instruction::Add, - PN, One, AddName); - - // Figure out which predecessors I have to play with... there should be - // exactly two... one of which is a loop predecessor, and one of which is not. - // - pred_iterator PI = pred_begin(Header); - assert(PI != pred_end(Header) && "Header node should have 2 preds!"); - BasicBlock *Pred1 = *PI; ++PI; - assert(PI != pred_end(Header) && "Header node should have 2 preds!"); - BasicBlock *Pred2 = *PI; - assert(++PI == pred_end(Header) && "Header node should have 2 preds!"); - - // Make Pred1 be the loop entrance predecessor, Pred2 be the Loop predecessor - if (Int->contains(Pred1)) std::swap(Pred1, Pred2); - - assert(!Int->contains(Pred1) && "Pred1 should be loop entrance!"); - assert( Int->contains(Pred2) && "Pred2 should be looping edge!"); - - // Link the instructions into the PHI node... - PN->addIncoming(Zero, Pred1); // The initializer is first argument - PN->addIncoming(AddNode, Pred2); // The step size is second PHI argument - - // Insert the PHI node into the Header of the loop. It shall be the first - // instruction, because the "Simple" Induction Variable must be first in the - // block. - // - BasicBlock::InstListType &IL = Header->getInstList(); - IL.push_front(PN); - - // Insert the Add instruction as the first (non-phi) instruction in the - // header node's basic block. - BasicBlock::iterator I = IL.begin(); - while (isa(*I)) ++I; - IL.insert(I, AddNode); - return PN; -} - -// ProcessInterval - This function is invoked once for each interval in the -// IntervalPartition of the program. It looks for auxilliary induction -// variables in loops. If it finds one, it: -// * Cannonicalizes the induction variable. This consists of: -// A. Making the first element of the PHI node be the loop invariant -// computation, and the second element be the linear induction portion. -// B. Changing the first element of the linear induction portion of the PHI -// node to be of the form ADD(PHI, ). -// * Add the induction variable PHI to a list of induction variables found. -// -// After this, a list of cannonical induction variables is known. This list -// is searched to see if there is an induction variable that counts from -// constant 0 with a step size of constant 1. If there is not one, one is -// injected into the loop. Thus a "simple" induction variable is always known -// -// One a simple induction variable is known, all other induction variables are -// modified to refer to the "simple" induction variable. -// -static bool ProcessInterval(Interval *Int) { - if (!Int->isLoop()) return false; // Not a loop? Ignore it! - - std::vector InductionVars; - - BasicBlock *Header = Int->getHeaderNode(); - // Loop over all of the PHI nodes in the interval header... - for (BasicBlock::iterator I = Header->begin(), E = Header->end(); - I != E && isa(*I); ++I) { - PHINode *PN = cast(*I); - if (PN->getNumIncomingValues() != 2) { // These should be eliminated by now. - cerr << "Found interval header with more than 2 predecessors! Ignoring\n"; - return false; // Todo, make an assertion. - } - - // For this to be an induction variable, one of the arguments must be a - // loop invariant expression, and the other must be an expression involving - // the PHI node, along with possible additions and subtractions of loop - // invariant values. - // - BasicBlock *BB1 = PN->getIncomingBlock(0); - Value *V1 = PN->getIncomingValue(0); - BasicBlock *BB2 = PN->getIncomingBlock(1); - Value *V2 = PN->getIncomingValue(1); - - // Figure out which computation is loop invariant... - if (!isLoopInvariant(Int, V1)) { - // V1 is *not* loop invariant. Check to see if V2 is: - if (isLoopInvariant(Int, V2)) { - // They *are* loop invariant. Exchange BB1/BB2 and V1/V2 so that - // V1 is always the loop invariant computation. - std::swap(V1, V2); std::swap(BB1, BB2); - } else { - // Neither value is loop invariant. Must not be an induction variable. - // This case can happen if there is an unreachable loop in the CFG that - // has two tail loops in it that was not split by the cleanup phase - // before. - continue; - } - } - - // At this point, we know that BB1/V1 are loop invariant. We don't know - // anything about BB2/V2. Check now to see if V2 is a linear induction - // variable. - // - cerr << "Found loop invariant computation: " << V1 << "\n"; - - if (!isLinearInductionVariable(Int, V2, PN)) - continue; // No, it is not a linear ind var, ignore the PHI node. - cerr << "Found linear induction variable: " << V2; - - // TODO: Cannonicalize V2 - - // Add this PHI node to the list of induction variables found... - InductionVars.push_back(PN); - } - - // No induction variables found? - if (InductionVars.empty()) return false; - - // Search to see if there is already a "simple" induction variable. - std::vector::iterator It = - find_if(InductionVars.begin(), InductionVars.end(), isSimpleInductionVar); - - PHINode *PrimaryIndVar; - - // A simple induction variable was not found, inject one now... - if (It == InductionVars.end()) { - PrimaryIndVar = InjectSimpleInductionVariable(Int); - } else { - // Move the PHI node for this induction variable to the start of the PHI - // list in HeaderNode... we do not need to do this for the inserted case - // because the inserted node will always be placed at the beginning of - // HeaderNode. - // - PrimaryIndVar = *It; - BasicBlock::iterator i = - find(Header->begin(), Header->end(), PrimaryIndVar); - assert(i != Header->end() && - "How could Primary IndVar not be in the header!?!!?"); - - if (i != Header->begin()) - std::iter_swap(i, Header->begin()); - } - - // Now we know that there is a simple induction variable PrimaryIndVar. - // Simplify all of the other induction variables to use this induction - // variable as their counter, and destroy the PHI nodes that correspond to - // the old indvars. - // - // TODO - - - cerr << "Found Interval Header with indvars (primary indvar should be first " - << "phi): \n" << Header << "\nPrimaryIndVar: " << PrimaryIndVar; - - return false; // TODO: true; -} - - -// ProcessIntervalPartition - This function loops over the interval partition -// processing each interval with ProcessInterval -// -static bool ProcessIntervalPartition(IntervalPartition &IP) { - // This currently just prints out information about the interval structure - // of the function... -#if 0 - static unsigned N = 0; - cerr << "\n***********Interval Partition #" << (++N) << "************\n\n"; - copy(IP.begin(), IP.end(), ostream_iterator(cerr, "\n")); - - cerr << "\n*********** PERFORMING WORK ************\n\n"; -#endif - // Loop over all of the intervals in the partition and look for induction - // variables in intervals that represent loops. - // - return reduce_apply(IP.begin(), IP.end(), bitwise_or(), false, - std::ptr_fun(ProcessInterval)); -} - -// DoInductionVariableCannonicalize - Simplify induction variables in loops. -// This function loops over an interval partition of a program, reducing it -// until the graph is gone. -// -bool InductionVariableCannonicalize::doIt(Function *M, IntervalPartition &IP) { - - bool Changed = false; - -#if 0 - while (!IP->isDegeneratePartition()) { - Changed |= ProcessIntervalPartition(*IP); - - // Calculate the reduced version of this graph until we get to an - // irreducible graph or a degenerate graph... - // - IntervalPartition *NewIP = new IntervalPartition(*IP, false); - if (NewIP->size() == IP->size()) { - cerr << "IRREDUCIBLE GRAPH FOUND!!!\n"; - return Changed; - } - delete IP; - IP = NewIP; - } - - delete IP; -#endif - return Changed; -} - - -bool InductionVariableCannonicalize::runOnFunction(Function *F) { - return doIt(F, getAnalysis()); -} - -// getAnalysisUsage - This function works on the call graph of a module. -// It is capable of updating the call graph to reflect the new state of the -// module. -// -void InductionVariableCannonicalize::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(IntervalPartition::ID); -}