Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
cf145fb8
Commit
cf145fb8
authored
Jun 18, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #617 from tjhance/lea
constant loading optimizations in rewriter
parents
3afc5d2e
25521cb7
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
263 additions
and
88 deletions
+263
-88
src/asm_writing/assembler.cpp
src/asm_writing/assembler.cpp
+32
-0
src/asm_writing/assembler.h
src/asm_writing/assembler.h
+2
-0
src/asm_writing/rewriter.cpp
src/asm_writing/rewriter.cpp
+184
-68
src/asm_writing/rewriter.h
src/asm_writing/rewriter.h
+41
-20
src/asm_writing/types.h
src/asm_writing/types.h
+4
-0
No files found.
src/asm_writing/assembler.cpp
View file @
cf145fb8
...
...
@@ -789,6 +789,38 @@ void Assembler::cmp(Indirect mem, Register reg) {
}
}
void
Assembler
::
lea
(
Indirect
mem
,
Register
reg
)
{
int
mem_idx
=
mem
.
base
.
regnum
;
int
reg_idx
=
reg
.
regnum
;
int
rex
=
REX_W
;
if
(
mem_idx
>=
8
)
{
rex
|=
REX_B
;
mem_idx
-=
8
;
}
if
(
reg_idx
>=
8
)
{
rex
|=
REX_R
;
reg_idx
-=
8
;
}
assert
(
mem_idx
>=
0
&&
mem_idx
<
8
);
assert
(
reg_idx
>=
0
&&
reg_idx
<
8
);
emitRex
(
rex
);
emitByte
(
0x8D
);
if
(
mem
.
offset
==
0
)
{
emitModRM
(
0b00
,
reg_idx
,
mem_idx
);
}
else
if
(
-
0x80
<=
mem
.
offset
&&
mem
.
offset
<
0x80
)
{
emitModRM
(
0b01
,
reg_idx
,
mem_idx
);
emitByte
(
mem
.
offset
);
}
else
{
assert
((
-
1L
<<
31
)
<=
mem
.
offset
&&
mem
.
offset
<
(
1L
<<
31
)
-
1
);
emitModRM
(
0b10
,
reg_idx
,
mem_idx
);
emitInt
(
mem
.
offset
,
4
);
}
}
void
Assembler
::
test
(
Register
reg1
,
Register
reg2
)
{
int
reg1_idx
=
reg1
.
regnum
;
int
reg2_idx
=
reg2
.
regnum
;
...
...
src/asm_writing/assembler.h
View file @
cf145fb8
...
...
@@ -136,6 +136,8 @@ public:
void
cmp
(
Indirect
mem
,
Immediate
imm
);
void
cmp
(
Indirect
mem
,
Register
reg
);
void
lea
(
Indirect
mem
,
Register
reg
);
void
test
(
Register
reg1
,
Register
reg2
);
void
jmp_cond
(
JumpDestination
dest
,
ConditionCode
condition
);
...
...
src/asm_writing/rewriter.cpp
View file @
cf145fb8
This diff is collapsed.
Click to expand it.
src/asm_writing/rewriter.h
View file @
cf145fb8
...
...
@@ -19,6 +19,7 @@
#include <memory>
#include <tuple>
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "asm_writing/assembler.h"
...
...
@@ -45,7 +46,6 @@ public:
Scratch
,
// stack location, relative to the scratch start
// For representing constants that fit in 32-bits, that can be encoded as immediates
Constant
,
AnyReg
,
// special type for use when specifying a location as a destination
None
,
// special type that represents the lack of a location, ex where a "ret void" gets returned
Uninitialized
,
// special type for an uninitialized (and invalid) location
...
...
@@ -64,9 +64,6 @@ public:
// only valid if type == Scratch; offset from the beginning of the scratch area
int32_t
scratch_offset
;
// only valid if type==Constant
int32_t
constant_val
;
int32_t
_data
;
};
...
...
@@ -121,8 +118,8 @@ namespace pyston {
// Replacement for unordered_map<Location, T>
template
<
class
T
>
class
LocMap
{
private:
static
const
int
N_REGS
=
16
;
static
const
int
N_XMM
=
16
;
static
const
int
N_REGS
=
assembler
::
Register
::
numRegs
()
;
static
const
int
N_XMM
=
assembler
::
XMMRegister
::
numRegs
()
;
static
const
int
N_SCRATCH
=
32
;
static
const
int
N_STACK
=
16
;
...
...
@@ -130,7 +127,6 @@ private:
T
map_xmm
[
N_XMM
];
T
map_scratch
[
N_SCRATCH
];
T
map_stack
[
N_STACK
];
std
::
unordered_map
<
int32_t
,
T
>
map_const
;
public:
LocMap
()
{
...
...
@@ -158,8 +154,6 @@ public:
assert
(
0
<=
l
.
scratch_offset
/
8
);
assert
(
l
.
scratch_offset
/
8
<
N_SCRATCH
);
return
map_scratch
[
l
.
scratch_offset
/
8
];
case
Location
:
:
Constant
:
return
map_const
[
l
.
constant_val
];
default:
RELEASE_ASSERT
(
0
,
"%d"
,
l
.
type
);
}
...
...
@@ -196,11 +190,6 @@ public:
m
.
emplace
(
Location
(
Location
::
Stack
,
i
*
8
),
map_stack
[
i
]);
}
}
for
(
std
::
pair
<
int32_t
,
RewriterVar
*>
p
:
map_const
)
{
if
(
p
.
second
!=
NULL
)
{
m
.
emplace
(
Location
(
Location
::
Constant
,
p
.
first
),
p
.
second
);
}
}
return
m
;
}
#endif
...
...
@@ -253,6 +242,9 @@ private:
bool
is_arg
;
Location
arg_loc
;
bool
is_constant
;
uint64_t
constant_value
;
llvm
::
SmallSet
<
std
::
tuple
<
int
,
uint64_t
,
bool
>
,
4
>
attr_guards
;
// used to detect duplicate guards
// Gets a copy of this variable in a register, spilling/reloading if necessary.
...
...
@@ -278,7 +270,7 @@ public:
static
int
nvars
;
#endif
RewriterVar
(
Rewriter
*
rewriter
)
:
rewriter
(
rewriter
),
next_use
(
0
),
is_arg
(
false
)
{
RewriterVar
(
Rewriter
*
rewriter
)
:
rewriter
(
rewriter
),
next_use
(
0
),
is_arg
(
false
)
,
is_constant
(
false
)
{
#ifndef NDEBUG
nvars
++
;
#endif
...
...
@@ -306,9 +298,36 @@ enum class ActionType { NORMAL, GUARD, MUTATION };
class
Rewriter
:
public
ICSlotRewrite
::
CommitHook
{
private:
// Helps generating the best code for loading a const integer value.
// By keeping track of the last known value of every register and reusing it.
class
ConstLoader
{
private:
const
uint64_t
unknown_value
=
0
;
Rewriter
*
rewriter
;
bool
tryRegRegMove
(
uint64_t
val
,
assembler
::
Register
dst_reg
);
bool
tryLea
(
uint64_t
val
,
assembler
::
Register
dst_reg
);
void
moveImmediate
(
uint64_t
val
,
assembler
::
Register
dst_reg
);
public:
ConstLoader
(
Rewriter
*
rewriter
);
// Searches if the specified value is already loaded into a register and if so it return the register
assembler
::
Register
findConst
(
uint64_t
val
,
bool
&
found_value
);
// Loads the constant into the specified register
void
loadConstIntoReg
(
uint64_t
val
,
assembler
::
Register
reg
);
// Loads the constant into any register or if already in a register just return it
assembler
::
Register
loadConst
(
uint64_t
val
,
Location
otherThan
=
Location
::
any
());
llvm
::
DenseMap
<
uint64_t
,
RewriterVar
*>
constToVar
;
};
std
::
unique_ptr
<
ICSlotRewrite
>
rewrite
;
assembler
::
Assembler
*
assembler
;
ConstLoader
const_loader
;
std
::
vector
<
RewriterVar
*>
vars
;
const
Location
return_location
;
...
...
@@ -379,6 +398,8 @@ private:
// Create a new var with no location.
RewriterVar
*
createNewVar
();
RewriterVar
*
createNewConstantVar
(
uint64_t
val
);
// Do the bookkeeping to say that var is now also in location l
void
addLocationToVar
(
RewriterVar
*
var
,
Location
l
);
// Do the bookkeeping to say that var is no longer in location l
...
...
@@ -387,7 +408,7 @@ private:
bool
finishAssembly
(
ICSlotInfo
*
picked_slot
,
int
continue_offset
)
override
;
void
_trap
();
void
_loadConst
(
RewriterVar
*
result
,
int64_t
val
,
Location
loc
);
void
_loadConst
(
RewriterVar
*
result
,
int64_t
val
);
void
_call
(
RewriterVar
*
result
,
bool
can_call_into_python
,
void
*
func_addr
,
const
RewriterVar
::
SmallVector
&
args
,
const
RewriterVar
::
SmallVector
&
args_xmm
);
void
_add
(
RewriterVar
*
result
,
RewriterVar
*
a
,
int64_t
b
,
Location
dest
);
...
...
@@ -396,9 +417,9 @@ private:
void
_allocateAndCopyPlus1
(
RewriterVar
*
result
,
RewriterVar
*
first_elem
,
RewriterVar
*
rest
,
int
n_rest
);
// The public versions of these are in RewriterVar
void
_addGuard
(
RewriterVar
*
var
,
uint64_t
val
);
void
_addGuardNotEq
(
RewriterVar
*
var
,
uint64_t
val
);
void
_addAttrGuard
(
RewriterVar
*
var
,
int
offset
,
uint64_t
val
,
bool
negate
=
false
);
void
_addGuard
(
RewriterVar
*
var
,
RewriterVar
*
val_constant
);
void
_addGuardNotEq
(
RewriterVar
*
var
,
RewriterVar
*
val_constant
);
void
_addAttrGuard
(
RewriterVar
*
var
,
int
offset
,
RewriterVar
*
val_constant
,
bool
negate
=
false
);
void
_getAttr
(
RewriterVar
*
result
,
RewriterVar
*
var
,
int
offset
,
Location
loc
=
Location
::
any
(),
assembler
::
MovType
type
=
assembler
::
MovType
::
Q
);
void
_getAttrFloat
(
RewriterVar
*
result
,
RewriterVar
*
var
,
int
offset
,
Location
loc
=
Location
::
any
());
...
...
src/asm_writing/types.h
View file @
cf145fb8
...
...
@@ -47,6 +47,8 @@ struct Register {
void
dump
()
const
;
static
Register
fromDwarf
(
int
dwarf_regnum
);
static
constexpr
int
numRegs
()
{
return
16
;
}
};
const
Register
RAX
(
0
);
...
...
@@ -88,6 +90,8 @@ struct XMMRegister {
bool
operator
!=
(
const
XMMRegister
&
rhs
)
const
{
return
!
(
*
this
==
rhs
);
}
void
dump
()
const
{
printf
(
"XMM%d
\n
"
,
regnum
);
}
static
constexpr
int
numRegs
()
{
return
16
;
}
};
const
XMMRegister
XMM0
(
0
);
...
...
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