Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
2
2022fall-Compiler_CMinus
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
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
李晓奇
2022fall-Compiler_CMinus
Commits
0454682c
Commit
0454682c
authored
Feb 05, 2023
by
lxq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
write reg-alloca for int values
parent
3d814ba8
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
373 additions
and
188 deletions
+373
-188
Reports/5-bonus/report.md
Reports/5-bonus/report.md
+47
-23
include/codegen/codegen.hpp
include/codegen/codegen.hpp
+102
-50
include/codegen/liverange.hpp
include/codegen/liverange.hpp
+14
-7
include/codegen/regalloc.hpp
include/codegen/regalloc.hpp
+18
-4
src/codegen/codegen.cpp
src/codegen/codegen.cpp
+170
-94
src/codegen/liverange.cpp
src/codegen/liverange.cpp
+8
-8
src/codegen/regalloc.cpp
src/codegen/regalloc.cpp
+14
-2
No files found.
Reports/5-bonus/report.md
View file @
0454682c
...
...
@@ -59,38 +59,38 @@ label7: ; preds = %label0
```
llvm
1
.
op1
=
0
in-set:
[
]
out-set:
[
op1
]
in-set:
[
]
out-set:
[
op1
]
2
.
br
label
%label0
in-set:
[
op1
]
out-set:
[
op1
]
in-set:
[
op1
]
out-set:
[
op1
]
3
.
%op2
=
icmp
slt
i32
%op1
,
10
in-set:
[
op1
]
out-set:
[
op2
op1
]
in-set:
[
op1
]
out-set:
[
op2
op1
]
4
.
%op3
=
zext
i1
%op2
to
i32
in-set:
[
op2
op1
]
out-set:
[
op3
op1
]
in-set:
[
op2
op1
]
out-set:
[
op3
op1
]
5
.
%op4
=
icmp
ne
i32
%op3
,
0
in-set:
[
op3
op1
]
out-set:
[
op4
op1
]
in-set:
[
op3
op1
]
out-set:
[
op4
op1
]
6
.
br
i1
%op4
,
label
%label5
,
label
%label7
in-set:
[
op4
op1
]
out-set:
[
op1
]
in-set:
[
op4
op1
]
out-set:
[
op1
]
7
.
call
void
@output
(
i32
%op1
)
in-set:
[
op1
]
out-set:
[
op1
]
in-set:
[
op1
]
out-set:
[
op1
]
8
.
%op6
=
add
i32
%op1
,
1
in-set:
[
op1
]
out-set:
[
op6
]
in-set:
[
op1
]
out-set:
[
op6
]
9
.
op1
=
op6
in-set:
[
op6
]
out-set:
[
op1
]
in-set:
[
op6
]
out-set:
[
op1
]
10
.
br
label
%label0
in-set:
[
op1
]
out-set:
[
op1
]
in-set:
[
op1
]
out-set:
[
op1
]
11
.
ret
i32
0
in-set:
[
]
out-set:
[
]
in-set:
[
]
out-set:
[
]
```
获得活跃区间:编号为i的指令,涉及两个端点:i-1和i,分别对应IN和OUT。由此得到各个变量的活跃区间是:
...
...
@@ -111,4 +111,28 @@ op6: <8, 8>
-
[
Documentations/5-bonus/寄存器分配.md · master · compiler_staff / 2022fall-Compiler_CMinus · GitLab
](
https://cscourse.ustc.edu.cn/vdir/Gitlab/compiler_staff/2022fall-compiler_cminus/-/blob/master/Documentations/5-bonus/%E5%AF%84%E5%AD%98%E5%99%A8%E5%88%86%E9%85%8D.md#poletto
)
i
程序有
`$a`
系列寄存器8个,
`$t`
系列9个,拿出
`$t0`
、
`$t1`
做IR生成汇编过程中的临时寄存器(这个方案仅在cminus下成立),所以可以自由分配的寄存器一共15个。
首先完成对于局部变量的寄存器分配,即全局变量、传参依旧通过栈进行。
程序分配寄存器时会对部分指令做特殊处理,具体如下:
-
`phi`
指令:还原为
`copy-stmt`
,所以寄存器照样分配,如果没分到使用栈内存
-
`alloca`
指令:这里忽略对于
`alloca`
指令的寄存器分配,
`alloca`
仍然使用栈存储,原因如下:
-
对于int|float的
`alloca`
,使用寄存器可以正常进行,只需将相关指令
`load`
和
`store`
分别成赋值即可。
-
但是对于数组的
`alloca`
,使用寄存器就很难模拟了。
即寄存器不能完成
`alloca`
的内存逻辑,同时经过
`mem2reg`
优化过后,不再有局部变量的声明,所以忽略对于
`alloca`
指令的寄存器分配。
-
`cmp`
、
`fcmp`
和
`zext`
指令:不做寄存器分配,也不做栈分配。
这实际是指令选择部分的内容:
因为在cminus中并没有bool变量,这些IR指令用到的i1类型都是临时的:只为分支指令服务,所以直接将这些指令集成到分支跳转的判断中。
-
`call`
指令:使用栈传参,caller保存自己用到的寄存器,被保存的寄存器的活跃区间覆盖
`call`
指令的程序点。
include/codegen/codegen.hpp
View file @
0454682c
...
...
@@ -9,15 +9,17 @@
#include "Module.h"
#include "Value.h"
#include "liverange.hpp"
#include "
logging
.hpp"
#include "
regalloc
.hpp"
#define __RO_PART__
// #a = 8, #t = 9, reserve $t0, $t1 for temporary
#define R_USABLE 17 - 2
#include <map>
#include <ostream>
#include <vector>
#define ALIGN(x, align) (((
x / align) + (x % align
? 1 : 0)) * align)
#define ALIGN(x, align) (((
(x) / align) + (((x) % align)
? 1 : 0)) * align)
// #define STACK_ALIGN(x) (((x / 16) + (x % 16 ? 1 : 0)) * 16)
#define STACK_ALIGN(x) ALIGN(x, 16)
...
...
@@ -27,7 +29,7 @@ using std::vector;
class
CodeGen
{
public:
CodeGen
(
Module
*
m_
)
:
m
(
m_
),
LRA
(
m_
,
phi_map
)
{}
CodeGen
(
Module
*
m_
)
:
m
(
m_
),
LRA
(
m_
,
phi_map
)
,
RA
(
R_USABLE
)
{}
string
print
()
{
string
result
;
...
...
@@ -42,35 +44,41 @@ class CodeGen {
void
run
();
private:
void
IR2assem
(
Instruction
&
,
BasicBlock
&
);
void
IR2assem
(
LoadInst
*
);
void
IR2assem
(
StoreInst
*
);
void
IR2assem
(
ReturnInst
*
);
void
IR2assem
(
GetElementPtrInst
*
);
void
IR2assem
(
CallInst
*
);
void
IR2assem
(
BranchInst
*
);
void
IR2assem
(
BinaryInst
*
);
void
IR2assem
(
FpToSiInst
*
);
void
IR2assem
(
SiToFpInst
*
);
void
IR2assem
(
PhiInst
*
)
{}
// The Instructions below will do nothing
void
IR2assem
(
AllocaInst
*
)
{}
// integration with BranchInst
void
IR2assem
(
CmpInst
*
)
{}
void
IR2assem
(
FCmpInst
*
)
{}
void
IR2assem
(
ZextInst
*
)
{}
//
// data member
//
std
::
map
<
Value
*
,
unsigned
int
>
off
;
// stack offset to $fp
std
::
map
<
Function
*
,
std
::
map
<
int
,
int
>>
func_arg_off
;
// to $sp
// total space for args, NOTE: not aligned
std
::
map
<
Function
*
,
int
>
func_arg_N
;
std
::
map
<
BasicBlock
*
,
std
::
vector
<
std
::
pair
<
Value
*
,
Value
*>>>
phi_map
;
std
::
map
<
Constant
*
,
std
::
string
>
ROdata
;
unsigned
int
stackN
;
// function local vars and so on
Function
*
cur_func
;
Module
*
m
;
vector
<
string
>
output
;
// register allocation
LRA
::
LiveRangeAnalyzer
LRA
;
RA
::
RegAllocator
RA
;
// some instruction has lvalue, but is stack-allocated,
// we need this variable to track the reg name which has rvalue.
// this variable is maintain by gencopy() and LoadInst.
string
last_reg
;
//
// function member
//
void
stackMemAlloc
();
void
stackMemDealloc
();
// load value `opk` to the specified register
// - for constant number, just load into reg
// - for global variables and pointers from alloca and GEP, read through
// address
// only use register a_id and t_
void
value2reg
(
Value
*
,
int
id
=
0
);
// In the case of register allocation, this function will return the
// allocated register for that value, if the value possesses no register,
// choose from from $t0 or $t1 based on id
__attribute__
((
warn_unused_result
))
string
value2reg
(
Value
*
,
int
i
=
0
);
// load the content in ptr to specified register.
// only use register a_id and t_
void
ptrContent2reg
(
Value
*
,
int
id
=
0
);
void
ptrContent2reg
(
Value
*
,
string
);
void
compute_arg_info
(
Function
*
);
string
bool2branch
(
Instruction
*
);
void
getPhiMap
();
...
...
@@ -80,15 +88,35 @@ class CodeGen {
output
.
push_back
(
"# "
+
print_as_op
(
copy
.
first
,
false
)
+
" = "
+
print_as_op
(
copy
.
second
,
false
));
auto
lvalue
=
static_cast
<
Instruction
*>
(
copy
.
first
);
value2reg
(
copy
.
second
);
back2stack
(
lvalue
);
auto
src_reg
=
value2reg
(
copy
.
second
);
if
(
gencopy
(
lvalue
,
src_reg
)
==
false
)
back2stack
(
lvalue
);
}
}
// if reg-allocation, store to the specific register
// or is stack-allocation, set last_reg for back2stack()
bool
gencopy
(
Value
*
lhs
,
string
rhs_reg
)
{
auto
[
lhs_reg
,
find
]
=
getRegName
(
lhs
);
if
(
not
find
)
{
// wait for back2stack() to store back
last_reg
=
rhs_reg
;
return
false
;
}
auto
is_float
=
lhs
->
get_type
()
->
is_float_type
();
if
(
rhs_reg
!=
lhs_reg
)
{
if
(
is_float
)
output
.
push_back
(
"fmov.s "
+
lhs_reg
+
", "
+
rhs_reg
);
else
output
.
push_back
(
"or "
+
lhs_reg
+
", $zero, "
+
rhs_reg
);
}
return
true
;
}
string
label_in_assem
(
BasicBlock
*
bb
)
{
string
label_in_assem
(
BasicBlock
*
bb
)
const
{
return
cur_func
->
get_name
()
+
bb
->
get_name
().
substr
(
5
);
}
int
typeLen
(
Type
*
type
)
{
int
typeLen
(
Type
*
type
)
const
{
if
(
type
->
is_float_type
())
return
4
;
else
if
(
type
->
is_integer_type
())
{
...
...
@@ -107,19 +135,19 @@ class CodeGen {
}
}
// assert the value needed to store back is in
$a0 or $f0
, according to the
// assert the value needed to store back is in
`last_reg`
, according to the
// value type
void
back2stack
(
Instruction
*
instr
)
{
// std::cerr << instr->print() << std::endl;
auto
type
=
instr
->
get_type
();
string
instr_ir
=
type
->
is_float_type
()
?
"fst"
:
"st"
;
string
suff
=
suffix
(
type
);
string
reg
=
type
->
is_float_type
()
?
"$fa0"
:
"$a0"
;
string
addr
=
"$fp, -"
+
std
::
to_string
(
off
[
instr
]
);
output
.
push_back
(
instr_ir
+
suff
+
" "
+
reg
+
", "
+
addr
);
//
string reg = type->is_float_type() ? "$fa0" : "$a0";
string
addr
=
"$fp, -"
+
std
::
to_string
(
off
.
at
(
instr
)
);
output
.
push_back
(
instr_ir
+
suff
+
" "
+
last_
reg
+
", "
+
addr
);
}
string
suffix
(
Type
*
type
)
{
string
suffix
(
Type
*
type
)
const
{
int
len
=
typeLen
(
type
);
switch
(
len
)
{
case
1
:
...
...
@@ -134,29 +162,53 @@ class CodeGen {
assert
(
false
&&
"no such suffix"
);
}
bool
no_stack_alloca
(
Instruction
*
instr
)
{
bool
no_stack_alloca
(
Instruction
*
instr
)
const
{
if
(
instr
->
is_void
())
return
true
;
if
(
instr
->
is_fcmp
()
or
instr
->
is_cmp
()
or
instr
->
is_zext
())
return
true
;
if
(
RA
.
get
().
find
(
instr
)
!=
RA
.
get
().
end
())
return
true
;
return
false
;
}
string
tmpregname
(
int
i
,
bool
is_float
)
const
{
assert
(
i
==
0
or
i
==
1
);
return
(
is_float
?
"$ft"
:
"$t"
)
+
to_string
(
i
);
}
std
::
map
<
Value
*
,
unsigned
int
>
off
;
// stack offset to $fp
std
::
map
<
Function
*
,
std
::
map
<
int
,
int
>>
func_arg_off
;
// to $sp
std
::
map
<
Function
*
,
int
>
func_arg_N
;
// total space for args
std
::
map
<
BasicBlock
*
,
std
::
vector
<
std
::
pair
<
Value
*
,
Value
*>>>
phi_map
;
std
::
map
<
Constant
*
,
std
::
string
>
ROdata
;
unsigned
int
stackN
;
// function local vars and so on
Function
*
cur_func
;
static
string
regname
(
int
i
,
bool
is_float
=
false
)
{
string
name
;
if
(
is_float
)
{
assert
(
false
&&
"not implemented!"
);
}
else
{
if
(
1
<=
i
and
i
<=
8
)
name
=
"$a"
+
to_string
(
i
-
1
);
else
if
(
9
<=
i
and
i
<=
R_USABLE
)
name
=
"$t"
+
to_string
(
i
-
9
+
2
);
}
return
name
;
}
Module
*
m
;
vector
<
string
>
output
;
pair
<
string
,
bool
>
getRegName
(
Value
*
,
int
=
0
)
const
;
// register allocation
LRA
::
LiveRangeAnalyzer
LRA
;
void
IR2assem
(
Instruction
&
,
BasicBlock
&
);
void
IR2assem
(
LoadInst
*
);
void
IR2assem
(
StoreInst
*
);
void
IR2assem
(
ReturnInst
*
);
void
IR2assem
(
GetElementPtrInst
*
);
void
IR2assem
(
CallInst
*
);
void
IR2assem
(
BranchInst
*
);
void
IR2assem
(
BinaryInst
*
);
void
IR2assem
(
FpToSiInst
*
);
void
IR2assem
(
SiToFpInst
*
);
void
IR2assem
(
PhiInst
*
)
{}
// The Instructions below will do nothing
void
IR2assem
(
AllocaInst
*
)
{}
// integration with BranchInst
void
IR2assem
(
CmpInst
*
)
{}
void
IR2assem
(
FCmpInst
*
)
{}
void
IR2assem
(
ZextInst
*
)
{}
};
#endif
include/codegen/liverange.hpp
View file @
0454682c
...
...
@@ -2,6 +2,7 @@
#define LIVERANGE_HPP
#include "Module.h"
#include "Value.h"
#include <iostream>
#include <map>
...
...
@@ -27,7 +28,6 @@ struct Interval {
using
LiveSet
=
set
<
Value
*>
;
using
PhiMap
=
map
<
BasicBlock
*
,
vector
<
pair
<
Value
*
,
Value
*>>>
;
using
LiveInterval
=
pair
<
Interval
,
Value
*>
;
struct
LiveIntervalCMP
{
bool
operator
()(
LiveInterval
const
&
lhs
,
LiveInterval
const
&
rhs
)
const
{
if
(
lhs
.
first
.
i
!=
rhs
.
first
.
i
)
...
...
@@ -36,29 +36,31 @@ struct LiveIntervalCMP {
return
lhs
.
second
<
rhs
.
second
;
}
};
using
LVITS
=
set
<
LiveInterval
,
LiveIntervalCMP
>
;
class
LiveRangeAnalyzer
{
public:
friend
class
CodeGen
;
public:
LiveRangeAnalyzer
(
Module
*
m_
,
PhiMap
&
phi_map_
)
:
m
(
m_
),
phi_map
(
phi_map_
)
{}
LiveRangeAnalyzer
()
=
delete
;
void
run
();
//
void run();
void
run
(
Function
*
);
void
clear
();
void
print
(
Function
*
func
,
bool
printSet
=
true
);
string
print_liveSet
(
const
LiveSet
&
ls
)
{
void
print
(
Function
*
func
,
bool
printSet
=
true
)
const
;
string
print_liveSet
(
const
LiveSet
&
ls
)
const
{
string
s
=
"[ "
;
for
(
auto
k
:
ls
)
s
+=
k
->
get_name
()
+
" "
;
s
+=
"]"
;
return
s
;
}
string
print_interval
(
Interval
&
i
)
{
string
print_interval
(
Interval
&
i
)
const
{
return
"<"
+
to_string
(
i
.
i
)
+
", "
+
to_string
(
i
.
j
)
+
">"
;
}
const
LVITS
&
get
()
{
return
liveIntervals
;
}
private:
Module
*
m
;
...
...
@@ -68,7 +70,8 @@ class LiveRangeAnalyzer {
map
<
Value
*
,
int
>
instr_id
;
map
<
pair
<
Value
*
,
Value
*>
,
int
>
cpstmt_id
;
const
PhiMap
&
phi_map
;
set
<
LiveInterval
,
LiveIntervalCMP
>
liveIntervals
;
LVITS
liveIntervals
;
map
<
Value
*
,
Interval
>
intervalmap
;
void
make_id
(
Function
*
);
void
make_interval
(
Function
*
);
...
...
@@ -86,6 +89,10 @@ class LiveRangeAnalyzer {
// Require: out-set is already set
// Return: the in-set(will not set IN-map)
LiveSet
transferFunction
(
Instruction
*
);
public:
const
decltype
(
instr_id
)
&
get_instr_id
()
{
return
instr_id
;
}
const
decltype
(
intervalmap
)
&
get_interval_map
()
{
return
intervalmap
;
}
};
}
// namespace LRA
#endif
include/codegen/regalloc.hpp
View file @
0454682c
#include "Value.h"
#include "liverange.hpp"
// using std::transform;
#include <iostream>
#include <string>
using
std
::
cout
;
using
std
::
endl
;
using
std
::
to_string
;
using
namespace
LRA
;
namespace
RA
{
#define MAXR 32
bool
no_reg_alloca
(
Value
*
v
);
struct
ActiveCMP
{
bool
operator
()(
LiveInterval
const
&
lhs
,
LiveInterval
const
&
rhs
)
const
{
if
(
lhs
.
first
.
j
!=
rhs
.
first
.
j
)
...
...
@@ -18,15 +27,20 @@ struct ActiveCMP {
class
RegAllocator
{
public:
RegAllocator
(
const
uint
R_
)
:
R
(
R_
),
used
{
false
}
{}
RegAllocator
(
const
uint
R_
)
:
R
(
R_
),
used
{
false
}
{
assert
(
R
<=
MAXR
);
}
RegAllocator
()
=
delete
;
// input set is sorted by increasing start point
void
LinearScan
(
set
<
LiveInterval
>
&
liveints
);
void
LinearScan
(
const
LVITS
&
liveints
);
void
reset
();
const
map
<
Value
*
,
int
>
&
get
()
const
{
return
regmap
;
}
void
print
(
string
(
*
regname
)(
int
))
{
for
(
auto
[
op
,
reg
]
:
regmap
)
cout
<<
op
->
get_name
()
<<
" ~ "
<<
regname
(
reg
)
<<
endl
;
}
private:
const
uint
R
;
bool
used
[
MAXR
];
bool
used
[
MAXR
+
1
];
// index range: 1 ~ R
map
<
Value
*
,
int
>
regmap
;
// sorted by increasing end point
set
<
LiveInterval
,
ActiveCMP
>
active
;
...
...
src/codegen/codegen.cpp
View file @
0454682c
This diff is collapsed.
Click to expand it.
src/codegen/liverange.cpp
View file @
0454682c
...
...
@@ -11,6 +11,7 @@ LiveRangeAnalyzer::clear() {
OUT
.
clear
();
instr_id
.
clear
();
cpstmt_id
.
clear
();
intervalmap
.
clear
();
liveIntervals
.
clear
();
}
...
...
@@ -133,24 +134,23 @@ LiveRangeAnalyzer::run(Function *func) {
void
LiveRangeAnalyzer
::
make_interval
(
Function
*
)
{
map
<
Value
*
,
Interval
>
liverange
;
for
(
int
time
=
1
;
time
<=
ir_cnt
;
++
time
)
{
for
(
auto
op
:
IN
.
at
(
time
))
{
auto
&
interval
=
liverange
[
op
];
auto
&
interval
=
intervalmap
[
op
];
if
(
interval
.
i
==
0
)
// uninitialized
interval
.
i
=
time
-
1
;
else
interval
.
j
=
time
-
1
;
}
for
(
auto
op
:
OUT
.
at
(
time
))
{
auto
&
interval
=
liverange
[
op
];
auto
&
interval
=
intervalmap
[
op
];
if
(
interval
.
i
==
0
)
// uninitialized
interval
.
i
=
time
;
else
interval
.
j
=
time
;
}
}
for
(
auto
[
op
,
interval
]
:
liverange
)
for
(
auto
[
op
,
interval
]
:
intervalmap
)
liveIntervals
.
insert
({
interval
,
op
});
}
...
...
@@ -188,7 +188,7 @@ LiveRangeAnalyzer::transferFunction(Instruction *instr) {
}
void
LiveRangeAnalyzer
::
print
(
Function
*
func
,
bool
printSet
)
{
// for debug
LiveRangeAnalyzer
::
print
(
Function
*
func
,
bool
printSet
)
const
{
// for debug
cout
<<
"Function "
<<
func
->
get_name
()
<<
endl
;
for
(
auto
&
bb
:
func
->
get_basic_blocks
())
{
for
(
auto
&
instr
:
bb
.
get_instructions
())
{
...
...
@@ -200,7 +200,7 @@ LiveRangeAnalyzer::print(Function *func, bool printSet) { // for debug
for
(
auto
pr
:
phi_map
.
find
(
&
bb
)
->
second
)
{
auto
[
lv
,
rv
]
=
pr
;
auto
idx
=
cpstmt_id
.
at
(
pr
);
cout
<<
cpstmt_id
[
pr
]
<<
". "
<<
lv
->
get_name
()
<<
" = "
cout
<<
cpstmt_id
.
at
(
pr
)
<<
". "
<<
lv
->
get_name
()
<<
" = "
<<
(
rv
->
get_name
()
==
""
?
rv
->
print
()
:
rv
->
get_name
())
<<
endl
;
...
...
@@ -213,8 +213,8 @@ LiveRangeAnalyzer::print(Function *func, bool printSet) { // for debug
}
}
// normal ir
cout
<<
instr_id
[
&
instr
]
<<
". "
<<
instr
.
print
()
<<
" # "
<<
&
instr
<<
endl
;
cout
<<
instr_id
.
at
(
&
instr
)
<<
". "
<<
instr
.
print
()
<<
" # "
<<
&
instr
<<
endl
;
if
(
not
printSet
)
continue
;
auto
idx
=
instr_id
.
at
(
&
instr
);
...
...
src/codegen/regalloc.cpp
View file @
0454682c
#include "regalloc.hpp"
#include "Instruction.h"
#include "liverange.hpp"
#include <algorithm>
using
std
::
for_each
;
using
namespace
RA
;
bool
RA
::
no_reg_alloca
(
Value
*
v
)
{
auto
instr
=
static_cast
<
Instruction
*>
(
v
);
return
instr
->
is_alloca
()
or
instr
->
is_cmp
()
or
instr
->
is_fcmp
()
or
instr
->
is_zext
();
}
void
RegAllocator
::
reset
()
{
regmap
.
clear
();
active
.
clear
();
for_each
(
used
,
used
+
R
,
[](
bool
&
u
)
{
u
=
false
;
});
for_each
(
used
,
used
+
R
+
1
,
[](
bool
&
u
)
{
u
=
false
;
});
}
void
RegAllocator
::
LinearScan
(
set
<
LiveInterval
>
&
liveints
)
{
RegAllocator
::
LinearScan
(
const
LVITS
&
liveints
)
{
reset
();
int
reg
;
for
(
auto
liveint
:
liveints
)
{
if
(
no_reg_alloca
(
liveint
.
second
))
continue
;
ExpireOldIntervals
(
liveint
);
if
(
active
.
size
()
==
R
)
SpillAtInterval
(
liveint
);
...
...
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