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
dbc15587
Commit
dbc15587
authored
Oct 17, 2014
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change how we create and represent patchpoints
parent
f074ed04
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
354 additions
and
275 deletions
+354
-275
src/asm_writing/icinfo.cpp
src/asm_writing/icinfo.cpp
+2
-2
src/asm_writing/icinfo.h
src/asm_writing/icinfo.h
+2
-2
src/codegen/compvars.cpp
src/codegen/compvars.cpp
+29
-41
src/codegen/irgen.h
src/codegen/irgen.h
+8
-8
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+2
-1
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+105
-80
src/codegen/irgen/irgenerator.h
src/codegen/irgen/irgenerator.h
+1
-1
src/codegen/llvm_interpreter.cpp
src/codegen/llvm_interpreter.cpp
+18
-10
src/codegen/patchpoints.cpp
src/codegen/patchpoints.cpp
+111
-78
src/codegen/patchpoints.h
src/codegen/patchpoints.h
+68
-51
src/codegen/stackmaps.h
src/codegen/stackmaps.h
+8
-1
No files found.
src/asm_writing/icinfo.cpp
View file @
dbc15587
...
...
@@ -198,8 +198,8 @@ ICInfo::ICInfo(void* start_addr, void* continue_addr, StackInfo stack_info, int
}
static
std
::
unordered_map
<
void
*
,
ICInfo
*>
ics_by_return_addr
;
void
registerCompiledPatchpoint
(
CompiledFunction
*
cf
,
uint8_t
*
start_addr
,
PatchpointSetupInfo
*
pp
,
StackInfo
stack_info
,
std
::
unordered_set
<
int
>
live_outs
)
{
void
registerCompiledPatchpoint
(
CompiledFunction
*
cf
,
uint8_t
*
start_addr
,
const
ICSetupInfo
*
pp
,
StackInfo
stack_info
,
std
::
unordered_set
<
int
>
live_outs
)
{
int
size
=
pp
->
totalSize
();
uint8_t
*
end_addr
=
start_addr
+
size
;
uint8_t
*
slowpath_addr
=
end_addr
;
...
...
src/asm_writing/icinfo.h
View file @
dbc15587
...
...
@@ -127,9 +127,9 @@ public:
friend
class
ICSlotRewrite
;
};
class
Patchpoint
SetupInfo
;
class
IC
SetupInfo
;
class
CompiledFunction
;
void
registerCompiledPatchpoint
(
CompiledFunction
*
cf
,
uint8_t
*
start_addr
,
Patchpoint
SetupInfo
*
,
StackInfo
stack_info
,
void
registerCompiledPatchpoint
(
CompiledFunction
*
cf
,
uint8_t
*
start_addr
,
const
IC
SetupInfo
*
,
StackInfo
stack_info
,
std
::
unordered_set
<
int
>
live_outs
);
ICInfo
*
getICInfo
(
void
*
rtn_addr
);
...
...
src/codegen/compvars.cpp
View file @
dbc15587
...
...
@@ -204,15 +204,14 @@ public:
// converted->getValue()->dump(); llvm::errs() << '\n';
bool
do_patchpoint
=
ENABLE_ICSETATTRS
&&
!
info
.
isInterpreted
();
if
(
do_patchpoint
)
{
PatchpointSetupInfo
*
pp
=
patchpoints
::
createSetattrPatchpoint
(
emitter
.
currentFunction
(),
info
.
getTypeRecorder
());
ICSetupInfo
*
pp
=
createSetattrIC
(
info
.
getTypeRecorder
());
std
::
vector
<
llvm
::
Value
*>
llvm_args
;
llvm_args
.
push_back
(
var
->
getValue
());
llvm_args
.
push_back
(
ptr
);
llvm_args
.
push_back
(
converted
->
getValue
());
emitter
.
create
Patchpoint
(
pp
,
(
void
*
)
pyston
::
setattr
,
llvm_args
,
info
.
exc_info
);
emitter
.
create
IC
(
pp
,
(
void
*
)
pyston
::
setattr
,
llvm_args
,
info
.
exc_info
);
}
else
{
emitter
.
createCall3
(
info
.
exc_info
,
g
.
funcs
.
setattr
,
var
->
getValue
(),
ptr
,
converted
->
getValue
());
}
...
...
@@ -227,14 +226,13 @@ public:
bool
do_patchpoint
=
false
;
if
(
do_patchpoint
)
{
PatchpointSetupInfo
*
pp
=
patchpoints
::
createDelattrPatchpoint
(
emitter
.
currentFunction
(),
info
.
getTypeRecorder
());
ICSetupInfo
*
pp
=
createDelattrIC
(
info
.
getTypeRecorder
());
std
::
vector
<
llvm
::
Value
*>
llvm_args
;
llvm_args
.
push_back
(
var
->
getValue
());
llvm_args
.
push_back
(
ptr
);
emitter
.
create
Patchpoint
(
pp
,
(
void
*
)
pyston
::
delattr
,
llvm_args
,
info
.
exc_info
);
emitter
.
create
IC
(
pp
,
(
void
*
)
pyston
::
delattr
,
llvm_args
,
info
.
exc_info
);
}
else
{
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
delattr
,
var
->
getValue
(),
ptr
);
}
...
...
@@ -274,15 +272,14 @@ public:
bool
do_patchpoint
=
ENABLE_ICGENERICS
&&
!
info
.
isInterpreted
();
llvm
::
Value
*
rtn
;
if
(
do_patchpoint
)
{
PatchpointSetupInfo
*
pp
=
patchpoints
::
createGenericPatchpoint
(
emitter
.
currentFunction
(),
info
.
getTypeRecorder
(),
true
,
256
);
ICSetupInfo
*
pp
=
createGenericIC
(
info
.
getTypeRecorder
(),
true
,
256
);
std
::
vector
<
llvm
::
Value
*>
llvm_args
;
llvm_args
.
push_back
(
var
->
getValue
());
rtn
=
emitter
.
create
Patchpoint
(
pp
,
(
void
*
)
pyston
::
unboxedLen
,
llvm_args
,
info
.
exc_info
).
getInstruction
(
);
rtn
=
emitter
.
create
IC
(
pp
,
(
void
*
)
pyston
::
unboxedLen
,
llvm_args
,
info
.
exc_info
);
}
else
{
rtn
=
emitter
.
createCall
(
info
.
exc_info
,
g
.
funcs
.
unboxedLen
,
var
->
getValue
())
.
getInstruction
()
;
rtn
=
emitter
.
createCall
(
info
.
exc_info
,
g
.
funcs
.
unboxedLen
,
var
->
getValue
());
}
assert
(
rtn
->
getType
()
==
g
.
i64
);
return
new
ConcreteCompilerVariable
(
INT
,
rtn
,
true
);
...
...
@@ -295,19 +292,16 @@ public:
bool
do_patchpoint
=
ENABLE_ICGETITEMS
&&
!
info
.
isInterpreted
();
llvm
::
Value
*
rtn
;
if
(
do_patchpoint
)
{
PatchpointSetupInfo
*
pp
=
patchpoints
::
createGetitemPatchpoint
(
emitter
.
currentFunction
(),
info
.
getTypeRecorder
());
ICSetupInfo
*
pp
=
createGetitemIC
(
info
.
getTypeRecorder
());
std
::
vector
<
llvm
::
Value
*>
llvm_args
;
llvm_args
.
push_back
(
var
->
getValue
());
llvm_args
.
push_back
(
converted_slice
->
getValue
());
llvm
::
Value
*
uncasted
=
emitter
.
createPatchpoint
(
pp
,
(
void
*
)
pyston
::
getitem
,
llvm_args
,
info
.
exc_info
).
getInstruction
();
llvm
::
Value
*
uncasted
=
emitter
.
createIC
(
pp
,
(
void
*
)
pyston
::
getitem
,
llvm_args
,
info
.
exc_info
);
rtn
=
emitter
.
getBuilder
()
->
CreateIntToPtr
(
uncasted
,
g
.
llvm_value_type_ptr
);
}
else
{
rtn
=
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
getitem
,
var
->
getValue
(),
converted_slice
->
getValue
())
.
getInstruction
();
rtn
=
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
getitem
,
var
->
getValue
(),
converted_slice
->
getValue
());
}
converted_slice
->
decvref
(
emitter
);
...
...
@@ -335,20 +329,18 @@ public:
}
if
(
do_patchpoint
)
{
PatchpointSetupInfo
*
pp
=
patchpoints
::
createBinexpPatchpoint
(
emitter
.
currentFunction
(),
info
.
getTypeRecorder
());
ICSetupInfo
*
pp
=
createBinexpIC
(
info
.
getTypeRecorder
());
std
::
vector
<
llvm
::
Value
*>
llvm_args
;
llvm_args
.
push_back
(
var
->
getValue
());
llvm_args
.
push_back
(
converted_rhs
->
getValue
());
llvm_args
.
push_back
(
getConstantInt
(
op_type
,
g
.
i32
));
llvm
::
Value
*
uncasted
=
emitter
.
createPatchpoint
(
pp
,
rt_func_addr
,
llvm_args
,
info
.
exc_info
).
getInstruction
();
llvm
::
Value
*
uncasted
=
emitter
.
createIC
(
pp
,
rt_func_addr
,
llvm_args
,
info
.
exc_info
);
rtn
=
emitter
.
getBuilder
()
->
CreateIntToPtr
(
uncasted
,
g
.
llvm_value_type_ptr
);
}
else
{
rtn
=
emitter
.
createCall3
(
info
.
exc_info
,
rt_func
,
var
->
getValue
(),
converted_rhs
->
getValue
(),
getConstantInt
(
op_type
,
g
.
i32
))
.
getInstruction
()
;
getConstantInt
(
op_type
,
g
.
i32
));
}
converted_rhs
->
decvref
(
emitter
);
...
...
@@ -383,17 +375,16 @@ CompilerVariable* UnknownType::getattr(IREmitter& emitter, const OpInfo& info, C
bool
do_patchpoint
=
ENABLE_ICGETATTRS
&&
!
info
.
isInterpreted
();
if
(
do_patchpoint
)
{
PatchpointSetupInfo
*
pp
=
patchpoints
::
createGetattrPatchpoint
(
emitter
.
currentFunction
(),
info
.
getTypeRecorder
());
ICSetupInfo
*
pp
=
createGetattrIC
(
info
.
getTypeRecorder
());
std
::
vector
<
llvm
::
Value
*>
llvm_args
;
llvm_args
.
push_back
(
var
->
getValue
());
llvm_args
.
push_back
(
ptr
);
llvm
::
Value
*
uncasted
=
emitter
.
create
Patchpoint
(
pp
,
raw_func
,
llvm_args
,
info
.
exc_info
).
getInstruction
(
);
llvm
::
Value
*
uncasted
=
emitter
.
create
IC
(
pp
,
raw_func
,
llvm_args
,
info
.
exc_info
);
rtn_val
=
emitter
.
getBuilder
()
->
CreateIntToPtr
(
uncasted
,
g
.
llvm_value_type_ptr
);
}
else
{
rtn_val
=
emitter
.
createCall2
(
info
.
exc_info
,
llvm_func
,
var
->
getValue
(),
ptr
)
.
getInstruction
()
;
rtn_val
=
emitter
.
createCall2
(
info
.
exc_info
,
llvm_func
,
var
->
getValue
(),
ptr
);
}
return
new
ConcreteCompilerVariable
(
UNKNOWN
,
rtn_val
,
true
);
}
...
...
@@ -483,10 +474,9 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
if
(
do_patchpoint
)
{
assert
(
func_addr
);
PatchpointSetupInfo
*
pp
=
patchpoints
::
createCallsitePatchpoint
(
emitter
.
currentFunction
(),
info
.
getTypeRecorder
(),
args
.
size
());
ICSetupInfo
*
pp
=
createCallsiteIC
(
info
.
getTypeRecorder
(),
args
.
size
());
llvm
::
Value
*
uncasted
=
emitter
.
create
Patchpoint
(
pp
,
func_addr
,
llvm_args
,
info
.
exc_info
).
getInstruction
(
);
llvm
::
Value
*
uncasted
=
emitter
.
create
IC
(
pp
,
func_addr
,
llvm_args
,
info
.
exc_info
);
assert
(
llvm
::
cast
<
llvm
::
FunctionType
>
(
llvm
::
cast
<
llvm
::
PointerType
>
(
func
->
getType
())
->
getElementType
())
->
getReturnType
()
==
g
.
llvm_value_type_ptr
);
...
...
@@ -500,7 +490,7 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
//}
// printf("%ld %ld\n", llvm_args.size(), args.size());
// printf("\n");
rtn
=
emitter
.
createCall
(
info
.
exc_info
,
func
,
llvm_args
)
.
getInstruction
()
;
rtn
=
emitter
.
createCall
(
info
.
exc_info
,
func
,
llvm_args
);
}
if
(
mallocsave
)
{
...
...
@@ -580,17 +570,15 @@ ConcreteCompilerVariable* UnknownType::nonzero(IREmitter& emitter, const OpInfo&
bool
do_patchpoint
=
ENABLE_ICNONZEROS
&&
!
info
.
isInterpreted
();
llvm
::
Value
*
rtn_val
;
if
(
do_patchpoint
)
{
PatchpointSetupInfo
*
pp
=
patchpoints
::
createNonzeroPatchpoint
(
emitter
.
currentFunction
(),
info
.
getTypeRecorder
());
ICSetupInfo
*
pp
=
createNonzeroIC
(
info
.
getTypeRecorder
());
std
::
vector
<
llvm
::
Value
*>
llvm_args
;
llvm_args
.
push_back
(
var
->
getValue
());
llvm
::
Value
*
uncasted
=
emitter
.
createPatchpoint
(
pp
,
(
void
*
)
pyston
::
nonzero
,
llvm_args
,
info
.
exc_info
).
getInstruction
();
llvm
::
Value
*
uncasted
=
emitter
.
createIC
(
pp
,
(
void
*
)
pyston
::
nonzero
,
llvm_args
,
info
.
exc_info
);
rtn_val
=
emitter
.
getBuilder
()
->
CreateTrunc
(
uncasted
,
g
.
i1
);
}
else
{
rtn_val
=
emitter
.
createCall
(
info
.
exc_info
,
g
.
funcs
.
nonzero
,
var
->
getValue
())
.
getInstruction
()
;
rtn_val
=
emitter
.
createCall
(
info
.
exc_info
,
g
.
funcs
.
nonzero
,
var
->
getValue
());
}
return
boolFromI1
(
emitter
,
rtn_val
);
}
...
...
@@ -840,13 +828,13 @@ public:
llvm
::
Value
*
v
;
/*if (op_type == AST_TYPE::Mod) {
v = emitter.createCall2(info.exc_info, g.funcs.mod_i64_i64, var->getValue(), converted_right->getValue())
.getInstruction()
;
;
} else if (op_type == AST_TYPE::Div || op_type == AST_TYPE::FloorDiv) {
v = emitter.createCall2(info.exc_info, g.funcs.div_i64_i64, var->getValue(), converted_right->getValue())
.getInstruction()
;
;
} else if (op_type == AST_TYPE::Pow) {
v = emitter.createCall2(info.exc_info, g.funcs.pow_i64_i64, var->getValue(), converted_right->getValue())
.getInstruction()
;
;
} else if (exp_type == BinOp || exp_type == AugBinOp) {
llvm::Instruction::BinaryOps binopcode;
switch (op_type) {
...
...
@@ -1047,16 +1035,16 @@ public:
bool
succeeded
=
true
;
if
(
op_type
==
AST_TYPE
::
Mod
)
{
v
=
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
mod_float_float
,
var
->
getValue
(),
converted_right
->
getValue
())
.
getInstruction
()
;
converted_right
->
getValue
());
}
else
if
(
op_type
==
AST_TYPE
::
Div
||
op_type
==
AST_TYPE
::
TrueDiv
)
{
v
=
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
div_float_float
,
var
->
getValue
(),
converted_right
->
getValue
())
.
getInstruction
()
;
converted_right
->
getValue
());
}
else
if
(
op_type
==
AST_TYPE
::
FloorDiv
)
{
v
=
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
floordiv_float_float
,
var
->
getValue
(),
converted_right
->
getValue
())
.
getInstruction
()
;
converted_right
->
getValue
());
}
else
if
(
op_type
==
AST_TYPE
::
Pow
)
{
v
=
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
pow_float_float
,
var
->
getValue
(),
converted_right
->
getValue
())
.
getInstruction
()
;
converted_right
->
getValue
());
}
else
if
(
exp_type
==
BinOp
||
exp_type
==
AugBinOp
)
{
llvm
::
Instruction
::
BinaryOps
binopcode
;
switch
(
op_type
)
{
...
...
src/codegen/irgen.h
View file @
dbc15587
...
...
@@ -52,7 +52,7 @@ public:
void
setEmitter
(
IREmitter
*
emitter
)
{
this
->
emitter
=
emitter
;
}
};
class
Patchpoint
SetupInfo
;
class
IC
SetupInfo
;
class
IREmitter
{
public:
...
...
@@ -69,13 +69,13 @@ public:
virtual
llvm
::
Function
*
getIntrinsic
(
llvm
::
Intrinsic
::
ID
)
=
0
;
virtual
llvm
::
CallSite
createCall
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
const
std
::
vector
<
llvm
::
Value
*>&
args
)
=
0
;
virtual
llvm
::
CallSite
createCall
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
)
=
0
;
virtual
llvm
::
CallSite
createCall2
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
,
llvm
::
Value
*
arg2
)
=
0
;
virtual
llvm
::
CallSite
createCall3
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
,
llvm
::
Value
*
arg2
,
llvm
::
Value
*
arg3
)
=
0
;
virtual
llvm
::
CallSite
createPatchpoint
(
const
PatchpointSetupInfo
*
pp
,
void
*
func_addr
,
const
std
::
vector
<
llvm
::
Value
*>&
args
,
ExcInfo
exc_info
)
=
0
;
virtual
llvm
::
Value
*
createCall
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
const
std
::
vector
<
llvm
::
Value
*>&
args
)
=
0
;
virtual
llvm
::
Value
*
createCall
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
)
=
0
;
virtual
llvm
::
Value
*
createCall2
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
,
llvm
::
Value
*
arg2
)
=
0
;
virtual
llvm
::
Value
*
createCall3
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
,
llvm
::
Value
*
arg2
,
llvm
::
Value
*
arg3
)
=
0
;
virtual
llvm
::
Value
*
createIC
(
const
ICSetupInfo
*
pp
,
void
*
func_addr
,
const
std
::
vector
<
llvm
::
Value
*>&
args
,
ExcInfo
exc_info
)
=
0
;
};
CompiledFunction
*
doCompile
(
SourceInfo
*
source
,
const
OSREntryDescriptor
*
entry_descriptor
,
...
...
src/codegen/irgen/hooks.cpp
View file @
dbc15587
...
...
@@ -129,7 +129,8 @@ static void compileIR(CompiledFunction* cf, EffortLevel::EffortLevel effort) {
}
StackMap
*
stackmap
=
parseStackMap
();
patchpoints
::
processStackmap
(
cf
,
stackmap
);
processStackmap
(
cf
,
stackmap
);
delete
stackmap
;
}
static
std
::
unordered_map
<
std
::
string
,
CompiledFunction
*>
machine_name_to_cf
;
...
...
src/codegen/irgen/irgenerator.cpp
View file @
dbc15587
...
...
@@ -15,6 +15,7 @@
#include "codegen/irgen/irgenerator.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include "analysis/function_analysis.h"
#include "analysis/scoping_analysis.h"
...
...
@@ -100,10 +101,67 @@ private:
IRGenState
*
irstate
;
IRBuilder
*
builder
;
llvm
::
BasicBlock
*&
curblock
;
IRGenerator
*
irgenerator
;
llvm
::
CallSite
emitCall
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
const
std
::
vector
<
llvm
::
Value
*>&
args
)
{
if
(
exc_info
.
needsInvoke
())
{
llvm
::
BasicBlock
*
normal_dest
=
llvm
::
BasicBlock
::
Create
(
g
.
context
,
curblock
->
getName
(),
irstate
->
getLLVMFunction
());
normal_dest
->
moveAfter
(
curblock
);
llvm
::
InvokeInst
*
rtn
=
getBuilder
()
->
CreateInvoke
(
callee
,
normal_dest
,
exc_info
.
exc_dest
,
args
);
getBuilder
()
->
SetInsertPoint
(
normal_dest
);
curblock
=
normal_dest
;
return
rtn
;
}
else
{
return
getBuilder
()
->
CreateCall
(
callee
,
args
);
}
}
llvm
::
CallSite
emitPatchpoint
(
llvm
::
Type
*
return_type
,
const
ICSetupInfo
*
pp
,
llvm
::
Value
*
func
,
const
std
::
vector
<
llvm
::
Value
*>&
args
,
const
std
::
vector
<
llvm
::
Value
*>&
ic_stackmap_args
,
ExcInfo
exc_info
)
{
if
(
pp
==
NULL
)
assert
(
ic_stackmap_args
.
size
()
==
0
);
PatchpointInfo
*
info
=
PatchpointInfo
::
create
(
currentFunction
(),
pp
,
ic_stackmap_args
.
size
());
int64_t
pp_id
=
reinterpret_cast
<
int64_t
>
(
info
);
int
pp_size
=
pp
?
pp
->
totalSize
()
:
CALL_ONLY_SIZE
;
std
::
vector
<
llvm
::
Value
*>
pp_args
;
pp_args
.
push_back
(
getConstantInt
(
pp_id
,
g
.
i64
));
// pp_id: will fill this in later
pp_args
.
push_back
(
getConstantInt
(
pp_size
,
g
.
i32
));
pp_args
.
push_back
(
func
);
pp_args
.
push_back
(
getConstantInt
(
args
.
size
(),
g
.
i32
));
pp_args
.
insert
(
pp_args
.
end
(),
args
.
begin
(),
args
.
end
());
int
num_scratch_bytes
=
info
->
scratchSize
();
llvm
::
Value
*
scratch_space
=
irstate
->
getScratchSpace
(
num_scratch_bytes
);
pp_args
.
push_back
(
scratch_space
);
pp_args
.
insert
(
pp_args
.
end
(),
ic_stackmap_args
.
begin
(),
ic_stackmap_args
.
end
());
llvm
::
Intrinsic
::
ID
intrinsic_id
;
if
(
return_type
->
isIntegerTy
()
||
return_type
->
isPointerTy
())
{
intrinsic_id
=
llvm
::
Intrinsic
::
experimental_patchpoint_i64
;
}
else
if
(
return_type
->
isVoidTy
())
{
intrinsic_id
=
llvm
::
Intrinsic
::
experimental_patchpoint_void
;
}
else
if
(
return_type
->
isDoubleTy
())
{
intrinsic_id
=
llvm
::
Intrinsic
::
experimental_patchpoint_double
;
}
else
{
return_type
->
dump
();
abort
();
}
llvm
::
Function
*
patchpoint
=
this
->
getIntrinsic
(
intrinsic_id
);
llvm
::
CallSite
rtn
=
this
->
emitCall
(
exc_info
,
patchpoint
,
pp_args
);
return
rtn
;
}
public:
explicit
IREmitterImpl
(
IRGenState
*
irstate
,
llvm
::
BasicBlock
*&
curblock
)
:
irstate
(
irstate
),
builder
(
new
IRBuilder
(
g
.
context
)),
curblock
(
curblock
)
{
explicit
IREmitterImpl
(
IRGenState
*
irstate
,
llvm
::
BasicBlock
*&
curblock
,
IRGenerator
*
irgenerator
)
:
irstate
(
irstate
),
builder
(
new
IRBuilder
(
g
.
context
)),
curblock
(
curblock
)
,
irgenerator
(
irgenerator
)
{
builder
->
setEmitter
(
this
);
builder
->
SetInsertPoint
(
curblock
);
}
...
...
@@ -122,66 +180,40 @@ public:
CompiledFunction
*
currentFunction
()
override
{
return
irstate
->
getCurFunction
();
}
llvm
::
CallSite
createCall
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
const
std
::
vector
<
llvm
::
Value
*>&
args
)
override
{
if
(
exc_info
.
needsInvoke
())
{
llvm
::
BasicBlock
*
normal_dest
=
llvm
::
BasicBlock
::
Create
(
g
.
context
,
curblock
->
getName
(),
irstate
->
getLLVMFunction
());
normal_dest
->
moveAfter
(
curblock
);
llvm
::
InvokeInst
*
rtn
=
getBuilder
()
->
CreateInvoke
(
callee
,
normal_dest
,
exc_info
.
exc_dest
,
args
);
getBuilder
()
->
SetInsertPoint
(
normal_dest
);
curblock
=
normal_dest
;
return
rtn
;
}
else
{
return
getBuilder
()
->
CreateCall
(
callee
,
args
);
}
llvm
::
Value
*
createCall
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
const
std
::
vector
<
llvm
::
Value
*>&
args
)
override
{
llvm
::
CallSite
cs
=
this
->
emitCall
(
exc_info
,
callee
,
args
);
return
cs
.
getInstruction
();
}
llvm
::
CallSite
createCall
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
)
override
{
llvm
::
Value
*
createCall
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
)
override
{
return
createCall
(
exc_info
,
callee
,
std
::
vector
<
llvm
::
Value
*>
({
arg1
}));
}
llvm
::
CallSite
createCall2
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
,
llvm
::
Value
*
arg2
)
override
{
llvm
::
Value
*
createCall2
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
,
llvm
::
Value
*
arg2
)
override
{
return
createCall
(
exc_info
,
callee
,
{
arg1
,
arg2
});
}
llvm
::
CallSite
createCall3
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
,
llvm
::
Value
*
arg2
,
llvm
::
Value
*
arg3
)
override
{
llvm
::
Value
*
createCall3
(
ExcInfo
exc_info
,
llvm
::
Value
*
callee
,
llvm
::
Value
*
arg1
,
llvm
::
Value
*
arg2
,
llvm
::
Value
*
arg3
)
override
{
return
createCall
(
exc_info
,
callee
,
{
arg1
,
arg2
,
arg3
});
}
llvm
::
CallSite
createPatchpoint
(
const
PatchpointSetupInfo
*
pp
,
void
*
func_addr
,
const
std
::
vector
<
llvm
::
Value
*>&
args
,
ExcInfo
exc_info
)
override
{
int64_t
pp_id
=
pp
->
getPatchpointId
();
int
pp_size
=
pp
->
totalSize
();
llvm
::
Value
*
createIC
(
const
ICSetupInfo
*
pp
,
void
*
func_addr
,
const
std
::
vector
<
llvm
::
Value
*>&
args
,
ExcInfo
exc_info
)
override
{
assert
(
irstate
->
getEffortLevel
()
!=
EffortLevel
::
INTERPRETED
);
std
::
vector
<
llvm
::
Value
*>
pp_args
;
pp_args
.
push_back
(
getConstantInt
(
pp_id
,
g
.
i64
));
pp_args
.
push_back
(
getConstantInt
(
pp_size
,
g
.
i32
));
pp_args
.
push_back
(
embedConstantPtr
(
func_addr
,
g
.
i8
->
getPointerTo
()));
pp_args
.
push_back
(
getConstantInt
(
args
.
size
(),
g
.
i32
));
std
::
vector
<
llvm
::
Value
*>
stackmap_args
;
pp_args
.
insert
(
pp_args
.
end
(),
args
.
begin
(),
args
.
end
());
int
num_scratch_bytes
=
pp
->
numScratchBytes
();
if
(
num_scratch_bytes
)
{
llvm
::
Value
*
scratch_space
=
irstate
->
getScratchSpace
(
num_scratch_bytes
);
pp_args
.
push_back
(
scratch_space
);
}
llvm
::
CallSite
rtn
=
emitPatchpoint
(
pp
->
hasReturnValue
()
?
g
.
i64
:
g
.
void_
,
pp
,
embedConstantPtr
(
func_addr
,
g
.
i8
->
getPointerTo
()),
args
,
stackmap_args
,
exc_info
);
llvm
::
Intrinsic
::
ID
intrinsic_id
=
pp
->
hasReturnValue
()
?
llvm
::
Intrinsic
::
experimental_patchpoint_i64
:
llvm
::
Intrinsic
::
experimental_patchpoint_void
;
llvm
::
Function
*
patchpoint
=
this
->
getIntrinsic
(
intrinsic_id
);
llvm
::
CallSite
rtn
=
this
->
createCall
(
exc_info
,
patchpoint
,
pp_args
);
rtn
.
setCallingConv
(
pp
->
getCallingConvention
());
return
rtn
;
return
rtn
.
getInstruction
()
;
}
};
IREmitter
*
createIREmitter
(
IRGenState
*
irstate
,
llvm
::
BasicBlock
*&
curblock
)
{
return
new
IREmitterImpl
(
irstate
,
curblock
);
IREmitter
*
createIREmitter
(
IRGenState
*
irstate
,
llvm
::
BasicBlock
*&
curblock
,
IRGenerator
*
irgenerator
)
{
return
new
IREmitterImpl
(
irstate
,
curblock
,
irgenerator
);
}
static
std
::
unordered_map
<
AST_expr
*
,
std
::
vector
<
const
std
::
string
*>*>
made_keyword_storage
;
...
...
@@ -223,8 +255,8 @@ public:
IRGeneratorImpl
(
IRGenState
*
irstate
,
std
::
unordered_map
<
CFGBlock
*
,
llvm
::
BasicBlock
*>&
entry_blocks
,
CFGBlock
*
myblock
,
TypeAnalysis
*
types
,
GuardList
&
out_guards
,
const
GuardList
&
in_guards
,
bool
is_partial
)
:
irstate
(
irstate
),
curblock
(
entry_blocks
[
myblock
]),
emitter
(
irstate
,
curblock
),
entry_blocks
(
entry_block
s
),
myblock
(
myblock
),
types
(
types
),
out_guards
(
out_guards
),
in_guards
(
in_guards
),
:
irstate
(
irstate
),
curblock
(
entry_blocks
[
myblock
]),
emitter
(
irstate
,
curblock
,
thi
s
),
entry_blocks
(
entry_blocks
),
myblock
(
myblock
),
types
(
types
),
out_guards
(
out_guards
),
in_guards
(
in_guards
),
state
(
is_partial
?
PARTIAL
:
RUNNING
)
{}
~
IRGeneratorImpl
()
{
delete
emitter
.
getBuilder
();
}
...
...
@@ -309,9 +341,9 @@ private:
cls
->
decvref
(
emitter
);
flags
->
decvref
(
emitter
);
llvm
::
Value
*
v
=
emitter
.
createCall
(
exc_info
,
g
.
funcs
.
isinstance
,
{
converted_obj
->
getValue
(),
converted_cls
->
getValue
()
,
converted_flags
->
getValue
()
}).
getInstruction
(
);
llvm
::
Value
*
v
=
emitter
.
createCall
(
exc_info
,
g
.
funcs
.
isinstance
,
{
converted_obj
->
getValue
(),
converted_cls
->
getValue
(),
converted_flags
->
getValue
()
}
);
assert
(
v
->
getType
()
==
g
.
i1
);
return
boolFromI1
(
emitter
,
v
);
...
...
@@ -403,8 +435,7 @@ private:
ConcreteCompilerVariable
*
converted_obj
=
obj
->
makeConverted
(
emitter
,
obj
->
getBoxType
());
obj
->
decvref
(
emitter
);
llvm
::
Value
*
v
=
emitter
.
createCall
(
exc_info
,
g
.
funcs
.
getiter
,
{
converted_obj
->
getValue
()
}).
getInstruction
();
llvm
::
Value
*
v
=
emitter
.
createCall
(
exc_info
,
g
.
funcs
.
getiter
,
{
converted_obj
->
getValue
()
});
assert
(
v
->
getType
()
==
g
.
llvm_value_type_ptr
);
return
new
ConcreteCompilerVariable
(
UNKNOWN
,
v
,
true
);
...
...
@@ -422,7 +453,7 @@ private:
assert
(
name
.
size
());
llvm
::
Value
*
r
=
emitter
.
createCall2
(
exc_info
,
g
.
funcs
.
importFrom
,
converted_module
->
getValue
(),
embedConstantPtr
(
&
name
,
g
.
llvm_str_type_ptr
))
.
getInstruction
()
;
embedConstantPtr
(
&
name
,
g
.
llvm_str_type_ptr
));
CompilerVariable
*
v
=
new
ConcreteCompilerVariable
(
UNKNOWN
,
r
,
true
);
...
...
@@ -440,9 +471,9 @@ private:
ConcreteCompilerVariable
*
converted_module
=
module
->
makeConverted
(
emitter
,
module
->
getBoxType
());
module
->
decvref
(
emitter
);
llvm
::
Value
*
r
=
emitter
.
createCall2
(
exc_info
,
g
.
funcs
.
importStar
,
converted_module
->
getValue
(),
embedConstantPtr
(
irstate
->
getSourceInfo
()
->
parent_module
,
g
.
llvm_module_type_ptr
)).
getInstruction
(
);
llvm
::
Value
*
r
=
emitter
.
createCall2
(
exc_info
,
g
.
funcs
.
importStar
,
converted_module
->
getValue
()
,
embedConstantPtr
(
irstate
->
getSourceInfo
()
->
parent_module
,
g
.
llvm_module_type_ptr
)
);
CompilerVariable
*
v
=
new
ConcreteCompilerVariable
(
UNKNOWN
,
r
,
true
);
converted_module
->
decvref
(
emitter
);
...
...
@@ -463,10 +494,9 @@ private:
const
std
::
string
&
module_name
=
static_cast
<
AST_Str
*>
(
node
->
args
[
2
])
->
s
;
llvm
::
Value
*
imported
=
emitter
.
createCall3
(
exc_info
,
g
.
funcs
.
import
,
getConstantInt
(
level
,
g
.
i32
),
converted_froms
->
getValue
(),
embedConstantPtr
(
&
module_name
,
g
.
llvm_str_type_ptr
)).
getInstruction
();
llvm
::
Value
*
imported
=
emitter
.
createCall3
(
exc_info
,
g
.
funcs
.
import
,
getConstantInt
(
level
,
g
.
i32
),
converted_froms
->
getValue
(),
embedConstantPtr
(
&
module_name
,
g
.
llvm_str_type_ptr
));
ConcreteCompilerVariable
*
v
=
new
ConcreteCompilerVariable
(
UNKNOWN
,
imported
,
true
);
converted_froms
->
decvref
(
emitter
);
...
...
@@ -713,22 +743,20 @@ private:
ConcreteCompilerVariable
*
_getGlobal
(
AST_Name
*
node
,
ExcInfo
exc_info
)
{
bool
do_patchpoint
=
ENABLE_ICGETGLOBALS
&&
(
irstate
->
getEffortLevel
()
!=
EffortLevel
::
INTERPRETED
);
if
(
do_patchpoint
)
{
PatchpointSetupInfo
*
pp
=
patchpoints
::
createGetGlobalPatchpoint
(
emitter
.
currentFunction
(),
getOpInfoForNode
(
node
,
exc_info
).
getTypeRecorder
());
ICSetupInfo
*
pp
=
createGetGlobalIC
(
getOpInfoForNode
(
node
,
exc_info
).
getTypeRecorder
());
std
::
vector
<
llvm
::
Value
*>
llvm_args
;
llvm_args
.
push_back
(
embedConstantPtr
(
irstate
->
getSourceInfo
()
->
parent_module
,
g
.
llvm_module_type_ptr
));
llvm_args
.
push_back
(
embedConstantPtr
(
&
node
->
id
,
g
.
llvm_str_type_ptr
));
llvm
::
Value
*
uncasted
=
emitter
.
createPatchpoint
(
pp
,
(
void
*
)
pyston
::
getGlobal
,
llvm_args
,
exc_info
).
getInstruction
();
llvm
::
Value
*
uncasted
=
emitter
.
createIC
(
pp
,
(
void
*
)
pyston
::
getGlobal
,
llvm_args
,
exc_info
);
llvm
::
Value
*
r
=
emitter
.
getBuilder
()
->
CreateIntToPtr
(
uncasted
,
g
.
llvm_value_type_ptr
);
return
new
ConcreteCompilerVariable
(
UNKNOWN
,
r
,
true
);
}
else
{
llvm
::
Value
*
r
=
emitter
.
createCall2
(
exc_info
,
g
.
funcs
.
getGlobal
,
embedConstantPtr
(
irstate
->
getSourceInfo
()
->
parent_module
,
g
.
llvm_module_type_ptr
),
embedConstantPtr
(
&
node
->
id
,
g
.
llvm_str_type_ptr
))
.
getInstruction
()
;
embedConstantPtr
(
&
node
->
id
,
g
.
llvm_str_type_ptr
));
return
new
ConcreteCompilerVariable
(
UNKNOWN
,
r
,
true
);
}
}
...
...
@@ -836,7 +864,7 @@ private:
var
->
decvref
(
emitter
);
std
::
vector
<
llvm
::
Value
*>
args
{
cvar
->
getValue
()
};
llvm
::
Value
*
rtn
=
emitter
.
createCall
(
exc_info
,
g
.
funcs
.
repr
,
args
)
.
getInstruction
()
;
llvm
::
Value
*
rtn
=
emitter
.
createCall
(
exc_info
,
g
.
funcs
.
repr
,
args
);
cvar
->
decvref
(
emitter
);
rtn
=
emitter
.
getBuilder
()
->
CreateBitCast
(
rtn
,
g
.
llvm_value_type_ptr
);
...
...
@@ -954,7 +982,7 @@ private:
operand
->
decvref
(
emitter
);
llvm
::
Value
*
rtn
=
emitter
.
createCall2
(
exc_info
,
g
.
funcs
.
unaryop
,
converted
->
getValue
(),
getConstantInt
(
node
->
op_type
,
g
.
i32
))
.
getInstruction
()
;
getConstantInt
(
node
->
op_type
,
g
.
i32
));
converted
->
decvref
(
emitter
);
return
new
ConcreteCompilerVariable
(
UNKNOWN
,
rtn
,
true
);
...
...
@@ -972,8 +1000,8 @@ private:
ConcreteCompilerVariable
*
convertedValue
=
value
->
makeConverted
(
emitter
,
value
->
getBoxType
());
value
->
decvref
(
emitter
);
llvm
::
Value
*
rtn
=
emitter
.
createCall2
(
exc_info
,
g
.
funcs
.
yield
,
convertedGenerator
->
getValue
(),
convertedValue
->
getValue
()).
getInstruction
(
);
llvm
::
Value
*
rtn
=
emitter
.
createCall2
(
exc_info
,
g
.
funcs
.
yield
,
convertedGenerator
->
getValue
(),
convertedValue
->
getValue
()
);
convertedGenerator
->
decvref
(
emitter
);
convertedValue
->
decvref
(
emitter
);
...
...
@@ -1302,15 +1330,14 @@ private:
// patchpoints if it couldn't.
bool
do_patchpoint
=
ENABLE_ICSETITEMS
&&
(
irstate
->
getEffortLevel
()
!=
EffortLevel
::
INTERPRETED
);
if
(
do_patchpoint
)
{
PatchpointSetupInfo
*
pp
=
patchpoints
::
createSetitemPatchpoint
(
emitter
.
currentFunction
(),
getEmptyOpInfo
(
exc_info
).
getTypeRecorder
());
ICSetupInfo
*
pp
=
createSetitemIC
(
getEmptyOpInfo
(
exc_info
).
getTypeRecorder
());
std
::
vector
<
llvm
::
Value
*>
llvm_args
;
llvm_args
.
push_back
(
converted_target
->
getValue
());
llvm_args
.
push_back
(
converted_slice
->
getValue
());
llvm_args
.
push_back
(
converted_val
->
getValue
());
emitter
.
create
Patchpoint
(
pp
,
(
void
*
)
pyston
::
setitem
,
llvm_args
,
exc_info
);
emitter
.
create
IC
(
pp
,
(
void
*
)
pyston
::
setitem
,
llvm_args
,
exc_info
);
}
else
{
emitter
.
createCall3
(
exc_info
,
g
.
funcs
.
setitem
,
converted_target
->
getValue
(),
converted_slice
->
getValue
(),
converted_val
->
getValue
());
...
...
@@ -1339,7 +1366,7 @@ private:
ConcreteCompilerVariable
*
converted_val
=
val
->
makeConverted
(
emitter
,
val
->
getBoxType
());
llvm
::
Value
*
unpacked
=
emitter
.
createCall2
(
exc_info
,
g
.
funcs
.
unpackIntoArray
,
converted_val
->
getValue
(),
getConstantInt
(
ntargets
,
g
.
i64
))
.
getInstruction
()
;
getConstantInt
(
ntargets
,
g
.
i64
));
assert
(
unpacked
->
getType
()
==
g
.
llvm_value_type_ptr
->
getPointerTo
());
converted_val
->
decvref
(
emitter
);
...
...
@@ -1461,7 +1488,7 @@ private:
llvm
::
Value
*
classobj
=
emitter
.
createCall3
(
exc_info
,
g
.
funcs
.
createUserClass
,
embedConstantPtr
(
&
node
->
name
,
g
.
llvm_str_type_ptr
),
bases_tuple
->
getValue
(),
converted_attr_dict
->
getValue
())
.
getInstruction
()
;
bases_tuple
->
getValue
(),
converted_attr_dict
->
getValue
());
// Note: createuserClass is free to manufacture non-class objects
CompilerVariable
*
cls
=
new
ConcreteCompilerVariable
(
UNKNOWN
,
classobj
,
true
);
...
...
@@ -1508,14 +1535,13 @@ private:
bool
do_patchpoint
=
ENABLE_ICDELITEMS
&&
(
irstate
->
getEffortLevel
()
!=
EffortLevel
::
INTERPRETED
);
if
(
do_patchpoint
)
{
PatchpointSetupInfo
*
pp
=
patchpoints
::
createDelitemPatchpoint
(
emitter
.
currentFunction
(),
getEmptyOpInfo
(
exc_info
).
getTypeRecorder
());
ICSetupInfo
*
pp
=
createDelitemIC
(
getEmptyOpInfo
(
exc_info
).
getTypeRecorder
());
std
::
vector
<
llvm
::
Value
*>
llvm_args
;
llvm_args
.
push_back
(
converted_target
->
getValue
());
llvm_args
.
push_back
(
converted_slice
->
getValue
());
emitter
.
create
Patchpoint
(
pp
,
(
void
*
)
pyston
::
delitem
,
llvm_args
,
exc_info
);
emitter
.
create
IC
(
pp
,
(
void
*
)
pyston
::
delitem
,
llvm_args
,
exc_info
);
}
else
{
emitter
.
createCall2
(
exc_info
,
g
.
funcs
.
delitem
,
converted_target
->
getValue
(),
converted_slice
->
getValue
());
}
...
...
@@ -1682,9 +1708,8 @@ private:
// begin code for handling of softspace
bool
new_softspace
=
(
i
<
nvals
-
1
)
||
(
!
node
->
nl
);
llvm
::
Value
*
dospace
=
emitter
.
createCall
(
exc_info
,
g
.
funcs
.
softspace
,
{
dest
->
getValue
(),
getConstantInt
(
new_softspace
,
g
.
i1
)
}).
getInstruction
();
llvm
::
Value
*
dospace
=
emitter
.
createCall
(
exc_info
,
g
.
funcs
.
softspace
,
{
dest
->
getValue
(),
getConstantInt
(
new_softspace
,
g
.
i1
)
});
assert
(
dospace
->
getType
()
==
g
.
i1
);
llvm
::
BasicBlock
*
ss_block
=
llvm
::
BasicBlock
::
Create
(
g
.
context
,
"softspace"
,
irstate
->
getLLVMFunction
());
...
...
@@ -1705,7 +1730,7 @@ private:
// end code for handling of softspace
llvm
::
Value
*
v
=
emitter
.
createCall
(
exc_info
,
g
.
funcs
.
str
,
{
converted
->
getValue
()
})
.
getInstruction
()
;
llvm
::
Value
*
v
=
emitter
.
createCall
(
exc_info
,
g
.
funcs
.
str
,
{
converted
->
getValue
()
});
v
=
emitter
.
getBuilder
()
->
CreateBitCast
(
v
,
g
.
llvm_value_type_ptr
);
auto
s
=
new
ConcreteCompilerVariable
(
STR
,
v
,
true
);
r
=
dest
->
callattr
(
emitter
,
getOpInfoForNode
(
node
,
exc_info
),
&
write_str
,
false
,
ArgPassSpec
(
1
),
{
s
},
...
...
src/codegen/irgen/irgenerator.h
View file @
dbc15587
...
...
@@ -199,7 +199,7 @@ public:
};
class
IREmitter
;
IREmitter
*
createIREmitter
(
IRGenState
*
irstate
,
llvm
::
BasicBlock
*&
curblock
);
IREmitter
*
createIREmitter
(
IRGenState
*
irstate
,
llvm
::
BasicBlock
*&
curblock
,
IRGenerator
*
irgenerator
=
NULL
);
IRGenerator
*
createIRGenerator
(
IRGenState
*
irstate
,
std
::
unordered_map
<
CFGBlock
*
,
llvm
::
BasicBlock
*>&
entry_blocks
,
CFGBlock
*
myblock
,
TypeAnalysis
*
types
,
GuardList
&
out_guards
,
const
GuardList
&
in_guards
,
bool
is_partial
);
...
...
src/codegen/llvm_interpreter.cpp
View file @
dbc15587
...
...
@@ -27,6 +27,7 @@
#include "codegen/codegen.h"
#include "codegen/irgen/hooks.h"
#include "codegen/irgen/util.h"
#include "codegen/patchpoints.h"
#include "core/common.h"
#include "core/stats.h"
#include "core/thread_utils.h"
...
...
@@ -566,32 +567,36 @@ Box* interpretFunction(llvm::Function* f, int nargs, Box* closure, Box* generato
llvm
::
InvokeInst
*
invoke
=
llvm
::
dyn_cast
<
llvm
::
InvokeInst
>
(
inst
);
void
*
f
;
int
arg_start
;
int
arg_start
,
num_args
;
if
(
cs
.
getCalledFunction
()
&&
(
cs
.
getCalledFunction
()
->
getName
()
==
"llvm.experimental.patchpoint.void"
||
cs
.
getCalledFunction
()
->
getName
()
==
"llvm.experimental.patchpoint.i64"
))
{
// cs.dump();
assert
(
0
&&
"shouldn't be generating patchpoints for interpretation!"
);
||
cs
.
getCalledFunction
()
->
getName
()
==
"llvm.experimental.patchpoint.i64"
||
cs
.
getCalledFunction
()
->
getName
()
==
"llvm.experimental.patchpoint.double"
))
{
// cs.dump();
#ifndef NDEBUG
// We use size == CALL_ONLY_SIZE to imply that the call isn't patchable
int
pp_size
=
(
int64_t
)
fetch
(
cs
.
getArgument
(
1
),
dl
,
symbols
).
n
;
ASSERT
(
pp_size
==
CALL_ONLY_SIZE
,
"shouldn't be generating patchpoints for interpretation"
);
#endif
f
=
(
void
*
)
fetch
(
cs
.
getArgument
(
2
),
dl
,
symbols
).
n
;
arg_start
=
4
;
num_args
=
(
int64_t
)
fetch
(
cs
.
getArgument
(
3
),
dl
,
symbols
).
n
;
}
else
{
f
=
(
void
*
)
fetch
(
cs
.
getCalledValue
(),
dl
,
symbols
).
n
;
arg_start
=
0
;
num_args
=
cs
.
arg_size
();
}
if
(
VERBOSITY
(
"interpreter"
)
>=
2
)
printf
(
"calling %s
\n
"
,
g
.
func_addr_registry
.
getFuncNameAtAddress
(
f
,
true
).
c_str
());
std
::
vector
<
Val
>
args
;
int
nargs
=
cs
.
arg_size
();
for
(
int
i
=
arg_start
;
i
<
nargs
;
i
++
)
{
for
(
int
i
=
arg_start
;
i
<
arg_start
+
num_args
;
i
++
)
{
// cs.getArgument(i)->dump();
args
.
push_back
(
fetch
(
cs
.
getArgument
(
i
),
dl
,
symbols
));
}
int
npassed_args
=
nargs
-
arg_start
;
// printf("%d %d %d\n", nargs, arg_start, npassed_args);
#ifdef TIME_INTERPRETS
this_us
+=
_t
.
end
();
#endif
...
...
@@ -603,7 +608,7 @@ Box* interpretFunction(llvm::Function* f, int nargs, Box* closure, Box* generato
else
mask
=
2
;
for
(
int
i
=
0
;
i
<
npassed
_args
;
i
++
)
{
for
(
int
i
=
arg_start
;
i
<
arg_start
+
num
_args
;
i
++
)
{
mask
<<=
1
;
if
(
cs
.
getArgument
(
i
)
->
getType
()
==
g
.
double_
)
mask
|=
1
;
...
...
@@ -636,6 +641,9 @@ Box* interpretFunction(llvm::Function* f, int nargs, Box* closure, Box* generato
case
0b1011
:
r
=
reinterpret_cast
<
int64_t
(
*
)(
double
,
double
)
>
(
f
)(
args
[
0
].
d
,
args
[
1
].
d
);
break
;
case
0b1100
:
r
=
reinterpret_cast
<
double
(
*
)(
int64_t
,
int64_t
)
>
(
f
)(
args
[
0
].
n
,
args
[
1
].
n
);
break
;
case
0b1111
:
r
=
reinterpret_cast
<
double
(
*
)(
double
,
double
)
>
(
f
)(
args
[
0
].
d
,
args
[
1
].
d
);
break
;
...
...
src/codegen/patchpoints.cpp
View file @
dbc15587
...
...
@@ -18,6 +18,8 @@
#include <unordered_map>
#include "asm_writing/icinfo.h"
#include "asm_writing/rewriter.h"
#include "codegen/compvars.h"
#include "codegen/stackmaps.h"
#include "core/common.h"
#include "core/options.h"
...
...
@@ -26,33 +28,71 @@
namespace
pyston
{
int
Patchpoint
SetupInfo
::
totalSize
()
const
{
int
call_size
=
13
;
int
IC
SetupInfo
::
totalSize
()
const
{
int
call_size
=
CALL_ONLY_SIZE
;
if
(
getCallingConvention
()
!=
llvm
::
CallingConv
::
C
)
{
//
have no idea what the precise number is:
call_size
=
128
;
//
14 bytes per reg that needs to be spilled
call_size
+=
14
*
4
;
}
return
num_slots
*
slot_size
+
call_size
;
}
int64_t
PatchpointSetupInfo
::
getPatchpointId
()
const
{
return
pp_id
;
}
static
std
::
unordered_map
<
int64_t
,
PatchpointSetupInfo
*>
new_patchpoints_by_id
;
static
std
::
vector
<
PatchpointInfo
*>
new_patchpoints
;
ICSetupInfo
*
ICSetupInfo
::
initialize
(
bool
has_return_value
,
int
num_slots
,
int
slot_size
,
ICType
type
,
TypeRecorder
*
type_recorder
)
{
ICSetupInfo
*
rtn
=
new
ICSetupInfo
(
type
,
num_slots
,
slot_size
,
has_return_value
,
type_recorder
);
PatchpointSetupInfo
*
PatchpointSetupInfo
::
initialize
(
bool
has_return_value
,
int
num_slots
,
int
slot_size
,
CompiledFunction
*
parent_cf
,
patchpoints
::
PatchpointType
type
,
TypeRecorder
*
type_recorder
)
{
static
int64_t
next_id
=
100
;
int64_t
id
=
next_id
++
;
// We use size == CALL_ONLY_SIZE to imply that the call isn't patchable
assert
(
rtn
->
totalSize
()
>
CALL_ONLY_SIZE
);
PatchpointSetupInfo
*
rtn
=
new
PatchpointSetupInfo
(
id
,
type
,
num_slots
,
slot_size
,
parent_cf
,
has_return_value
,
type_recorder
);
new_patchpoints_by_id
[
id
]
=
rtn
;
return
rtn
;
}
namespace
patchpoints
{
int
PatchpointInfo
::
patchpointSize
()
{
if
(
icinfo
)
{
int
r
=
icinfo
->
totalSize
();
assert
(
r
>
CALL_ONLY_SIZE
);
return
r
;
}
return
CALL_ONLY_SIZE
;
}
static
int
extractScratchOffset
(
PatchpointInfo
*
pp
,
StackMap
::
Record
*
r
)
{
StackMap
::
Record
::
Location
l
=
r
->
locations
[
pp
->
scratchStackmapArg
()];
static
const
int
DWARF_RBP_REGNUM
=
6
;
assert
(
l
.
type
==
StackMap
::
Record
::
Location
::
LocationType
::
Direct
);
assert
(
l
.
regnum
==
DWARF_RBP_REGNUM
);
return
l
.
offset
;
}
static
std
::
unordered_set
<
int
>
extractLiveOuts
(
StackMap
::
Record
*
r
,
llvm
::
CallingConv
::
ID
cc
)
{
std
::
unordered_set
<
int
>
live_outs
;
// Using the C calling convention, there shouldn't be any non-callee-save registers in here,
// but LLVM is conservative and will add some. So with the C cc, ignored the specified live outs
if
(
cc
!=
llvm
::
CallingConv
::
C
)
{
for
(
const
auto
&
live_out
:
r
->
live_outs
)
{
live_outs
.
insert
(
live_out
.
regnum
);
}
}
// llvm doesn't consider callee-save registers to be live
// if they're never allocated, but I think it makes much more
// sense to track them as live_outs.
// Unfortunately this means we need to be conservative about it unless
// we can change llvm's behavior.
live_outs
.
insert
(
3
);
live_outs
.
insert
(
12
);
live_outs
.
insert
(
13
);
live_outs
.
insert
(
14
);
live_outs
.
insert
(
15
);
return
live_outs
;
}
void
processStackmap
(
CompiledFunction
*
cf
,
StackMap
*
stackmap
)
{
int
nrecords
=
stackmap
?
stackmap
->
records
.
size
()
:
0
;
...
...
@@ -64,104 +104,97 @@ void processStackmap(CompiledFunction* cf, StackMap* stackmap) {
const
StackMap
::
StackSizeRecord
&
stack_size_record
=
stackmap
->
stack_size_records
[
0
];
int
stack_size
=
stack_size_record
.
stack_size
;
Patchpoint
SetupInfo
*
pp
=
new_patchpoints_by_id
[
r
->
id
]
;
Patchpoint
Info
*
pp
=
reinterpret_cast
<
PatchpointInfo
*>
(
r
->
id
)
;
assert
(
pp
);
bool
has_scratch
=
(
pp
->
numScratchBytes
()
!=
0
);
int
scratch_rbp_offset
=
0
;
if
(
has_scratch
)
{
assert
(
r
->
locations
.
size
()
==
1
);
if
(
VERBOSITY
())
printf
(
"Processing pp %ld
\n
"
,
reinterpret_cast
<
int64_t
>
(
pp
));
StackMap
::
Record
::
Location
l
=
r
->
locations
[
0
]
;
assert
(
r
->
locations
.
size
()
==
pp
->
totalStackmapArgs
())
;
static
const
int
DWARF_RBP_REGNUM
=
6
;
int
scratch_rbp_offset
=
extractScratchOffset
(
pp
,
r
);
int
scratch_size
=
pp
->
scratchSize
();
assert
(
scratch_size
%
sizeof
(
void
*
)
==
0
);
assert
(
scratch_rbp_offset
%
sizeof
(
void
*
)
==
0
);
assert
(
l
.
type
==
2
);
// "Direct"
assert
(
l
.
regnum
==
DWARF_RBP_REGNUM
);
scratch_rbp_offset
=
l
.
offset
;
}
else
{
assert
(
r
->
locations
.
size
()
==
0
);
}
uint8_t
*
start_addr
=
(
uint8_t
*
)
pp
->
parentFunction
()
->
code
+
r
->
offset
;
uint8_t
*
end_addr
=
start_addr
+
pp
->
patchpointSize
();
uint8_t
*
func_addr
=
(
uint8_t
*
)
pp
->
parent_cf
->
code
;
assert
(
func_addr
);
uint8_t
*
start_addr
=
func_addr
+
r
->
offset
;
const
ICSetupInfo
*
ic
=
pp
->
getICInfo
()
;
if
(
ic
==
NULL
)
continue
;
std
::
unordered_set
<
int
>
live_outs
;
for
(
const
auto
&
live_out
:
r
->
live_outs
)
{
live_outs
.
insert
(
live_out
.
regnum
);
}
std
::
unordered_set
<
int
>
live_outs
(
extractLiveOuts
(
r
,
ic
->
getCallingConvention
()));
// llvm doesn't consider callee-save registers to be live
// if they're never allocated, but I think it makes much more
// sense to track them as live_outs.
// Unfortunately this means we need to be conservative about it unless
// we can change llvm's behavior.
live_outs
.
insert
(
3
);
live_outs
.
insert
(
12
);
live_outs
.
insert
(
13
);
live_outs
.
insert
(
14
);
live_outs
.
insert
(
15
);
registerCompiledPatchpoint
(
cf
,
start_addr
,
pp
,
StackInfo
({
stack_size
,
has_scratch
,
pp
->
numScratchBytes
(),
scratch_rbp_offset
}),
registerCompiledPatchpoint
(
cf
,
start_addr
,
ic
,
StackInfo
({
stack_size
,
true
,
scratch_size
,
scratch_rbp_offset
}),
std
::
move
(
live_outs
));
}
for
(
const
std
::
pair
<
int64_t
,
PatchpointSetupInfo
*>&
p
:
new_patchpoints_by_id
)
{
delete
p
.
second
;
for
(
PatchpointInfo
*
pp
:
new_patchpoints
)
{
const
ICSetupInfo
*
ic
=
pp
->
getICInfo
();
if
(
ic
)
delete
ic
;
delete
pp
;
}
new_patchpoints_by_id
.
clear
();
new_patchpoints
.
clear
();
}
PatchpointInfo
*
PatchpointInfo
::
create
(
CompiledFunction
*
parent_cf
,
const
ICSetupInfo
*
icinfo
,
int
num_ic_stackmap_args
)
{
if
(
icinfo
==
NULL
)
assert
(
num_ic_stackmap_args
==
0
);
auto
*
r
=
new
PatchpointInfo
(
parent_cf
,
icinfo
,
num_ic_stackmap_args
);
new_patchpoints
.
push_back
(
r
);
return
r
;
}
PatchpointSetupInfo
*
createGenericPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
,
bool
has_return_value
,
int
size
)
{
return
PatchpointSetupInfo
::
initialize
(
has_return_value
,
1
,
size
,
parent_cf
,
Generic
,
type_recorder
);
ICSetupInfo
*
createGenericIC
(
TypeRecorder
*
type_recorder
,
bool
has_return_value
,
int
size
)
{
return
ICSetupInfo
::
initialize
(
has_return_value
,
1
,
size
,
ICSetupInfo
::
Generic
,
type_recorder
);
}
PatchpointSetupInfo
*
createGetattrPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
)
{
return
PatchpointSetupInfo
::
initialize
(
true
,
1
,
512
,
parent_cf
,
Getattr
,
type_recorder
);
ICSetupInfo
*
createGetattrIC
(
TypeRecorder
*
type_recorder
)
{
return
ICSetupInfo
::
initialize
(
true
,
1
,
512
,
ICSetupInfo
::
Getattr
,
type_recorder
);
}
PatchpointSetupInfo
*
createGetitemPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
)
{
return
PatchpointSetupInfo
::
initialize
(
true
,
1
,
512
,
parent_cf
,
Getitem
,
type_recorder
);
ICSetupInfo
*
createGetitemIC
(
TypeRecorder
*
type_recorder
)
{
return
ICSetupInfo
::
initialize
(
true
,
1
,
512
,
ICSetupInfo
::
Getitem
,
type_recorder
);
}
PatchpointSetupInfo
*
createSetitemPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
)
{
return
PatchpointSetupInfo
::
initialize
(
true
,
1
,
256
,
parent_cf
,
Setitem
,
type_recorder
);
ICSetupInfo
*
createSetitemIC
(
TypeRecorder
*
type_recorder
)
{
return
ICSetupInfo
::
initialize
(
true
,
1
,
256
,
ICSetupInfo
::
Setitem
,
type_recorder
);
}
PatchpointSetupInfo
*
createDelitemPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
)
{
return
PatchpointSetupInfo
::
initialize
(
false
,
1
,
256
,
parent_cf
,
Delitem
,
type_recorder
);
ICSetupInfo
*
createDelitemIC
(
TypeRecorder
*
type_recorder
)
{
return
ICSetupInfo
::
initialize
(
false
,
1
,
256
,
ICSetupInfo
::
Delitem
,
type_recorder
);
}
PatchpointSetupInfo
*
createSetattrPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
)
{
return
PatchpointSetupInfo
::
initialize
(
false
,
2
,
512
,
parent_cf
,
Setattr
,
type_recorder
);
ICSetupInfo
*
createSetattrIC
(
TypeRecorder
*
type_recorder
)
{
return
ICSetupInfo
::
initialize
(
false
,
2
,
512
,
ICSetupInfo
::
Setattr
,
type_recorder
);
}
PatchpointSetupInfo
*
createDelattrPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
)
{
return
PatchpointSetupInfo
::
initialize
(
false
,
1
,
144
,
parent_cf
,
Delattr
,
type_recorder
);
ICSetupInfo
*
createDelattrIC
(
TypeRecorder
*
type_recorder
)
{
return
ICSetupInfo
::
initialize
(
false
,
1
,
144
,
ICSetupInfo
::
Delattr
,
type_recorder
);
}
PatchpointSetupInfo
*
createCallsitePatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
,
int
num_args
)
{
ICSetupInfo
*
createCallsiteIC
(
TypeRecorder
*
type_recorder
,
int
num_args
)
{
// TODO These are very large, but could probably be made much smaller with IC optimizations
// - using rewriter2 for better code
// - not emitting duplicate guards
return
PatchpointSetupInfo
::
initialize
(
true
,
3
,
640
+
48
*
num_args
,
parent_cf
,
Callsite
,
type_recorder
);
return
ICSetupInfo
::
initialize
(
true
,
3
,
640
+
48
*
num_args
,
ICSetupInfo
::
Callsite
,
type_recorder
);
}
PatchpointSetupInfo
*
createGetGlobalPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
)
{
return
PatchpointSetupInfo
::
initialize
(
true
,
1
,
128
,
parent_cf
,
GetGlobal
,
type_recorder
);
ICSetupInfo
*
createGetGlobalIC
(
TypeRecorder
*
type_recorder
)
{
return
ICSetupInfo
::
initialize
(
true
,
1
,
128
,
ICSetupInfo
::
GetGlobal
,
type_recorder
);
}
PatchpointSetupInfo
*
createBinexpPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
)
{
return
PatchpointSetupInfo
::
initialize
(
true
,
4
,
512
,
parent_cf
,
Binexp
,
type_recorder
);
ICSetupInfo
*
createBinexpIC
(
TypeRecorder
*
type_recorder
)
{
return
ICSetupInfo
::
initialize
(
true
,
4
,
512
,
ICSetupInfo
::
Binexp
,
type_recorder
);
}
PatchpointSetupInfo
*
createNonzeroPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
)
{
return
PatchpointSetupInfo
::
initialize
(
true
,
2
,
64
,
parent_cf
,
Nonzero
,
type_recorder
);
ICSetupInfo
*
createNonzeroIC
(
TypeRecorder
*
type_recorder
)
{
return
ICSetupInfo
::
initialize
(
true
,
2
,
64
,
ICSetupInfo
::
Nonzero
,
type_recorder
);
}
}
// namespace patchpoints
}
// namespace pyston
src/codegen/patchpoints.h
View file @
dbc15587
...
...
@@ -20,85 +20,102 @@
#include "llvm/IR/CallingConv.h"
#include "codegen/stackmaps.h"
#include "core/common.h"
namespace
pyston
{
class
CompiledFunction
;
class
CompilerType
;
struct
StackMap
;
class
TypeRecorder
;
class
ICSetupInfo
;
namespace
patchpoints
{
enum
PatchpointType
{
Generic
,
Callsite
,
GetGlobal
,
Getattr
,
Setattr
,
Delattr
,
Getitem
,
Setitem
,
Delitem
,
Binexp
,
Nonzero
,
};
}
static
const
int
CALL_ONLY_SIZE
=
13
;
class
CompiledFunction
;
void
processStackmap
(
CompiledFunction
*
cf
,
StackMap
*
stackmap
)
;
class
PatchpointSetup
Info
{
struct
Patchpoint
Info
{
private:
PatchpointSetupInfo
(
int64_t
pp_id
,
patchpoints
::
PatchpointType
type
,
int
num_slots
,
int
slot_size
,
CompiledFunction
*
parent_cf
,
bool
has_return_value
,
TypeRecorder
*
type_recorder
)
:
pp_id
(
pp_id
),
type
(
type
),
num_slots
(
num_slots
),
slot_size
(
slot_size
),
has_return_value
(
has_return_value
),
parent_cf
(
parent_cf
),
type_recorder
(
type_recorder
)
{}
CompiledFunction
*
const
parent_cf
;
const
ICSetupInfo
*
icinfo
;
int
num_ic_stackmap_args
;
PatchpointInfo
(
CompiledFunction
*
parent_cf
,
const
ICSetupInfo
*
icinfo
,
int
num_ic_stackmap_args
)
:
parent_cf
(
parent_cf
),
icinfo
(
icinfo
),
num_ic_stackmap_args
(
num_ic_stackmap_args
)
{}
public:
const
ICSetupInfo
*
getICInfo
()
{
return
icinfo
;
}
int
patchpointSize
();
CompiledFunction
*
parentFunction
()
{
return
parent_cf
;
}
int
scratchStackmapArg
()
{
return
0
;
}
int
scratchSize
()
{
return
80
;
}
int
icStackmapArgsStart
()
{
return
1
;
}
int
numICStackmapArgs
()
{
return
num_ic_stackmap_args
;
}
const
int64_t
pp_id
;
int
totalStackmapArgs
()
{
return
icStackmapArgsStart
()
+
numICStackmapArgs
();
}
static
PatchpointInfo
*
create
(
CompiledFunction
*
parent_cf
,
const
ICSetupInfo
*
icinfo
,
int
num_ic_stackmap_args
);
};
class
ICSetupInfo
{
public:
const
patchpoints
::
PatchpointType
type
;
enum
ICType
{
Generic
,
Callsite
,
GetGlobal
,
Getattr
,
Setattr
,
Delattr
,
Getitem
,
Setitem
,
Delitem
,
Binexp
,
Nonzero
,
};
private:
ICSetupInfo
(
ICType
type
,
int
num_slots
,
int
slot_size
,
bool
has_return_value
,
TypeRecorder
*
type_recorder
)
:
type
(
type
),
num_slots
(
num_slots
),
slot_size
(
slot_size
),
has_return_value
(
has_return_value
),
type_recorder
(
type_recorder
)
{}
public:
const
ICType
type
;
const
int
num_slots
,
slot_size
;
const
bool
has_return_value
;
CompiledFunction
*
const
parent_cf
;
TypeRecorder
*
const
type_recorder
;
int
totalSize
()
const
;
int64_t
getPatchpointId
()
const
;
bool
hasReturnValue
()
const
{
return
has_return_value
;
}
int
numScratchBytes
()
const
{
return
64
;
}
llvm
::
CallingConv
::
ID
getCallingConvention
()
const
{
// The plan is to switch probably everything over to PreseveAll (and potentially AnyReg),
// but for only switch Getattr so the testing can be localized:
if
(
type
==
patchpoints
::
Getattr
||
type
==
patchpoints
::
Setattr
)
if
(
type
==
Getattr
||
type
==
Setattr
)
return
llvm
::
CallingConv
::
PreserveAll
;
return
llvm
::
CallingConv
::
C
;
}
static
PatchpointSetupInfo
*
initialize
(
bool
has_return_value
,
int
num_slots
,
int
slot_size
,
CompiledFunction
*
parent_cf
,
patchpoints
::
PatchpointType
type
,
TypeRecorder
*
type_recorder
);
static
ICSetupInfo
*
initialize
(
bool
has_return_value
,
int
num_slots
,
int
slot_size
,
ICType
type
,
TypeRecorder
*
type_recorder
);
};
struct
StackMap
;
namespace
patchpoints
{
void
processStackmap
(
CompiledFunction
*
cf
,
StackMap
*
stackmap
);
PatchpointSetupInfo
*
createGenericPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
,
bool
has_return_value
,
int
size
);
PatchpointSetupInfo
*
createCallsitePatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
,
int
num_args
);
PatchpointSetupInfo
*
createGetGlobalPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
);
PatchpointSetupInfo
*
createGetattrPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
);
PatchpointSetupInfo
*
createSetattrPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
);
PatchpointSetupInfo
*
createDelattrPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
);
PatchpointSetupInfo
*
createGetitemPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
);
PatchpointSetupInfo
*
createSetitemPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
);
PatchpointSetupInfo
*
createDelitemPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
);
PatchpointSetupInfo
*
createBinexpPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
);
PatchpointSetupInfo
*
createNonzeroPatchpoint
(
CompiledFunction
*
parent_cf
,
TypeRecorder
*
type_recorder
);
}
ICSetupInfo
*
createGenericIC
(
TypeRecorder
*
type_recorder
,
bool
has_return_value
,
int
size
);
ICSetupInfo
*
createCallsiteIC
(
TypeRecorder
*
type_recorder
,
int
num_args
);
ICSetupInfo
*
createGetGlobalIC
(
TypeRecorder
*
type_recorder
);
ICSetupInfo
*
createGetattrIC
(
TypeRecorder
*
type_recorder
);
ICSetupInfo
*
createSetattrIC
(
TypeRecorder
*
type_recorder
);
ICSetupInfo
*
createDelattrIC
(
TypeRecorder
*
type_recorder
);
ICSetupInfo
*
createGetitemIC
(
TypeRecorder
*
type_recorder
);
ICSetupInfo
*
createSetitemIC
(
TypeRecorder
*
type_recorder
);
ICSetupInfo
*
createDelitemIC
(
TypeRecorder
*
type_recorder
);
ICSetupInfo
*
createBinexpIC
(
TypeRecorder
*
type_recorder
);
ICSetupInfo
*
createNonzeroIC
(
TypeRecorder
*
type_recorder
);
}
// namespace pyston
...
...
src/codegen/stackmaps.h
View file @
dbc15587
...
...
@@ -32,7 +32,14 @@ struct StackMap {
struct
Record
{
struct
__attribute__
((
__packed__
))
Location
{
uint8_t
type
;
enum
LocationType
:
uint8_t
{
Register
=
0x1
,
Direct
=
0x2
,
Indirect
=
0x3
,
Constant
=
0x4
,
ConstIndex
=
0x5
,
}
type
;
uint8_t
flags
;
uint16_t
regnum
;
int32_t
offset
;
...
...
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