aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar/InductionVars.cpp
blob: a9e4c5b5cb0fbef445d683b0b3a4e2310e01bde3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//===- 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 (that used to contain
//     at least one induction variable)
//   - This induction variable starts at 0 and steps by 1 per iteration
//   - All other preexisting induction variables are adjusted to operate in
//     terms of this primary induction variable
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/Intervals.h"
#include "llvm/Opt/AllOpts.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Tools/STLExtras.h"

static bool ProcessInterval(cfg::Interval *Int) {
  if (!Int->isLoop()) return false;  // Not a loop?  Ignore it!

  cerr << "Found Looping Interval: " << Int; //->HeaderNode;
  return false;
}

static bool ProcessIntervalPartition(cfg::IntervalPartition &IP) {
  // This currently just prints out information about the interval structure
  // of the method...
  static unsigned N = 0;
  cerr << "\n***********Interval Partition #" << (++N) << "************\n\n";
  copy(IP.begin(), IP.end(), ostream_iterator<cfg::Interval*>(cerr, "\n"));

  cerr << "\n*********** PERFORMING WORK ************\n\n";

  // 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<bool>(), false,
		      ptr_fun(ProcessInterval));
}

// DoInductionVariableCannonicalize - Simplify induction variables in loops
//
bool DoInductionVariableCannonicalize(Method *M) {
  cfg::IntervalPartition *IP = new cfg::IntervalPartition(M);
  bool Changed = false;

  while (!IP->isDegeneratePartition()) {
    Changed |= ProcessIntervalPartition(*IP);

    // Calculate the reduced version of this graph until we get to an 
    // irreducible graph or a degenerate graph...
    //
    cfg::IntervalPartition *NewIP = new cfg::IntervalPartition(*IP, false);
    if (NewIP->size() == IP->size()) {
      cerr << "IRREDUCIBLE GRAPH FOUND!!!\n";
      return Changed;
    }
    delete IP;
    IP = NewIP;
  }

  delete IP;
  return Changed;
}