Commit efe0d887 authored by lxq's avatar lxq

start loop analysis code

parent 29b9788b
...@@ -4,13 +4,16 @@ ...@@ -4,13 +4,16 @@
#include "BasicBlock.h" #include "BasicBlock.h"
#include "Module.h" #include "Module.h"
#include "PassManager.hpp" #include "PassManager.hpp"
#include "Type.h"
#include <map>
#include <ostream> #include <ostream>
#include <string> #include <string>
#include <vector> #include <vector>
using std::cout; using std::cout;
using std::endl; using std::endl;
using std::map;
using std::string; using std::string;
using std::to_string; using std::to_string;
using std::vector; using std::vector;
...@@ -20,8 +23,29 @@ namespace Graph { ...@@ -20,8 +23,29 @@ namespace Graph {
using Edge = std::pair<BasicBlock *, BasicBlock *>; using Edge = std::pair<BasicBlock *, BasicBlock *>;
using BackEdgeList = vector<Edge>; using BackEdgeList = vector<Edge>;
using SimpleLoop = vector<BasicBlock *>; using SimpleLoop = vector<BasicBlock *>;
}
struct BackEdgeSearcher {
BackEdgeSearcher(BasicBlock *entry) { dfsrun(entry); }
void dfsrun(BasicBlock *bb);
vector<BasicBlock *> path;
map<BasicBlock *, bool> vis;
BackEdgeList edges;
};
} // namespace Graph
namespace Analysis{
struct LoopAnalysis {
LoopAnalysis(const Graph::SimpleLoop &);
LoopAnalysis() = delete;
enum { INT, FLOAT, UNDEF} Type;
union {
int v;
float fv;
} initial, delta, threshold;
};}
/* This is a class to unroll simple loops: /* This is a class to unroll simple loops:
* - strict structure: * - strict structure:
......
#include "LoopUnroll.hpp" #include "LoopUnroll.hpp"
#include "BasicBlock.h" #include "BasicBlock.h"
#include "Constant.h"
#include "Function.h" #include "Function.h"
#include "Instruction.h" #include "Instruction.h"
#include "syntax_analyzer.h" #include "syntax_analyzer.h"
#include <map>
#include <vector> #include <vector>
using std::find; using std::find;
using std::map;
using namespace Graph; using namespace Graph;
using namespace Analysis;
struct BackEdgeSearcher { void
BackEdgeSearcher(BasicBlock *entry) { dfsrun(entry); } LoopUnroll::run() {
for (auto &_f : m_->get_functions()) {
if (_f.is_declaration())
continue;
auto func = &_f;
// cout << func->get_name() << endl;
auto belist = detect_back(func);
auto sloops = check_sloops(belist);
cout << "get simple loops for function " << func->get_name() << ":\n";
for (auto sl : sloops) {
cout << "\t";
for (auto p : sl)
cout << p->get_name() << " ";
cout << "\n";
}
}
}
void dfsrun(BasicBlock *bb) { LoopAnalysis::LoopAnalysis(const Graph::SimpleLoop &sl) {
vis[bb] = true; auto b = sl.front();
path.push_back(bb); auto e = sl.back();
for (auto succ : bb->get_succ_basic_blocks()) {
if (vis[succ]) { // In `p`, get stop number(const)
string type; Value *i;
Edge edge(bb, succ); auto rit = b->get_instructions().rbegin();
if (find(path.rbegin(), path.rend(), succ) == path.rend()) { assert(dynamic_cast<BranchInst *>(&*rit) &&
type = "cross-edge"; "The end instruction of a block should be branch");
i = (rit++)->get_operand(0);
assert(i == &*rit && dynamic_cast<CmpInst *>(&*rit) &&
static_cast<CmpInst *>(&*rit)->get_cmp_op() == CmpInst::NE &&
"should be neq 0");
i = (rit++)->get_operand(0);
assert(i == &*rit && dynamic_cast<ZextInst *>(&*rit) && "neqz");
i = (rit++)->get_operand(0);
assert(
i == &*rit &&
(dynamic_cast<CmpInst *>(&*rit) or dynamic_cast<FCmpInst *>(&*rit)) &&
"cmp or fcmp");
if (dynamic_cast<Constant *>(rit->get_operand(0)) or
dynamic_cast<Constant *>(rit->get_operand(1))) {
if (dynamic_cast<CmpInst *>(&*rit)) {
Type = FLOAT;
auto constfloat = dynamic_cast<ConstantFP *>(rit->get_operand(1));
assert(constfloat &&
"the case const at operand(0) not implemented");
threshold.fv = constfloat->get_value();
} else { } else {
type = "back-edge"; Type = INT;
edges.push_back(edge); auto constint = dynamic_cast<ConstantInt *>(rit->get_operand(1));
assert(constint && "the case const at operand(0) not implemented");
threshold.v = constint->get_value();
} }
/* cout << "find " << type << ": " << LoopUnroll::str(edge) } else {
* << "\n"; */ Type = UNDEF;
} else return;
dfsrun(succ);
} }
path.pop_back(); // get control value and initial value
auto control = rit->get_operand(0);
auto it = b->get_instructions().begin();
for (; it != b->get_instructions().end(); ++it) {
auto phi = dynamic_cast<PhiInst *>(&*it);
assert(phi && "unexpected structure for while block");
if (&*it != control)
continue;
assert(phi->get_operand(3) == e && "the orther case not implemented");
if (dynamic_cast<Constant *>(phi->get_operand(0))) {
switch (Type) {
case INT:
initial.v = static_cast<ConstantInt *>(phi->get_operand(0))
->get_value();
break;
case FLOAT:
initial.fv = static_cast<ConstantFP *>(phi->get_operand(0))
->get_value();
break;
case UNDEF:
assert(false);
break;
}
} else {
Type = UNDEF;
return;
}
} }
vector<BasicBlock *> path; // get delta
map<BasicBlock *, bool> vis;
BackEdgeList edges;
};
BackEdgeList // check correctness
LoopUnroll::detect_back(Function *func) {
BackEdgeSearcher search(func->get_entry_block()); // count loop
return search.edges;
} }
vector<SimpleLoop> vector<SimpleLoop>
...@@ -91,21 +149,32 @@ LoopUnroll::check_sloops(const BackEdgeList &belist) const { ...@@ -91,21 +149,32 @@ LoopUnroll::check_sloops(const BackEdgeList &belist) const {
} }
return sloops; return sloops;
} }
BackEdgeList
LoopUnroll::detect_back(Function *func) {
BackEdgeSearcher search(func->get_entry_block());
return search.edges;
}
void void
LoopUnroll::run() { BackEdgeSearcher::dfsrun(BasicBlock *bb) {
for (auto &_f : m_->get_functions()) { vis[bb] = true;
if (_f.is_declaration()) path.push_back(bb);
continue; for (auto succ : bb->get_succ_basic_blocks()) {
auto func = &_f; if (vis[succ]) {
// cout << func->get_name() << endl; string type;
auto belist = detect_back(func); Edge edge(bb, succ);
auto sloops = check_sloops(belist); if (find(path.rbegin(), path.rend(), succ) == path.rend()) {
cout << "get simple loops for function " << func->get_name() << ":\n"; type = "cross-edge";
for (auto sl : sloops) { } else {
cout << "\t"; type = "back-edge";
for (auto p : sl) edges.push_back(edge);
cout << p->get_name() << " ";
cout << "\n";
} }
/* cout << "find " << type << ": " << LoopUnroll::str(edge)
* << "\n"; */
} else
dfsrun(succ);
} }
path.pop_back();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment