37 #include "tce_config.h"
43 #include <llvm/Analysis/LoopPass.h>
44 #include <llvm/Analysis/ScalarEvolution.h>
45 #include <llvm/Support/CommandLine.h>
47 #include "tce_config.h"
49 #include <llvm/IR/Module.h>
50 #include <llvm/IR/Constants.h>
51 #include <llvm/Analysis/LoopInfo.h>
52 #include "llvm/Transforms/Scalar.h"
53 #include "llvm/Transforms/Utils.h"
54 #include <llvm/Pass.h>
55 #include "llvm/CodeGen/Passes.h"
58 #include "llvm/InitializePasses.h"
62 static llvm::cl::opt<bool>
64 (
"dump-loop-info", llvm::cl::init(
false), llvm::cl::Hidden,
65 llvm::cl::desc(
"Dump information about loops to files named [modulename].loopinfo.txt."));
68 "find-innerloops-test",
69 "Finds inner loops test.",
false,
true);
73 "Finds info of the inner loops in the program.",
75 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
76 INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
77 INITIALIZE_PASS_DEPENDENCY(LCSSAWrapperPass)
80 "Finds info of the inner loops in the
program.",
100 AU.setPreservesCFG();
101 AU.addRequiredID(llvm::LoopSimplifyID);
102 AU.addRequiredID(llvm::LCSSAID);
103 AU.addPreservedID(llvm::LCSSAID);
104 AU.addRequired<llvm::LoopInfoWrapperPass>();
105 AU.addRequired<llvm::ScalarEvolutionWrapperPass>();
106 AU.addPreserved<llvm::LoopInfoWrapperPass>();
107 AU.addPreserved<llvm::ScalarEvolutionWrapperPass>();
113 for (DumpFileIndex::iterator i = dumpFiles.begin();
114 i != dumpFiles.end(); ++i) {
115 std::ostream* stream = (*i).second;
131 std::string moduleName =
132 l->getHeader()->getParent()->getParent()->getModuleIdentifier();
133 std::string fName = moduleName +
".loopinfo.txt";
134 if (moduleName ==
"<stdin>") {
135 fName =
"loopinfo.txt";
138 if (dumpFiles.find(moduleName) == dumpFiles.end()) {
139 std::fstream* outStream =
142 std::ios_base::out | std::ios_base::trunc);
143 dumpFiles[moduleName] = outStream;
145 return *dumpFiles[moduleName];
157 std::ostringstream ss;
158 assert(l->getHeader() != NULL);
159 assert(l->getHeader()->getParent() != NULL);
160 std::string curProcName = l->getHeader()->getParent()->getName().str();
161 ss <<
"in " << curProcName <<
"()";
172 const std::vector<llvm::Loop*>& subLoops = l->getSubLoops();
174 unsigned subLoopCount = subLoops.size();
175 unsigned tripCount = getSmallConstantTripCount(l);
176 unsigned bbCount = l->getBlocks().size();
180 llvm::SmallVector<llvm::BasicBlock*, 10> exitingBlocks;
192 l->getExitingBlocks(exitingBlocks);
193 unsigned exitingBlockCount = exitingBlocks.size();
196 unsigned callCount = 0;
197 if (subLoopCount == 0) {
198 for (llvm::LoopBase<llvm::BasicBlock, llvm::Loop>::
200 l->block_begin(); bb != l->block_end(); ++bb) {
201 llvm::BasicBlock& basicBlock = **bb;
202 for (llvm::BasicBlock::iterator i = basicBlock.begin();
203 i != basicBlock.end(); ++i) {
204 llvm::Instruction& instruction = *i;
205 if (instruction.getOpcode() == llvm::Instruction::Call)
211 const bool innerLoop =
212 bbCount == 1 && subLoopCount == 0 && callCount == 0;
215 if (dump && tripCount > 0) {
216 out(l) <<
"found an inner loop with trip count "
217 << tripCount << std::endl;
219 assert(l->getBlocks().size() > 0);
222 loopInfos_[l->getBlocks()[0]] = loopInfo;
226 out(l) <<
"loop: " << loopDescription(l) << std::endl
227 <<
"depth: " << l->getLoopDepth() << std::endl;
228 out(l) <<
"sub loops: " << subLoopCount << std::endl;
229 out(l) <<
"trip count: ";
230 if (tripCount != 0) {
231 out(l) <<
"constant: " << tripCount;
233 out(l) <<
"unknown ";
236 out(l) <<
"basic blocks: " << bbCount << std::endl;
238 if (subLoopCount == 0)
239 out(l) <<
"calls: " << callCount << std::endl;
255 ScalarEvolution *SE =
256 &getAnalysis<llvm::ScalarEvolutionWrapperPass>().getSE();
257 llvm::BasicBlock* loopLatch = loop->getLoopLatch();
261 if (loopLatch == NULL || !loop->isLoopExiting(loopLatch))
263 return SE->getSmallConstantTripCount(loop, loopLatch);