Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
a1c1e7b8
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a1c1e7b8
编写于
10月 08, 2015
作者:
V
VSadov
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #5731 from VSadov/optFixVb
Ported fix for #5530 to VB
上级
e763d73c
8331d976
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
142 addition
and
49 deletion
+142
-49
src/Compilers/VisualBasic/Portable/CodeGen/Optimizer/StackScheduler.Analyzer.vb
...sic/Portable/CodeGen/Optimizer/StackScheduler.Analyzer.vb
+35
-24
src/Compilers/VisualBasic/Portable/CodeGen/Optimizer/StackScheduler.LocalDefUseSpan.vb
...table/CodeGen/Optimizer/StackScheduler.LocalDefUseSpan.vb
+26
-21
src/Compilers/VisualBasic/Portable/CodeGen/Optimizer/StackScheduler.vb
.../VisualBasic/Portable/CodeGen/Optimizer/StackScheduler.vb
+13
-4
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTests.vb
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTests.vb
+68
-0
未找到文件。
src/Compilers/VisualBasic/Portable/CodeGen/Optimizer/StackScheduler.Analyzer.vb
浏览文件 @
a1c1e7b8
...
@@ -73,7 +73,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
...
@@ -73,7 +73,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
' this is the top of eval stack
' this is the top of eval stack
DeclareLocal
(
_empty
,
0
)
DeclareLocal
(
_empty
,
0
)
Record
Var
Write
(
_empty
)
Record
Dummy
Write
(
_empty
)
End
Sub
End
Sub
Public
Shared
Function
Analyze
(
Public
Shared
Function
Analyze
(
...
@@ -576,16 +576,25 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
...
@@ -576,16 +576,25 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
' Such call will push the receiver ref before the arguments
' Such call will push the receiver ref before the arguments
' so we need to ensure that arguments cannot use stack temps
' so we need to ensure that arguments cannot use stack temps
Dim
leftType
As
TypeSymbol
=
left
.
Type
Dim
leftType
As
TypeSymbol
=
left
.
Type
Dim
cookie
As
Object
=
Nothing
Dim
mayPushReceiver
As
Boolean
=
False
If
right
.
Kind
=
BoundKind
.
ObjectCreationExpression
Then
If
right
.
Kind
=
BoundKind
.
ObjectCreationExpression
Then
Dim
ctor
=
DirectCast
(
right
,
BoundObjectCreationExpression
).
ConstructorOpt
Dim
ctor
=
DirectCast
(
right
,
BoundObjectCreationExpression
).
ConstructorOpt
If
ctor
IsNot
Nothing
AndAlso
ctor
.
ParameterCount
<>
0
Then
If
ctor
IsNot
Nothing
AndAlso
ctor
.
ParameterCount
<>
0
Then
cookie
=
GetStackStateCookie
()
mayPushReceiver
=
True
End
If
End
If
End
If
End
If
If
mayPushReceiver
Then
'push unknown value just to prevent access to stack locals.
PushEvalStack
(
Nothing
,
ExprContext
.
Address
)
End
If
right
=
VisitExpression
(
node
.
Right
,
rhsContext
)
right
=
VisitExpression
(
node
.
Right
,
rhsContext
)
If
mayPushReceiver
Then
PopEvalStack
()
End
If
' if assigning to a local, now it is the time to record the Write
' if assigning to a local, now it is the time to record the Write
If
storedAssignmentLocal
IsNot
Nothing
Then
If
storedAssignmentLocal
IsNot
Nothing
Then
' this assert will fire if code relies on implicit CLR coercions
' this assert will fire if code relies on implicit CLR coercions
...
@@ -599,12 +608,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
...
@@ -599,12 +608,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
RecordVarWrite
(
storedAssignmentLocal
.
LocalSymbol
)
RecordVarWrite
(
storedAssignmentLocal
.
LocalSymbol
)
End
If
End
If
If
cookie
IsNot
Nothing
Then
' There is still RHS on the stack, adjust for that
Me
.
PopEvalStack
()
EnsureStackState
(
cookie
)
End
If
Return
node
.
Update
(
left
,
Nothing
,
right
,
node
.
SuppressObjectClone
,
node
.
Type
)
Return
node
.
Update
(
left
,
Nothing
,
right
,
node
.
SuppressObjectClone
,
node
.
Type
)
End
Function
End
Function
...
@@ -1147,7 +1150,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
...
@@ -1147,7 +1150,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
Dim
dummy
As
New
DummyLocal
(
Me
.
_container
)
Dim
dummy
As
New
DummyLocal
(
Me
.
_container
)
Me
.
_dummyVariables
.
Add
(
dummy
,
dummy
)
Me
.
_dummyVariables
.
Add
(
dummy
,
dummy
)
Me
.
_locals
.
Add
(
dummy
,
New
LocalDefUseInfo
(
Me
.
StackDepth
))
Me
.
_locals
.
Add
(
dummy
,
New
LocalDefUseInfo
(
Me
.
StackDepth
))
Record
Var
Write
(
dummy
)
Record
Dummy
Write
(
dummy
)
Return
dummy
Return
dummy
End
Function
End
Function
...
@@ -1166,7 +1169,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
...
@@ -1166,7 +1169,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
dummy
=
New
DummyLocal
(
Me
.
_container
)
dummy
=
New
DummyLocal
(
Me
.
_container
)
Me
.
_dummyVariables
.
Add
(
label
,
dummy
)
Me
.
_dummyVariables
.
Add
(
label
,
dummy
)
Me
.
_locals
.
Add
(
dummy
,
New
LocalDefUseInfo
(
Me
.
StackDepth
))
Me
.
_locals
.
Add
(
dummy
,
New
LocalDefUseInfo
(
Me
.
StackDepth
))
Record
Var
Write
(
dummy
)
Record
Dummy
Write
(
dummy
)
End
If
End
If
End
Sub
End
Sub
...
@@ -1241,6 +1244,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
...
@@ -1241,6 +1244,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
End
Function
End
Function
Private
Sub
RecordVarWrite
(
local
As
LocalSymbol
)
Private
Sub
RecordVarWrite
(
local
As
LocalSymbol
)
Debug
.
Assert
(
local
.
SynthesizedKind
<>
SynthesizedLocalKind
.
OptimizerTemp
)
If
Not
CanScheduleToStack
(
local
)
Then
If
Not
CanScheduleToStack
(
local
)
Then
Return
Return
End
If
End
If
...
@@ -1250,26 +1255,32 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
...
@@ -1250,26 +1255,32 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
Return
Return
End
If
End
If
' if accessing real val, check stack
' check stack
If
Not
TypeOf
local
Is
DummyLocal
Then
' -1 because real assignment "consumes" value.
Dim
evalStack
=
Me
.
StackDepth
-
1
' -1 because real assignment "consumes" value.
Dim
evalStack
=
Me
.
StackDepth
-
1
If
locInfo
.
StackAtDeclaration
<>
evalStack
Then
If
locInfo
.
StackAtDeclaration
<>
evalStack
Then
' writing at different eval stack.
' writing at different eval stack.
locInfo
.
ShouldNotSchedule
()
locInfo
.
ShouldNotSchedule
()
Return
Return
End
If
Else
' dummy must be accessed on same stack.
Debug
.
Assert
(
local
Is
_empty
OrElse
locInfo
.
StackAtDeclaration
=
StackDepth
())
End
If
End
If
Dim
locDef
=
New
LocalDefUseSpan
(
Me
.
_counter
)
Dim
locDef
=
New
LocalDefUseSpan
(
Me
.
_counter
)
locInfo
.
localDefs
.
Add
(
locDef
)
locInfo
.
localDefs
.
Add
(
locDef
)
End
Sub
End
Sub
Private
Sub
RecordDummyWrite
(
local
As
LocalSymbol
)
Debug
.
Assert
(
local
.
SynthesizedKind
=
SynthesizedLocalKind
.
OptimizerTemp
)
Dim
locInfo
=
_locals
(
local
)
' dummy must be accessed on same stack.
Debug
.
Assert
(
local
Is
_empty
OrElse
locInfo
.
StackAtDeclaration
=
StackDepth
())
Dim
locDef
=
New
LocalDefUseSpan
(
Me
.
_counter
)
locInfo
.
localDefs
.
Add
(
locDef
)
End
Sub
Private
Sub
ShouldNotSchedule
(
local
As
LocalSymbol
)
Private
Sub
ShouldNotSchedule
(
local
As
LocalSymbol
)
Dim
localDefInfo
As
LocalDefUseInfo
=
Nothing
Dim
localDefInfo
As
LocalDefUseInfo
=
Nothing
If
_locals
.
TryGetValue
(
local
,
localDefInfo
)
Then
If
_locals
.
TryGetValue
(
local
,
localDefInfo
)
Then
...
...
src/Compilers/VisualBasic/Portable/CodeGen/Optimizer/StackScheduler.LocalDefUseSpan.vb
浏览文件 @
a1c1e7b8
...
@@ -39,37 +39,42 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
...
@@ -39,37 +39,42 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
End
Function
End
Function
''' <summary>
''' <summary>
''' That said, when current and other use spans are regular spans we can have
''' when current And other use spans are regular spans we can have only 2 conflict cases:
''' only 2 conflict cases:
''' [1, 3) conflicts with [0, 2)
''' [1, 3) conflicts with [0, 2)
''' [1, 3) conflicts with [2, 4)
''' [1, 3) conflicts with [2, 4)
'''
'''
'''
specifically:
'''
NOTE: With regular spans, it is not possible for two spans to share an edge point
'''
[1, 3) does not conflict with [0, 1)
'''
unless they belong to the same local. (because we cannot aceess two real locals at the same time)
'''
'''
''' NOTE: with regular spans, it is not possible to have start1 == start2 or
''' specifically:
''' end1 == end2 since at the same node we can access only one real local.
''' [1, 3) does Not conflict with [0, 1) since such spans would need to belong to the same local
'''
''' However at the same node we can access one or more dummy locals. So we can
''' have start1 == start2 and end1 == end2 scenarios, but only if the other span
''' is a span of a dummy.
''' </summary>
''' </summary>
Public
Function
ConflictsWith
(
other
As
LocalDefUseSpan
)
As
Boolean
Public
Function
ConflictsWith
(
other
As
LocalDefUseSpan
)
As
Boolean
' NOTE: this logic is moved from CS as-is
Return
Contains
(
other
.
Start
)
Xor
Contains
(
other
.
End
)
' TODO: revise the definition of ConflictsWith
End
Function
Dim
containsStart
As
Boolean
=
other
.
ContainsStart
(
Me
.
Start
)
Dim
containsEnd
=
other
.
ContainsEnd
(
Me
.
End
)
Private
Function
Contains
(
val
As
Integer
)
As
Boolean
Return
containsStart
Xor
containsEnd
Return
Me
.
Start
<
val
AndAlso
Me
.
End
>
val
End
Function
End
Function
Private
Function
ContainsStart
(
otherStart
As
Integer
)
As
Boolean
''' <summary>
Return
Me
.
Start
<=
otherStart
AndAlso
Me
.
End
>
otherStart
''' Dummy locals represent implicit control flow
''' it is not allowed for a regular local span to cross into or
''' be immediately adjacent to a dummy span.
'''
''' specifically:
''' [1, 3) does conflict with [0, 1) since that would imply a value flowing into or out of a span surrounded by a branch/label
'''
''' </summary>
Public
Function
ConflictsWithDummy
(
dummy
As
LocalDefUseSpan
)
As
Boolean
Return
Includes
(
dummy
.
Start
)
Xor
Includes
(
dummy
.
End
)
End
Function
End
Function
Private
Function
ContainsEnd
(
otherEnd
As
Integer
)
As
Boolean
Private
Function
Includes
(
val
As
Integer
)
As
Boolean
Return
Me
.
Start
<
otherEnd
AndAlso
Me
.
End
>
otherEnd
Return
Me
.
Start
<
=
val
AndAlso
Me
.
End
>=
val
End
Function
End
Function
End
Class
End
Class
End
Class
End
Class
...
...
src/Compilers/VisualBasic/Portable/CodeGen/Optimizer/StackScheduler.vb
浏览文件 @
a1c1e7b8
...
@@ -63,8 +63,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
...
@@ -63,8 +63,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
Next
Next
Next
Next
' TODO: perf. This can be simplified to not use a query.
Dim
dummyCnt
=
defs
.
Count
' TODO: perf. This can be simplified to not use a query.
' order locals by the number of usages, then by the declaration in descending order
' order locals by the number of usages, then by the declaration in descending order
For
Each
localInfo
In
From
i
In
info
For
Each
localInfo
In
From
i
In
info
Where
i
.
Value
.
localDefs
.
Count
>
0
Where
i
.
Value
.
localDefs
.
Count
>
0
...
@@ -85,14 +86,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
...
@@ -85,14 +86,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
For
Each
newDef
In
localInfo
.
Value
.
localDefs
For
Each
newDef
In
localInfo
.
Value
.
localDefs
Debug
.
Assert
(
Not
intersects
)
Debug
.
Assert
(
Not
intersects
)
' TODO: This piece makes the whole thing O(n^2), revise
For
i
=
0
To
dummyCnt
-
1
For
i
=
0
To
defs
.
Count
-
1
If
newDef
.
ConflictsWithDummy
(
defs
(
i
))
Then
If
newDef
.
ConflictsWith
(
defs
(
i
))
Then
intersects
=
True
intersects
=
True
Exit
For
Exit
For
End
If
End
If
Next
Next
If
Not
intersects
Then
For
i
=
dummyCnt
To
defs
.
Count
-
1
If
newDef
.
ConflictsWith
(
defs
(
i
))
Then
intersects
=
True
Exit
For
End
If
Next
End
If
If
intersects
Then
If
intersects
Then
info
.
Remove
(
localInfo
.
Key
)
info
.
Remove
(
localInfo
.
Key
)
Exit
For
Exit
For
...
...
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTests.vb
浏览文件 @
a1c1e7b8
...
@@ -13403,5 +13403,73 @@ End Structure
...
@@ -13403,5 +13403,73 @@ End Structure
)
)
End Sub
End Sub
<Fact()>
Public Sub InplaceCtorUsesLocal()
Dim c = CompileAndVerify(
<compilation>
<file name="
a
.
vb
">
<![CDATA[
Module Module1
Private arr As S1() = New S1(1) {}
Structure S1
Public a, b As Integer
Public Sub New(a As Integer, b As Integer)
Me.a = a
Me.b = b
End Sub
Public Sub New(a As Integer)
Me.a = a
End Sub
End Structure
Sub Main()
Dim arg = System.Math.Max(1, 2)
Dim val = New S1(arg, arg)
arr(0) = val
System.Console.WriteLine(arr(0).a)
End Sub
End Module
]]>
</file>
</compilation>, options:=TestOptions.ReleaseExe,
expectedOutput:="
2
")
c.VerifyIL("
Module1
.
Main
",
<![CDATA[
{
// Code size 51 (0x33)
.maxstack 3
.locals init (Integer V_0, //arg
Module1.S1 V_1) //val
IL_0000: ldc.i4.1
IL_0001: ldc.i4.2
IL_0002: call "
Function
System
.
Math
.
Max
(
Integer
,
Integer
)
As
Integer
"
IL_0007: stloc.0
IL_0008: ldloca.s V_1
IL_000a: ldloc.0
IL_000b: ldloc.0
IL_000c: call "
Sub
Module1
.
S1
.
.
ctor
(
Integer
,
Integer
)
"
IL_0011: ldsfld "
Module1
.
arr
As
Module1
.
S1
()
"
IL_0016: ldc.i4.0
IL_0017: ldloc.1
IL_0018: stelem "
Module1
.
S1
"
IL_001d: ldsfld "
Module1
.
arr
As
Module1
.
S1
()
"
IL_0022: ldc.i4.0
IL_0023: ldelema "
Module1
.
S1
"
IL_0028: ldfld "
Module1
.
S1
.
a
As
Integer
"
IL_002d: call "
Sub
System
.
Console
.
WriteLine
(
Integer
)
"
IL_0032: ret
}
]]>)
End Sub
End Class
End Class
End Namespace
End Namespace
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录