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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
std::map<BasicBlock*,TreeNode*> bb_map;
std::map<BasicBlock*,unsigned int> nums_map;
// Spawn Random If
{
// Gen Random Tree
TreeNode tree;
genRandomTree(&tree, origBB_list.size());
tree.walk();
if( allocNode(&tree, 0, 0x7fffffff) ) { // 0x7fffffff
std::vector<BasicBlock*>::iterator iter= origBB_list.begin();
BasicBlock *head=createRandomBasicBlock(&tree, loopEntry->getParent(), switchVar, iter, &bb_map);
BranchInst::Create(head, loopEntry);
}
} // Spawn Random If
// 生成一颗不规则的二叉树 叶子节点的数量为基本块的数量
int llvm::FlatteningEnhanced::genRandomTree(TreeNode *node,int node_limit)
{
std::list<TreeNode*> son_list;
son_list.push_back(node);
// 当叶子节点数量达到node_limit时终止生成
while(son_list.size()!=node_limit)
{
// 从所有孩子节点中随机挑选一个孩子节点
std::list<TreeNode*>::iterator tmp = llvm::Utils::randomChooseElementFromList(&son_list);
TreeNode *node=*tmp;
node->expandNode();
son_list.push_back(node->left);
son_list.push_back(node->right);
son_list.erase(tmp);
}
return son_list.size();
}
// 在[l, r]的大区间上,为当前节点的所有子节点设定一段唯一的左闭右开的区间
bool llvm::FlatteningEnhanced::allocNode(TreeNode *node,unsigned int l,unsigned int r)
{
if(r-l<node->limit)
return false;
node->l=l;
node->r=r;
if(node->left==NULL && node->right==NULL)
return true;
unsigned int var;
if(r-l-node->limit==0)
var=0;
else
var=rand()%(r-l-node->limit);
unsigned int mid=l+node->left->limit+var;
if(!allocNode(node->left,l,mid) || !allocNode(node->right,mid,r))
return false;
return true;
}
// 把基本块排列到所有叶子节点上 并创建子分发块
BasicBlock * llvm::FlatteningEnhanced::createRandomBasicBlock(TreeNode *node,Function *f,Value *var,std::vector<BasicBlock*>::iterator &iter,std::map<BasicBlock*,TreeNode*> *bb_info)
{
// 若是叶子节点 则对该节点建立到基本块的映射
if(node->left==NULL && node->right==NULL)
{
BasicBlock *bb=*iter;
bb_info->insert(std::pair<BasicBlock*,TreeNode*>(bb,node));
iter++;
return bb;
}
// 若非叶子节点 建立一个分发块
BasicBlock *left_bb=createRandomBasicBlock(node->left,f,var,iter,bb_info);
BasicBlock *right_bb=createRandomBasicBlock(node->right,f,var,iter,bb_info);
BasicBlock *node_bb=BasicBlock::Create(f->getContext(),"knot",f);
if(node->left->r!=node->right->l) // 左闭右开区间断言
errs()<<"Error!\n";
// 在分发块末尾插入if语句 若switch变量小于 node->left->r 则跳转到node->left 否则跳转到node->right
LoadInst *load=new LoadInst(TYPE_I32, var, "", node_bb);
ICmpInst *condition=new ICmpInst(*node_bb, ICmpInst::ICMP_ULT, load, ConstantInt::get(TYPE_I32, node->left->r));
BranchInst::Create(left_bb,right_bb,(Value*)condition,node_bb);
return node_bb;
}
|