-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLowerFomralArguments.cpp
More file actions
199 lines (190 loc) · 8.53 KB
/
Copy pathLowerFomralArguments.cpp
File metadata and controls
199 lines (190 loc) · 8.53 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/**
* @file RISCVISel.cpp
* @brief RISC-V 后端参数传递和并行参数处理实现
* @details 本文件实现了 RISC-V 后端的形式参数传递以及并行函数参数的特殊处理。主要功能包括:
* - 处理并行函数的参数传递,通过全局地址加载和内存操作将参数从堆栈加载到寄存器。
* - 普通函数的参数传递,根据参数类型和数量,将参数从堆栈或物理寄存器加载到虚拟寄存器。
*/
#include "../include/backend/RISCVISel.hpp"
/// @todo 参数带有浮点数的情况
void LowerFormalArgumentsParallel(Function* func,RISCVLoweringContext& ctx){
auto& params=func->GetParams();
auto addressreg=ctx.createVReg(riscv_ptr);
auto addressinst=new RISCVMIR(RISCVMIR::LoadGlobalAddr);
addressinst->SetDef(addressreg);
addressinst->AddOperand(OuterTag::GetOuterTag("buildin_parallel_arg_storage"));
ctx(addressinst);
auto mvaddress=[&](int offset){
auto addi=new RISCVMIR(RISCVMIR::_addi);
addi->SetDef(addressreg);
addi->AddOperand(addressreg);
addi->AddOperand(Imm::GetImm(ConstIRInt::GetNewConstant(offset)));
ctx(addi);
};
for(auto& paramptr:params){
auto param=paramptr.get();
auto tp=param->GetType();
VirRegister* reg=nullptr;
auto load2reg=[&](RISCVMIR::RISCVISA _opcode,RISCVType _tp){
auto mir=new RISCVMIR(_opcode);
reg=ctx.createVReg(_tp);
mir->SetDef(reg);
mir->AddOperand(addressreg);
ctx.insert_val2mop(param,reg);
ctx(mir);
mvaddress(tp->get_size());
};
if(dynamic_cast<PointerType*>(tp)){
assert(tp->get_size()==8);
load2reg(RISCVMIR::_ld,riscv_ptr);
}
else if(tp==FloatType::NewFloatTypeGet()){
assert(tp->get_size()==4);
load2reg(RISCVMIR::_flw,riscv_float32);
}
else{
assert(tp->get_size()==4);
load2reg(RISCVMIR::_lw,riscv_i32);
}
}
// call fenceArgLoaderd
auto fenceArgLoaded=BuildInFunction::GetBuildInFunction("buildin_FenceArgLoaded");
auto call=new RISCVMIR(RISCVMIR::call);
call->AddOperand(ctx.mapping(fenceArgLoaded));
ctx(call);
}
void LowerFormalArguments(Function* func, RISCVLoweringContext& ctx) {
if(func->tag==Function::ParallelBody){
LowerFormalArgumentsParallel(func,ctx);
return;
}
#define M(x) ctx.mapping(x)
int IntMaxNum=8, FloatMaxNum=8;
std::unique_ptr<RISCVFrame>& frame = ctx.GetCurFunction()->GetFrame();
std::vector<std::unique_ptr<Value>>& params = func->GetParams();
RISCVFunction* RISCVfunc = dynamic_cast<RISCVFunction*>(M(func));
std::vector<int>& spillnodes = RISCVfunc->GetParamNeedSpill();
if(!params.empty()) {
RISCVType type;
int offset = 0;
for(auto it=spillnodes.rbegin(); it!=spillnodes.rend(); it++) {
// load param from stack to reg
type = RISCVTyper(params[*it]->GetType());
VirRegister* vreg = ctx.createVReg(type);
PhyRegister* preg = PhyRegister::GetPhyReg(PhyRegister::PhyReg::s0);
StackRegister* stackreg = new StackRegister(PhyRegister::PhyReg::s0, offset);
ctx.insert_val2mop(params[*it].get(), vreg);
if(type == riscv_i32) {
RISCVMIR* loadinst = new RISCVMIR(RISCVMIR::_lw);
loadinst->SetDef(vreg);
loadinst->AddOperand(stackreg);
ctx(loadinst);
offset+=4;
}
else if(type == riscv_float32) {
RISCVMIR* loadinst = new RISCVMIR(RISCVMIR::_flw);
loadinst->SetDef(vreg);
loadinst->AddOperand(stackreg);
ctx(loadinst);
offset+=4;
}
else if(type == riscv_ptr) {
RISCVMIR* loadinst = new RISCVMIR(RISCVMIR::_ld);
loadinst->SetDef(vreg);
loadinst->AddOperand(stackreg);
ctx(loadinst);
offset+=8;
}
else {
// riscv_none
assert(0&&"LowerFormalArguments: Error type");
}
}
int regint=PhyRegister::PhyReg::a0;
int regfloat=PhyRegister::PhyReg::fa0;
for(int index=0;index<params.size();index++) {
if(std::find(spillnodes.begin(), spillnodes.end(), index)!=spillnodes.end()) {
continue;
}
else {
RISCVType type = RISCVTyper(params[index]->GetType());
VirRegister* vreg = ctx.createVReg(type);
if(type==riscv_i32 || type==riscv_ptr) {
RISCVMIR* inst = new RISCVMIR(RISCVMIR::mv);
inst->SetDef(vreg);
inst->AddOperand(PhyRegister::GetPhyReg(static_cast<PhyRegister::PhyReg>(regint)));
ctx.insert_val2mop(params[index].get(), vreg);
ctx(inst);
regint++;
}
else if(type==riscv_float32) {
RISCVMIR* inst = new RISCVMIR(RISCVMIR::_fmv_s);
inst->SetDef(vreg);
inst->AddOperand(PhyRegister::GetPhyReg(static_cast<PhyRegister::PhyReg>(regfloat)));
ctx.insert_val2mop(params[index].get(), vreg);
ctx(inst);
regfloat++;
}
else {
assert(0&&"LowerFormalArguments: Error type");
}
}
}
}
#undef M
// std::vector<std::unique_ptr<Value>>& params = func->GetParams();
// if (params.size()==0) {return;}
// else {
// int paramnum=params.size();
// int min=paramnum>8?8:paramnum;
// if(paramnum>8) {
// int offset =0;
// for(int i=paramnum-1; i>min-1; --i) {
// if(params[i]->GetType()->GetTypeEnum()==InnerDataType::IR_Value_INT) {
// auto loadinst = new RISCVMIR(RISCVMIR::_lw);
// VirRegister* vreg = ctx.createVReg(RISCVTyper(params[i]->GetType()));
// loadinst->SetDef(vreg);
// PhyRegister* preg = PhyRegister::GetPhyReg(PhyRegister::PhyReg::s0);
// StackRegister* stackreg = new StackRegister(PhyRegister::PhyReg::s0, offset);
// loadinst->AddOperand(stackreg);
// ctx.insert_val2mop(params[i].get(), vreg);
// ctx(loadinst);
// offset+=4;
// }
// else if(params[i]->GetType()->GetTypeEnum()==InnerDataType::IR_Value_Float) {
// auto loadinst = new RISCVMIR(RISCVMIR::_flw);
// VirRegister* vreg = ctx.createVReg(RISCVTyper(params[i]->GetType()));
// loadinst->SetDef(vreg);
// PhyRegister* preg = PhyRegister::GetPhyReg(PhyRegister::PhyReg::s0);
// StackRegister* stackreg = new StackRegister(PhyRegister::PhyReg::s0, offset);
// loadinst->AddOperand(stackreg);
// ctx.insert_val2mop(params[i].get(), vreg);
// ctx(loadinst);
// offset+=4;
// }
// else if(params[i]->GetType()->GetTypeEnum()==InnerDataType::IR_PTR){
// auto loadinst = new RISCVMIR(RISCVMIR::_ld);
// VirRegister* vreg = ctx.createVReg(RISCVTyper(params[i]->GetType()));
// loadinst->SetDef(vreg);
// PhyRegister* preg = PhyRegister::GetPhyReg(PhyRegister::PhyReg::s0);
// StackRegister* stackreg = new StackRegister(PhyRegister::PhyReg::s0, offset);
// loadinst->AddOperand(stackreg);
// ctx.insert_val2mop(params[i].get(), vreg);
// ctx(loadinst);
// offset+=8;
// }
// else assert(0&&"Error type in param");
// }
// }
// int regnum=PhyRegister::PhyReg::a0;
// for (int i=0; i<min; ++i) {
// VirRegister* vreg = ctx.createVReg(RISCVTyper(params[i]->GetType()));
// auto minst = new RISCVMIR(RISCVMIR::mv);
// minst->SetDef(vreg);
// minst->AddOperand(PhyRegister::GetPhyReg(static_cast<PhyRegister::PhyReg>(regnum)));
// ctx.insert_val2mop(params[i].get(), vreg);
// ctx(minst);
// regnum+=1;
// }
// }
}