-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRISCVLowering.cpp
More file actions
130 lines (112 loc) · 3.93 KB
/
Copy pathRISCVLowering.cpp
File metadata and controls
130 lines (112 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* @file RISCVLowering.cpp
* @brief RISC-V 代码生成和优化实现文件
* @details 本文件实现了 RISC-V 模块和函数的代码生成与优化过程。主要包括全局参数的降低、内置函数转换、
* φ节点消除、指令选择、寄存器分配、死代码消除、调度、帧生成和代码布局等步骤。
*/
#include "../include/backend/RISCVLowering.hpp"
#include "../include/backend/BuildInFunctionTransform.hpp"
#include "../include/backend/PhiElimination.hpp"
#include "../include/backend/PostRACalleeSavedLegalizer.hpp"
#include "../include/backend/Scheduler.hpp"
#include "../include/backend/CodeLayout.hpp"
#include "../include/backend/DeleteDeadBlock.hpp"
#include "../include/backend/Scheduler.hpp"
extern std::string asmoutput_path;
RISCVAsmPrinter *asmprinter = nullptr;
void RISCVModuleLowering::LowerGlobalArgument(Module *m)
{
// need file name
asmprinter = new RISCVAsmPrinter(asmoutput_path, m, ctx);
}
bool RISCVModuleLowering::run(Module *m)
{
LowerGlobalArgument(m);
RISCVFunctionLowering funclower(ctx, asmprinter);
auto &funcS = m->GetFuncTion();
for (auto &func : funcS)
{
if (funclower.run(func.get()))
{
func->print();
std::cerr << "FUNC Lowering failed\n";
}
}
asmprinter->printAsm();
return false;
}
bool RISCVFunctionLowering::run(Function *m)
{
if(m->get_tag() == Function::BuildIn) {
return false;
}
/// @note this function is used to lower buildin function to the correct form
/// @note and in order to solving user function which have the same name as buildin function
BuildInFunctionTransform buildin;
buildin.run(m);
/// @note after isel, all insts will be User with an opcode. Only call, ret is not dealt with after this
/// @todo deal with alloca and imm
/// @todo a scheduler can be added here, before or when emitting code to 3-address code
/// @note This is destory SSA form to 3-address code with mixture of phy and vir regs
auto mfunc = ctx.mapping(m)->as<RISCVFunction>();
ctx(mfunc);
RISCVISel isel(ctx, asmprinter);
isel.run(m);
PhiElimination phi(ctx);
phi.run(m);
asmprinter->SetTextSegment(new textSegment(ctx));
asmprinter->GetData()->GenerateTempvarList(ctx);
// // asmprinter->GetData()->LegalizeGloablVar(ctx);
// Backend DCE before RA
bool modified = true;
while (modified)
{
modified = false;
BackendDCE dcebefore(mfunc, ctx);
modified |= dcebefore.RunImpl();
}
// Pre_RA_Scheduler pre_scheduler;
// pre_scheduler.ScheduleOnFunction(ctx);
// Register Allocation
RegAllocImpl regalloc(mfunc, ctx);
regalloc.RunGCpass();
std::cout << std::flush;
for (auto block : *(ctx.GetCurFunction()))
{
for (auto it = block->begin(); it != block->end();)
{
auto inst = *it;
++it;
if (inst->GetOpcode() == RISCVMIR::RISCVISA::MarkDead)
delete inst;
}
}
modified = true;
// Backend DCE after RA
while (modified)
{
modified = false;
BackendDCE dceafter(ctx.GetCurFunction(), ctx);
modified |= dceafter.RunImpl();
}
// Pre_RA_Scheduler pre_scheduler;
// pre_sclheduer.ScheduleOnFunction(ctx);
// Post_RA_Scheduler post_scheduler;
// post_scheduler.ScheduleOnFunction(ctx);
// Generate Frame of current Function
// And generate the head and tail of frame here
PostRACalleeSavedLegalizer callee_saved_legalizer;
callee_saved_legalizer.run(ctx.GetCurFunction());
auto& frame = ctx.GetCurFunction()->GetFrame();
frame->GenerateFrame();
frame->GenerateFrameHead();
frame->GenerateFrameTail();
// legal.run_afterRA();
Legalize legal(ctx);
legal.run();
auto dbd=DeleteDeadBlock();
dbd.run(ctx.GetCurFunction());
auto layout=CodeLayout();
layout.run(mfunc);
return false;
}