25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
llvm::Function* getOrCreateFunc( const Context& c, const builtins::Func& func, const string& name,
llvm::Function::LinkageTypes linkageType );
void runOptimizationPasses();
bool emitToFile( const string& filename, llvm::CodeGenFileType type );
private:
struct Infos
{
Infos( const Context& c ) : context( c ) {}
const Context& context;
llvm::BasicBlock* allocaBasicBlock = nullptr;
llvm::AllocaInst* lastEmittedAlloca = nullptr;
using storage_type = cir::TempStorage< NullInit< llvm::Value* > >;
ptr< storage_type > temporaries = make_shared< storage_type >();
};
llvm::Function* getCurrentFunction() const
{
return m_llvmBuilder.GetInsertBlock()->getParent();
}
llvm::BasicBlock* buildCFG( Infos& inf, llvm::Function* llvmFunc, const ptr< cir::CFG >& pCFG );
llvm::BasicBlock* buildBasicBlock( Infos& inf, const ptr< cir::BasicBlock >& pBB );
llvm::Value* buildValue( Infos& inf, const Value& val );
llvm::Constant* buildConstant( Infos& inf, const Value& val );
llvm::Constant* buildConstantPointer( Infos& inf, const builtins::PointerType& ptType, const Value& v );
llvm::Value* buildInstruction( Infos& inf, const cir::Instruction& instr );
llvm::Value* buildInstruction( Infos& inf, const monostate& );
llvm::Value* buildInstruction( Infos& inf, const cir::Call& call );
llvm::Value* buildInstruction( Infos& inf, const cir::VarAddr& va );
llvm::Value* buildInstruction( Infos& inf, const cir::TempAddr& ta );
llvm::Value* buildInstruction( Infos& inf, const cir::Select& s );
llvm::Value* buildInstruction( Infos& inf, const cir::CreateTemporary& ct );
llvm::Value* buildInstruction( Infos& inf, const cir::GetTemporary& gt );
llvm::Value* buildInstruction( Infos& inf, const cir::AllocVar& av );
llvm::Value* buildInstruction( Infos& inf, const cir::Load& load );
llvm::Value* buildInstruction( Infos& inf, const cir::Store& store );
llvm::Value* buildInstruction( Infos& inf, const cir::Phi& p );
llvm::Value* buildInstruction( Infos& inf, const cir::Not& uo );
llvm::Value* buildInstruction( Infos& inf, const cir::And& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::Or& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::Xor& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::Implies& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::Shl& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::LShr& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::AShr& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::Add& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::Sub& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::Mul& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::UDiv& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::SDiv& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::URem& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::SRem& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::Eq& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::Neq& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::UGT& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::UGE& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::ULT& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::ULE& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::SGT& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::SGE& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::SLT& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::SLE& bo );
llvm::Value* buildInstruction( Infos& inf, const cir::Assert& ass );
llvm::Value* buildInstruction( Infos& inf, const cir::Placeholder& ph );
llvm::Value* buildInstruction( Infos& inf, const cir::PHOverride& pho );
llvm::Value* buildInstruction( Infos& inf, const cir::GhostCall& gc );
bool buildTerminator( Infos& inf, const cir::Terminator& terminator );
bool buildTerminator( Infos& inf, const cir::Ret& r );
bool buildTerminator( Infos& inf, const cir::Branch& b );
bool buildTerminator( Infos& inf, const cir::CondBranch& cb );
bool buildTerminator( Infos& inf, const cir::GhostBranch& gb );
template< typename T >
bool buildTerminator( Infos& inf, const T& t )
{
return false;
}
llvm::Value* buildAlloca( Infos& inf, llvm::Type* type );
llvm::Value* createTemporary( Infos& inf, uint32_t index, llvm::Value* pValue ) const;
llvm::Module m_llvmModule;
llvm::DataLayout m_dataLayout;
llvm::IRBuilder<> m_llvmBuilder;
llvm::TargetMachine* m_targetMachine = nullptr;
unordered_map< string, llvm::GlobalVariable* > m_strings;
|
|
>
|
>
>
>
>
>
>
>
>
|
|
|
|
|
>
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
llvm::Function* getOrCreateFunc( const Context& c, const builtins::Func& func, const string& name,
llvm::Function::LinkageTypes linkageType );
void runOptimizationPasses();
bool emitToFile( const string& filename, llvm::CodeGenFileType type );
private:
struct State
{
State( const Context& c, llvm::Function* f ) :
context( c ),
llvmFunc( f )
{}
const Context& context;
llvm::Function* llvmFunc = nullptr;
llvm::BasicBlock* allocaBasicBlock = nullptr;
llvm::AllocaInst* lastEmittedAlloca = nullptr;
using storage_type = cir::TempStorage< NullInit< llvm::Value* > >;
ptr< storage_type > temporaries = make_shared< storage_type >();
Stack stack;
};
static llvm::BasicBlock* GetOrCreateLLVMBB( State& st, const ptr< cir::BasicBlock >& pBB );
llvm::Function* getCurrentFunction() const
{
return m_llvmBuilder.GetInsertBlock()->getParent();
}
llvm::BasicBlock* buildCFG( State& st, llvm::Function* llvmFunc, const ptr< cir::CFG >& pCFG );
llvm::BasicBlock* buildBasicBlock( State& st, const ptr< cir::BasicBlock >& pBB );
llvm::Value* buildValue( State& st, const Value& val );
llvm::Constant* buildConstant( State& st, const Value& val );
llvm::Constant* buildConstantPointer( State& st, const builtins::PointerType& ptType, const Value& v );
bool buildInstruction( State& st, const cir::InstrSeq& is );
bool buildInstruction( State& st, const cir::Instruction& instr );
bool buildInstruction( State& st, const monostate& );
bool buildInstruction( State& st, const cir::Call& call );
bool buildInstruction( State& st, const cir::Constant& ct );
bool buildInstruction( State& st, const cir::VarAddr& va );
bool buildInstruction( State& st, const cir::TempAddr& ta );
bool buildInstruction( State& st, const cir::Select& s );
bool buildInstruction( State& st, const cir::CreateTemporary& ct );
bool buildInstruction( State& st, const cir::GetTemporary& gt );
bool buildInstruction( State& st, const cir::AllocVar& av );
bool buildInstruction( State& st, const cir::Load& load );
bool buildInstruction( State& st, const cir::Store& store );
bool buildInstruction( State& st, const cir::Phi& p );
bool buildInstruction( State& st, const cir::Not& uo );
bool buildInstruction( State& st, const cir::And& bo );
bool buildInstruction( State& st, const cir::Or& bo );
bool buildInstruction( State& st, const cir::Xor& bo );
bool buildInstruction( State& st, const cir::Implies& bo );
bool buildInstruction( State& st, const cir::Shl& bo );
bool buildInstruction( State& st, const cir::LShr& bo );
bool buildInstruction( State& st, const cir::AShr& bo );
bool buildInstruction( State& st, const cir::Add& bo );
bool buildInstruction( State& st, const cir::Sub& bo );
bool buildInstruction( State& st, const cir::Mul& bo );
bool buildInstruction( State& st, const cir::UDiv& bo );
bool buildInstruction( State& st, const cir::SDiv& bo );
bool buildInstruction( State& st, const cir::URem& bo );
bool buildInstruction( State& st, const cir::SRem& bo );
bool buildInstruction( State& st, const cir::Eq& bo );
bool buildInstruction( State& st, const cir::Neq& bo );
bool buildInstruction( State& st, const cir::UGT& bo );
bool buildInstruction( State& st, const cir::UGE& bo );
bool buildInstruction( State& st, const cir::ULT& bo );
bool buildInstruction( State& st, const cir::ULE& bo );
bool buildInstruction( State& st, const cir::SGT& bo );
bool buildInstruction( State& st, const cir::SGE& bo );
bool buildInstruction( State& st, const cir::SLT& bo );
bool buildInstruction( State& st, const cir::SLE& bo );
bool buildInstruction( State& st, const cir::Assert& ass );
bool buildInstruction( State& st, const cir::Placeholder& ph );
bool buildInstruction( State& st, const cir::PHOverride& pho );
bool buildInstruction( State& st, const cir::GhostCall& gc );
bool buildTerminator( State& st, const cir::Terminator& terminator );
bool buildTerminator( State& st, const cir::RetVoid& r );
bool buildTerminator( State& st, const cir::Ret& r );
bool buildTerminator( State& st, const cir::Branch& b );
bool buildTerminator( State& st, const cir::CondBranch& cb );
bool buildTerminator( State& st, const cir::GhostBranch& gb );
template< typename T >
bool buildTerminator( State& st, const T& t )
{
return false;
}
llvm::Value* buildAlloca( State& st, llvm::Type* type );
llvm::Value* createTemporary( State& st, uint32_t index, llvm::Value* pValue ) const;
llvm::Module m_llvmModule;
llvm::DataLayout m_dataLayout;
llvm::IRBuilder<> m_llvmBuilder;
llvm::TargetMachine* m_targetMachine = nullptr;
unordered_map< string, llvm::GlobalVariable* > m_strings;
|