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
8052061e
Commit
8052061e
authored
Jun 21, 2016
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change analysis APIs to take vregs
parent
18c6b30c
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
57 additions
and
61 deletions
+57
-61
src/analysis/function_analysis.cpp
src/analysis/function_analysis.cpp
+9
-20
src/analysis/function_analysis.h
src/analysis/function_analysis.h
+5
-5
src/analysis/type_analysis.cpp
src/analysis/type_analysis.cpp
+10
-12
src/analysis/type_analysis.h
src/analysis/type_analysis.h
+2
-2
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+2
-2
src/codegen/irgen.cpp
src/codegen/irgen.cpp
+12
-7
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+17
-13
No files found.
src/analysis/function_analysis.cpp
View file @
8052061e
...
...
@@ -415,11 +415,10 @@ void DefinednessAnalysis::run(VRegMap<DefinednessAnalysis::DefinitionLevel> init
us_definedness
.
log
(
_t
.
end
());
}
DefinednessAnalysis
::
DefinitionLevel
DefinednessAnalysis
::
isDefinedAtEnd
(
InternedString
name
,
CFGBlock
*
block
)
{
DefinednessAnalysis
::
DefinitionLevel
DefinednessAnalysis
::
isDefinedAtEnd
(
int
vreg
,
CFGBlock
*
block
)
{
assert
(
defined_at_end
.
count
(
block
));
auto
&&
map
=
defined_at_end
.
find
(
block
)
->
second
;
auto
cfg
=
block
->
cfg
;
return
map
[
cfg
->
getVRegInfo
().
getVReg
(
name
)];
return
map
[
vreg
];
}
const
VRegSet
&
DefinednessAnalysis
::
getDefinedVregsAtEnd
(
CFGBlock
*
block
)
{
...
...
@@ -488,40 +487,30 @@ const VRegSet& PhiAnalysis::getAllRequiredFor(CFGBlock* block) {
return
required_phis
.
find
(
block
)
->
second
;
}
// TODO: switch this to taking a vreg
bool
PhiAnalysis
::
isRequired
(
InternedString
name
,
CFGBlock
*
block
)
{
assert
(
!
startswith
(
name
.
s
(),
"!"
));
bool
PhiAnalysis
::
isRequired
(
int
vreg
,
CFGBlock
*
block
)
{
assert
(
required_phis
.
count
(
block
));
return
required_phis
.
find
(
block
)
->
second
[
block
->
cfg
->
getVRegInfo
().
getVReg
(
name
)
];
return
required_phis
.
find
(
block
)
->
second
[
vreg
];
}
bool
PhiAnalysis
::
isRequiredAfter
(
InternedString
name
,
CFGBlock
*
block
)
{
assert
(
!
startswith
(
name
.
s
(),
"!"
));
bool
PhiAnalysis
::
isRequiredAfter
(
int
vreg
,
CFGBlock
*
block
)
{
// If there are multiple successors, then none of them are allowed
// to require any phi nodes
if
(
block
->
successors
.
size
()
!=
1
)
return
false
;
// Fall back to the other method:
return
isRequired
(
name
,
block
->
successors
[
0
]);
return
isRequired
(
vreg
,
block
->
successors
[
0
]);
}
bool
PhiAnalysis
::
isPotentiallyUndefinedAfter
(
InternedString
name
,
CFGBlock
*
block
)
{
assert
(
!
startswith
(
name
.
s
(),
"!"
));
bool
PhiAnalysis
::
isPotentiallyUndefinedAfter
(
int
vreg
,
CFGBlock
*
block
)
{
for
(
auto
b
:
block
->
successors
)
{
if
(
isPotentiallyUndefinedAt
(
name
,
b
))
if
(
isPotentiallyUndefinedAt
(
vreg
,
b
))
return
true
;
}
return
false
;
}
bool
PhiAnalysis
::
isPotentiallyUndefinedAt
(
InternedString
name
,
CFGBlock
*
block
)
{
assert
(
!
startswith
(
name
.
s
(),
"!"
));
auto
cfg
=
block
->
cfg
;
int
vreg
=
cfg
->
getVRegInfo
().
getVReg
(
name
);
bool
PhiAnalysis
::
isPotentiallyUndefinedAt
(
int
vreg
,
CFGBlock
*
block
)
{
assert
(
definedness
.
defined_at_beginning
.
count
(
block
));
return
definedness
.
defined_at_beginning
.
find
(
block
)
->
second
[
vreg
]
!=
DefinednessAnalysis
::
Defined
;
}
...
...
src/analysis/function_analysis.h
View file @
8052061e
...
...
@@ -163,7 +163,7 @@ public:
void
run
(
VRegMap
<
DefinitionLevel
>
initial_map
,
CFGBlock
*
initial_block
,
ScopeInfo
*
scope_info
);
DefinitionLevel
isDefinedAtEnd
(
InternedString
name
,
CFGBlock
*
block
);
DefinitionLevel
isDefinedAtEnd
(
int
vreg
,
CFGBlock
*
block
);
const
VRegSet
&
getDefinedVregsAtEnd
(
CFGBlock
*
block
);
friend
class
PhiAnalysis
;
...
...
@@ -186,15 +186,15 @@ public:
bool
initials_need_phis
,
LivenessAnalysis
*
liveness
,
ScopeInfo
*
scope_info
);
// TODO: convert these to taking vregs
bool
isRequired
(
InternedString
name
,
CFGBlock
*
block
);
bool
isRequiredAfter
(
InternedString
name
,
CFGBlock
*
block
);
bool
isRequired
(
int
vreg
,
CFGBlock
*
block
);
bool
isRequiredAfter
(
int
vreg
,
CFGBlock
*
block
);
const
VRegSet
&
getAllRequiredAfter
(
CFGBlock
*
block
);
const
VRegSet
&
getAllRequiredFor
(
CFGBlock
*
block
);
// TODO: convert these to taking vregs
// If "name" may be undefined at the beginning of any immediate successor block of "block":
bool
isPotentiallyUndefinedAfter
(
InternedString
name
,
CFGBlock
*
block
);
bool
isPotentiallyUndefinedAfter
(
int
vreg
,
CFGBlock
*
block
);
// If "name" may be undefined at the beginning of "block"
bool
isPotentiallyUndefinedAt
(
InternedString
name
,
CFGBlock
*
block
);
bool
isPotentiallyUndefinedAt
(
int
vreg
,
CFGBlock
*
block
);
};
std
::
unique_ptr
<
LivenessAnalysis
>
computeLivenessInfo
(
CFG
*
);
...
...
src/analysis/type_analysis.cpp
View file @
8052061e
...
...
@@ -40,20 +40,20 @@ namespace pyston {
class
NullTypeAnalysis
:
public
TypeAnalysis
{
public:
ConcreteCompilerType
*
getTypeAtBlockStart
(
InternedString
name
,
CFGBlock
*
block
)
override
;
ConcreteCompilerType
*
getTypeAtBlockEnd
(
InternedString
name
,
CFGBlock
*
block
)
override
;
ConcreteCompilerType
*
getTypeAtBlockStart
(
int
vreg
,
CFGBlock
*
block
)
override
;
ConcreteCompilerType
*
getTypeAtBlockEnd
(
int
vreg
,
CFGBlock
*
block
)
override
;
BoxedClass
*
speculatedExprClass
(
AST_expr
*
)
override
{
return
NULL
;
}
BoxedClass
*
speculatedExprClass
(
AST_slice
*
)
override
{
return
NULL
;
}
};
ConcreteCompilerType
*
NullTypeAnalysis
::
getTypeAtBlockStart
(
InternedString
name
,
CFGBlock
*
block
)
{
ConcreteCompilerType
*
NullTypeAnalysis
::
getTypeAtBlockStart
(
int
vreg
,
CFGBlock
*
block
)
{
return
UNKNOWN
;
}
ConcreteCompilerType
*
NullTypeAnalysis
::
getTypeAtBlockEnd
(
InternedString
name
,
CFGBlock
*
block
)
{
ConcreteCompilerType
*
NullTypeAnalysis
::
getTypeAtBlockEnd
(
int
vreg
,
CFGBlock
*
block
)
{
assert
(
block
->
successors
.
size
()
>
0
);
return
getTypeAtBlockStart
(
name
,
block
->
successors
[
0
]);
return
getTypeAtBlockStart
(
vreg
,
block
->
successors
[
0
]);
}
...
...
@@ -695,19 +695,17 @@ private:
speculation
(
speculation
)
{}
public:
ConcreteCompilerType
*
getTypeAtBlockEnd
(
InternedString
name
,
CFGBlock
*
block
)
override
{
ConcreteCompilerType
*
getTypeAtBlockEnd
(
int
vreg
,
CFGBlock
*
block
)
override
{
assert
(
block
->
successors
.
size
()
>
0
);
return
getTypeAtBlockStart
(
name
,
block
->
successors
[
0
]);
return
getTypeAtBlockStart
(
vreg
,
block
->
successors
[
0
]);
}
ConcreteCompilerType
*
getTypeAtBlockStart
(
InternedString
name
,
CFGBlock
*
block
)
override
{
int
vreg
=
block
->
cfg
->
getVRegInfo
().
getVReg
(
name
);
ConcreteCompilerType
*
getTypeAtBlockStart
(
int
vreg
,
CFGBlock
*
block
)
override
{
assert
(
starting_types
.
count
(
block
));
CompilerType
*
base
=
starting_types
.
find
(
block
)
->
second
[
vreg
];
ASSERT
(
base
!=
NULL
,
"%s %d"
,
name
.
c_str
(),
block
->
idx
);
ASSERT
(
base
!=
NULL
,
"%s %d"
,
block
->
cfg
->
getVRegInfo
().
getName
(
vreg
)
.
c_str
(),
block
->
idx
);
ConcreteCompilerType
*
rtn
=
base
->
getConcreteType
();
ASSERT
(
rtn
!=
NULL
,
"%s %d"
,
name
.
c_str
(),
block
->
idx
);
ASSERT
(
rtn
!=
NULL
,
"%s %d"
,
block
->
cfg
->
getVRegInfo
().
getName
(
vreg
)
.
c_str
(),
block
->
idx
);
return
rtn
;
}
...
...
src/analysis/type_analysis.h
View file @
8052061e
...
...
@@ -39,8 +39,8 @@ public:
virtual
~
TypeAnalysis
()
{}
virtual
ConcreteCompilerType
*
getTypeAtBlockStart
(
InternedString
name
,
CFGBlock
*
block
)
=
0
;
virtual
ConcreteCompilerType
*
getTypeAtBlockEnd
(
InternedString
name
,
CFGBlock
*
block
)
=
0
;
virtual
ConcreteCompilerType
*
getTypeAtBlockStart
(
int
vreg
,
CFGBlock
*
block
)
=
0
;
virtual
ConcreteCompilerType
*
getTypeAtBlockEnd
(
int
vreg
,
CFGBlock
*
block
)
=
0
;
virtual
BoxedClass
*
speculatedExprClass
(
AST_expr
*
)
=
0
;
virtual
BoxedClass
*
speculatedExprClass
(
AST_slice
*
)
=
0
;
};
...
...
src/codegen/ast_interpreter.cpp
View file @
8052061e
...
...
@@ -722,7 +722,7 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {
for
(
auto
&&
sym
:
getSymVRegMap
())
{
if
(
!
liveness
->
isLiveAtEnd
(
sym
.
second
,
current_block
))
{
dead_vregs
.
push_back
(
sym
.
second
);
}
else
if
(
phis
->
isRequiredAfter
(
sym
.
first
,
current_block
))
{
}
else
if
(
phis
->
isRequiredAfter
(
sym
.
second
,
current_block
))
{
assert
(
scope_info
->
getScopeTypeOfName
(
sym
.
first
)
!=
ScopeInfo
::
VarScopeType
::
GLOBAL
);
}
else
{
}
...
...
@@ -753,7 +753,7 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {
InternedString
name
=
source_info
->
cfg
->
getVRegInfo
().
getName
(
vreg
);
Box
*
val
=
vregs
[
vreg
];
if
(
phis
->
isPotentiallyUndefinedAfter
(
name
,
current_block
))
{
if
(
phis
->
isPotentiallyUndefinedAfter
(
vreg
,
current_block
))
{
bool
is_defined
=
val
!=
NULL
;
// TODO only mangle once
sorted_symbol_table
[
getIsDefinedName
(
name
,
source_info
->
getInternedStrings
())]
=
(
Box
*
)
is_defined
;
...
...
src/codegen/irgen.cpp
View file @
8052061e
...
...
@@ -286,7 +286,8 @@ static std::vector<std::pair<CFGBlock*, CFGBlock*>> computeBlockTraversalOrder(c
return
rtn
;
}
static
ConcreteCompilerType
*
getTypeAtBlockStart
(
TypeAnalysis
*
types
,
InternedString
name
,
CFGBlock
*
block
)
{
static
ConcreteCompilerType
*
getTypeAtBlockStart
(
TypeAnalysis
*
types
,
InternedString
name
,
const
VRegInfo
&
vreg_info
,
CFGBlock
*
block
)
{
if
(
isIsDefinedName
(
name
))
return
BOOL
;
else
if
(
name
.
s
()
==
PASSED_GENERATOR_NAME
)
...
...
@@ -295,8 +296,11 @@ static ConcreteCompilerType* getTypeAtBlockStart(TypeAnalysis* types, InternedSt
return
CLOSURE
;
else
if
(
name
.
s
()
==
CREATED_CLOSURE_NAME
)
return
CLOSURE
;
else
return
types
->
getTypeAtBlockStart
(
name
,
block
);
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.
return
types
->
getTypeAtBlockStart
(
vreg_info
.
getVReg
(
name
),
block
);
}
}
static
bool
shouldPhisOwnThisSym
(
llvm
::
StringRef
name
)
{
...
...
@@ -362,6 +366,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
assert
(
phi_analysis
);
CFG
*
cfg
=
source
->
cfg
;
auto
&&
vreg_info
=
cfg
->
getVRegInfo
();
if
(
entry_descriptor
!=
NULL
)
assert
(
blocks
.
count
(
cfg
->
getStartingBlock
())
==
0
);
...
...
@@ -456,7 +461,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
}
ConcreteCompilerType
*
phi_type
;
phi_type
=
getTypeAtBlockStart
(
types
,
p
.
first
,
target_block
);
phi_type
=
getTypeAtBlockStart
(
types
,
p
.
first
,
vreg_info
,
target_block
);
irstate
->
getRefcounts
()
->
setType
(
from_arg
,
RefType
::
BORROWED
);
...
...
@@ -625,7 +630,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
if
(
p
.
first
.
s
()
==
FRAME_INFO_PTR_NAME
)
continue
;
ConcreteCompilerType
*
analyzed_type
=
getTypeAtBlockStart
(
types
,
p
.
first
,
block
);
ConcreteCompilerType
*
analyzed_type
=
getTypeAtBlockStart
(
types
,
p
.
first
,
vreg_info
,
block
);
// printf("For %s, given %s, analyzed for %s\n", p.first.c_str(), p.second->debugName().c_str(),
// analyzed_type->debugName().c_str());
...
...
@@ -655,7 +660,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
for
(
const
int
vreg
:
phi_analysis
->
getAllRequiredFor
(
block
))
{
auto
s
=
cfg
->
getVRegInfo
().
getName
(
vreg
);
names
.
insert
(
s
);
if
(
phi_analysis
->
isPotentiallyUndefinedAfter
(
s
,
block
->
predecessors
[
0
]))
{
if
(
phi_analysis
->
isPotentiallyUndefinedAfter
(
vreg
,
block
->
predecessors
[
0
]))
{
names
.
insert
(
getIsDefinedName
(
s
,
source
->
getInternedStrings
()));
}
}
...
...
@@ -673,7 +678,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
for
(
const
InternedString
&
s
:
names
)
{
// printf("adding guessed phi for %s\n", s.c_str());
ConcreteCompilerType
*
type
=
getTypeAtBlockStart
(
types
,
s
,
block
);
ConcreteCompilerType
*
type
=
getTypeAtBlockStart
(
types
,
s
,
vreg_info
,
block
);
llvm
::
PHINode
*
phi
=
emitter
->
getBuilder
()
->
CreatePHI
(
type
->
llvmType
(),
block
->
predecessors
.
size
(),
s
.
s
());
if
(
type
->
getBoxType
()
==
type
)
{
...
...
src/codegen/irgen/irgenerator.cpp
View file @
8052061e
...
...
@@ -2657,12 +2657,13 @@ private:
// ASSERT(p.first[0] != '!' || isIsDefinedName(p.first), "left a fake variable in the real
// symbol table? '%s'", p.first.c_str());
if
(
!
irstate
->
getLiveness
()
->
isLiveAtEnd
(
cfg
->
getVRegInfo
().
getVReg
(
p
.
first
),
myblock
))
{
int
vreg
=
cfg
->
getVRegInfo
().
getVReg
(
p
.
first
);
if
(
!
irstate
->
getLiveness
()
->
isLiveAtEnd
(
vreg
,
myblock
))
{
symbol_table
.
erase
(
getIsDefinedName
(
p
.
first
));
symbol_table
.
erase
(
p
.
first
);
}
else
if
(
irstate
->
getPhis
()
->
isRequiredAfter
(
p
.
first
,
myblock
))
{
}
else
if
(
irstate
->
getPhis
()
->
isRequiredAfter
(
vreg
,
myblock
))
{
assert
(
scope_info
->
getScopeTypeOfName
(
p
.
first
)
!=
ScopeInfo
::
VarScopeType
::
GLOBAL
);
ConcreteCompilerType
*
phi_type
=
types
->
getTypeAtBlockEnd
(
p
.
first
,
myblock
);
ConcreteCompilerType
*
phi_type
=
types
->
getTypeAtBlockEnd
(
vreg
,
myblock
);
assert
(
phi_type
->
isUsable
());
// printf("Converting %s from %s to %s\n", p.first.c_str(),
// p.second->getType()->debugName().c_str(), phi_type->debugName().c_str());
...
...
@@ -2675,7 +2676,7 @@ private:
// TODO getTypeAtBlockEnd will automatically convert up to the concrete type, which we don't
// want
// here, but this is just for debugging so I guess let it happen for now:
ConcreteCompilerType
*
ending_type
=
types
->
getTypeAtBlockEnd
(
p
.
first
,
myblock
);
ConcreteCompilerType
*
ending_type
=
types
->
getTypeAtBlockEnd
(
vreg
,
myblock
);
RELEASE_ASSERT
(
p
.
second
->
canConvertTo
(
ending_type
),
"%s is supposed to be %s, but somehow is %s"
,
p
.
first
.
c_str
(),
ending_type
->
debugName
().
c_str
(),
p
.
second
->
getType
()
->
debugName
().
c_str
());
...
...
@@ -2685,13 +2686,12 @@ private:
for
(
int
vreg
:
irstate
->
getPhis
()
->
getAllRequiredAfter
(
myblock
))
{
auto
name
=
irstate
->
getCFG
()
->
getVRegInfo
().
getName
(
vreg
);
auto
it
=
&
name
;
// hack, remove
if
(
VERBOSITY
()
>=
3
)
printf
(
"phi will be required for %s
\n
"
,
it
->
c_str
());
assert
(
scope_info
->
getScopeTypeOfName
(
*
it
)
!=
ScopeInfo
::
VarScopeType
::
GLOBAL
);
CompilerVariable
*&
cur
=
symbol_table
[
*
it
];
printf
(
"phi will be required for %s
\n
"
,
name
.
c_str
());
assert
(
scope_info
->
getScopeTypeOfName
(
name
)
!=
ScopeInfo
::
VarScopeType
::
GLOBAL
);
CompilerVariable
*&
cur
=
symbol_table
[
name
];
InternedString
defined_name
=
getIsDefinedName
(
*
it
);
InternedString
defined_name
=
getIsDefinedName
(
name
);
if
(
cur
!=
NULL
)
{
// printf("defined on this path; ");
...
...
@@ -2699,7 +2699,7 @@ private:
ConcreteCompilerVariable
*
is_defined
=
static_cast
<
ConcreteCompilerVariable
*>
(
_popFake
(
defined_name
,
true
));
if
(
irstate
->
getPhis
()
->
isPotentiallyUndefinedAfter
(
*
it
,
myblock
))
{
if
(
irstate
->
getPhis
()
->
isPotentiallyUndefinedAfter
(
vreg
,
myblock
))
{
// printf("is potentially undefined later, so marking it defined\n");
if
(
is_defined
)
{
_setFake
(
defined_name
,
is_defined
);
...
...
@@ -2712,7 +2712,7 @@ private:
}
}
else
{
// printf("no st entry, setting undefined\n");
ConcreteCompilerType
*
phi_type
=
types
->
getTypeAtBlockEnd
(
*
it
,
myblock
);
ConcreteCompilerType
*
phi_type
=
types
->
getTypeAtBlockEnd
(
vreg
,
myblock
);
assert
(
phi_type
->
isUsable
());
// Forward an incref'd None instead of a NULL.
...
...
@@ -2769,6 +2769,9 @@ public:
SymbolTable
*
st
=
new
SymbolTable
(
symbol_table
);
ConcreteSymbolTable
*
phi_st
=
new
ConcreteSymbolTable
();
auto
cfg
=
source
->
cfg
;
auto
&&
vreg_info
=
cfg
->
getVRegInfo
();
// This should have been consumed:
assert
(
incoming_exc_state
.
empty
());
...
...
@@ -2799,7 +2802,8 @@ public:
// We have one successor, but they have more than one predecessor.
// We're going to sort out which symbols need to go in phi_st and which belong inst.
for
(
SymbolTable
::
iterator
it
=
st
->
begin
();
it
!=
st
->
end
();)
{
if
(
allowableFakeEndingSymbol
(
it
->
first
)
||
irstate
->
getPhis
()
->
isRequiredAfter
(
it
->
first
,
myblock
))
{
if
(
allowableFakeEndingSymbol
(
it
->
first
)
||
irstate
->
getPhis
()
->
isRequiredAfter
(
cfg
->
getVRegInfo
().
getVReg
(
it
->
first
),
myblock
))
{
// this conversion should have already happened... should refactor this.
ConcreteCompilerType
*
ending_type
;
if
(
isIsDefinedName
(
it
->
first
.
s
()))
{
...
...
@@ -2814,7 +2818,7 @@ public:
}
else
if
(
it
->
first
.
s
()
==
FRAME_INFO_PTR_NAME
)
{
ending_type
=
FRAME_INFO
;
}
else
{
ending_type
=
types
->
getTypeAtBlockEnd
(
it
->
first
,
myblock
);
ending_type
=
types
->
getTypeAtBlockEnd
(
vreg_info
.
getVReg
(
it
->
first
)
,
myblock
);
}
assert
(
ending_type
->
isUsable
());
//(*phi_st)[it->first] = it->second->makeConverted(emitter, it->second->getConcreteType());
...
...
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