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()) {
void dfsrun(BasicBlock *bb) { if (_f.is_declaration())
vis[bb] = true; continue;
path.push_back(bb); auto func = &_f;
for (auto succ : bb->get_succ_basic_blocks()) { // cout << func->get_name() << endl;
if (vis[succ]) { auto belist = detect_back(func);
string type; auto sloops = check_sloops(belist);
Edge edge(bb, succ); cout << "get simple loops for function " << func->get_name() << ":\n";
if (find(path.rbegin(), path.rend(), succ) == path.rend()) { for (auto sl : sloops) {
type = "cross-edge"; cout << "\t";
} else { for (auto p : sl)
type = "back-edge"; cout << p->get_name() << " ";
edges.push_back(edge); cout << "\n";
}
/* cout << "find " << type << ": " << LoopUnroll::str(edge)
* << "\n"; */
} else
dfsrun(succ);
} }
}
}
path.pop_back(); LoopAnalysis::LoopAnalysis(const Graph::SimpleLoop &sl) {
auto b = sl.front();
auto e = sl.back();
// In `p`, get stop number(const)
Value *i;
auto rit = b->get_instructions().rbegin();
assert(dynamic_cast<BranchInst *>(&*rit) &&
"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 {
Type = INT;
auto constint = dynamic_cast<ConstantInt *>(rit->get_operand(1));
assert(constint && "the case const at operand(0) not implemented");
threshold.v = constint->get_value();
}
} else {
Type = UNDEF;
return;
} }
vector<BasicBlock *> path; // get control value and initial value
map<BasicBlock *, bool> vis; auto control = rit->get_operand(0);
BackEdgeList edges; 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;
}
}
BackEdgeList // get delta
LoopUnroll::detect_back(Function *func) {
BackEdgeSearcher search(func->get_entry_block()); // check correctness
return search.edges;
// count loop
} }
vector<SimpleLoop> vector<SimpleLoop>
...@@ -58,8 +116,8 @@ LoopUnroll::check_sloops(const BackEdgeList &belist) const { ...@@ -58,8 +116,8 @@ LoopUnroll::check_sloops(const BackEdgeList &belist) const {
b->get_pre_basic_blocks().size() != 2) b->get_pre_basic_blocks().size() != 2)
continue; continue;
bool flag = true; bool flag = true;
// the start node should have 2*2 degree, and others have 1*1 degree // the start node should have 2*2 degree, and others have 1*1 degree
// one exception: br to neg_idx_except // one exception: br to neg_idx_except
for (auto p = e; p != b; p = *p->get_pre_basic_blocks().begin()) { for (auto p = e; p != b; p = *p->get_pre_basic_blocks().begin()) {
if (p->get_pre_basic_blocks().size() != 1) { if (p->get_pre_basic_blocks().size() != 1) {
flag = false; flag = false;
...@@ -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