-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBlock.cpp
More file actions
138 lines (125 loc) · 4.21 KB
/
Block.cpp
File metadata and controls
138 lines (125 loc) · 4.21 KB
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "Block.h"
#include <stdio.h>
Block::Block(unsigned int identifier, std::string label) :
_id(identifier),
_label(label)
{
}
Block::~Block()
{
}
unsigned int
Block::getId()
{
return _id;
}
std::string
Block::getLabel()
{
return _label;
}
Nodes
Block::getNodes()
{
return _nodes;
}
void
Block::setId(unsigned int value)
{
_id = value;
}
void
Block::setLabel(std::string value)
{
_label = value;
}
void
Block::appendNode(pNode node)
{
_nodes.push_back(node);
}
int
Block::findEdge(llvm::BasicBlock* block, std::map<llvm::BasicBlock*, pBlock> blocks)
{
int result = -1;
// The result is the id of the first node that should be displayed starting
// from the supplied block and traversing nodes (including across blocks)
// until one is found that should be displayed.
std::map<llvm::BasicBlock*, pBlock>::iterator entry = blocks.find(block);
if (entry != blocks.end()) {
Nodes nodes = entry->second->getNodes();
if (nodes.size() > 0) {
bool found = false;
for (unsigned int j = 0; j < nodes.size(); j++) {
if (nodes[j]->getNodeLabel().length() > 0) {
result = nodes[j]->getNodeId();
found = true;
break;
}
}
// If a node could not be found, recursively call findEdge for each block.
if (!found) {
std::map<std::string, llvm::BasicBlock*> i_blocks = nodes[nodes.size() - 1]->getBlockEdges();
result = findEdge(i_blocks.begin()->second, blocks);
}
}
}
return result;
}
void
Block::processNodes(std::map<llvm::BasicBlock*, pBlock> blocks)
{
// This is ugly, but works (in principle and reality).
// nextNodeId holds the id of the node to point to.
// Iterate through the nodes, starting at the end of the list.
// If we have identified the exit node id (ie, where we
// jump to another block), simply connect to the nextNodeId.
// Otherwise, we need to traverse through the connected
// blocks until we find a node suitable for display.
int nextNodeId = -1;
for (int i = _nodes.size() - 1; i >= 0; i--) {
if (nextNodeId > 0) {
// Only nodes with existing labels are processed
if (_nodes[i]->getNodeLabel().length() > 0) {
// Convert the next node id to a string and assign the
// current node as the next node since we're working backwards.
char buffer[255];
sprintf(buffer, "%d", nextNodeId);
_nodes[i]->addNodeEdge(new Edge(buffer));
nextNodeId = _nodes[i]->getNodeId();
}
} else {
if (_nodes[i]->getNodeLabel().length() > 0) {
/*
char buffer[255];
sprintf(buffer, "%d", nextNodeId);
std::string edgeLabel = std::string(buffer);
_nodes[i]->addNodeEdge(new Edge(edgeLabel));
*/
nextNodeId = _nodes[i]->getNodeId();
}
// Determine the blocks the node links to
std::map<std::string, llvm::BasicBlock*> mapping =
_nodes[i]->getBlockEdges();
// For each node this one links to...
for (std::map<std::string, llvm::BasicBlock*>::iterator it = mapping.begin();
it != mapping.end();
it++) {
// Find the id for the edge that corresponds to the first node that
// would be displayed. If the node has a label, it is
// the next id and the found edge is it's next id.
// Otherwise, the next id is the found edge.
int edgeId = findEdge(it->second, blocks);
if (_nodes[i]->getNodeLabel().length() > 0) {
char buffer[255];
sprintf(buffer, "%d", edgeId);
std::string edgeLabel = std::string(buffer);
_nodes[i]->addNodeEdge(new Edge(edgeLabel, it->first));
nextNodeId = _nodes[i]->getNodeId();
} else {
nextNodeId = edgeId;
}
}
}
}
}