Skip to content

Commit 82cdb89

Browse files
committed
Emit types
1 parent 94a6014 commit 82cdb89

File tree

17 files changed

+455
-9
lines changed

17 files changed

+455
-9
lines changed

include/Builder.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@ class Builder {
1717
Node *newBasicBlockNode();
1818
Node *newInstructionNode();
1919
Node *newValueNode();
20+
Node *newTypeNode();
2021

2122
void connectModule(Node *moduleNode, Node *anyNode);
2223
void connectFunction(Node *functionNode, Node *anyNode);
24+
void connectArgument(Node *functionNode, Node *argumentNode, unsigned order);
2325
void connectInstruction(Node *instructionNode, Node *anyNode);
2426
void connectBasicBlocks(Node *successor, Node *predecessor);
25-
void connectOperand(Node *instructionNode, Node *anyValue, unsigned index);
27+
void connectOperand(Node *instructionNode, Node *anyValue, unsigned order);
28+
void connectPointeeType(Node *pointerNode, Node *pointeeNode);
29+
void connectFunctionReturnType(Node *functionType, Node *returnType);
30+
void connectFunctionParameterType(Node *functionType, Node *parameterType, unsigned order);
31+
void connectStructElementType(Node *structType, Node *elementType, unsigned order);
32+
void connectElementType(Node *type, Node *elementType);
33+
void connectType(Node *type, Node *node);
2634

2735
const std::vector<std::unique_ptr<Node>> &getNodes() const;
2836
const std::vector<std::unique_ptr<Edge>> &getEdges() const;

include/Edge.h

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

66
namespace llvm2graphml {
77

8-
enum class EdgeKind { Module, Function, Successor, Predecessor, Instruction, Operand };
8+
enum class EdgeKind {
9+
Module,
10+
Function,
11+
Argument,
12+
Successor,
13+
Predecessor,
14+
Instruction,
15+
Operand,
16+
PointeeType,
17+
ReturnType,
18+
ParameterType,
19+
ElementType,
20+
Type
21+
};
922

1023
class Edge {
1124
public:

include/Emitter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@ namespace llvm2graphml {
1717

1818
class Builder;
1919
class Node;
20+
class TypeEmitter;
2021

2122
class Emitter {
2223
public:
23-
explicit Emitter(Builder &builder);
24+
Emitter(Builder &builder, TypeEmitter &typeEmitter);
2425
void emit(const llvm::Module *module);
2526

2627
private:
2728
Builder &builder;
29+
TypeEmitter &typeEmitter;
2830
std::unordered_map<const llvm::Value *, Node *> emittedValues;
2931

3032
void dispatchInstruction(const llvm::Instruction *instruction, Node *node);

include/Node.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
namespace llvm2graphml {
77

8-
enum class NodeKind { Module, Function, BasicBlock, Instruction, Value };
8+
enum class NodeKind { Module, Function, BasicBlock, Instruction, Value, Type };
9+
910
enum class ValueKind {
1011
Argument,
1112
ConstantInt,
@@ -27,6 +28,25 @@ enum class ValueKind {
2728
ConstantAggregateZero,
2829
ConstantDataVector,
2930
};
31+
enum class TypeKind {
32+
Integer,
33+
Void,
34+
Half,
35+
Float,
36+
Double,
37+
X86_FP80,
38+
FP128,
39+
PPC_FP128,
40+
Metadata,
41+
X86_MMX,
42+
Token,
43+
Function,
44+
Struct,
45+
Array,
46+
Pointer,
47+
Vector,
48+
Label
49+
};
3050

3151
class Node {
3252
public:
@@ -43,6 +63,8 @@ class Node {
4363
Node &setBasicBlockCount(uint64_t basicBlockCount);
4464
Node &setInstructionOpcode(const char *opcodeName);
4565
Node &setValueKind(ValueKind valueKind);
66+
Node &setTypeKind(TypeKind typeKind);
67+
Node &setBitwidth(uint64_t bitwidth);
4668

4769
const Properties &getProperties() const;
4870
uint64_t getID() const;

include/TypeEmitter.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#pragma once
2+
3+
#include <llvm/IR/DerivedTypes.h>
4+
#include <unordered_map>
5+
6+
namespace llvm {
7+
8+
class Type;
9+
10+
}
11+
12+
namespace llvm2graphml {
13+
14+
class Node;
15+
class Builder;
16+
17+
class TypeEmitter {
18+
public:
19+
explicit TypeEmitter(Builder &builder);
20+
Node *emitType(const llvm::Type *type);
21+
22+
private:
23+
Builder &builder;
24+
std::unordered_map<const llvm::Type *, Node *> emittedTypes;
25+
26+
void dispatchType(const llvm::Type *type, Node *node);
27+
28+
// Extension Points
29+
void fillIn(const llvm::IntegerType *type, Node *node);
30+
void fillIn(const llvm::FunctionType *type, Node *node);
31+
void fillIn(const llvm::StructType *type, Node *node);
32+
void fillIn(const llvm::ArrayType *type, Node *node);
33+
void fillIn(const llvm::PointerType *type, Node *node);
34+
void fillIn(const llvm::VectorType *type, Node *node);
35+
};
36+
37+
} // namespace llvm2graphml

include/Types.def

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Inspired by LLVM's Value.def and Instruction.def
2+
3+
#ifndef HANDLE_TYPE
4+
#define HANDLE_TYPE(Name)
5+
#endif
6+
7+
#ifndef HANDLE_PRIMITIVE_TYPE
8+
#define HANDLE_PRIMITIVE_TYPE(Name) HANDLE_TYPE(Name)
9+
#endif
10+
11+
#ifndef HANDLE_DERIVED_TYPE
12+
#define HANDLE_DERIVED_TYPE(Name) HANDLE_TYPE(Name)
13+
#endif
14+
15+
HANDLE_PRIMITIVE_TYPE(Void)
16+
HANDLE_PRIMITIVE_TYPE(Half)
17+
HANDLE_PRIMITIVE_TYPE(Float)
18+
HANDLE_PRIMITIVE_TYPE(Double)
19+
HANDLE_PRIMITIVE_TYPE(X86_FP80)
20+
HANDLE_PRIMITIVE_TYPE(FP128)
21+
HANDLE_PRIMITIVE_TYPE(PPC_FP128)
22+
HANDLE_PRIMITIVE_TYPE(Label)
23+
HANDLE_PRIMITIVE_TYPE(Metadata)
24+
HANDLE_PRIMITIVE_TYPE(X86_MMX)
25+
HANDLE_PRIMITIVE_TYPE(Token)
26+
27+
HANDLE_DERIVED_TYPE(Integer)
28+
HANDLE_DERIVED_TYPE(Function)
29+
HANDLE_DERIVED_TYPE(Struct)
30+
HANDLE_DERIVED_TYPE(Array)
31+
HANDLE_DERIVED_TYPE(Pointer)
32+
HANDLE_DERIVED_TYPE(Vector)
33+
34+
#undef HANDLE_TYPE
35+
#undef HANDLE_PRIMITIVE_TYPE
36+
#undef HANDLE_DERIVED_TYPE

src/Builder.cpp

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ Node *Builder::newValueNode() {
4242
return newNode(NodeKind::Value);
4343
}
4444

45+
Node *Builder::newTypeNode() {
46+
return newNode(NodeKind::Type);
47+
}
48+
4549
/// Edge Connectors
4650

4751
void Builder::connectModule(Node *moduleNode, Node *anyNode) {
@@ -56,6 +60,14 @@ void Builder::connectFunction(Node *functionNode, Node *anyNode) {
5660
newEdge(anyNode->getID(), functionNode->getID())->setKind(EdgeKind::Function);
5761
}
5862

63+
void Builder::connectArgument(Node *functionNode, Node *argumentNode, unsigned order) {
64+
assert(functionNode->getKind() == NodeKind::Function);
65+
66+
Edge *edge = newEdge(functionNode->getID(), argumentNode->getID());
67+
edge->setKind(EdgeKind::Argument);
68+
edge->setOrder(order);
69+
}
70+
5971
void Builder::connectInstruction(Node *instructionNode, Node *anyNode) {
6072
assert(instructionNode->getKind() == NodeKind::Instruction);
6173

@@ -70,10 +82,57 @@ void Builder::connectBasicBlocks(Node *successor, Node *predecessor) {
7082
newEdge(successor->getID(), predecessor->getID())->setKind(EdgeKind::Predecessor);
7183
}
7284

73-
void Builder::connectOperand(Node *instructionNode, Node *anyValue, unsigned index) {
85+
void Builder::connectOperand(Node *instructionNode, Node *anyValue, unsigned order) {
7486
assert(instructionNode->getKind() == NodeKind::Instruction);
7587

7688
Edge *edge = newEdge(instructionNode->getID(), anyValue->getID());
7789
edge->setKind(EdgeKind::Operand);
78-
edge->setOrder(index);
90+
edge->setOrder(order);
91+
}
92+
93+
void Builder::connectPointeeType(Node *pointerNode, Node *pointeeNode) {
94+
assert(pointerNode->getKind() == NodeKind::Type);
95+
assert(pointeeNode->getKind() == NodeKind::Type);
96+
97+
newEdge(pointerNode->getID(), pointeeNode->getID())->setKind(EdgeKind::PointeeType);
98+
}
99+
100+
void Builder::connectFunctionParameterType(Node *functionType, Node *parameterType,
101+
unsigned order) {
102+
assert(functionType->getKind() == NodeKind::Type);
103+
assert(parameterType->getKind() == NodeKind::Type);
104+
105+
Edge *edge = newEdge(functionType->getID(), parameterType->getID());
106+
edge->setKind(EdgeKind::ParameterType);
107+
edge->setOrder(order);
108+
}
109+
110+
void Builder::connectFunctionReturnType(Node *functionType, Node *returnType) {
111+
assert(functionType->getKind() == NodeKind::Type);
112+
assert(returnType->getKind() == NodeKind::Type);
113+
114+
newEdge(functionType->getID(), returnType->getID())->setKind(EdgeKind::ReturnType);
115+
}
116+
117+
void Builder::connectStructElementType(llvm2graphml::Node *structType,
118+
llvm2graphml::Node *elementType, unsigned order) {
119+
assert(structType->getKind() == NodeKind::Type);
120+
assert(elementType->getKind() == NodeKind::Type);
121+
122+
Edge *edge = newEdge(structType->getID(), elementType->getID());
123+
edge->setKind(EdgeKind::ElementType);
124+
edge->setOrder(order);
125+
}
126+
127+
void Builder::connectElementType(Node *type, Node *elementType) {
128+
assert(type->getKind() == NodeKind::Type);
129+
assert(elementType->getKind() == NodeKind::Type);
130+
131+
newEdge(type->getID(), elementType->getID())->setKind(EdgeKind::ElementType);
132+
}
133+
134+
void Builder::connectType(Node *type, Node *node) {
135+
assert(type->getKind() == NodeKind::Type);
136+
137+
newEdge(node->getID(), type->getID())->setKind(EdgeKind::Type);
79138
}

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ set (SOURCES
88
Logger.cpp
99
BitcodeLoader.cpp
1010
Emitter.cpp
11+
TypeEmitter.cpp
1112
llvm2graphmlTool.cpp
1213
)
1314

src/Edge.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ static std::string edgeKindToString(EdgeKind kind) {
1616
return "instruction";
1717
case EdgeKind::Operand:
1818
return "operand";
19+
case EdgeKind::PointeeType:
20+
return "pointee_type";
21+
case EdgeKind::ReturnType:
22+
return "return_type";
23+
case EdgeKind::ParameterType:
24+
return "parameter_type";
25+
case EdgeKind::ElementType:
26+
return "element_type";
27+
case EdgeKind::Argument:
28+
return "argument";
29+
case EdgeKind::Type:
30+
return "type";
1931
}
2032
}
2133

src/Emitter.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
#include "Emitter.h"
22
#include "Builder.h"
3+
#include "TypeEmitter.h"
34
#include <llvm/IR/CFG.h>
45
#include <llvm/IR/InstIterator.h>
56
#include <llvm/IR/Module.h>
67

78
using namespace llvm2graphml;
89

9-
Emitter::Emitter(Builder &builder) : builder(builder) {}
10+
Emitter::Emitter(Builder &builder, TypeEmitter &typeEmitter)
11+
: builder(builder), typeEmitter(typeEmitter) {}
1012

1113
void Emitter::emit(const llvm::Module *module) {
1214
Node *moduleNode = builder.newModuleNode();
@@ -17,6 +19,12 @@ void Emitter::emit(const llvm::Module *module) {
1719
builder.connectFunction(functionNode, moduleNode);
1820
builder.connectModule(moduleNode, functionNode);
1921

22+
unsigned argumentIndex = 0;
23+
for (const llvm::Argument &argument : function.args()) {
24+
Node *argumentNode = emit(&argument);
25+
builder.connectArgument(functionNode, argumentNode, argumentIndex++);
26+
}
27+
2028
for (const llvm::BasicBlock &basicBlock : function.getBasicBlockList()) {
2129
Node *basicBlockNode = emit(&basicBlock);
2230
builder.connectFunction(functionNode, basicBlockNode);
@@ -117,6 +125,8 @@ Node *Emitter::emit(const llvm::Value *value) {
117125
emittedNode->setName(value->getName());
118126
}
119127
emittedValues[value] = emittedNode;
128+
Node *typeNode = typeEmitter.emitType(value->getType());
129+
builder.connectType(typeNode, emittedNode);
120130

121131
return emittedNode;
122132
}

0 commit comments

Comments
 (0)