Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
2
2025ustc-jianmu-compiler
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Service Desk
Milestones
Merge Requests
43
Merge Requests
43
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
compiler_staff
2025ustc-jianmu-compiler
Commits
a6d37a3d
Commit
a6d37a3d
authored
Nov 26, 2025
by
Yang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
switch to clang
parent
5d4ea841
Changes
21
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
685 additions
and
138 deletions
+685
-138
.clangd
.clangd
+2
-0
CMakeLists.txt
CMakeLists.txt
+16
-0
include/common/util.hpp
include/common/util.hpp
+9
-0
include/lightir/BasicBlock.hpp
include/lightir/BasicBlock.hpp
+2
-0
include/lightir/Constant.hpp
include/lightir/Constant.hpp
+6
-1
include/lightir/Function.hpp
include/lightir/Function.hpp
+5
-0
include/lightir/GlobalVariable.hpp
include/lightir/GlobalVariable.hpp
+2
-0
include/lightir/Instruction.hpp
include/lightir/Instruction.hpp
+20
-42
include/lightir/Type.hpp
include/lightir/Type.hpp
+3
-0
include/lightir/Value.hpp
include/lightir/Value.hpp
+2
-0
lldb_formatters.py
lldb_formatters.py
+9
-6
src/common/CMakeLists.txt
src/common/CMakeLists.txt
+1
-1
src/common/util.cpp
src/common/util.cpp
+15
-0
src/lightir/BasicBlock.cpp
src/lightir/BasicBlock.cpp
+11
-0
src/lightir/Constant.cpp
src/lightir/Constant.cpp
+48
-1
src/lightir/Function.cpp
src/lightir/Function.cpp
+63
-32
src/lightir/GlobalVariable.cpp
src/lightir/GlobalVariable.cpp
+12
-0
src/lightir/IRprinter.cpp
src/lightir/IRprinter.cpp
+355
-4
src/lightir/Instruction.cpp
src/lightir/Instruction.cpp
+51
-51
src/lightir/Type.cpp
src/lightir/Type.cpp
+46
-0
src/lightir/Value.cpp
src/lightir/Value.cpp
+7
-0
No files found.
.clangd
0 → 100644
View file @
a6d37a3d
CompileFlags:
Add: [-std=c++17]
\ No newline at end of file
CMakeLists.txt
View file @
a6d37a3d
cmake_minimum_required
(
VERSION 3.8
)
cmake_minimum_required
(
VERSION 3.8
)
include
(
CheckCXXCompilerFlag
)
project
(
CMINUSF
)
project
(
CMINUSF
)
set
(
CMAKE_C_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-std=c99"
)
set
(
CMAKE_C_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-std=c99"
)
...
@@ -9,6 +11,20 @@ SET(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fsaniti
...
@@ -9,6 +11,20 @@ SET(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fsaniti
set
(
default_build_type
"Debug"
)
set
(
default_build_type
"Debug"
)
if
(
CMAKE_BUILD_TYPE STREQUAL
"Debug"
)
if
(
CMAKE_CXX_COMPILER_ID MATCHES
"Clang"
)
check_cxx_compiler_flag
(
"-fstandalone-debug"
CXX_SUPPORTS_STANDALONE_DEBUG
)
if
(
CXX_SUPPORTS_STANDALONE_DEBUG
)
message
(
STATUS
"Adding -fstandalone-debug for Clang"
)
set
(
CMAKE_CXX_FLAGS_DEBUG
"
${
CMAKE_CXX_FLAGS_DEBUG
}
-fstandalone-debug"
)
else
()
message
(
STATUS
"Clang does not support -fstandalone-debug, skipping"
)
endif
()
else
()
message
(
STATUS
"Use Gcc"
)
endif
()
endif
()
if
(
CMAKE_BUILD_TYPE STREQUAL
"Debug"
)
if
(
CMAKE_BUILD_TYPE STREQUAL
"Debug"
)
add_definitions
(
-DDEBUG_BUILD
)
add_definitions
(
-DDEBUG_BUILD
)
endif
()
endif
()
...
...
include/common/util.hpp
0 → 100644
View file @
a6d37a3d
#ifndef UTIL_HPP
#define UTIL_HPP
#include "string"
std
::
string
ptr_to_str
(
const
void
*
ptr
);
#endif
\ No newline at end of file
include/lightir/BasicBlock.hpp
View file @
a6d37a3d
...
@@ -79,6 +79,8 @@ class BasicBlock : public Value {
...
@@ -79,6 +79,8 @@ class BasicBlock : public Value {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
private:
private:
explicit
BasicBlock
(
Module
*
m
,
const
std
::
string
&
name
,
Function
*
parent
);
explicit
BasicBlock
(
Module
*
m
,
const
std
::
string
&
name
,
Function
*
parent
);
...
...
include/lightir/Constant.hpp
View file @
a6d37a3d
...
@@ -15,6 +15,11 @@ public:
...
@@ -15,6 +15,11 @@ public:
Constant
(
Type
*
ty
,
const
std
::
string
&
name
=
""
)
:
User
(
ty
,
name
)
{}
Constant
(
Type
*
ty
,
const
std
::
string
&
name
=
""
)
:
User
(
ty
,
name
)
{}
~
Constant
()
override
;
~
Constant
()
override
;
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
// 用于 lldb 调试生成 summary
std
::
string
safe_print_help
()
const
;
protected:
protected:
};
};
...
...
include/lightir/Function.hpp
View file @
a6d37a3d
...
@@ -47,6 +47,8 @@ class Function : public Value {
...
@@ -47,6 +47,8 @@ class Function : public Value {
// 用于检查函数的基本块是否存在问题
// 用于检查函数的基本块是否存在问题
void
check_for_block_relation_error
()
const
;
void
check_for_block_relation_error
()
const
;
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
private:
private:
std
::
list
<
BasicBlock
*>
basic_blocks_
;
std
::
list
<
BasicBlock
*>
basic_blocks_
;
std
::
list
<
Argument
>
arguments_
;
std
::
list
<
Argument
>
arguments_
;
...
@@ -77,6 +79,9 @@ class Argument : public Value {
...
@@ -77,6 +79,9 @@ class Argument : public Value {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
private:
private:
Function
*
parent_
;
Function
*
parent_
;
unsigned
arg_no_
;
// argument No.
unsigned
arg_no_
;
// argument No.
...
...
include/lightir/GlobalVariable.hpp
View file @
a6d37a3d
...
@@ -12,6 +12,8 @@ class GlobalVariable : public User {
...
@@ -12,6 +12,8 @@ class GlobalVariable : public User {
GlobalVariable
(
const
std
::
string
&
name
,
Module
*
m
,
Type
*
ty
,
bool
is_const
,
GlobalVariable
(
const
std
::
string
&
name
,
Module
*
m
,
Type
*
ty
,
bool
is_const
,
Constant
*
init
=
nullptr
);
Constant
*
init
=
nullptr
);
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
public:
public:
GlobalVariable
(
const
GlobalVariable
&
other
)
=
delete
;
GlobalVariable
(
const
GlobalVariable
&
other
)
=
delete
;
GlobalVariable
(
GlobalVariable
&&
other
)
noexcept
=
delete
;
GlobalVariable
(
GlobalVariable
&&
other
)
noexcept
=
delete
;
...
...
include/lightir/Instruction.hpp
View file @
a6d37a3d
...
@@ -111,23 +111,14 @@ class Instruction : public User {
...
@@ -111,23 +111,14 @@ class Instruction : public User {
bool
isTerminator
()
const
{
return
is_br
()
||
is_ret
();
}
bool
isTerminator
()
const
{
return
is_br
()
||
is_ret
();
}
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
private:
private:
OpID
op_id_
;
OpID
op_id_
;
BasicBlock
*
parent_
;
BasicBlock
*
parent_
;
};
};
template
<
typename
Inst
>
class
BaseInst
:
public
Instruction
{
class
IBinaryInst
:
public
Instruction
{
protected:
template
<
typename
...
Args
>
static
Inst
*
create
(
Args
&&
...
args
)
{
return
new
Inst
(
std
::
forward
<
Args
>
(
args
)...);
}
template
<
typename
...
Args
>
BaseInst
(
Args
&&
...
args
)
:
Instruction
(
std
::
forward
<
Args
>
(
args
)...)
{}
};
class
IBinaryInst
:
public
BaseInst
<
IBinaryInst
>
{
friend
BaseInst
<
IBinaryInst
>
;
private:
private:
IBinaryInst
(
OpID
id
,
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
);
IBinaryInst
(
OpID
id
,
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
);
...
@@ -141,8 +132,7 @@ class IBinaryInst : public BaseInst<IBinaryInst> {
...
@@ -141,8 +132,7 @@ class IBinaryInst : public BaseInst<IBinaryInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
FBinaryInst
:
public
BaseInst
<
FBinaryInst
>
{
class
FBinaryInst
:
public
Instruction
{
friend
BaseInst
<
FBinaryInst
>
;
private:
private:
FBinaryInst
(
OpID
id
,
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
);
FBinaryInst
(
OpID
id
,
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
);
...
@@ -156,13 +146,13 @@ class FBinaryInst : public BaseInst<FBinaryInst> {
...
@@ -156,13 +146,13 @@ class FBinaryInst : public BaseInst<FBinaryInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
ICmpInst
:
public
BaseInst
<
ICmpInst
>
{
class
ICmpInst
:
public
Instruction
{
friend
BaseInst
<
ICmpInst
>
;
private:
private:
ICmpInst
(
OpID
id
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
);
ICmpInst
(
OpID
id
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
);
public:
public:
static
ICmpInst
*
create_ge
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
);
static
ICmpInst
*
create_ge
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
);
static
ICmpInst
*
create_gt
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
);
static
ICmpInst
*
create_gt
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
);
static
ICmpInst
*
create_le
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
);
static
ICmpInst
*
create_le
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
);
...
@@ -173,8 +163,7 @@ class ICmpInst : public BaseInst<ICmpInst> {
...
@@ -173,8 +163,7 @@ class ICmpInst : public BaseInst<ICmpInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
FCmpInst
:
public
BaseInst
<
FCmpInst
>
{
class
FCmpInst
:
public
Instruction
{
friend
BaseInst
<
FCmpInst
>
;
private:
private:
FCmpInst
(
OpID
id
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
);
FCmpInst
(
OpID
id
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
);
...
@@ -190,8 +179,7 @@ class FCmpInst : public BaseInst<FCmpInst> {
...
@@ -190,8 +179,7 @@ class FCmpInst : public BaseInst<FCmpInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
CallInst
:
public
BaseInst
<
CallInst
>
{
class
CallInst
:
public
Instruction
{
friend
BaseInst
<
CallInst
>
;
protected:
protected:
CallInst
(
Function
*
func
,
const
std
::
vector
<
Value
*>&
args
,
BasicBlock
*
bb
);
CallInst
(
Function
*
func
,
const
std
::
vector
<
Value
*>&
args
,
BasicBlock
*
bb
);
...
@@ -204,15 +192,14 @@ class CallInst : public BaseInst<CallInst> {
...
@@ -204,15 +192,14 @@ class CallInst : public BaseInst<CallInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
BranchInst
:
public
BaseInst
<
BranchInst
>
{
class
BranchInst
:
public
Instruction
{
friend
BaseInst
<
BranchInst
>
;
private:
private:
BranchInst
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
,
BranchInst
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
,
BasicBlock
*
bb
);
BasicBlock
*
bb
);
~
BranchInst
()
override
;
public:
public:
~
BranchInst
()
override
;
BranchInst
(
const
BranchInst
&
other
)
=
delete
;
BranchInst
(
const
BranchInst
&
other
)
=
delete
;
BranchInst
(
BranchInst
&&
other
)
noexcept
=
delete
;
BranchInst
(
BranchInst
&&
other
)
noexcept
=
delete
;
BranchInst
&
operator
=
(
const
BranchInst
&
other
)
=
delete
;
BranchInst
&
operator
=
(
const
BranchInst
&
other
)
=
delete
;
...
@@ -229,8 +216,7 @@ public:
...
@@ -229,8 +216,7 @@ public:
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
ReturnInst
:
public
BaseInst
<
ReturnInst
>
{
class
ReturnInst
:
public
Instruction
{
friend
BaseInst
<
ReturnInst
>
;
private:
private:
ReturnInst
(
Value
*
val
,
BasicBlock
*
bb
);
ReturnInst
(
Value
*
val
,
BasicBlock
*
bb
);
...
@@ -243,8 +229,7 @@ class ReturnInst : public BaseInst<ReturnInst> {
...
@@ -243,8 +229,7 @@ class ReturnInst : public BaseInst<ReturnInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
GetElementPtrInst
:
public
BaseInst
<
GetElementPtrInst
>
{
class
GetElementPtrInst
:
public
Instruction
{
friend
BaseInst
<
GetElementPtrInst
>
;
private:
private:
GetElementPtrInst
(
Value
*
ptr
,
const
std
::
vector
<
Value
*>&
idxs
,
BasicBlock
*
bb
);
GetElementPtrInst
(
Value
*
ptr
,
const
std
::
vector
<
Value
*>&
idxs
,
BasicBlock
*
bb
);
...
@@ -258,8 +243,7 @@ class GetElementPtrInst : public BaseInst<GetElementPtrInst> {
...
@@ -258,8 +243,7 @@ class GetElementPtrInst : public BaseInst<GetElementPtrInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
StoreInst
:
public
BaseInst
<
StoreInst
>
{
class
StoreInst
:
public
Instruction
{
friend
BaseInst
<
StoreInst
>
;
StoreInst
(
Value
*
val
,
Value
*
ptr
,
BasicBlock
*
bb
);
StoreInst
(
Value
*
val
,
Value
*
ptr
,
BasicBlock
*
bb
);
...
@@ -272,8 +256,7 @@ class StoreInst : public BaseInst<StoreInst> {
...
@@ -272,8 +256,7 @@ class StoreInst : public BaseInst<StoreInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
LoadInst
:
public
BaseInst
<
LoadInst
>
{
class
LoadInst
:
public
Instruction
{
friend
BaseInst
<
LoadInst
>
;
LoadInst
(
Value
*
ptr
,
BasicBlock
*
bb
);
LoadInst
(
Value
*
ptr
,
BasicBlock
*
bb
);
...
@@ -286,8 +269,7 @@ class LoadInst : public BaseInst<LoadInst> {
...
@@ -286,8 +269,7 @@ class LoadInst : public BaseInst<LoadInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
AllocaInst
:
public
BaseInst
<
AllocaInst
>
{
class
AllocaInst
:
public
Instruction
{
friend
BaseInst
<
AllocaInst
>
;
AllocaInst
(
Type
*
ty
,
BasicBlock
*
bb
);
AllocaInst
(
Type
*
ty
,
BasicBlock
*
bb
);
...
@@ -302,8 +284,7 @@ class AllocaInst : public BaseInst<AllocaInst> {
...
@@ -302,8 +284,7 @@ class AllocaInst : public BaseInst<AllocaInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
ZextInst
:
public
BaseInst
<
ZextInst
>
{
class
ZextInst
:
public
Instruction
{
friend
BaseInst
<
ZextInst
>
;
private:
private:
ZextInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
);
ZextInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
);
...
@@ -317,8 +298,7 @@ class ZextInst : public BaseInst<ZextInst> {
...
@@ -317,8 +298,7 @@ class ZextInst : public BaseInst<ZextInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
FpToSiInst
:
public
BaseInst
<
FpToSiInst
>
{
class
FpToSiInst
:
public
Instruction
{
friend
BaseInst
<
FpToSiInst
>
;
private:
private:
FpToSiInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
);
FpToSiInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
);
...
@@ -332,8 +312,7 @@ class FpToSiInst : public BaseInst<FpToSiInst> {
...
@@ -332,8 +312,7 @@ class FpToSiInst : public BaseInst<FpToSiInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
SiToFpInst
:
public
BaseInst
<
SiToFpInst
>
{
class
SiToFpInst
:
public
Instruction
{
friend
BaseInst
<
SiToFpInst
>
;
private:
private:
SiToFpInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
);
SiToFpInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
);
...
@@ -346,8 +325,7 @@ class SiToFpInst : public BaseInst<SiToFpInst> {
...
@@ -346,8 +325,7 @@ class SiToFpInst : public BaseInst<SiToFpInst> {
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
};
class
PhiInst
:
public
BaseInst
<
PhiInst
>
{
class
PhiInst
:
public
Instruction
{
friend
BaseInst
<
PhiInst
>
;
private:
private:
PhiInst
(
Type
*
ty
,
const
std
::
vector
<
Value
*>&
vals
,
PhiInst
(
Type
*
ty
,
const
std
::
vector
<
Value
*>&
vals
,
...
...
include/lightir/Type.hpp
View file @
a6d37a3d
...
@@ -53,6 +53,9 @@ class Type {
...
@@ -53,6 +53,9 @@ class Type {
std
::
string
print
()
const
;
std
::
string
print
()
const
;
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
private:
private:
TypeID
tid_
;
TypeID
tid_
;
Module
*
m_
;
Module
*
m_
;
...
...
include/lightir/Value.hpp
View file @
a6d37a3d
...
@@ -57,6 +57,8 @@ class Value {
...
@@ -57,6 +57,8 @@ class Value {
return
dynamic_cast
<
const
T
*>
(
this
);
return
dynamic_cast
<
const
T
*>
(
this
);
}
}
// 用于 lldb 调试生成 summary
std
::
string
safe_get_name_or_ptr
()
const
;
private:
private:
Type
*
type_
;
Type
*
type_
;
std
::
list
<
Use
>
use_list_
;
// who use this value
std
::
list
<
Use
>
use_list_
;
// who use this value
...
...
lldb_formatters.py
View file @
a6d37a3d
...
@@ -3,21 +3,24 @@ import lldb
...
@@ -3,21 +3,24 @@ import lldb
def
parseString
(
val
:
lldb
.
SBValue
):
def
parseString
(
val
:
lldb
.
SBValue
):
summary
=
val
.
GetSummary
()
or
val
.
GetValue
()
summary
=
val
.
GetSummary
()
or
val
.
GetValue
()
if
summary
:
if
summary
:
# 去掉两端引号,只留裸文本(可选)
if
summary
.
startswith
(
'"'
)
and
summary
.
endswith
(
'"'
):
if
summary
.
startswith
(
'"'
)
and
summary
.
endswith
(
'"'
):
summary
=
summary
[
1
:
-
1
]
summary
=
summary
[
1
:
-
1
]
return
summary
return
summary
return
""
return
""
def
TypePrinterSummary
(
valobj
:
lldb
.
SBValue
,
internal_dict
):
def
SafePrintSummary
(
valobj
:
lldb
.
SBValue
,
internal_dict
):
# 调用 print 函数进行显示
name
:
lldb
.
SBValue
=
valobj
.
EvaluateExpression
(
"this->safe_print()"
)
name
:
lldb
.
SBValue
=
valobj
.
EvaluateExpression
(
"print()"
);
return
parseString
(
name
)
return
parseString
(
name
)
def
__lldb_init_module
(
debugger
:
lldb
.
SBDebugger
,
internal_dict
):
def
__lldb_init_module
(
debugger
:
lldb
.
SBDebugger
,
internal_dict
):
types
=
[
"Type"
,
"IntegerType"
,
"FunctionType"
,
"ArrayType"
,
"PointerType"
,
"FloatType"
]
types
=
[
"Type"
,
"IntegerType"
,
"FunctionType"
,
"ArrayType"
,
"PointerType"
,
"FloatType"
,
"Constant"
,
"ConstantInt"
,
"ConstantArray"
,
"ConstantZero"
,
"ConstantFP"
,
"Function"
,
"Argument"
,
"BasicBlock"
,
"GlobalVariable"
,
"Instruction"
,
"IBinaryInst"
,
"FBinaryInst"
,
"ICmpInst"
,
"FCmpInst"
,
"CallInst"
,
"BranchInst"
,
"ReturnInst"
,
"GetElementPtrInst"
,
"StoreInst"
,
"LoadInst"
,
"AllocaInst"
,
"ZextInst"
,
"FpToSiInst"
,
"SiToFpInst"
,
"PhiInst"
]
for
i
in
types
:
for
i
in
types
:
debugger
.
HandleCommand
(
debugger
.
HandleCommand
(
f"type summary add -F lldb_formatters.
TypePrinter
Summary
{
i
}
-w my"
f"type summary add -F lldb_formatters.
SafePrint
Summary
{
i
}
-w my"
)
)
debugger
.
HandleCommand
(
"type category enable my"
)
debugger
.
HandleCommand
(
"type category enable my"
)
\ No newline at end of file
src/common/CMakeLists.txt
View file @
a6d37a3d
...
@@ -2,7 +2,7 @@ add_library(common STATIC
...
@@ -2,7 +2,7 @@ add_library(common STATIC
syntax_tree.c
syntax_tree.c
ast.cpp
ast.cpp
logging.cpp
logging.cpp
)
util.cpp
)
target_link_libraries
(
common
)
target_link_libraries
(
common
)
src/common/util.cpp
0 → 100644
View file @
a6d37a3d
#include "util.hpp"
std
::
string
ptr_to_str
(
const
void
*
ptr
)
{
const
char
*
translate
=
"0123456789abcdef"
;
uintptr_t
addr
=
reinterpret_cast
<
uintptr_t
>
(
ptr
);
uintptr_t
a
=
addr
&
0xF
;
uintptr_t
b
=
(
addr
>>
4
)
&
0xF
;
uintptr_t
c
=
(
addr
>>
8
)
&
0xF
;
uintptr_t
d
=
(
addr
>>
12
)
&
0xF
;
return
{
'<'
,
translate
[
d
],
translate
[
c
],
translate
[
b
],
translate
[
a
],
'>'
};
}
src/lightir/BasicBlock.cpp
View file @
a6d37a3d
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
#include "Function.hpp"
#include "Function.hpp"
#include "IRprinter.hpp"
#include "IRprinter.hpp"
#include "Module.hpp"
#include "Module.hpp"
#include "util.hpp"
#include <cassert>
#include <cassert>
...
@@ -102,6 +103,16 @@ std::string BasicBlock::print() {
...
@@ -102,6 +103,16 @@ std::string BasicBlock::print() {
return
bb_ir
;
return
bb_ir
;
}
}
std
::
string
BasicBlock
::
safe_print
()
const
{
Function
*
parent
=
parent_
;
auto
parentName
=
((
parent
!=
nullptr
)
?
parent
->
get_name
()
:
"f<null>"
);
auto
name
=
get_name
();
if
(
name
.
empty
())
name
=
"b"
+
ptr_to_str
(
this
);
if
(
parentName
.
empty
())
parentName
=
"f"
+
ptr_to_str
(
parent
);
return
parentName
+
":"
+
name
+
" "
+
std
::
to_string
(
instr_list_
.
size
())
+
"inst pre "
+
std
::
to_string
(
pre_bbs_
.
size
())
+
"b suc "
+
std
::
to_string
(
succ_bbs_
.
size
())
+
"b"
;
}
BasicBlock
::~
BasicBlock
()
BasicBlock
::~
BasicBlock
()
{
{
for
(
auto
inst
:
instr_list_
)
delete
inst
;
for
(
auto
inst
:
instr_list_
)
delete
inst
;
...
...
src/lightir/Constant.cpp
View file @
a6d37a3d
...
@@ -31,6 +31,53 @@ static std::unordered_map<Type *, std::unique_ptr<ConstantZero>> cached_zero;
...
@@ -31,6 +31,53 @@ static std::unordered_map<Type *, std::unique_ptr<ConstantZero>> cached_zero;
Constant
::~
Constant
()
=
default
;
Constant
::~
Constant
()
=
default
;
std
::
string
Constant
::
safe_print
()
const
{
Type
*
ty
=
this
->
get_type
();
return
(
ty
==
nullptr
?
"<null>"
:
get_type
()
->
safe_print
())
+
" "
+
safe_print_help
();
}
std
::
string
Constant
::
safe_print_help
()
const
{
if
(
dynamic_cast
<
const
ConstantZero
*>
(
this
))
{
return
"zeroinitializer"
;
}
if
(
auto
constant
=
dynamic_cast
<
const
ConstantInt
*>
(
this
))
{
Type
*
ty
=
this
->
get_type
();
if
(
ty
!=
nullptr
&&
ty
->
is_int1_type
())
{
return
constant
->
get_value
()
==
0
?
"false"
:
"true"
;
}
return
std
::
to_string
(
constant
->
get_value
());
}
if
(
auto
constant
=
dynamic_cast
<
const
ConstantFP
*>
(
this
))
{
std
::
stringstream
fp_ir_ss
;
std
::
string
fp_ir
;
double
val
=
constant
->
get_value
();
uint64_t
uval
;
memcpy
(
&
uval
,
&
val
,
sizeof
(
double
));
fp_ir_ss
<<
"0x"
<<
std
::
hex
<<
uval
<<
'\n'
;
fp_ir_ss
>>
fp_ir
;
return
std
::
to_string
(
val
)
+
"("
+
fp_ir
+
")"
;
}
if
(
auto
constant
=
dynamic_cast
<
const
ConstantArray
*>
(
this
))
{
std
::
string
const_ir
=
"["
;
for
(
int
i
=
0
;
i
<
constant
->
get_size_of_array
();
i
++
)
{
Constant
*
element
=
constant
->
get_element_value
(
i
);
const_ir
+=
(
element
==
nullptr
?
"<null>"
:
element
->
safe_print_help
());
if
(
i
<
constant
->
get_size_of_array
())
{
const_ir
+=
", "
;
}
}
const_ir
+=
"]"
;
return
const_ir
;
}
return
"<error>"
;
}
ConstantInt
*
ConstantInt
::
get
(
int
val
,
Module
*
m
)
{
ConstantInt
*
ConstantInt
::
get
(
int
val
,
Module
*
m
)
{
if
(
cached_int
.
find
(
std
::
make_pair
(
val
,
m
))
!=
cached_int
.
end
())
if
(
cached_int
.
find
(
std
::
make_pair
(
val
,
m
))
!=
cached_int
.
end
())
return
cached_int
[
std
::
make_pair
(
val
,
m
)].
get
();
return
cached_int
[
std
::
make_pair
(
val
,
m
)].
get
();
...
@@ -51,7 +98,7 @@ std::string ConstantInt::print() {
...
@@ -51,7 +98,7 @@ std::string ConstantInt::print() {
std
::
string
const_ir
;
std
::
string
const_ir
;
Type
*
ty
=
this
->
get_type
();
Type
*
ty
=
this
->
get_type
();
if
(
ty
->
is_integer_type
()
&&
if
(
ty
->
is_integer_type
()
&&
stat
ic_cast
<
IntegerType
*>
(
ty
)
->
get_num_bits
()
==
1
)
{
dynam
ic_cast
<
IntegerType
*>
(
ty
)
->
get_num_bits
()
==
1
)
{
// int1
// int1
const_ir
+=
(
this
->
get_value
()
==
0
)
?
"false"
:
"true"
;
const_ir
+=
(
this
->
get_value
()
==
0
)
?
"false"
:
"true"
;
}
else
{
}
else
{
...
...
src/lightir/Function.cpp
View file @
a6d37a3d
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
#include <unordered_set>
#include <unordered_set>
#include <queue>
#include <queue>
Function
::
Function
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Module
*
parent
)
Function
::
Function
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Module
*
parent
)
:
Value
(
ty
,
name
),
parent_
(
parent
),
seq_cnt_
(
0
)
{
:
Value
(
ty
,
name
),
parent_
(
parent
),
seq_cnt_
(
0
)
{
// num_args_ = ty->getNumParams();
// num_args_ = ty->getNumParams();
parent
->
add_function
(
this
);
parent
->
add_function
(
this
);
...
@@ -21,16 +21,16 @@ Function::~Function()
...
@@ -21,16 +21,16 @@ Function::~Function()
for
(
auto
bb
:
basic_blocks_
)
delete
bb
;
for
(
auto
bb
:
basic_blocks_
)
delete
bb
;
}
}
Function
*
Function
::
create
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Function
*
Function
::
create
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Module
*
parent
)
{
Module
*
parent
)
{
return
new
Function
(
ty
,
name
,
parent
);
return
new
Function
(
ty
,
name
,
parent
);
}
}
FunctionType
*
Function
::
get_function_type
()
const
{
FunctionType
*
Function
::
get_function_type
()
const
{
return
dynamic_cast
<
FunctionType
*>
(
get_type
());
return
dynamic_cast
<
FunctionType
*>
(
get_type
());
}
}
Type
*
Function
::
get_return_type
()
const
{
Type
*
Function
::
get_return_type
()
const
{
return
get_function_type
()
->
get_return_type
();
return
get_function_type
()
->
get_return_type
();
}
}
...
@@ -40,9 +40,9 @@ unsigned Function::get_num_of_args() const {
...
@@ -40,9 +40,9 @@ unsigned Function::get_num_of_args() const {
unsigned
Function
::
get_num_basic_blocks
()
const
{
return
static_cast
<
unsigned
>
(
basic_blocks_
.
size
());
}
unsigned
Function
::
get_num_basic_blocks
()
const
{
return
static_cast
<
unsigned
>
(
basic_blocks_
.
size
());
}
Module
*
Function
::
get_parent
()
const
{
return
parent_
;
}
Module
*
Function
::
get_parent
()
const
{
return
parent_
;
}
void
Function
::
remove
(
BasicBlock
*
bb
)
{
void
Function
::
remove
(
BasicBlock
*
bb
)
{
basic_blocks_
.
remove
(
bb
);
basic_blocks_
.
remove
(
bb
);
for
(
auto
pre
:
bb
->
get_pre_basic_blocks
())
{
for
(
auto
pre
:
bb
->
get_pre_basic_blocks
())
{
pre
->
remove_succ_basic_block
(
bb
);
pre
->
remove_succ_basic_block
(
bb
);
...
@@ -52,15 +52,15 @@ void Function::remove(BasicBlock *bb) {
...
@@ -52,15 +52,15 @@ void Function::remove(BasicBlock *bb) {
}
}
}
}
void
Function
::
add_basic_block
(
BasicBlock
*
bb
)
{
basic_blocks_
.
push_back
(
bb
);
}
void
Function
::
add_basic_block
(
BasicBlock
*
bb
)
{
basic_blocks_
.
push_back
(
bb
);
}
void
Function
::
set_instr_name
()
{
void
Function
::
set_instr_name
()
{
std
::
map
<
Value
*
,
int
>
seq
;
std
::
map
<
Value
*
,
int
>
seq
;
for
(
auto
&
arg
:
this
->
get_args
())
{
for
(
auto
&
arg
:
this
->
get_args
())
{
if
(
seq
.
find
(
&
arg
)
==
seq
.
end
())
{
if
(
seq
.
find
(
&
arg
)
==
seq
.
end
())
{
auto
seq_num
=
seq
.
size
()
+
seq_cnt_
;
auto
seq_num
=
seq
.
size
()
+
seq_cnt_
;
if
(
arg
.
set_name
(
"arg"
+
std
::
to_string
(
seq_num
)))
{
if
(
arg
.
set_name
(
"arg"
+
std
::
to_string
(
seq_num
)))
{
seq
.
insert
({
&
arg
,
seq_num
});
seq
.
insert
({
&
arg
,
seq_num
});
}
}
}
}
}
}
...
@@ -68,14 +68,14 @@ void Function::set_instr_name() {
...
@@ -68,14 +68,14 @@ void Function::set_instr_name() {
if
(
seq
.
find
(
bb
)
==
seq
.
end
())
{
if
(
seq
.
find
(
bb
)
==
seq
.
end
())
{
auto
seq_num
=
seq
.
size
()
+
seq_cnt_
;
auto
seq_num
=
seq
.
size
()
+
seq_cnt_
;
if
(
bb
->
set_name
(
"label"
+
std
::
to_string
(
seq_num
)))
{
if
(
bb
->
set_name
(
"label"
+
std
::
to_string
(
seq_num
)))
{
seq
.
insert
({
bb
,
seq_num
});
seq
.
insert
({
bb
,
seq_num
});
}
}
}
}
for
(
auto
instr
:
bb
->
get_instructions
())
{
for
(
auto
instr
:
bb
->
get_instructions
())
{
if
(
!
instr
->
is_void
()
&&
seq
.
find
(
instr
)
==
seq
.
end
())
{
if
(
!
instr
->
is_void
()
&&
seq
.
find
(
instr
)
==
seq
.
end
())
{
auto
seq_num
=
seq
.
size
()
+
seq_cnt_
;
auto
seq_num
=
seq
.
size
()
+
seq_cnt_
;
if
(
instr
->
set_name
(
"op"
+
std
::
to_string
(
seq_num
)))
{
if
(
instr
->
set_name
(
"op"
+
std
::
to_string
(
seq_num
)))
{
seq
.
insert
({
instr
,
seq_num
});
seq
.
insert
({
instr
,
seq_num
});
}
}
}
}
}
}
...
@@ -88,7 +88,8 @@ std::string Function::print() {
...
@@ -88,7 +88,8 @@ std::string Function::print() {
std
::
string
func_ir
;
std
::
string
func_ir
;
if
(
this
->
is_declaration
())
{
if
(
this
->
is_declaration
())
{
func_ir
+=
"declare "
;
func_ir
+=
"declare "
;
}
else
{
}
else
{
func_ir
+=
"define "
;
func_ir
+=
"define "
;
}
}
...
@@ -102,12 +103,13 @@ std::string Function::print() {
...
@@ -102,12 +103,13 @@ std::string Function::print() {
for
(
unsigned
i
=
0
;
i
<
this
->
get_num_of_args
();
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
this
->
get_num_of_args
();
i
++
)
{
if
(
i
)
if
(
i
)
func_ir
+=
", "
;
func_ir
+=
", "
;
func_ir
+=
dynamic_cast
<
FunctionType
*>
(
this
->
get_type
())
func_ir
+=
dynamic_cast
<
FunctionType
*>
(
this
->
get_type
())
->
get_param_type
(
i
)
->
get_param_type
(
i
)
->
print
();
->
print
();
}
}
}
else
{
}
for
(
auto
&
arg
:
get_args
())
{
else
{
for
(
auto
&
arg
:
get_args
())
{
if
(
&
arg
!=
&*
get_args
().
begin
())
if
(
&
arg
!=
&*
get_args
().
begin
())
func_ir
+=
", "
;
func_ir
+=
", "
;
func_ir
+=
arg
.
print
();
func_ir
+=
arg
.
print
();
...
@@ -118,7 +120,8 @@ std::string Function::print() {
...
@@ -118,7 +120,8 @@ std::string Function::print() {
// print bb
// print bb
if
(
this
->
is_declaration
())
{
if
(
this
->
is_declaration
())
{
func_ir
+=
"
\n
"
;
func_ir
+=
"
\n
"
;
}
else
{
}
else
{
func_ir
+=
" {"
;
func_ir
+=
" {"
;
func_ir
+=
"
\n
"
;
func_ir
+=
"
\n
"
;
for
(
auto
bb
:
this
->
get_basic_blocks
())
{
for
(
auto
bb
:
this
->
get_basic_blocks
())
{
...
@@ -138,6 +141,19 @@ std::string Argument::print() {
...
@@ -138,6 +141,19 @@ std::string Argument::print() {
return
arg_ir
;
return
arg_ir
;
}
}
std
::
string
Argument
::
safe_print
()
const
{
auto
parent
=
parent_
;
if
(
parent
==
nullptr
)
{
return
"@<null> arg"
+
std
::
to_string
(
arg_no_
)
+
" <unknow type>"
;
}
auto
ty
=
parent
->
get_function_type
();
if
(
ty
==
nullptr
||
ty
->
get_num_of_args
()
<=
arg_no_
)
return
"@"
+
parent
->
get_name
()
+
" arg"
+
std
::
to_string
(
arg_no_
)
+
" <unknow type>"
;
auto
ty2
=
ty
->
get_param_type
(
arg_no_
);
return
"@"
+
parent
->
get_name
()
+
" arg"
+
std
::
to_string
(
arg_no_
)
+
" "
+
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
());
}
void
Function
::
check_for_block_relation_error
()
const
void
Function
::
check_for_block_relation_error
()
const
{
{
...
@@ -150,11 +166,11 @@ void Function::check_for_block_relation_error() const
...
@@ -150,11 +166,11 @@ void Function::check_for_block_relation_error() const
for
(
auto
bb
:
basic_blocks_
)
for
(
auto
bb
:
basic_blocks_
)
{
{
assert
((
bb
->
get_parent
()
==
this
)
&&
"函数 F 的基本块表中包含基本块 a, 但 a 的 get_parent 方法不返回 F"
);
assert
((
bb
->
get_parent
()
==
this
)
&&
"函数 F 的基本块表中包含基本块 a, 但 a 的 get_parent 方法不返回 F"
);
for
(
auto
i
:
bb
->
get_succ_basic_blocks
())
for
(
auto
i
:
bb
->
get_succ_basic_blocks
())
{
{
assert
((
bbs
.
count
(
i
))
&&
"函数 F 的基本块表中包含基本块 a, a 的后继块表中的某基本块 b 不在 F 的基本块表中"
);
assert
((
bbs
.
count
(
i
))
&&
"函数 F 的基本块表中包含基本块 a, a 的后继块表中的某基本块 b 不在 F 的基本块表中"
);
}
}
for
(
auto
i
:
bb
->
get_pre_basic_blocks
())
for
(
auto
i
:
bb
->
get_pre_basic_blocks
())
{
{
assert
((
bbs
.
count
(
i
))
&&
"函数 F 的基本块表中包含基本块 a, a 的前驱块表中的某基本块 b 不在 F 的基本块表中"
);
assert
((
bbs
.
count
(
i
))
&&
"函数 F 的基本块表中包含基本块 a, a 的前驱块表中的某基本块 b 不在 F 的基本块表中"
);
}
}
...
@@ -170,7 +186,7 @@ void Function::check_for_block_relation_error() const
...
@@ -170,7 +186,7 @@ void Function::check_for_block_relation_error() const
// 检查基本块前驱后继关系是否是与 branch 指令对应
// 检查基本块前驱后继关系是否是与 branch 指令对应
for
(
auto
bb
:
basic_blocks_
)
for
(
auto
bb
:
basic_blocks_
)
{
{
if
(
!
bb
->
get_succ_basic_blocks
().
empty
())
{
if
(
!
bb
->
get_succ_basic_blocks
().
empty
())
{
std
::
unordered_set
<
BasicBlock
*>
suc_table
;
std
::
unordered_set
<
BasicBlock
*>
suc_table
;
std
::
unordered_set
<
BasicBlock
*>
br_get
;
std
::
unordered_set
<
BasicBlock
*>
br_get
;
for
(
auto
suc
:
bb
->
get_succ_basic_blocks
())
for
(
auto
suc
:
bb
->
get_succ_basic_blocks
())
...
@@ -179,18 +195,18 @@ void Function::check_for_block_relation_error() const
...
@@ -179,18 +195,18 @@ void Function::check_for_block_relation_error() const
for
(
auto
i
:
ops
)
for
(
auto
i
:
ops
)
{
{
auto
bb2
=
dynamic_cast
<
BasicBlock
*>
(
i
);
auto
bb2
=
dynamic_cast
<
BasicBlock
*>
(
i
);
if
(
bb2
!=
nullptr
)
br_get
.
emplace
(
bb2
);
if
(
bb2
!=
nullptr
)
br_get
.
emplace
(
bb2
);
}
}
// 这三个检查保证有问题会报错,但不保证每次报错的基本块都相同
// 这三个检查保证有问题会报错,但不保证每次报错的基本块都相同
// 例如 A, B 两个基本块都存在问题,可能有时 A 报错有时 B 报错
// 例如 A, B 两个基本块都存在问题,可能有时 A 报错有时 B 报错
for
(
auto
i
:
suc_table
)
for
(
auto
i
:
suc_table
)
assert
(
br_get
.
count
(
i
)
&&
"基本块 A 的后继块有 B,但 B 并未在 A 的 br 指令中出现"
);
assert
(
br_get
.
count
(
i
)
&&
"基本块 A 的后继块有 B,但 B 并未在 A 的 br 指令中出现"
);
for
(
auto
i
:
br_get
)
for
(
auto
i
:
br_get
)
assert
(
suc_table
.
count
(
i
)
&&
"基本块 A 的后继块没有 B,但 B 在 A 的 br 指令中出现了"
);
assert
(
suc_table
.
count
(
i
)
&&
"基本块 A 的后继块没有 B,但 B 在 A 的 br 指令中出现了"
);
for
(
auto
i
:
suc_table
)
{
for
(
auto
i
:
suc_table
)
{
bool
ok
=
false
;
bool
ok
=
false
;
for
(
auto
j
:
i
->
get_pre_basic_blocks
())
{
for
(
auto
j
:
i
->
get_pre_basic_blocks
())
{
if
(
j
==
bb
)
{
if
(
j
==
bb
)
{
ok
=
true
;
ok
=
true
;
break
;
break
;
}
}
...
@@ -222,7 +238,22 @@ void Function::check_for_block_relation_error() const
...
@@ -222,7 +238,22 @@ void Function::check_for_block_relation_error() const
{
{
for
(
auto
inst
:
bb
->
get_instructions
())
for
(
auto
inst
:
bb
->
get_instructions
())
{
{
assert
((
inst
->
get_parent
()
==
bb
)
&&
"基本块 A 指令表包含指令 b, 但是 b 的 get_parent 函数不返回 A"
);
assert
((
inst
->
get_parent
()
==
bb
)
&&
"基本块 A 指令表包含指令 b, 但是 b 的 get_parent 函数不返回 A"
);
}
}
}
}
}
}
std
::
string
Function
::
safe_print
()
const
{
auto
ty
=
this
->
get_function_type
();
if
(
ty
==
nullptr
)
return
"unknown type @"
+
get_name
();
auto
ty2
=
ty
->
get_return_type
();
std
::
string
func_ir
=
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
())
+
" @"
;
func_ir
+=
get_name
()
+
"("
;
for
(
unsigned
i
=
0
;
i
<
ty
->
get_num_of_args
();
i
++
)
{
if
(
i
)
func_ir
+=
", "
;
auto
ty3
=
ty
->
get_param_type
(
i
);
func_ir
+=
(
ty3
==
nullptr
?
"<null>"
:
ty3
->
safe_print
());
}
return
func_ir
+
") "
+
std
::
to_string
(
basic_blocks_
.
size
())
+
"b"
;
}
src/lightir/GlobalVariable.cpp
View file @
a6d37a3d
...
@@ -11,6 +11,18 @@ GlobalVariable::GlobalVariable(const std::string& name, Module *m, Type *ty,
...
@@ -11,6 +11,18 @@ GlobalVariable::GlobalVariable(const std::string& name, Module *m, Type *ty,
}
}
}
// global操作数为initval
}
// global操作数为initval
std
::
string
GlobalVariable
::
safe_print
()
const
{
std
::
string
ret
;
if
(
is_const_
)
ret
+=
"const "
;
auto
ty
=
get_type
();
if
(
ty
==
nullptr
)
ret
+=
"<null> "
;
else
ret
+=
ty
->
safe_print
()
+
" "
;
ret
+=
get_name
();
if
(
init_val_
!=
nullptr
)
ret
+=
" "
+
init_val_
->
safe_print_help
();
return
ret
;
}
GlobalVariable
*
GlobalVariable
::
create
(
const
std
::
string
&
name
,
Module
*
m
,
Type
*
ty
,
GlobalVariable
*
GlobalVariable
::
create
(
const
std
::
string
&
name
,
Module
*
m
,
Type
*
ty
,
bool
is_const
,
bool
is_const
,
Constant
*
init
=
nullptr
)
{
Constant
*
init
=
nullptr
)
{
...
...
src/lightir/IRprinter.cpp
View file @
a6d37a3d
...
@@ -23,6 +23,127 @@ std::string print_as_op(Value *v, bool print_ty) {
...
@@ -23,6 +23,127 @@ std::string print_as_op(Value *v, bool print_ty) {
return
op_ir
;
return
op_ir
;
}
}
static
std
::
string
safe_print_op_as_op
(
const
Instruction
*
v
,
unsigned
idx
,
bool
print_ty
)
{
if
(
v
->
get_num_operand
()
<=
idx
)
return
"op<unknown>"
;
Value
*
val
=
v
->
get_operand
(
idx
);
if
(
val
==
nullptr
)
return
"op<null>"
;
std
::
string
op_ir
;
if
(
print_ty
)
{
auto
ty
=
val
->
get_type
();
if
(
ty
==
nullptr
)
op_ir
+=
"t<null> "
;
else
{
op_ir
+=
ty
->
safe_print
();
op_ir
+=
" "
;
}
}
if
(
dynamic_cast
<
GlobalVariable
*>
(
val
)
||
dynamic_cast
<
Function
*>
(
val
))
{
op_ir
+=
"@"
+
val
->
safe_get_name_or_ptr
();
}
else
if
(
auto
constant
=
dynamic_cast
<
Constant
*>
(
val
))
{
op_ir
+=
constant
->
safe_print_help
();
}
else
{
op_ir
+=
"%"
+
val
->
safe_get_name_or_ptr
();
}
return
op_ir
;
}
static
std
::
string
safe_print_as_op
(
const
Value
*
v
,
bool
print_ty
)
{
std
::
string
op_ir
;
if
(
print_ty
)
{
auto
ty
=
v
->
get_type
();
if
(
ty
==
nullptr
)
op_ir
+=
"t<null> "
;
else
{
op_ir
+=
ty
->
safe_print
();
op_ir
+=
" "
;
}
}
if
(
dynamic_cast
<
const
GlobalVariable
*>
(
v
)
||
dynamic_cast
<
const
Function
*>
(
v
))
{
op_ir
+=
"@"
+
v
->
safe_get_name_or_ptr
();
}
else
if
(
auto
constant
=
dynamic_cast
<
const
Constant
*>
(
v
))
{
op_ir
+=
constant
->
safe_print_help
();
}
else
{
op_ir
+=
"%"
+
v
->
safe_get_name_or_ptr
();
}
return
op_ir
;
}
static
const
char
*
safe_print_instr_op_name
(
Instruction
::
OpID
id
)
{
switch
(
id
)
{
case
Instruction
::
ret
:
return
"ret"
;
case
Instruction
::
br
:
return
"br"
;
case
Instruction
::
add
:
return
"add"
;
case
Instruction
::
sub
:
return
"sub"
;
case
Instruction
::
mul
:
return
"mul"
;
case
Instruction
::
sdiv
:
return
"sdiv"
;
case
Instruction
::
fadd
:
return
"fadd"
;
case
Instruction
::
fsub
:
return
"fsub"
;
case
Instruction
::
fmul
:
return
"fmul"
;
case
Instruction
::
fdiv
:
return
"fdiv"
;
case
Instruction
::
alloca
:
return
"alloca"
;
case
Instruction
::
load
:
return
"load"
;
case
Instruction
::
store
:
return
"store"
;
case
Instruction
::
ge
:
return
"sge"
;
case
Instruction
::
gt
:
return
"sgt"
;
case
Instruction
::
le
:
return
"sle"
;
case
Instruction
::
lt
:
return
"slt"
;
case
Instruction
::
eq
:
return
"eq"
;
case
Instruction
::
ne
:
return
"ne"
;
case
Instruction
::
fge
:
return
"uge"
;
case
Instruction
::
fgt
:
return
"ugt"
;
case
Instruction
::
fle
:
return
"ule"
;
case
Instruction
::
flt
:
return
"ult"
;
case
Instruction
::
feq
:
return
"ueq"
;
case
Instruction
::
fne
:
return
"une"
;
case
Instruction
::
phi
:
return
"phi"
;
case
Instruction
::
call
:
return
"call"
;
case
Instruction
::
getelementptr
:
return
"getelementptr"
;
case
Instruction
::
zext
:
return
"zext"
;
case
Instruction
::
fptosi
:
return
"fptosi"
;
case
Instruction
::
sitofp
:
return
"sitofp"
;
}
return
"inst<unknown>"
;
}
std
::
string
print_instr_op_name
(
Instruction
::
OpID
id
)
{
std
::
string
print_instr_op_name
(
Instruction
::
OpID
id
)
{
switch
(
id
)
{
switch
(
id
)
{
case
Instruction
::
ret
:
case
Instruction
::
ret
:
...
@@ -91,6 +212,236 @@ std::string print_instr_op_name(Instruction::OpID id) {
...
@@ -91,6 +212,236 @@ std::string print_instr_op_name(Instruction::OpID id) {
assert
(
false
&&
"Must be bug"
);
assert
(
false
&&
"Must be bug"
);
}
}
std
::
string
Instruction
::
safe_print
()
const
{
switch
(
op_id_
)
{
case
ret
:
{
std
::
string
instr_ir
;
instr_ir
+=
get_instr_op_name
();
instr_ir
+=
" "
;
if
(
!
dynamic_cast
<
const
ReturnInst
*>
(
this
)
->
is_void_ret
())
{
instr_ir
+=
this
->
get_operand
(
0
)
->
get_type
()
->
print
();
instr_ir
+=
" "
;
instr_ir
+=
print_as_op
(
this
->
get_operand
(
0
),
false
);
}
else
{
instr_ir
+=
"void"
;
}
return
instr_ir
;
}
case
br
:
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
());
instr_ir
+=
" "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
if
(
dynamic_cast
<
const
BranchInst
*>
(
this
)
->
is_cond_br
())
{
instr_ir
+=
", "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
1
,
true
);
instr_ir
+=
", "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
2
,
true
);
}
return
instr_ir
;
}
case
add
:
case
sub
:
case
mul
:
case
sdiv
:
case
fadd
:
case
fsub
:
case
fmul
:
case
fdiv
:
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
instr_ir
+=
safe_print_instr_op_name
(
op_id_
);
instr_ir
+=
" "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
instr_ir
+=
", "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
1
,
true
);
return
instr_ir
;
}
case
alloca
:
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
instr_ir
+=
get_instr_op_name
();
instr_ir
+=
" "
;
auto
ty
=
get_type
();
if
(
ty
==
nullptr
||
!
ty
->
is_pointer_type
())
{
instr_ir
+=
"t<unknown>"
;
}
else
{
auto
ty2
=
ty
->
get_pointer_element_type
();
if
(
ty2
==
nullptr
)
instr_ir
+=
"t<null>"
;
else
instr_ir
+=
ty2
->
safe_print
();
}
return
instr_ir
;
}
case
load
:
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
());
instr_ir
+=
" "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
return
instr_ir
;
}
case
store
:
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
());
instr_ir
+=
" "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
instr_ir
+=
", "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
1
,
true
);
return
instr_ir
;
}
case
ge
:
case
gt
:
case
le
:
case
lt
:
case
eq
:
case
ne
:
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = icmp "
;
instr_ir
+=
safe_print_instr_op_name
(
op_id_
);
instr_ir
+=
" "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
instr_ir
+=
", "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
1
,
true
);
return
instr_ir
;
}
case
fge
:
case
fgt
:
case
fle
:
case
flt
:
case
feq
:
case
fne
:
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = fcmp "
;
instr_ir
+=
safe_print_instr_op_name
(
op_id_
);
instr_ir
+=
" "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
instr_ir
+=
", "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
1
,
true
);
return
instr_ir
;
}
case
phi
:
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
());
instr_ir
+=
" "
;
for
(
unsigned
i
=
0
;
i
<
this
->
get_num_operand
()
/
2
;
i
++
)
{
if
(
i
>
0
)
instr_ir
+=
", "
;
instr_ir
+=
"[ "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
i
<<
1
,
true
);
instr_ir
+=
", "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
(
i
<<
1
)
+
1
,
true
);
instr_ir
+=
" ]"
;
}
return
instr_ir
;
}
case
call
:
{
std
::
string
instr_ir
;
auto
ty
=
get_type
();
if
(
ty
==
nullptr
||
!
ty
->
is_void_type
())
{
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
}
instr_ir
+=
safe_print_instr_op_name
(
op_id_
);
instr_ir
+=
" "
;
if
(
get_num_operand
()
==
0
)
{
return
instr_ir
+
"<error no operand>"
;
}
auto
op0
=
get_operand
(
0
);
if
(
op0
==
nullptr
)
{
instr_ir
+=
"ft<null> "
;
}
else
{
if
(
auto
fty
=
dynamic_cast
<
FunctionType
*>
(
ty
))
{
auto
ty3
=
fty
->
get_return_type
();
if
(
ty3
==
nullptr
)
instr_ir
+=
"t<null> "
;
else
instr_ir
+=
ty3
->
safe_print
();
}
else
{
instr_ir
+=
"<error not func> "
;
instr_ir
+=
safe_print_as_op
(
op0
,
true
);
return
instr_ir
;
}
}
instr_ir
+=
" "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
false
);
instr_ir
+=
"("
;
for
(
unsigned
i
=
1
;
i
<
this
->
get_num_operand
();
i
++
)
{
if
(
i
>
1
)
instr_ir
+=
", "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
i
,
true
);
}
instr_ir
+=
")"
;
return
instr_ir
;
}
case
getelementptr
:
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
());
instr_ir
+=
" "
;
for
(
unsigned
i
=
0
;
i
<
this
->
get_num_operand
();
i
++
)
{
if
(
i
>
0
)
instr_ir
+=
", "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
i
,
true
);
}
return
instr_ir
;
}
case
zext
:
case
fptosi
:
case
sitofp
:
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
());
instr_ir
+=
" "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
return
instr_ir
;
}
}
std
::
string
str
;
str
+=
safe_print_as_op
(
this
,
true
);
str
+=
" = unknown inst"
;
return
str
;
}
template
<
class
BinInst
>
template
<
class
BinInst
>
static
std
::
string
print_binary_inst
(
const
BinInst
&
inst
)
{
static
std
::
string
print_binary_inst
(
const
BinInst
&
inst
)
{
std
::
string
instr_ir
;
std
::
string
instr_ir
;
...
@@ -111,6 +462,7 @@ static std::string print_binary_inst(const BinInst &inst) {
...
@@ -111,6 +462,7 @@ static std::string print_binary_inst(const BinInst &inst) {
return
instr_ir
;
return
instr_ir
;
}
}
std
::
string
IBinaryInst
::
print
()
{
return
print_binary_inst
(
*
this
);
}
std
::
string
IBinaryInst
::
print
()
{
return
print_binary_inst
(
*
this
);
}
std
::
string
FBinaryInst
::
print
()
{
return
print_binary_inst
(
*
this
);
}
std
::
string
FBinaryInst
::
print
()
{
return
print_binary_inst
(
*
this
);
}
template
<
class
CMP
>
template
<
class
CMP
>
...
@@ -140,6 +492,7 @@ static std::string print_cmp_inst(const CMP &inst) {
...
@@ -140,6 +492,7 @@ static std::string print_cmp_inst(const CMP &inst) {
return
instr_ir
;
return
instr_ir
;
}
}
std
::
string
ICmpInst
::
print
()
{
return
print_cmp_inst
(
*
this
);
}
std
::
string
ICmpInst
::
print
()
{
return
print_cmp_inst
(
*
this
);
}
std
::
string
FCmpInst
::
print
()
{
return
print_cmp_inst
(
*
this
);
}
std
::
string
FCmpInst
::
print
()
{
return
print_cmp_inst
(
*
this
);
}
std
::
string
CallInst
::
print
()
{
std
::
string
CallInst
::
print
()
{
...
@@ -185,12 +538,10 @@ std::string BranchInst::print() {
...
@@ -185,12 +538,10 @@ std::string BranchInst::print() {
std
::
string
ReturnInst
::
print
()
{
std
::
string
ReturnInst
::
print
()
{
std
::
string
instr_ir
;
std
::
string
instr_ir
;
instr_ir
+=
get_instr_op_name
(
);
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
()
);
instr_ir
+=
" "
;
instr_ir
+=
" "
;
if
(
!
is_void_ret
())
{
if
(
!
is_void_ret
())
{
instr_ir
+=
this
->
get_operand
(
0
)
->
get_type
()
->
print
();
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
instr_ir
+=
" "
;
instr_ir
+=
print_as_op
(
this
->
get_operand
(
0
),
false
);
}
else
{
}
else
{
instr_ir
+=
"void"
;
instr_ir
+=
"void"
;
}
}
...
...
src/lightir/Instruction.cpp
View file @
a6d37a3d
...
@@ -26,7 +26,7 @@ std::string Instruction::get_instr_op_name() const {
...
@@ -26,7 +26,7 @@ std::string Instruction::get_instr_op_name() const {
}
}
IBinaryInst
::
IBinaryInst
(
OpID
id
,
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
IBinaryInst
::
IBinaryInst
(
OpID
id
,
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
:
BaseInst
<
IBinaryInst
>
(
bb
->
get_module
()
->
get_int32_type
(),
id
,
bb
)
{
:
Instruction
(
bb
->
get_module
()
->
get_int32_type
(),
id
,
bb
)
{
assert
(
v1
->
get_type
()
->
is_int32_type
()
&&
v2
->
get_type
()
->
is_int32_type
()
&&
assert
(
v1
->
get_type
()
->
is_int32_type
()
&&
v2
->
get_type
()
->
is_int32_type
()
&&
"IBinaryInst operands are not both i32"
);
"IBinaryInst operands are not both i32"
);
add_operand
(
v1
);
add_operand
(
v1
);
...
@@ -34,20 +34,20 @@ IBinaryInst::IBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb)
...
@@ -34,20 +34,20 @@ IBinaryInst::IBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb)
}
}
IBinaryInst
*
IBinaryInst
::
create_add
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
IBinaryInst
*
IBinaryInst
::
create_add
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
add
,
v1
,
v2
,
bb
);
return
new
IBinaryInst
(
add
,
v1
,
v2
,
bb
);
}
}
IBinaryInst
*
IBinaryInst
::
create_sub
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
IBinaryInst
*
IBinaryInst
::
create_sub
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
sub
,
v1
,
v2
,
bb
);
return
new
IBinaryInst
(
sub
,
v1
,
v2
,
bb
);
}
}
IBinaryInst
*
IBinaryInst
::
create_mul
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
IBinaryInst
*
IBinaryInst
::
create_mul
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
mul
,
v1
,
v2
,
bb
);
return
new
IBinaryInst
(
mul
,
v1
,
v2
,
bb
);
}
}
IBinaryInst
*
IBinaryInst
::
create_sdiv
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
IBinaryInst
*
IBinaryInst
::
create_sdiv
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
sdiv
,
v1
,
v2
,
bb
);
return
new
IBinaryInst
(
sdiv
,
v1
,
v2
,
bb
);
}
}
FBinaryInst
::
FBinaryInst
(
OpID
id
,
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
FBinaryInst
::
FBinaryInst
(
OpID
id
,
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
:
BaseInst
<
FBinaryInst
>
(
bb
->
get_module
()
->
get_float_type
(),
id
,
bb
)
{
:
Instruction
(
bb
->
get_module
()
->
get_float_type
(),
id
,
bb
)
{
assert
(
v1
->
get_type
()
->
is_float_type
()
&&
v2
->
get_type
()
->
is_float_type
()
&&
assert
(
v1
->
get_type
()
->
is_float_type
()
&&
v2
->
get_type
()
->
is_float_type
()
&&
"FBinaryInst operands are not both float"
);
"FBinaryInst operands are not both float"
);
add_operand
(
v1
);
add_operand
(
v1
);
...
@@ -55,20 +55,20 @@ FBinaryInst::FBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb)
...
@@ -55,20 +55,20 @@ FBinaryInst::FBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb)
}
}
FBinaryInst
*
FBinaryInst
::
create_fadd
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
FBinaryInst
*
FBinaryInst
::
create_fadd
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
fadd
,
v1
,
v2
,
bb
);
return
new
FBinaryInst
(
fadd
,
v1
,
v2
,
bb
);
}
}
FBinaryInst
*
FBinaryInst
::
create_fsub
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
FBinaryInst
*
FBinaryInst
::
create_fsub
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
fsub
,
v1
,
v2
,
bb
);
return
new
FBinaryInst
(
fsub
,
v1
,
v2
,
bb
);
}
}
FBinaryInst
*
FBinaryInst
::
create_fmul
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
FBinaryInst
*
FBinaryInst
::
create_fmul
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
fmul
,
v1
,
v2
,
bb
);
return
new
FBinaryInst
(
fmul
,
v1
,
v2
,
bb
);
}
}
FBinaryInst
*
FBinaryInst
::
create_fdiv
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
FBinaryInst
*
FBinaryInst
::
create_fdiv
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
fdiv
,
v1
,
v2
,
bb
);
return
new
FBinaryInst
(
fdiv
,
v1
,
v2
,
bb
);
}
}
ICmpInst
::
ICmpInst
(
OpID
id
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
)
ICmpInst
::
ICmpInst
(
OpID
id
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
)
:
BaseInst
<
ICmpInst
>
(
bb
->
get_module
()
->
get_int1_type
(),
id
,
bb
)
{
:
Instruction
(
bb
->
get_module
()
->
get_int1_type
(),
id
,
bb
)
{
assert
(
lhs
->
get_type
()
->
is_int32_type
()
&&
assert
(
lhs
->
get_type
()
->
is_int32_type
()
&&
rhs
->
get_type
()
->
is_int32_type
()
&&
rhs
->
get_type
()
->
is_int32_type
()
&&
"CmpInst operands are not both i32"
);
"CmpInst operands are not both i32"
);
...
@@ -77,26 +77,26 @@ ICmpInst::ICmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb)
...
@@ -77,26 +77,26 @@ ICmpInst::ICmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb)
}
}
ICmpInst
*
ICmpInst
::
create_ge
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
ICmpInst
*
ICmpInst
::
create_ge
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
ge
,
v1
,
v2
,
bb
);
return
new
ICmpInst
(
ge
,
v1
,
v2
,
bb
);
}
}
ICmpInst
*
ICmpInst
::
create_gt
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
ICmpInst
*
ICmpInst
::
create_gt
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
gt
,
v1
,
v2
,
bb
);
return
new
ICmpInst
(
gt
,
v1
,
v2
,
bb
);
}
}
ICmpInst
*
ICmpInst
::
create_le
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
ICmpInst
*
ICmpInst
::
create_le
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
le
,
v1
,
v2
,
bb
);
return
new
ICmpInst
(
le
,
v1
,
v2
,
bb
);
}
}
ICmpInst
*
ICmpInst
::
create_lt
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
ICmpInst
*
ICmpInst
::
create_lt
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
lt
,
v1
,
v2
,
bb
);
return
new
ICmpInst
(
lt
,
v1
,
v2
,
bb
);
}
}
ICmpInst
*
ICmpInst
::
create_eq
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
ICmpInst
*
ICmpInst
::
create_eq
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
eq
,
v1
,
v2
,
bb
);
return
new
ICmpInst
(
eq
,
v1
,
v2
,
bb
);
}
}
ICmpInst
*
ICmpInst
::
create_ne
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
ICmpInst
*
ICmpInst
::
create_ne
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
ne
,
v1
,
v2
,
bb
);
return
new
ICmpInst
(
ne
,
v1
,
v2
,
bb
);
}
}
FCmpInst
::
FCmpInst
(
OpID
id
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
)
FCmpInst
::
FCmpInst
(
OpID
id
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
)
:
BaseInst
<
FCmpInst
>
(
bb
->
get_module
()
->
get_int1_type
(),
id
,
bb
)
{
:
Instruction
(
bb
->
get_module
()
->
get_int1_type
(),
id
,
bb
)
{
assert
(
lhs
->
get_type
()
->
is_float_type
()
&&
assert
(
lhs
->
get_type
()
->
is_float_type
()
&&
rhs
->
get_type
()
->
is_float_type
()
&&
rhs
->
get_type
()
->
is_float_type
()
&&
"FCmpInst operands are not both float"
);
"FCmpInst operands are not both float"
);
...
@@ -105,26 +105,26 @@ FCmpInst::FCmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb)
...
@@ -105,26 +105,26 @@ FCmpInst::FCmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb)
}
}
FCmpInst
*
FCmpInst
::
create_fge
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
FCmpInst
*
FCmpInst
::
create_fge
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
fge
,
v1
,
v2
,
bb
);
return
new
FCmpInst
(
fge
,
v1
,
v2
,
bb
);
}
}
FCmpInst
*
FCmpInst
::
create_fgt
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
FCmpInst
*
FCmpInst
::
create_fgt
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
fgt
,
v1
,
v2
,
bb
);
return
new
FCmpInst
(
fgt
,
v1
,
v2
,
bb
);
}
}
FCmpInst
*
FCmpInst
::
create_fle
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
FCmpInst
*
FCmpInst
::
create_fle
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
fle
,
v1
,
v2
,
bb
);
return
new
FCmpInst
(
fle
,
v1
,
v2
,
bb
);
}
}
FCmpInst
*
FCmpInst
::
create_flt
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
FCmpInst
*
FCmpInst
::
create_flt
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
flt
,
v1
,
v2
,
bb
);
return
new
FCmpInst
(
flt
,
v1
,
v2
,
bb
);
}
}
FCmpInst
*
FCmpInst
::
create_feq
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
FCmpInst
*
FCmpInst
::
create_feq
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
feq
,
v1
,
v2
,
bb
);
return
new
FCmpInst
(
feq
,
v1
,
v2
,
bb
);
}
}
FCmpInst
*
FCmpInst
::
create_fne
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
FCmpInst
*
FCmpInst
::
create_fne
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
)
{
return
create
(
fne
,
v1
,
v2
,
bb
);
return
new
FCmpInst
(
fne
,
v1
,
v2
,
bb
);
}
}
CallInst
::
CallInst
(
Function
*
func
,
const
std
::
vector
<
Value
*>&
args
,
BasicBlock
*
bb
)
CallInst
::
CallInst
(
Function
*
func
,
const
std
::
vector
<
Value
*>&
args
,
BasicBlock
*
bb
)
:
BaseInst
<
CallInst
>
(
func
->
get_return_type
(),
call
,
bb
)
{
:
Instruction
(
func
->
get_return_type
(),
call
,
bb
)
{
assert
(
func
->
get_type
()
->
is_function_type
()
&&
"Not a function"
);
assert
(
func
->
get_type
()
->
is_function_type
()
&&
"Not a function"
);
assert
((
func
->
get_num_of_args
()
==
args
.
size
())
&&
"Wrong number of args"
);
assert
((
func
->
get_num_of_args
()
==
args
.
size
())
&&
"Wrong number of args"
);
add_operand
(
func
);
add_operand
(
func
);
...
@@ -138,7 +138,7 @@ CallInst::CallInst(Function *func, const std::vector<Value *>& args, BasicBlock
...
@@ -138,7 +138,7 @@ CallInst::CallInst(Function *func, const std::vector<Value *>& args, BasicBlock
CallInst
*
CallInst
::
create_call
(
Function
*
func
,
const
std
::
vector
<
Value
*>&
args
,
CallInst
*
CallInst
::
create_call
(
Function
*
func
,
const
std
::
vector
<
Value
*>&
args
,
BasicBlock
*
bb
)
{
BasicBlock
*
bb
)
{
return
create
(
func
,
args
,
bb
);
return
new
CallInst
(
func
,
args
,
bb
);
}
}
FunctionType
*
CallInst
::
get_function_type
()
const
{
FunctionType
*
CallInst
::
get_function_type
()
const
{
...
@@ -147,7 +147,7 @@ FunctionType *CallInst::get_function_type() const {
...
@@ -147,7 +147,7 @@ FunctionType *CallInst::get_function_type() const {
BranchInst
::
BranchInst
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
,
BranchInst
::
BranchInst
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
,
BasicBlock
*
bb
)
BasicBlock
*
bb
)
:
BaseInst
<
BranchInst
>
(
bb
->
get_module
()
->
get_void_type
(),
br
,
bb
)
{
:
Instruction
(
bb
->
get_module
()
->
get_void_type
(),
br
,
bb
)
{
if
(
cond
==
nullptr
)
{
// conditionless jump
if
(
cond
==
nullptr
)
{
// conditionless jump
assert
(
if_false
==
nullptr
&&
"Given false-bb on conditionless jump"
);
assert
(
if_false
==
nullptr
&&
"Given false-bb on conditionless jump"
);
add_operand
(
if_true
);
add_operand
(
if_true
);
...
@@ -186,15 +186,15 @@ BranchInst::~BranchInst() {
...
@@ -186,15 +186,15 @@ BranchInst::~BranchInst() {
BranchInst
*
BranchInst
::
create_cond_br
(
Value
*
cond
,
BasicBlock
*
if_true
,
BranchInst
*
BranchInst
::
create_cond_br
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
,
BasicBlock
*
bb
)
{
BasicBlock
*
if_false
,
BasicBlock
*
bb
)
{
return
create
(
cond
,
if_true
,
if_false
,
bb
);
return
new
BranchInst
(
cond
,
if_true
,
if_false
,
bb
);
}
}
BranchInst
*
BranchInst
::
create_br
(
BasicBlock
*
if_true
,
BasicBlock
*
bb
)
{
BranchInst
*
BranchInst
::
create_br
(
BasicBlock
*
if_true
,
BasicBlock
*
bb
)
{
return
create
(
nullptr
,
if_true
,
nullptr
,
bb
);
return
new
BranchInst
(
nullptr
,
if_true
,
nullptr
,
bb
);
}
}
ReturnInst
::
ReturnInst
(
Value
*
val
,
BasicBlock
*
bb
)
ReturnInst
::
ReturnInst
(
Value
*
val
,
BasicBlock
*
bb
)
:
BaseInst
<
ReturnInst
>
(
bb
->
get_module
()
->
get_void_type
(),
ret
,
bb
)
{
:
Instruction
(
bb
->
get_module
()
->
get_void_type
(),
ret
,
bb
)
{
if
(
val
==
nullptr
)
{
if
(
val
==
nullptr
)
{
assert
(
bb
->
get_parent
()
->
get_return_type
()
->
is_void_type
());
assert
(
bb
->
get_parent
()
->
get_return_type
()
->
is_void_type
());
}
else
{
}
else
{
...
@@ -207,17 +207,17 @@ ReturnInst::ReturnInst(Value *val, BasicBlock *bb)
...
@@ -207,17 +207,17 @@ ReturnInst::ReturnInst(Value *val, BasicBlock *bb)
}
}
ReturnInst
*
ReturnInst
::
create_ret
(
Value
*
val
,
BasicBlock
*
bb
)
{
ReturnInst
*
ReturnInst
::
create_ret
(
Value
*
val
,
BasicBlock
*
bb
)
{
return
create
(
val
,
bb
);
return
new
ReturnInst
(
val
,
bb
);
}
}
ReturnInst
*
ReturnInst
::
create_void_ret
(
BasicBlock
*
bb
)
{
ReturnInst
*
ReturnInst
::
create_void_ret
(
BasicBlock
*
bb
)
{
return
create
(
nullptr
,
bb
);
return
new
ReturnInst
(
nullptr
,
bb
);
}
}
bool
ReturnInst
::
is_void_ret
()
const
{
return
get_num_operand
()
==
0
;
}
bool
ReturnInst
::
is_void_ret
()
const
{
return
get_num_operand
()
==
0
;
}
GetElementPtrInst
::
GetElementPtrInst
(
Value
*
ptr
,
const
std
::
vector
<
Value
*>&
idxs
,
GetElementPtrInst
::
GetElementPtrInst
(
Value
*
ptr
,
const
std
::
vector
<
Value
*>&
idxs
,
BasicBlock
*
bb
)
BasicBlock
*
bb
)
:
BaseInst
<
GetElementPtrInst
>
(
PointerType
::
get
(
get_element_type
(
ptr
,
idxs
)),
:
Instruction
(
PointerType
::
get
(
get_element_type
(
ptr
,
idxs
)),
getelementptr
,
bb
)
{
getelementptr
,
bb
)
{
add_operand
(
ptr
);
add_operand
(
ptr
);
for
(
auto
idx
:
idxs
)
for
(
auto
idx
:
idxs
)
...
@@ -258,11 +258,11 @@ Type *GetElementPtrInst::get_element_type() const {
...
@@ -258,11 +258,11 @@ Type *GetElementPtrInst::get_element_type() const {
GetElementPtrInst
*
GetElementPtrInst
::
create_gep
(
Value
*
ptr
,
GetElementPtrInst
*
GetElementPtrInst
::
create_gep
(
Value
*
ptr
,
const
std
::
vector
<
Value
*>&
idxs
,
const
std
::
vector
<
Value
*>&
idxs
,
BasicBlock
*
bb
)
{
BasicBlock
*
bb
)
{
return
create
(
ptr
,
idxs
,
bb
);
return
new
GetElementPtrInst
(
ptr
,
idxs
,
bb
);
}
}
StoreInst
::
StoreInst
(
Value
*
val
,
Value
*
ptr
,
BasicBlock
*
bb
)
StoreInst
::
StoreInst
(
Value
*
val
,
Value
*
ptr
,
BasicBlock
*
bb
)
:
BaseInst
<
StoreInst
>
(
bb
->
get_module
()
->
get_void_type
(),
store
,
bb
)
{
:
Instruction
(
bb
->
get_module
()
->
get_void_type
(),
store
,
bb
)
{
assert
((
ptr
->
get_type
()
->
get_pointer_element_type
()
==
val
->
get_type
())
&&
assert
((
ptr
->
get_type
()
->
get_pointer_element_type
()
==
val
->
get_type
())
&&
"StoreInst ptr is not a pointer to val type"
);
"StoreInst ptr is not a pointer to val type"
);
add_operand
(
val
);
add_operand
(
val
);
...
@@ -270,11 +270,11 @@ StoreInst::StoreInst(Value *val, Value *ptr, BasicBlock *bb)
...
@@ -270,11 +270,11 @@ StoreInst::StoreInst(Value *val, Value *ptr, BasicBlock *bb)
}
}
StoreInst
*
StoreInst
::
create_store
(
Value
*
val
,
Value
*
ptr
,
BasicBlock
*
bb
)
{
StoreInst
*
StoreInst
::
create_store
(
Value
*
val
,
Value
*
ptr
,
BasicBlock
*
bb
)
{
return
create
(
val
,
ptr
,
bb
);
return
new
StoreInst
(
val
,
ptr
,
bb
);
}
}
LoadInst
::
LoadInst
(
Value
*
ptr
,
BasicBlock
*
bb
)
LoadInst
::
LoadInst
(
Value
*
ptr
,
BasicBlock
*
bb
)
:
BaseInst
<
LoadInst
>
(
ptr
->
get_type
()
->
get_pointer_element_type
(),
load
,
:
Instruction
(
ptr
->
get_type
()
->
get_pointer_element_type
(),
load
,
bb
)
{
bb
)
{
assert
((
get_type
()
->
is_integer_type
()
or
get_type
()
->
is_float_type
()
or
assert
((
get_type
()
->
is_integer_type
()
or
get_type
()
->
is_float_type
()
or
get_type
()
->
is_pointer_type
())
&&
get_type
()
->
is_pointer_type
())
&&
...
@@ -283,12 +283,12 @@ LoadInst::LoadInst(Value *ptr, BasicBlock *bb)
...
@@ -283,12 +283,12 @@ LoadInst::LoadInst(Value *ptr, BasicBlock *bb)
}
}
LoadInst
*
LoadInst
::
create_load
(
Value
*
ptr
,
BasicBlock
*
bb
)
{
LoadInst
*
LoadInst
::
create_load
(
Value
*
ptr
,
BasicBlock
*
bb
)
{
return
create
(
ptr
,
bb
);
return
new
LoadInst
(
ptr
,
bb
);
}
}
AllocaInst
::
AllocaInst
(
Type
*
ty
,
BasicBlock
*
bb
)
AllocaInst
::
AllocaInst
(
Type
*
ty
,
BasicBlock
*
bb
)
:
BaseInst
<
AllocaInst
>
(
PointerType
::
get
(
ty
),
alloca
,
bb
)
{
:
Instruction
(
PointerType
::
get
(
ty
),
alloca
,
bb
)
{
static
constexpr
std
::
array
allowed_alloc_type
=
{
static
constexpr
std
::
array
<
Type
::
TypeID
,
4
>
allowed_alloc_type
=
{
Type
::
IntegerTyID
,
Type
::
FloatTyID
,
Type
::
ArrayTyID
,
Type
::
PointerTyID
};
Type
::
IntegerTyID
,
Type
::
FloatTyID
,
Type
::
ArrayTyID
,
Type
::
PointerTyID
};
assert
(
std
::
find
(
allowed_alloc_type
.
begin
(),
allowed_alloc_type
.
end
(),
assert
(
std
::
find
(
allowed_alloc_type
.
begin
(),
allowed_alloc_type
.
end
(),
ty
->
get_type_id
())
!=
allowed_alloc_type
.
end
()
&&
ty
->
get_type_id
())
!=
allowed_alloc_type
.
end
()
&&
...
@@ -296,11 +296,11 @@ AllocaInst::AllocaInst(Type *ty, BasicBlock *bb)
...
@@ -296,11 +296,11 @@ AllocaInst::AllocaInst(Type *ty, BasicBlock *bb)
}
}
AllocaInst
*
AllocaInst
::
create_alloca
(
Type
*
ty
,
BasicBlock
*
bb
)
{
AllocaInst
*
AllocaInst
::
create_alloca
(
Type
*
ty
,
BasicBlock
*
bb
)
{
return
create
(
ty
,
bb
);
return
new
AllocaInst
(
ty
,
bb
);
}
}
ZextInst
::
ZextInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
ZextInst
::
ZextInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
:
BaseInst
<
ZextInst
>
(
ty
,
zext
,
bb
)
{
:
Instruction
(
ty
,
zext
,
bb
)
{
assert
(
val
->
get_type
()
->
is_integer_type
()
&&
assert
(
val
->
get_type
()
->
is_integer_type
()
&&
"ZextInst operand is not integer"
);
"ZextInst operand is not integer"
);
assert
(
ty
->
is_integer_type
()
&&
"ZextInst destination type is not integer"
);
assert
(
ty
->
is_integer_type
()
&&
"ZextInst destination type is not integer"
);
...
@@ -312,14 +312,14 @@ ZextInst::ZextInst(Value *val, Type *ty, BasicBlock *bb)
...
@@ -312,14 +312,14 @@ ZextInst::ZextInst(Value *val, Type *ty, BasicBlock *bb)
}
}
ZextInst
*
ZextInst
::
create_zext
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
{
ZextInst
*
ZextInst
::
create_zext
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
{
return
create
(
val
,
ty
,
bb
);
return
new
ZextInst
(
val
,
ty
,
bb
);
}
}
ZextInst
*
ZextInst
::
create_zext_to_i32
(
Value
*
val
,
BasicBlock
*
bb
)
{
ZextInst
*
ZextInst
::
create_zext_to_i32
(
Value
*
val
,
BasicBlock
*
bb
)
{
return
create
(
val
,
bb
->
get_module
()
->
get_int32_type
(),
bb
);
return
new
ZextInst
(
val
,
bb
->
get_module
()
->
get_int32_type
(),
bb
);
}
}
FpToSiInst
::
FpToSiInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
FpToSiInst
::
FpToSiInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
:
BaseInst
<
FpToSiInst
>
(
ty
,
fptosi
,
bb
)
{
:
Instruction
(
ty
,
fptosi
,
bb
)
{
assert
(
val
->
get_type
()
->
is_float_type
()
&&
assert
(
val
->
get_type
()
->
is_float_type
()
&&
"FpToSiInst operand is not float"
);
"FpToSiInst operand is not float"
);
assert
(
ty
->
is_integer_type
()
&&
assert
(
ty
->
is_integer_type
()
&&
...
@@ -328,14 +328,14 @@ FpToSiInst::FpToSiInst(Value *val, Type *ty, BasicBlock *bb)
...
@@ -328,14 +328,14 @@ FpToSiInst::FpToSiInst(Value *val, Type *ty, BasicBlock *bb)
}
}
FpToSiInst
*
FpToSiInst
::
create_fptosi
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
{
FpToSiInst
*
FpToSiInst
::
create_fptosi
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
{
return
create
(
val
,
ty
,
bb
);
return
new
FpToSiInst
(
val
,
ty
,
bb
);
}
}
FpToSiInst
*
FpToSiInst
::
create_fptosi_to_i32
(
Value
*
val
,
BasicBlock
*
bb
)
{
FpToSiInst
*
FpToSiInst
::
create_fptosi_to_i32
(
Value
*
val
,
BasicBlock
*
bb
)
{
return
create
(
val
,
bb
->
get_module
()
->
get_int32_type
(),
bb
);
return
new
FpToSiInst
(
val
,
bb
->
get_module
()
->
get_int32_type
(),
bb
);
}
}
SiToFpInst
::
SiToFpInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
SiToFpInst
::
SiToFpInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
:
BaseInst
<
SiToFpInst
>
(
ty
,
sitofp
,
bb
)
{
:
Instruction
(
ty
,
sitofp
,
bb
)
{
assert
(
val
->
get_type
()
->
is_integer_type
()
&&
assert
(
val
->
get_type
()
->
is_integer_type
()
&&
"SiToFpInst operand is not integer"
);
"SiToFpInst operand is not integer"
);
assert
(
ty
->
is_float_type
()
&&
"SiToFpInst destination type is not float"
);
assert
(
ty
->
is_float_type
()
&&
"SiToFpInst destination type is not float"
);
...
@@ -343,12 +343,12 @@ SiToFpInst::SiToFpInst(Value *val, Type *ty, BasicBlock *bb)
...
@@ -343,12 +343,12 @@ SiToFpInst::SiToFpInst(Value *val, Type *ty, BasicBlock *bb)
}
}
SiToFpInst
*
SiToFpInst
::
create_sitofp
(
Value
*
val
,
BasicBlock
*
bb
)
{
SiToFpInst
*
SiToFpInst
::
create_sitofp
(
Value
*
val
,
BasicBlock
*
bb
)
{
return
create
(
val
,
bb
->
get_module
()
->
get_float_type
(),
bb
);
return
new
SiToFpInst
(
val
,
bb
->
get_module
()
->
get_float_type
(),
bb
);
}
}
PhiInst
::
PhiInst
(
Type
*
ty
,
const
std
::
vector
<
Value
*>&
vals
,
PhiInst
::
PhiInst
(
Type
*
ty
,
const
std
::
vector
<
Value
*>&
vals
,
const
std
::
vector
<
BasicBlock
*>&
val_bbs
,
BasicBlock
*
bb
)
const
std
::
vector
<
BasicBlock
*>&
val_bbs
,
BasicBlock
*
bb
)
:
BaseInst
<
PhiInst
>
(
ty
,
phi
)
{
:
Instruction
(
ty
,
phi
)
{
assert
(
vals
.
size
()
==
val_bbs
.
size
()
&&
"Unmatched vals and bbs"
);
assert
(
vals
.
size
()
==
val_bbs
.
size
()
&&
"Unmatched vals and bbs"
);
for
(
unsigned
i
=
0
;
i
<
vals
.
size
();
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
vals
.
size
();
i
++
)
{
assert
(
ty
==
vals
[
i
]
->
get_type
()
&&
"Bad type for phi"
);
assert
(
ty
==
vals
[
i
]
->
get_type
()
&&
"Bad type for phi"
);
...
@@ -361,5 +361,5 @@ PhiInst::PhiInst(Type *ty, const std::vector<Value *>& vals,
...
@@ -361,5 +361,5 @@ PhiInst::PhiInst(Type *ty, const std::vector<Value *>& vals,
PhiInst
*
PhiInst
::
create_phi
(
Type
*
ty
,
BasicBlock
*
bb
,
PhiInst
*
PhiInst
::
create_phi
(
Type
*
ty
,
BasicBlock
*
bb
,
const
std
::
vector
<
Value
*>&
vals
,
const
std
::
vector
<
Value
*>&
vals
,
const
std
::
vector
<
BasicBlock
*>&
val_bbs
)
{
const
std
::
vector
<
BasicBlock
*>&
val_bbs
)
{
return
create
(
ty
,
vals
,
val_bbs
,
bb
);
return
new
PhiInst
(
ty
,
vals
,
val_bbs
,
bb
);
}
}
src/lightir/Type.cpp
View file @
a6d37a3d
...
@@ -111,6 +111,52 @@ std::string Type::print() const {
...
@@ -111,6 +111,52 @@ std::string Type::print() const {
return
type_ir
;
return
type_ir
;
}
}
std
::
string
Type
::
safe_print
()
const
{
switch
(
this
->
get_type_id
())
{
case
VoidTyID
:
return
"void"
;
case
LabelTyID
:
return
"label"
;
case
IntegerTyID
:
{
auto
ty
=
dynamic_cast
<
const
IntegerType
*>
(
this
);
if
(
ty
==
nullptr
)
return
"<not IntegerType>"
;
return
"i"
+
std
::
to_string
(
ty
->
get_num_bits
());
}
case
FunctionTyID
:
{
auto
ty
=
dynamic_cast
<
const
FunctionType
*>
(
this
);
if
(
ty
==
nullptr
)
return
"<not FunctionType>"
;
auto
ty2
=
ty
->
get_return_type
();
std
::
string
type_ir
=
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
())
+
" ("
;
for
(
unsigned
i
=
0
;
i
<
ty
->
get_num_of_args
();
i
++
)
{
if
(
i
)
type_ir
+=
", "
;
ty2
=
ty
->
get_param_type
(
i
);
type_ir
+=
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
());
}
return
type_ir
+
")"
;
}
case
PointerTyID
:
{
auto
ty
=
dynamic_cast
<
const
PointerType
*>
(
this
);
if
(
ty
==
nullptr
)
return
"<not PointerType>"
;
auto
ty2
=
ty
->
get_element_type
();
return
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
())
+
"*"
;
}
case
ArrayTyID
:
{
auto
ty
=
dynamic_cast
<
const
ArrayType
*>
(
this
);
if
(
ty
==
nullptr
)
return
"<not ArrayType>"
;
auto
ty2
=
ty
->
get_element_type
();
return
"["
+
std
::
to_string
(
ty
->
get_num_of_elements
())
+
"x"
+
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
())
+
"]"
;
}
case
FloatTyID
:
return
"float"
;
}
return
"<error>"
;
}
IntegerType
::
IntegerType
(
unsigned
num_bits
,
Module
*
m
)
IntegerType
::
IntegerType
(
unsigned
num_bits
,
Module
*
m
)
:
Type
(
Type
::
IntegerTyID
,
m
),
num_bits_
(
num_bits
)
:
Type
(
Type
::
IntegerTyID
,
m
),
num_bits_
(
num_bits
)
{
{
...
...
src/lightir/Value.cpp
View file @
a6d37a3d
#include "Value.hpp"
#include "Value.hpp"
#include "User.hpp"
#include "User.hpp"
#include "util.hpp"
Value
::~
Value
()
{
replace_all_use_with
(
nullptr
);
}
Value
::~
Value
()
{
replace_all_use_with
(
nullptr
);
}
...
@@ -42,3 +43,9 @@ void Value::replace_use_with_if(Value *new_val,
...
@@ -42,3 +43,9 @@ void Value::replace_use_with_if(Value *new_val,
use
.
val_
->
set_operand
(
use
.
arg_no_
,
new_val
);
use
.
val_
->
set_operand
(
use
.
arg_no_
,
new_val
);
}
}
}
}
std
::
string
Value
::
safe_get_name_or_ptr
()
const
{
if
(
name_
.
empty
())
return
ptr_to_str
(
this
);
return
name_
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment