ForLoopV2.h 1.87 KB
Newer Older
guruhegde's avatar
guruhegde committed
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
#ifndef TAS_FORLOOPV2_H
#define TAS_FORLOOPV2_H

#include <llvm/Analysis/LoopInfo.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Value.h>

namespace tas {

// This is similar to Loop object available in LoopInfo object
// but simple.
class IRLoop {
  llvm::BasicBlock * PreHeader;
  llvm::BasicBlock * Header;
  llvm::BasicBlock * Latch;
  llvm::BasicBlock * EmptyBody; // Useful for creating empty loop.
  llvm::AllocaInst * IdxAlloca;
  llvm::SmallVector<llvm::BasicBlock *, 4> Blocks;

public:
  IRLoop() = default;

  void analyze(llvm::Loop * L);
guruhegde's avatar
guruhegde committed
26
  void constructEmptyLoop(llvm::AllocaInst * TripCount,
guruhegde's avatar
guruhegde committed
27 28
                          llvm::BasicBlock * InsertAfter);
  void extractLoopSkeleton(llvm::Loop * L);
guruhegde's avatar
guruhegde committed
29
  void setLoopBlocks(std::vector<llvm::BasicBlock *> & Blocks);
guruhegde's avatar
guruhegde committed
30 31 32 33 34 35 36 37

  llvm::BasicBlock * getPreHeader() {
    return PreHeader;
  }

  llvm::BasicBlock * getHeader() {
    return Header;
  }
guruhegde's avatar
guruhegde committed
38 39 40 41 42 43 44 45 46 47

  void printLooopInfo() {
    llvm::errs() << "LoopInfo:";
    Header->printAsOperand(llvm::errs());
    llvm::errs() << "  ";
    Latch->printAsOperand(llvm::errs());
    llvm::errs() << "  ";
    llvm::errs() << *IdxAlloca << "\n";
    llvm::errs() << " No of Blocks = " << Blocks.size() << "\n";
  }
guruhegde's avatar
guruhegde committed
48 49 50 51 52 53 54 55 56 57
};

class LoopBodyTraverser {
  llvm::SmallVector<llvm::BasicBlock *, 4> ExitBlocks;

public:
  LoopBodyTraverser(llvm::Loop * L) {
    L->getExitBlocks(ExitBlocks);
  }

guruhegde's avatar
guruhegde committed
58 59 60 61
  void traverse(std::vector<llvm::BasicBlock *> & Blocks,
                llvm::BasicBlock * Start, llvm::BasicBlock * End);

  void traverseReverse(std::vector<llvm::BasicBlock *> & Blocks,
guruhegde's avatar
guruhegde committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
                llvm::BasicBlock * Start, llvm::BasicBlock * End);

  void printExitBlocks() {
    llvm::errs() << "Exit blocks = ";
    for (auto & BB : ExitBlocks) {
      BB->printAsOperand(llvm::errs());
      llvm::errs() << " ";
    }
    llvm::errs() << "\n";
  }
};

}

#endif