Skip to content

Commit 94a6014

Browse files
committed
Introduce emitter
1 parent 9756e0a commit 94a6014

File tree

12 files changed

+594
-59
lines changed

12 files changed

+594
-59
lines changed

include/Builder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,23 @@
66
#include <memory>
77
#include <vector>
88

9+
#include <llvm/IR/Instructions.h>
10+
911
namespace llvm2graphml {
1012

1113
class Builder {
1214
public:
1315
Node *newModuleNode();
1416
Node *newFunctionNode();
1517
Node *newBasicBlockNode();
18+
Node *newInstructionNode();
19+
Node *newValueNode();
1620

1721
void connectModule(Node *moduleNode, Node *anyNode);
1822
void connectFunction(Node *functionNode, Node *anyNode);
23+
void connectInstruction(Node *instructionNode, Node *anyNode);
1924
void connectBasicBlocks(Node *successor, Node *predecessor);
25+
void connectOperand(Node *instructionNode, Node *anyValue, unsigned index);
2026

2127
const std::vector<std::unique_ptr<Node>> &getNodes() const;
2228
const std::vector<std::unique_ptr<Edge>> &getEdges() const;

include/Edge.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55

66
namespace llvm2graphml {
77

8-
enum class EdgeKind { Module, Function, Successor, Predecessor };
8+
enum class EdgeKind { Module, Function, Successor, Predecessor, Instruction, Operand };
99

1010
class Edge {
1111
public:
1212
Edge(uint64_t id, uint64_t source, uint64_t target);
1313

1414
void setKind(EdgeKind kind);
15+
void setOrder(unsigned order);
1516

1617
const Properties &getProperties() const;
1718
uint64_t getID() const;

include/Emitter.h

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#pragma once
2+
3+
#include <llvm/IR/Instructions.h>
4+
#include <unordered_map>
5+
6+
namespace llvm {
7+
8+
class Module;
9+
class Function;
10+
class BasicBlock;
11+
class Instruction;
12+
class ReturnInst;
13+
14+
} // namespace llvm
15+
16+
namespace llvm2graphml {
17+
18+
class Builder;
19+
class Node;
20+
21+
class Emitter {
22+
public:
23+
explicit Emitter(Builder &builder);
24+
void emit(const llvm::Module *module);
25+
26+
private:
27+
Builder &builder;
28+
std::unordered_map<const llvm::Value *, Node *> emittedValues;
29+
30+
void dispatchInstruction(const llvm::Instruction *instruction, Node *node);
31+
Node *emit(const llvm::Value *value);
32+
33+
/// Extension points
34+
35+
void fillIn(const llvm::Module *module, Node *node);
36+
void fillIn(const llvm::Function *function, Node *node);
37+
void fillIn(const llvm::BasicBlock *basicBlock, Node *node);
38+
39+
void fillIn(const llvm::Argument *argument, Node *node);
40+
void fillIn(const llvm::ConstantInt *constant, Node *node);
41+
void fillIn(const llvm::ConstantFP *constant, Node *node);
42+
void fillIn(const llvm::ConstantPointerNull *constant, Node *node);
43+
void fillIn(const llvm::ConstantTokenNone *constant, Node *node);
44+
void fillIn(const llvm::UndefValue *undefValue, Node *node);
45+
void fillIn(const llvm::InlineAsm *inlineAsm, Node *node);
46+
void fillIn(const llvm::MetadataAsValue *metadataAsValue, llvm2graphml::Node *node);
47+
void fillIn(const llvm::BlockAddress *blockAddress, llvm2graphml::Node *node);
48+
void fillIn(const llvm::ConstantArray *constantArray, llvm2graphml::Node *node);
49+
void fillIn(const llvm::ConstantDataArray *constantArray, llvm2graphml::Node *node);
50+
void fillIn(const llvm::GlobalAlias *globalAlias, llvm2graphml::Node *node);
51+
void fillIn(const llvm::GlobalIFunc *globalIFunc, llvm2graphml::Node *node);
52+
void fillIn(const llvm::GlobalVariable *globalVariable, llvm2graphml::Node *node);
53+
void fillIn(const llvm::ConstantExpr *constantExpr, llvm2graphml::Node *node);
54+
void fillIn(const llvm::ConstantStruct *constantStruct, llvm2graphml::Node *node);
55+
void fillIn(const llvm::ConstantVector *constantVector, llvm2graphml::Node *node);
56+
void fillIn(const llvm::ConstantAggregateZero *constantZero, llvm2graphml::Node *node);
57+
void fillIn(const llvm::ConstantDataVector *constantVector, llvm2graphml::Node *node);
58+
59+
void fillIn(const llvm::Instruction *instruction, Node *node);
60+
void fillIn(const llvm::ReturnInst *instruction, Node *node);
61+
void fillIn(const llvm::BranchInst *instruction, Node *node);
62+
void fillIn(const llvm::SwitchInst *instruction, Node *node);
63+
void fillIn(const llvm::IndirectBrInst *instruction, Node *node);
64+
void fillIn(const llvm::InvokeInst *instruction, Node *node);
65+
void fillIn(const llvm::ResumeInst *instruction, Node *node);
66+
void fillIn(const llvm::UnreachableInst *instruction, Node *node);
67+
void fillIn(const llvm::CleanupReturnInst *instruction, Node *node);
68+
void fillIn(const llvm::CatchReturnInst *instruction, Node *node);
69+
void fillIn(const llvm::CatchSwitchInst *instruction, Node *node);
70+
void fillIn(const llvm::CallBrInst *instruction, Node *node);
71+
void fillIn(const llvm::UnaryOperator *instruction, Node *node);
72+
void fillIn(const llvm::BinaryOperator *instruction, Node *node);
73+
void fillIn(const llvm::AllocaInst *instruction, Node *node);
74+
void fillIn(const llvm::LoadInst *instruction, Node *node);
75+
void fillIn(const llvm::StoreInst *instruction, Node *node);
76+
void fillIn(const llvm::GetElementPtrInst *instruction, Node *node);
77+
void fillIn(const llvm::FenceInst *instruction, Node *node);
78+
void fillIn(const llvm::AtomicCmpXchgInst *instruction, Node *node);
79+
void fillIn(const llvm::AtomicRMWInst *instruction, Node *node);
80+
void fillIn(const llvm::TruncInst *instruction, Node *node);
81+
void fillIn(const llvm::ZExtInst *instruction, Node *node);
82+
void fillIn(const llvm::SExtInst *instruction, Node *node);
83+
void fillIn(const llvm::FPToUIInst *instruction, Node *node);
84+
void fillIn(const llvm::FPToSIInst *instruction, Node *node);
85+
void fillIn(const llvm::UIToFPInst *instruction, Node *node);
86+
void fillIn(const llvm::SIToFPInst *instruction, Node *node);
87+
void fillIn(const llvm::FPTruncInst *instruction, Node *node);
88+
void fillIn(const llvm::FPExtInst *instruction, Node *node);
89+
void fillIn(const llvm::PtrToIntInst *instruction, Node *node);
90+
void fillIn(const llvm::IntToPtrInst *instruction, Node *node);
91+
void fillIn(const llvm::BitCastInst *instruction, Node *node);
92+
void fillIn(const llvm::AddrSpaceCastInst *instruction, Node *node);
93+
void fillIn(const llvm::CleanupPadInst *instruction, Node *node);
94+
void fillIn(const llvm::CatchPadInst *instruction, Node *node);
95+
void fillIn(const llvm::ICmpInst *instruction, Node *node);
96+
void fillIn(const llvm::FCmpInst *instruction, Node *node);
97+
void fillIn(const llvm::PHINode *instruction, Node *node);
98+
void fillIn(const llvm::CallInst *instruction, Node *node);
99+
void fillIn(const llvm::SelectInst *instruction, Node *node);
100+
void fillIn(const llvm::VAArgInst *instruction, Node *node);
101+
void fillIn(const llvm::ExtractElementInst *instruction, Node *node);
102+
void fillIn(const llvm::InsertElementInst *instruction, Node *node);
103+
void fillIn(const llvm::ShuffleVectorInst *instruction, Node *node);
104+
void fillIn(const llvm::ExtractValueInst *instruction, Node *node);
105+
void fillIn(const llvm::InsertValueInst *instruction, Node *node);
106+
void fillIn(const llvm::LandingPadInst *instruction, Node *node);
107+
};
108+
109+
} // namespace llvm2graphml

include/Node.h

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,44 @@
55

66
namespace llvm2graphml {
77

8-
enum class NodeKind { Module, Function, BasicBlock };
8+
enum class NodeKind { Module, Function, BasicBlock, Instruction, Value };
9+
enum class ValueKind {
10+
Argument,
11+
ConstantInt,
12+
ConstantFP,
13+
ConstantPointerNull,
14+
ConstantTokenNone,
15+
ConstantArray,
16+
ConstantDataArray,
17+
UndefValue,
18+
InlineAsm,
19+
MetadataAsValue,
20+
BlockAddress,
21+
GlobalAlias,
22+
GlobalIFunc,
23+
GlobalVariable,
24+
ConstantExpr,
25+
ConstantStruct,
26+
ConstantVector,
27+
ConstantAggregateZero,
28+
ConstantDataVector,
29+
};
930

1031
class Node {
1132
public:
1233
explicit Node(uint64_t id, NodeKind kind);
1334

14-
void setModuleIdentifier(std::string identifier);
15-
void setName(std::string name);
16-
void setIsDeclaration(bool isDeclaration);
17-
void setIsVarArg(bool isVarArg);
18-
void setIsIntrinsic(bool isIntrinsic);
19-
void setNumOperands(uint64_t numOperands);
20-
void setArgSize(uint64_t argSize);
21-
void setInstructionCount(uint64_t instructionCount);
22-
void setBasicBlockCount(uint64_t basicBlockCount);
35+
Node &setModuleIdentifier(std::string identifier);
36+
Node &setName(std::string name);
37+
Node &setIsDeclaration(bool isDeclaration);
38+
Node &setIsVarArg(bool isVarArg);
39+
Node &setIsIntrinsic(bool isIntrinsic);
40+
Node &setNumOperands(uint64_t numOperands);
41+
Node &setArgSize(uint64_t argSize);
42+
Node &setInstructionCount(uint64_t instructionCount);
43+
Node &setBasicBlockCount(uint64_t basicBlockCount);
44+
Node &setInstructionOpcode(const char *opcodeName);
45+
Node &setValueKind(ValueKind valueKind);
2346

2447
const Properties &getProperties() const;
2548
uint64_t getID() const;

src/Builder.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ Node *Builder::newBasicBlockNode() {
3434
return newNode(NodeKind::BasicBlock);
3535
}
3636

37+
Node *Builder::newInstructionNode() {
38+
return newNode(NodeKind::Instruction);
39+
}
40+
41+
Node *Builder::newValueNode() {
42+
return newNode(NodeKind::Value);
43+
}
44+
3745
/// Edge Connectors
3846

3947
void Builder::connectModule(Node *moduleNode, Node *anyNode) {
@@ -48,10 +56,24 @@ void Builder::connectFunction(Node *functionNode, Node *anyNode) {
4856
newEdge(anyNode->getID(), functionNode->getID())->setKind(EdgeKind::Function);
4957
}
5058

59+
void Builder::connectInstruction(Node *instructionNode, Node *anyNode) {
60+
assert(instructionNode->getKind() == NodeKind::Instruction);
61+
62+
newEdge(anyNode->getID(), instructionNode->getID())->setKind(EdgeKind::Instruction);
63+
}
64+
5165
void Builder::connectBasicBlocks(Node *successor, Node *predecessor) {
5266
assert(successor->getKind() == NodeKind::BasicBlock);
5367
assert(predecessor->getKind() == NodeKind::BasicBlock);
5468

5569
newEdge(predecessor->getID(), successor->getID())->setKind(EdgeKind::Successor);
5670
newEdge(successor->getID(), predecessor->getID())->setKind(EdgeKind::Predecessor);
5771
}
72+
73+
void Builder::connectOperand(Node *instructionNode, Node *anyValue, unsigned index) {
74+
assert(instructionNode->getKind() == NodeKind::Instruction);
75+
76+
Edge *edge = newEdge(instructionNode->getID(), anyValue->getID());
77+
edge->setKind(EdgeKind::Operand);
78+
edge->setOrder(index);
79+
}

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set (SOURCES
77
Builder.cpp
88
Logger.cpp
99
BitcodeLoader.cpp
10+
Emitter.cpp
1011
llvm2graphmlTool.cpp
1112
)
1213

src/Edge.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ static std::string edgeKindToString(EdgeKind kind) {
1212
return "successor";
1313
case EdgeKind::Predecessor:
1414
return "predecessor";
15+
case EdgeKind::Instruction:
16+
return "instruction";
17+
case EdgeKind::Operand:
18+
return "operand";
1519
}
1620
}
1721

@@ -37,3 +41,7 @@ uint64_t Edge::getSourceID() const {
3741
uint64_t Edge::getTargetID() const {
3842
return targetId;
3943
}
44+
45+
void Edge::setOrder(unsigned order) {
46+
properties.setLongProperty("order", order);
47+
}

0 commit comments

Comments
 (0)