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
061e994b
Commit
061e994b
authored
Jun 24, 2016
by
Kevin Modzelewski
Committed by
Kevin Modzelewski
Jul 06, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move closure/generators out of the irgen symbol table
parent
8052061e
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
172 additions
and
168 deletions
+172
-168
src/analysis/function_analysis.cpp
src/analysis/function_analysis.cpp
+1
-1
src/analysis/function_analysis.h
src/analysis/function_analysis.h
+8
-0
src/analysis/type_analysis.cpp
src/analysis/type_analysis.cpp
+1
-1
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+2
-23
src/codegen/compvars.cpp
src/codegen/compvars.cpp
+6
-10
src/codegen/compvars.h
src/codegen/compvars.h
+1
-1
src/codegen/irgen.cpp
src/codegen/irgen.cpp
+38
-68
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+96
-62
src/codegen/irgen/irgenerator.h
src/codegen/irgen/irgenerator.h
+11
-0
src/core/cfg.cpp
src/core/cfg.cpp
+4
-2
src/core/types.h
src/core/types.h
+4
-0
No files found.
src/analysis/function_analysis.cpp
View file @
061e994b
...
...
@@ -585,7 +585,7 @@ std::unique_ptr<PhiAnalysis> computeRequiredPhis(const OSREntryDescriptor* entry
continue
;
if
(
p
.
first
.
s
()
==
PASSED_CLOSURE_NAME
||
p
.
first
.
s
()
==
FRAME_INFO_PTR_NAME
||
p
.
first
.
s
()
==
PASSED_GENERATOR_NAME
||
p
.
first
.
s
()
==
CREATED_CLOSURE_NAME
)
continue
;
assert
(
0
)
;
int
vreg
=
cfg
->
getVRegInfo
().
getVReg
(
p
.
first
);
ASSERT
(
initial_map
[
vreg
]
==
DefinednessAnalysis
::
Undefined
,
"%s %d"
,
p
.
first
.
c_str
(),
initial_map
[
vreg
]);
if
(
potentially_undefined
.
count
(
p
.
first
.
s
()))
...
...
src/analysis/function_analysis.h
View file @
061e994b
...
...
@@ -115,6 +115,14 @@ public:
v
[
vreg
]
=
true
;
}
int
numSet
()
const
{
int
r
=
0
;
for
(
auto
b
:
v
)
if
(
b
)
r
++
;
return
r
;
}
class
iterator
{
public:
const
VRegSet
&
set
;
...
...
src/analysis/type_analysis.cpp
View file @
061e994b
...
...
@@ -905,7 +905,7 @@ TypeAnalysis* doTypeAnalysis(const OSREntryDescriptor* entry_descriptor, EffortL
continue
;
if
(
p
.
first
.
s
()
==
PASSED_CLOSURE_NAME
||
p
.
first
.
s
()
==
FRAME_INFO_PTR_NAME
||
p
.
first
.
s
()
==
PASSED_GENERATOR_NAME
||
p
.
first
.
s
()
==
CREATED_CLOSURE_NAME
)
continue
;
assert
(
0
)
;
initial_types
[
vreg_info
.
getVReg
(
p
.
first
)]
=
p
.
second
;
}
...
...
src/codegen/ast_interpreter.cpp
View file @
061e994b
...
...
@@ -775,32 +775,12 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {
return
nullptr
;
}
if
(
generator
)
{
// generated is only borrowed in order to not introduce cycles
sorted_symbol_table
[
source_info
->
getInternedStrings
().
get
(
PASSED_GENERATOR_NAME
)]
=
generator
;
}
if
(
frame_info
.
passed_closure
)
sorted_symbol_table
[
source_info
->
getInternedStrings
().
get
(
PASSED_CLOSURE_NAME
)]
=
incref
(
frame_info
.
passed_closure
);
if
(
created_closure
)
sorted_symbol_table
[
source_info
->
getInternedStrings
().
get
(
CREATED_CLOSURE_NAME
)]
=
incref
(
created_closure
);
sorted_symbol_table
[
source_info
->
getInternedStrings
().
get
(
FRAME_INFO_PTR_NAME
)]
=
(
Box
*
)
&
frame_info
;
if
(
found_entry
==
nullptr
)
{
OSREntryDescriptor
*
entry
=
OSREntryDescriptor
::
create
(
getMD
(),
node
,
CXX
);
for
(
auto
&
it
:
sorted_symbol_table
)
{
if
(
isIsDefinedName
(
it
.
first
))
entry
->
args
[
it
.
first
]
=
BOOL
;
else
if
(
it
.
first
.
s
()
==
PASSED_GENERATOR_NAME
)
entry
->
args
[
it
.
first
]
=
GENERATOR
;
else
if
(
it
.
first
.
s
()
==
PASSED_CLOSURE_NAME
||
it
.
first
.
s
()
==
CREATED_CLOSURE_NAME
)
entry
->
args
[
it
.
first
]
=
CLOSURE
;
else
if
(
it
.
first
.
s
()
==
FRAME_INFO_PTR_NAME
)
entry
->
args
[
it
.
first
]
=
FRAME_INFO
;
else
{
assert
(
it
.
first
.
s
()[
0
]
!=
'!'
);
entry
->
args
[
it
.
first
]
=
UNKNOWN
;
...
...
@@ -821,9 +801,8 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {
UNAVOIDABLE_STAT_TIMER
(
t0
,
"us_timer_in_jitted_code"
);
CompiledFunction
*
partial_func
=
compilePartialFuncInternal
(
&
exit
);
auto
arg_tuple
=
getTupleFromArgsArray
(
&
arg_array
[
0
],
arg_array
.
size
());
Box
*
r
=
partial_func
->
call
(
std
::
get
<
0
>
(
arg_tuple
),
std
::
get
<
1
>
(
arg_tuple
),
std
::
get
<
2
>
(
arg_tuple
),
std
::
get
<
3
>
(
arg_tuple
));
// generated is only borrowed in order to not introduce cycles
Box
*
r
=
partial_func
->
call_osr
(
generator
,
created_closure
,
&
frame_info
,
&
arg_array
[
0
]);
if
(
partial_func
->
exception_style
==
CXX
)
{
assert
(
r
);
...
...
src/codegen/compvars.cpp
View file @
061e994b
...
...
@@ -821,19 +821,15 @@ ConcreteCompilerVariable* UnknownType::hasnext(IREmitter& emitter, const OpInfo&
return
boolFromI1
(
emitter
,
rtn_val
);
}
CompilerVariable
*
makeFunction
(
IREmitter
&
emitter
,
FunctionMetadata
*
f
,
CompilerVariabl
e
*
closure
,
llvm
::
Value
*
globals
,
CompilerVariable
*
makeFunction
(
IREmitter
&
emitter
,
FunctionMetadata
*
f
,
llvm
::
Valu
e
*
closure
,
llvm
::
Value
*
globals
,
const
std
::
vector
<
ConcreteCompilerVariable
*>&
defaults
)
{
// Unlike the FunctionMetadata*, which can be shared between recompilations, the Box* around it
// should be created anew every time the functiondef is encountered
llvm
::
Value
*
closure_v
;
ConcreteCompilerVariable
*
convertedClosure
=
NULL
;
if
(
closure
)
{
convertedClosure
=
closure
->
makeConverted
(
emitter
,
closure
->
getConcreteType
());
closure_v
=
convertedClosure
->
getValue
();
}
else
{
closure_v
=
getNullPtr
(
g
.
llvm_closure_type_ptr
);
emitter
.
setType
(
closure_v
,
RefType
::
BORROWED
);
if
(
!
closure
)
{
closure
=
getNullPtr
(
g
.
llvm_closure_type_ptr
);
emitter
.
setType
(
closure
,
RefType
::
BORROWED
);
}
llvm
::
SmallVector
<
llvm
::
Value
*
,
4
>
array_passed_args
;
...
...
@@ -860,8 +856,8 @@ CompilerVariable* makeFunction(IREmitter& emitter, FunctionMetadata* f, Compiler
// emitter.createCall().
llvm
::
Instruction
*
boxed
=
emitter
.
getBuilder
()
->
CreateCall
(
g
.
funcs
.
createFunctionFromMetadata
,
std
::
vector
<
llvm
::
Value
*>
{
embedRelocatablePtr
(
f
,
g
.
llvm_functionmetadata_type_ptr
),
closure
_v
,
globals
,
scratch
,
getConstantInt
(
defaults
.
size
(),
g
.
i64
)
});
std
::
vector
<
llvm
::
Value
*>
{
embedRelocatablePtr
(
f
,
g
.
llvm_functionmetadata_type_ptr
),
closure
,
globals
,
scratch
,
getConstantInt
(
defaults
.
size
(),
g
.
i64
)
});
emitter
.
setType
(
boxed
,
RefType
::
OWNED
);
// The refcounter needs to know that this call "uses" the arguments that got passed via scratch.
...
...
src/codegen/compvars.h
View file @
061e994b
...
...
@@ -361,7 +361,7 @@ UnboxedSlice extractSlice(CompilerVariable* slice);
#if 0
CompilerVariable* makeUnicode(IREmitter& emitter, llvm::StringRef);
#endif
CompilerVariable
*
makeFunction
(
IREmitter
&
emitter
,
FunctionMetadata
*
,
CompilerVariabl
e
*
closure
,
llvm
::
Value
*
globals
,
CompilerVariable
*
makeFunction
(
IREmitter
&
emitter
,
FunctionMetadata
*
,
llvm
::
Valu
e
*
closure
,
llvm
::
Value
*
globals
,
const
std
::
vector
<
ConcreteCompilerVariable
*>&
defaults
);
ConcreteCompilerVariable
*
undefVariable
();
CompilerVariable
*
makeTuple
(
const
std
::
vector
<
CompilerVariable
*>&
elts
);
...
...
src/codegen/irgen.cpp
View file @
061e994b
...
...
@@ -290,12 +290,6 @@ static ConcreteCompilerType* getTypeAtBlockStart(TypeAnalysis* types, InternedSt
CFGBlock
*
block
)
{
if
(
isIsDefinedName
(
name
))
return
BOOL
;
else
if
(
name
.
s
()
==
PASSED_GENERATOR_NAME
)
return
GENERATOR
;
else
if
(
name
.
s
()
==
PASSED_CLOSURE_NAME
)
return
CLOSURE
;
else
if
(
name
.
s
()
==
CREATED_CLOSURE_NAME
)
return
CLOSURE
;
else
{
// This could crash if we call getTypeAtBlockStart on something that doesn't have a type or vreg.
// Luckily it looks like we don't do that.
...
...
@@ -306,7 +300,7 @@ static ConcreteCompilerType* getTypeAtBlockStart(TypeAnalysis* types, InternedSt
static
bool
shouldPhisOwnThisSym
(
llvm
::
StringRef
name
)
{
// generating unnecessary increfs to the passed generator would introduce cycles inside the generator
if
(
name
==
PASSED_GENERATOR_NAME
)
return
false
;
assert
(
0
)
;
return
true
;
}
...
...
@@ -384,7 +378,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
llvm_entry_blocks
[
block
]
=
llvm
::
BasicBlock
::
Create
(
g
.
context
,
buf
,
irstate
->
getLLVMFunction
());
}
llvm
::
Value
*
osr_frame_info_arg
=
NULL
;
llvm
::
Value
*
osr_frame_info_arg
=
NULL
,
*
osr_generator
=
NULL
,
*
osr_created_closure
=
NULL
;
// the function entry block, where we add the type guards [no guards anymore]
llvm
::
BasicBlock
*
osr_entry_block
=
NULL
;
...
...
@@ -415,24 +409,25 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
}
// Handle loading symbols from the passed osr arguments:
osr_generator
=
func_args
[
0
];
osr_created_closure
=
func_args
[
1
];
osr_frame_info_arg
=
func_args
[
2
];
llvm
::
Value
*
passed_vars
=
func_args
[
3
];
assert
(
func_args
.
size
()
==
4
);
irstate
->
getRefcounts
()
->
setType
(
osr_generator
,
RefType
::
BORROWED
);
irstate
->
getRefcounts
()
->
setType
(
osr_created_closure
,
RefType
::
BORROWED
);
if
(
source
->
is_generator
)
irstate
->
setPassedGenerator
(
osr_generator
);
if
(
source
->
getScopeInfo
()
->
createsClosure
())
irstate
->
setCreatedClosure
(
osr_created_closure
);
int
arg_num
=
-
1
;
for
(
const
auto
&
p
:
entry_descriptor
->
args
)
{
llvm
::
Value
*
from_arg
;
arg_num
++
;
if
(
arg_num
<
3
)
{
from_arg
=
func_args
[
arg_num
];
#ifndef NDEBUG
if
(
from_arg
->
getType
()
!=
p
.
second
->
llvmType
())
{
from_arg
->
getType
()
->
dump
();
printf
(
"
\n
"
);
p
.
second
->
llvmType
()
->
dump
();
printf
(
"
\n
"
);
}
#endif
assert
(
from_arg
->
getType
()
==
p
.
second
->
llvmType
());
}
else
{
ASSERT
(
func_args
.
size
()
==
4
,
"%ld"
,
func_args
.
size
());
llvm
::
Value
*
ptr
=
entry_emitter
->
getBuilder
()
->
CreateConstGEP1_32
(
func_args
[
3
],
arg_num
-
3
);
llvm
::
Value
*
ptr
=
entry_emitter
->
getBuilder
()
->
CreateConstGEP1_32
(
passed_vars
,
arg_num
);
if
(
p
.
second
==
INT
)
{
ptr
=
entry_emitter
->
getBuilder
()
->
CreateBitCast
(
ptr
,
g
.
i64
->
getPointerTo
());
}
else
if
(
p
.
second
==
BOOL
)
{
...
...
@@ -451,14 +446,6 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
}
from_arg
=
entry_emitter
->
getBuilder
()
->
CreateLoad
(
ptr
);
assert
(
from_arg
->
getType
()
==
p
.
second
->
llvmType
());
}
if
(
from_arg
->
getType
()
==
g
.
llvm_frame_info_type
->
getPointerTo
())
{
assert
(
p
.
first
.
s
()
==
FRAME_INFO_PTR_NAME
);
osr_frame_info_arg
=
from_arg
;
// Don't add the frame info to the symbol table since we will store it separately:
continue
;
}
ConcreteCompilerType
*
phi_type
;
phi_type
=
getTypeAtBlockStart
(
types
,
p
.
first
,
vreg_info
,
target_block
);
...
...
@@ -665,17 +652,6 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
}
}
if
(
source
->
getScopeInfo
()
->
createsClosure
())
names
.
insert
(
source
->
getInternedStrings
().
get
(
CREATED_CLOSURE_NAME
));
if
(
source
->
getScopeInfo
()
->
takesClosure
())
names
.
insert
(
source
->
getInternedStrings
().
get
(
PASSED_CLOSURE_NAME
));
if
(
source
->
is_generator
)
{
assert
(
0
&&
"not sure if this is correct"
);
names
.
insert
(
source
->
getInternedStrings
().
get
(
PASSED_GENERATOR_NAME
));
}
for
(
const
InternedString
&
s
:
names
)
{
// printf("adding guessed phi for %s\n", s.c_str());
ConcreteCompilerType
*
type
=
getTypeAtBlockStart
(
types
,
s
,
vreg_info
,
block
);
...
...
@@ -1062,17 +1038,11 @@ CompiledFunction* doCompile(FunctionMetadata* md, SourceInfo* source, ParamNames
llvm_arg_types
.
push_back
(
spec
->
arg_types
[
i
]
->
llvmType
());
}
}
else
{
int
arg_num
=
-
1
;
for
(
const
auto
&
p
:
entry_descriptor
->
args
)
{
arg_num
++
;
// printf("Loading %s: %s\n", p.first.c_str(), p.second->debugName().c_str());
if
(
arg_num
<
3
)
llvm_arg_types
.
push_back
(
p
.
second
->
llvmType
());
else
{
// For simplicity, OSR entries always take all possible arguments:
llvm_arg_types
.
push_back
(
g
.
llvm_generator_type_ptr
);
llvm_arg_types
.
push_back
(
g
.
llvm_closure_type_ptr
);
llvm_arg_types
.
push_back
(
g
.
llvm_frame_info_type
->
getPointerTo
());
llvm_arg_types
.
push_back
(
g
.
llvm_value_type_ptr
->
getPointerTo
());
break
;
}
}
}
CompiledFunction
*
cf
=
new
CompiledFunction
(
NULL
,
spec
,
NULL
,
effort
,
exception_style
,
entry_descriptor
);
...
...
src/codegen/irgen/irgenerator.cpp
View file @
061e994b
...
...
@@ -68,6 +68,38 @@ IRGenState::IRGenState(FunctionMetadata* md, CompiledFunction* cf, SourceInfo* s
IRGenState
::~
IRGenState
()
{
}
llvm
::
Value
*
IRGenState
::
getPassedClosure
()
{
assert
(
getScopeInfo
()
->
takesClosure
());
assert
(
passed_closure
);
return
passed_closure
;
}
llvm
::
Value
*
IRGenState
::
getCreatedClosure
()
{
assert
(
getScopeInfo
()
->
createsClosure
());
assert
(
created_closure
);
return
created_closure
;
}
llvm
::
Value
*
IRGenState
::
getPassedGenerator
()
{
assert
(
source_info
->
is_generator
);
assert
(
passed_generator
);
return
passed_generator
;
}
void
IRGenState
::
setPassedClosure
(
llvm
::
Value
*
v
)
{
assert
(
getScopeInfo
()
->
takesClosure
());
assert
(
!
passed_closure
);
passed_closure
=
v
;
}
void
IRGenState
::
setCreatedClosure
(
llvm
::
Value
*
v
)
{
assert
(
getScopeInfo
()
->
createsClosure
());
assert
(
!
created_closure
);
created_closure
=
v
;
}
void
IRGenState
::
setPassedGenerator
(
llvm
::
Value
*
v
)
{
assert
(
source_info
->
is_generator
);
assert
(
!
passed_generator
);
passed_generator
=
v
;
}
llvm
::
Value
*
IRGenState
::
getScratchSpace
(
int
min_bytes
)
{
llvm
::
BasicBlock
&
entry_block
=
getLLVMFunction
()
->
getEntryBlock
();
...
...
@@ -238,6 +270,11 @@ void IRGenState::setupFrameInfoVar(llvm::Value* passed_closure, llvm::Value* pas
getRefcounts
()
->
setType
(
this
->
boxed_locals
,
RefType
::
BORROWED
);
}
if
(
getScopeInfo
()
->
takesClosure
())
{
passed_closure
=
builder
.
CreateLoad
(
getPassedClosureGep
(
builder
,
frame_info_arg
));
getRefcounts
()
->
setType
(
passed_closure
,
RefType
::
BORROWED
);
this
->
setPassedClosure
(
passed_closure
);
}
}
else
{
// The "normal" case
llvm
::
AllocaInst
*
al
=
builder
.
CreateAlloca
(
g
.
llvm_frame_info_type
,
NULL
,
"frame_info"
);
...
...
@@ -1333,8 +1370,8 @@ private:
// closure = closure->parent;
// closure->elts[deref_info.offset]
// Where the parent lookup is done `deref_info.num_parents_from_passed_closure` times
CompilerVariable
*
closure
=
symbol_table
[
internString
(
PASSED_CLOSURE_NAME
)]
;
llvm
::
Value
*
closureValue
=
closure
->
makeConverted
(
emitter
,
CLOSURE
)
->
getValue
(
);
llvm
::
Value
*
closureValue
=
irstate
->
getPassedClosure
()
;
assert
(
closureValue
);
for
(
int
i
=
0
;
i
<
deref_info
.
num_parents_from_passed_closure
;
i
++
)
{
closureValue
=
emitter
.
getBuilder
()
->
CreateLoad
(
getClosureParentGep
(
emitter
,
closureValue
));
emitter
.
setType
(
closureValue
,
RefType
::
BORROWED
);
...
...
@@ -1543,15 +1580,11 @@ private:
}
CompilerVariable
*
evalYield
(
AST_Yield
*
node
,
const
UnwindInfo
&
unw_info
)
{
CompilerVariable
*
generator
=
symbol_table
[
internString
(
PASSED_GENERATOR_NAME
)];
assert
(
generator
);
ConcreteCompilerVariable
*
convertedGenerator
=
generator
->
makeConverted
(
emitter
,
generator
->
getBoxType
());
CompilerVariable
*
value
=
node
->
value
?
evalExpr
(
node
->
value
,
unw_info
)
:
emitter
.
getNone
();
ConcreteCompilerVariable
*
convertedValue
=
value
->
makeConverted
(
emitter
,
value
->
getBoxType
());
std
::
vector
<
llvm
::
Value
*>
args
;
args
.
push_back
(
convertedGenerator
->
getValue
());
args
.
push_back
(
irstate
->
getPassedGenerator
());
args
.
push_back
(
convertedValue
->
getValue
());
args
.
push_back
(
getConstantInt
(
0
,
g
.
i32
));
// the refcounting inserter handles yields specially and adds all
// owned objects as additional arguments to it
...
...
@@ -1594,15 +1627,15 @@ private:
FunctionMetadata
*
md
=
wrapFunction
(
node
,
nullptr
,
node
->
body
,
irstate
->
getSourceInfo
());
// TODO duplication with _createFunction:
CompilerVariable
*
created
_closure
=
NULL
;
llvm
::
Value
*
this
_closure
=
NULL
;
if
(
scope_info
->
takesClosure
())
{
if
(
irstate
->
getScopeInfo
()
->
createsClosure
())
{
created_closure
=
symbol_table
[
internString
(
CREATED_CLOSURE_NAME
)]
;
this_closure
=
irstate
->
getCreatedClosure
()
;
}
else
{
assert
(
irstate
->
getScopeInfo
()
->
passesThroughClosure
());
created_closure
=
symbol_table
[
internString
(
PASSED_CLOSURE_NAME
)]
;
this_closure
=
irstate
->
getPassedClosure
()
;
}
assert
(
created
_closure
);
assert
(
this
_closure
);
}
// TODO kind of silly to create the function just to usually-delete it afterwards;
...
...
@@ -1610,7 +1643,7 @@ private:
// but since the classdef can't create its own closure, shouldn't need to explicitly
// create that scope to pass the closure through.
assert
(
irstate
->
getSourceInfo
()
->
scoping
->
areGlobalsFromModule
());
CompilerVariable
*
func
=
makeFunction
(
emitter
,
md
,
created
_closure
,
irstate
->
getGlobalsIfCustom
(),
{});
CompilerVariable
*
func
=
makeFunction
(
emitter
,
md
,
this
_closure
,
irstate
->
getGlobalsIfCustom
(),
{});
CompilerVariable
*
attr_dict
=
func
->
call
(
emitter
,
getEmptyOpInfo
(
unw_info
),
ArgPassSpec
(
0
),
{},
NULL
);
...
...
@@ -1643,8 +1676,6 @@ private:
defaults
.
push_back
(
converted
);
}
CompilerVariable
*
created_closure
=
NULL
;
bool
takes_closure
;
// Optimization: when compiling a module, it's nice to not have to run analyses into the
// entire module's source code.
...
...
@@ -1659,17 +1690,18 @@ private:
bool
is_generator
=
md
->
source
->
is_generator
;
llvm
::
Value
*
this_closure
=
NULL
;
if
(
takes_closure
)
{
if
(
irstate
->
getScopeInfo
()
->
createsClosure
())
{
created_closure
=
symbol_table
[
internString
(
CREATED_CLOSURE_NAME
)]
;
this_closure
=
irstate
->
getCreatedClosure
()
;
}
else
{
assert
(
irstate
->
getScopeInfo
()
->
passesThroughClosure
());
created_closure
=
symbol_table
[
internString
(
PASSED_CLOSURE_NAME
)]
;
this_closure
=
irstate
->
getPassedClosure
()
;
}
assert
(
created
_closure
);
assert
(
this
_closure
);
}
CompilerVariable
*
func
=
makeFunction
(
emitter
,
md
,
created
_closure
,
irstate
->
getGlobalsIfCustom
(),
defaults
);
CompilerVariable
*
func
=
makeFunction
(
emitter
,
md
,
this
_closure
,
irstate
->
getGlobalsIfCustom
(),
defaults
);
return
func
;
}
...
...
@@ -1959,9 +1991,7 @@ private:
size_t
offset
=
irstate
->
getScopeInfo
()
->
getClosureOffset
(
name
);
// This is basically `closure->elts[offset] = val;`
CompilerVariable
*
closure
=
symbol_table
[
internString
(
CREATED_CLOSURE_NAME
)];
llvm
::
Value
*
closureValue
=
closure
->
makeConverted
(
emitter
,
CLOSURE
)
->
getValue
();
llvm
::
Value
*
gep
=
getClosureElementGep
(
emitter
,
closureValue
,
offset
);
llvm
::
Value
*
gep
=
getClosureElementGep
(
emitter
,
irstate
->
getCreatedClosure
(),
offset
);
if
(
prev
)
{
auto
load
=
emitter
.
getBuilder
()
->
CreateLoad
(
gep
);
emitter
.
setType
(
load
,
RefType
::
OWNED
);
...
...
@@ -2313,6 +2343,8 @@ private:
void
doExpr
(
AST_Expr
*
node
,
const
UnwindInfo
&
unw_info
)
{
CompilerVariable
*
var
=
evalExpr
(
node
->
value
,
unw_info
);
}
void
doOSRExit
(
llvm
::
BasicBlock
*
normal_target
,
AST_Jump
*
osr_key
)
{
RELEASE_ASSERT
(
0
,
"I don't think this can get hit any more and it has not been updated"
);
#if 0
llvm::BasicBlock* starting_block = curblock;
llvm::BasicBlock* onramp = llvm::BasicBlock::Create(g.context, "onramp", irstate->getLLVMFunction());
...
...
@@ -2468,6 +2500,7 @@ private:
emitter.getBuilder()->CreateRet(rtn);
emitter.getBuilder()->SetInsertPoint(starting_block);
#endif
}
void
doJump
(
AST_Jump
*
node
,
const
UnwindInfo
&
unw_info
)
{
...
...
@@ -2631,11 +2664,7 @@ private:
_doSet
(
name
,
var
,
unw_info
);
}
bool
allowableFakeEndingSymbol
(
InternedString
name
)
{
// TODO this would be a great place to be able to use interned versions of the static names...
return
isIsDefinedName
(
name
.
s
())
||
name
.
s
()
==
PASSED_CLOSURE_NAME
||
name
.
s
()
==
CREATED_CLOSURE_NAME
||
name
.
s
()
==
PASSED_GENERATOR_NAME
;
}
bool
allowableFakeEndingSymbol
(
InternedString
name
)
{
return
isIsDefinedName
(
name
.
s
());
}
void
endBlock
(
State
new_state
)
{
assert
(
state
==
RUNNING
);
...
...
@@ -2743,6 +2772,24 @@ public:
// nice for debugging though.
typedef
std
::
pair
<
InternedString
,
CompilerVariable
*>
Entry
;
std
::
vector
<
Entry
>
sorted_symbol_table
(
symbol_table
.
begin
(),
symbol_table
.
end
());
// TODO: at some point it would be nice to pass these separately
auto
source
=
irstate
->
getSourceInfo
();
if
(
source
->
is_generator
)
sorted_symbol_table
.
push_back
(
Entry
(
source
->
getInternedStrings
().
get
(
PASSED_GENERATOR_NAME
),
new
ConcreteCompilerVariable
(
GENERATOR
,
irstate
->
getPassedGenerator
())));
auto
scoping
=
source
->
getScopeInfo
();
if
(
scoping
->
takesClosure
())
sorted_symbol_table
.
push_back
(
Entry
(
source
->
getInternedStrings
().
get
(
PASSED_CLOSURE_NAME
),
new
ConcreteCompilerVariable
(
CLOSURE
,
irstate
->
getPassedClosure
())));
if
(
scoping
->
createsClosure
())
sorted_symbol_table
.
push_back
(
Entry
(
source
->
getInternedStrings
().
get
(
CREATED_CLOSURE_NAME
),
new
ConcreteCompilerVariable
(
CLOSURE
,
irstate
->
getCreatedClosure
())));
std
::
sort
(
sorted_symbol_table
.
begin
(),
sorted_symbol_table
.
end
(),
[](
const
Entry
&
lhs
,
const
Entry
&
rhs
)
{
return
lhs
.
first
<
rhs
.
first
;
});
for
(
const
auto
&
p
:
sorted_symbol_table
)
{
...
...
@@ -2810,13 +2857,13 @@ public:
assert
(
it
->
second
->
getType
()
==
BOOL
);
ending_type
=
BOOL
;
}
else
if
(
it
->
first
.
s
()
==
PASSED_CLOSURE_NAME
)
{
ending_type
=
getPassedClosureType
(
);
RELEASE_ASSERT
(
0
,
""
);
}
else
if
(
it
->
first
.
s
()
==
CREATED_CLOSURE_NAME
)
{
ending_type
=
getCreatedClosureType
(
);
RELEASE_ASSERT
(
0
,
""
);
}
else
if
(
it
->
first
.
s
()
==
PASSED_GENERATOR_NAME
)
{
ending_type
=
GENERATOR
;
RELEASE_ASSERT
(
0
,
""
)
;
}
else
if
(
it
->
first
.
s
()
==
FRAME_INFO_PTR_NAME
)
{
ending_type
=
FRAME_INFO
;
RELEASE_ASSERT
(
0
,
""
)
;
}
else
{
ending_type
=
types
->
getTypeAtBlockEnd
(
vreg_info
.
getVReg
(
it
->
first
),
myblock
);
}
...
...
@@ -2834,6 +2881,9 @@ public:
void
giveLocalSymbol
(
InternedString
name
,
CompilerVariable
*
var
)
override
{
assert
(
name
.
s
()
!=
"None"
);
assert
(
name
.
s
()
!=
FRAME_INFO_PTR_NAME
);
assert
(
name
.
s
()
!=
CREATED_CLOSURE_NAME
);
assert
(
name
.
s
()
!=
PASSED_CLOSURE_NAME
);
assert
(
name
.
s
()
!=
PASSED_GENERATOR_NAME
);
ASSERT
(
irstate
->
getScopeInfo
()
->
getScopeTypeOfName
(
name
)
!=
ScopeInfo
::
VarScopeType
::
GLOBAL
,
"%s"
,
name
.
c_str
());
...
...
@@ -2854,39 +2904,32 @@ public:
}
}
ConcreteCompilerType
*
getPassedClosureType
()
{
// TODO could know the exact closure shape
return
CLOSURE
;
}
ConcreteCompilerType
*
getCreatedClosureType
()
{
// TODO could know the exact closure shape
return
CLOSURE
;
}
void
doFunctionEntry
(
const
ParamNames
&
param_names
,
const
std
::
vector
<
ConcreteCompilerType
*>&
arg_types
)
override
{
assert
(
param_names
.
totalParameters
()
==
arg_types
.
size
());
auto
scope_info
=
irstate
->
getScopeInfo
();
// TODO: move this to irgen.cpp?
llvm
::
Function
::
arg_iterator
AI
=
irstate
->
getLLVMFunction
()
->
arg_begin
();
llvm
::
Value
*
passed_closure
=
NULL
;
llvm
::
Value
*
generator
=
NULL
;
llvm
::
Value
*
globals
=
NULL
;
llvm
::
Value
*
passed_closure_or_null
;
if
(
scope_info
->
takesClosure
())
{
passed_closure
=
AI
;
passed_closure_or_null
=
AI
;
irstate
->
setPassedClosure
(
passed_closure_or_null
);
++
AI
;
emitter
.
setType
(
passed_closure
,
RefType
::
BORROWED
);
emitter
.
setType
(
passed_closure
_or_null
,
RefType
::
BORROWED
);
}
else
{
passed_closure
=
getNullPtr
(
g
.
llvm_closure_type_ptr
);
emitter
.
setType
(
passed_closure
,
RefType
::
BORROWED
);
passed_closure
_or_null
=
getNullPtr
(
g
.
llvm_closure_type_ptr
);
emitter
.
setType
(
passed_closure
_or_null
,
RefType
::
BORROWED
);
}
if
(
irstate
->
getSourceInfo
()
->
is_generator
)
{
generator
=
AI
;
emitter
.
setType
(
generator
,
RefType
::
BORROWED
);
auto
passed_generator
=
AI
;
irstate
->
setPassedGenerator
(
passed_generator
);
emitter
.
setType
(
passed_generator
,
RefType
::
BORROWED
);
++
AI
;
}
...
...
@@ -2900,24 +2943,15 @@ public:
emitter
.
setType
(
globals
,
RefType
::
BORROWED
);
}
irstate
->
setupFrameInfoVar
(
passed_closure
,
globals
);
if
(
scope_info
->
takesClosure
())
{
symbol_table
[
internString
(
PASSED_CLOSURE_NAME
)]
=
new
ConcreteCompilerVariable
(
getPassedClosureType
(),
passed_closure
);
}
irstate
->
setupFrameInfoVar
(
passed_closure_or_null
,
globals
);
if
(
scope_info
->
createsClosure
())
{
llvm
::
Value
*
new_closure
=
emitter
.
getBuilder
()
->
CreateCall2
(
g
.
funcs
.
createClosure
,
passed_closure
,
getConstantInt
(
scope_info
->
getClosureSize
(),
g
.
i64
));
emitter
.
setType
(
new_closure
,
RefType
::
OWNED
);
symbol_table
[
internString
(
CREATED_CLOSURE_NAME
)]
=
new
ConcreteCompilerVariable
(
getCreatedClosureType
(),
new_closure
);
auto
created_closure
=
emitter
.
getBuilder
()
->
CreateCall2
(
g
.
funcs
.
createClosure
,
passed_closure_or_null
,
getConstantInt
(
scope_info
->
getClosureSize
(),
g
.
i64
));
irstate
->
setCreatedClosure
(
created_closure
);
emitter
.
setType
(
created_closure
,
RefType
::
OWNED
);
}
if
(
irstate
->
getSourceInfo
()
->
is_generator
)
symbol_table
[
internString
(
PASSED_GENERATOR_NAME
)]
=
new
ConcreteCompilerVariable
(
GENERATOR
,
generator
);
std
::
vector
<
llvm
::
Value
*>
python_parameters
;
for
(
int
i
=
0
;
i
<
arg_types
.
size
();
i
++
)
{
assert
(
AI
!=
irstate
->
getLLVMFunction
()
->
arg_end
());
...
...
src/codegen/irgen/irgenerator.h
View file @
061e994b
...
...
@@ -75,6 +75,9 @@ private:
llvm
::
Value
*
globals
;
llvm
::
Value
*
vregs
;
llvm
::
Value
*
stmt
;
llvm
::
Value
*
passed_closure
=
NULL
,
*
created_closure
=
NULL
,
*
passed_generator
=
NULL
;
int
scratch_size
;
public:
...
...
@@ -121,6 +124,14 @@ public:
ParamNames
*
getParamNames
()
{
return
param_names
;
}
llvm
::
Value
*
getPassedClosure
();
llvm
::
Value
*
getCreatedClosure
();
llvm
::
Value
*
getPassedGenerator
();
void
setPassedClosure
(
llvm
::
Value
*
);
void
setCreatedClosure
(
llvm
::
Value
*
);
void
setPassedGenerator
(
llvm
::
Value
*
);
// Returns the custom globals, or the module if the globals come from the module.
llvm
::
Value
*
getGlobals
();
// Returns the custom globals, or null if the globals come from the module.
...
...
src/core/cfg.cpp
View file @
061e994b
...
...
@@ -517,9 +517,11 @@ private:
return
node
;
}
void
pushJump
(
CFGBlock
*
target
,
bool
allow_backedge
=
false
)
{
void
pushJump
(
CFGBlock
*
target
,
bool
allow_backedge
=
false
,
int
lineno
=
0
)
{
AST_Jump
*
rtn
=
new
AST_Jump
();
rtn
->
target
=
target
;
rtn
->
lineno
=
lineno
;
push_back
(
rtn
);
curblock
->
connectTo
(
target
,
allow_backedge
);
curblock
=
nullptr
;
...
...
@@ -2264,7 +2266,7 @@ public:
curblock
->
connectTo
(
end_false
);
curblock
=
end_true
;
pushJump
(
loop_block
,
true
);
pushJump
(
loop_block
,
true
,
getLastLinenoSub
(
node
->
body
.
back
())
);
curblock
=
end_false
;
pushJump
(
else_block
);
...
...
src/core/types.h
View file @
061e994b
...
...
@@ -316,6 +316,7 @@ class BoxedGenerator;
class
ICInfo
;
class
LocationMap
;
class
JitCodeBlock
;
class
FrameInfo
;
extern
std
::
vector
<
Box
*>
constants
;
extern
std
::
vector
<
Box
*>
late_constants
;
// constants that should be freed after normal constants
...
...
@@ -346,6 +347,8 @@ public:
// The function pointer to the generated code. For convenience, it can be accessed
// as one of many different types.
// TODO: we instead make these functions that make sure that the function actually
// matches the C signature that we would return.
union
{
Box
*
(
*
call
)(
Box
*
,
Box
*
,
Box
*
,
Box
**
);
Box
*
(
*
closure_call
)(
BoxedClosure
*
,
Box
*
,
Box
*
,
Box
*
,
Box
**
);
...
...
@@ -354,6 +357,7 @@ public:
Box
*
(
*
call1
)(
Box
*
,
Box
*
,
Box
*
,
Box
*
,
Box
**
);
Box
*
(
*
call2
)(
Box
*
,
Box
*
,
Box
*
,
Box
*
,
Box
*
,
Box
**
);
Box
*
(
*
call3
)(
Box
*
,
Box
*
,
Box
*
,
Box
*
,
Box
*
,
Box
*
,
Box
**
);
Box
*
(
*
call_osr
)(
BoxedGenerator
*
,
BoxedClosure
*
,
FrameInfo
*
,
Box
**
);
void
*
code
;
uintptr_t
code_start
;
};
...
...
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