Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
swiftshader
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
swiftshader
Commits
bd2e2315
Commit
bd2e2315
authored
Mar 15, 2016
by
John Porto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Subzero. Uses unique_ptrs in the emit queue.
Because explicit memory ownership is awesome! BUG= R=stichnot@chromium.org Review URL:
https://codereview.chromium.org/1804133002
.
parent
a78e4baa
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
69 additions
and
53 deletions
+69
-53
IceCfg.h
src/IceCfg.h
+3
-1
IceGlobalContext.cpp
src/IceGlobalContext.cpp
+29
-24
IceGlobalContext.h
src/IceGlobalContext.h
+4
-2
IceThreading.cpp
src/IceThreading.cpp
+8
-7
IceThreading.h
src/IceThreading.h
+14
-12
IceTranslator.cpp
src/IceTranslator.cpp
+8
-5
IceTranslator.h
src/IceTranslator.h
+3
-2
No files found.
src/IceCfg.h
View file @
bd2e2315
...
...
@@ -174,7 +174,9 @@ public:
template
<
typename
T
=
Assembler
>
T
*
getAssembler
()
const
{
return
llvm
::
dyn_cast
<
T
>
(
TargetAssembler
.
get
());
}
Assembler
*
releaseAssembler
()
{
return
TargetAssembler
.
release
();
}
std
::
unique_ptr
<
Assembler
>
releaseAssembler
()
{
return
std
::
move
(
TargetAssembler
);
}
bool
hasComputedFrame
()
const
;
bool
getFocusedTiming
()
const
{
return
FocusedTiming
;
}
void
setFocusedTiming
()
{
FocusedTiming
=
true
;
}
...
...
src/IceGlobalContext.cpp
View file @
bd2e2315
...
...
@@ -319,14 +319,14 @@ void GlobalContext::translateFunctions() {
}
Func
->
translate
();
EmitterWorkItem
*
Item
=
nullptr
;
std
::
unique_ptr
<
EmitterWorkItem
>
Item
;
if
(
Func
->
hasError
())
{
getErrorStatus
()
->
assign
(
EC_Translation
);
OstreamLocker
L
(
this
);
getStrError
()
<<
"ICE translation error: "
<<
Func
->
getFunctionName
()
<<
": "
<<
Func
->
getError
()
<<
": "
<<
Func
->
getFunctionNameAndSize
()
<<
"
\n
"
;
Item
=
new
EmitterWorkItem
(
Func
->
getSequenceNumber
());
Item
=
makeUnique
<
EmitterWorkItem
>
(
Func
->
getSequenceNumber
());
}
else
{
Func
->
getAssembler
<>
()
->
setInternal
(
Func
->
getInternal
());
switch
(
getFlags
().
getOutFileType
())
{
...
...
@@ -337,10 +337,11 @@ void GlobalContext::translateFunctions() {
// stats have been fully collected into this thread's TLS.
// Dump them before TLS is reset for the next Cfg.
dumpStats
(
Func
->
getFunctionNameAndSize
());
Assembler
*
Asm
=
Func
->
releaseAssembler
();
auto
Asm
=
Func
->
releaseAssembler
();
// Copy relevant fields into Asm before Func is deleted.
Asm
->
setFunctionName
(
Func
->
getFunctionName
());
Item
=
new
EmitterWorkItem
(
Func
->
getSequenceNumber
(),
Asm
);
Item
=
makeUnique
<
EmitterWorkItem
>
(
Func
->
getSequenceNumber
(),
std
::
move
(
Asm
));
Item
->
setGlobalInits
(
Func
->
getGlobalInits
());
}
break
;
case
FT_Asm
:
...
...
@@ -348,13 +349,14 @@ void GlobalContext::translateFunctions() {
// to be dumped.
std
::
unique_ptr
<
VariableDeclarationList
>
GlobalInits
=
Func
->
getGlobalInits
();
Item
=
new
EmitterWorkItem
(
Func
->
getSequenceNumber
(),
Func
.
release
());
Item
=
makeUnique
<
EmitterWorkItem
>
(
Func
->
getSequenceNumber
(),
std
::
move
(
Func
));
Item
->
setGlobalInits
(
std
::
move
(
GlobalInits
));
break
;
}
}
assert
(
Item
);
emitQueueBlockingPush
(
Item
);
assert
(
Item
!=
nullptr
);
emitQueueBlockingPush
(
std
::
move
(
Item
)
);
// The Cfg now gets deleted as Func goes out of scope.
}
}
...
...
@@ -362,9 +364,10 @@ void GlobalContext::translateFunctions() {
namespace
{
// Ensure Pending is large enough that Pending[Index] is valid.
void
resizePending
(
std
::
vector
<
EmitterWorkItem
*>
&
Pending
,
uint32_t
Index
)
{
if
(
Index
>=
Pending
.
size
())
Utils
::
reserveAndResize
(
Pending
,
Index
+
1
);
void
resizePending
(
std
::
vector
<
std
::
unique_ptr
<
EmitterWorkItem
>>
*
Pending
,
uint32_t
Index
)
{
if
(
Index
>=
Pending
->
size
())
Utils
::
reserveAndResize
(
*
Pending
,
Index
+
1
);
}
}
// end of anonymous namespace
...
...
@@ -471,7 +474,7 @@ void GlobalContext::emitItems() {
// the work queue, and if it's not the item we're waiting for, we
// insert it into Pending and repeat. The work item is deleted
// after it is processed.
std
::
vector
<
EmitterWorkItem
*
>
Pending
;
std
::
vector
<
std
::
unique_ptr
<
EmitterWorkItem
>
>
Pending
;
uint32_t
DesiredSequenceNumber
=
getFirstSequenceNumber
();
uint32_t
ShuffleStartIndex
=
DesiredSequenceNumber
;
uint32_t
ShuffleEndIndex
=
DesiredSequenceNumber
;
...
...
@@ -483,12 +486,11 @@ void GlobalContext::emitItems() {
RandomNumberGenerator
RNG
(
getFlags
().
getRandomSeed
(),
RPE_FunctionReordering
);
while
(
!
EmitQueueEmpty
)
{
resizePending
(
Pending
,
DesiredSequenceNumber
);
resizePending
(
&
Pending
,
DesiredSequenceNumber
);
// See if Pending contains DesiredSequenceNumber.
EmitterWorkItem
*
RawItem
=
Pending
[
DesiredSequenceNumber
];
if
(
RawItem
==
nullptr
)
{
if
(
Pending
[
DesiredSequenceNumber
]
==
nullptr
)
{
// We need to fetch an EmitterWorkItem from the queue.
RawItem
=
emitQueueBlockingPop
();
auto
RawItem
=
emitQueueBlockingPop
();
if
(
RawItem
==
nullptr
)
{
// This is the notifier for an empty queue.
EmitQueueEmpty
=
true
;
...
...
@@ -498,16 +500,18 @@ void GlobalContext::emitItems() {
if
(
Threaded
&&
ItemSeq
!=
DesiredSequenceNumber
)
{
// Not the desired one, add it to Pending but do not increase
// DesiredSequenceNumber. Continue the loop, do not emit the item.
resizePending
(
Pending
,
ItemSeq
);
Pending
[
ItemSeq
]
=
RawItem
;
resizePending
(
&
Pending
,
ItemSeq
);
Pending
[
ItemSeq
]
=
std
::
move
(
RawItem
)
;
continue
;
}
// ItemSeq == DesiredSequenceNumber, we need to check if we should
// emit it or not. If !Threaded, we're OK with ItemSeq !=
// DesiredSequenceNumber.
Pending
[
DesiredSequenceNumber
]
=
RawItem
;
Pending
[
DesiredSequenceNumber
]
=
std
::
move
(
RawItem
)
;
}
}
const
auto
*
CurrentWorkItem
=
Pending
[
DesiredSequenceNumber
].
get
();
// We have the desired EmitterWorkItem or nullptr as the end notifier.
// If the emitter queue is not empty, increase DesiredSequenceNumber and
// ShuffleEndIndex.
...
...
@@ -524,7 +528,7 @@ void GlobalContext::emitItems() {
// holding an arbitrarily large GlobalDeclarationList.
if
(
!
EmitQueueEmpty
&&
ShuffleEndIndex
-
ShuffleStartIndex
<
ShuffleWindowSize
&&
Raw
Item
->
getKind
()
!=
EmitterWorkItem
::
WI_GlobalInits
)
CurrentWork
Item
->
getKind
()
!=
EmitterWorkItem
::
WI_GlobalInits
)
continue
;
// Emit the EmitterWorkItem between Pending[ShuffleStartIndex] to
...
...
@@ -538,7 +542,7 @@ void GlobalContext::emitItems() {
// Emit the item from ShuffleStartIndex to ShuffleEndIndex.
for
(
uint32_t
I
=
ShuffleStartIndex
;
I
<
ShuffleEndIndex
;
I
++
)
{
std
::
unique_ptr
<
EmitterWorkItem
>
Item
(
Pending
[
I
]);
std
::
unique_ptr
<
EmitterWorkItem
>
Item
=
std
::
move
(
Pending
[
I
]);
switch
(
Item
->
getKind
())
{
case
EmitterWorkItem
:
:
WI_Nop
:
...
...
@@ -862,7 +866,7 @@ void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) {
assert
(
Func
);
{
TimerMarker
_
(
TimerStack
::
TT_qTransPush
,
this
);
OptQ
.
blockingPush
(
Func
.
release
(
));
OptQ
.
blockingPush
(
std
::
move
(
Func
));
}
if
(
getFlags
().
isSequential
())
translateFunctions
();
...
...
@@ -873,17 +877,18 @@ std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() {
return
std
::
unique_ptr
<
Cfg
>
(
OptQ
.
blockingPop
());
}
void
GlobalContext
::
emitQueueBlockingPush
(
EmitterWorkItem
*
Item
)
{
void
GlobalContext
::
emitQueueBlockingPush
(
std
::
unique_ptr
<
EmitterWorkItem
>
Item
)
{
assert
(
Item
);
{
TimerMarker
_
(
TimerStack
::
TT_qEmitPush
,
this
);
EmitQ
.
blockingPush
(
Item
);
EmitQ
.
blockingPush
(
std
::
move
(
Item
)
);
}
if
(
getFlags
().
isSequential
())
emitItems
();
}
EmitterWorkItem
*
GlobalContext
::
emitQueueBlockingPop
()
{
std
::
unique_ptr
<
EmitterWorkItem
>
GlobalContext
::
emitQueueBlockingPop
()
{
TimerMarker
_
(
TimerStack
::
TT_qEmitPop
,
this
);
return
EmitQ
.
blockingPop
();
}
...
...
src/IceGlobalContext.h
View file @
bd2e2315
...
...
@@ -28,9 +28,11 @@
#include <array>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>
#include <type_traits>
#include <utility>
#include <vector>
namespace
Ice
{
...
...
@@ -336,8 +338,8 @@ public:
void
lowerJumpTables
();
void
emitQueueBlockingPush
(
EmitterWorkItem
*
Item
);
EmitterWorkItem
*
emitQueueBlockingPop
();
void
emitQueueBlockingPush
(
std
::
unique_ptr
<
EmitterWorkItem
>
Item
);
std
::
unique_ptr
<
EmitterWorkItem
>
emitQueueBlockingPop
();
void
emitQueueNotifyEnd
()
{
EmitQ
.
notifyEnd
();
}
void
initParserThread
()
{
...
...
src/IceThreading.cpp
View file @
bd2e2315
...
...
@@ -22,15 +22,16 @@ namespace Ice {
EmitterWorkItem
::
EmitterWorkItem
(
uint32_t
Seq
)
:
Sequence
(
Seq
),
Kind
(
WI_Nop
),
GlobalInits
(
nullptr
),
Function
(
nullptr
),
RawFunc
(
nullptr
)
{}
EmitterWorkItem
::
EmitterWorkItem
(
uint32_t
Seq
,
VariableDeclarationList
*
D
)
:
Sequence
(
Seq
),
Kind
(
WI_GlobalInits
),
GlobalInits
(
D
),
Function
(
nullptr
),
EmitterWorkItem
::
EmitterWorkItem
(
uint32_t
Seq
,
std
::
unique_ptr
<
VariableDeclarationList
>
D
)
:
Sequence
(
Seq
),
Kind
(
WI_GlobalInits
),
GlobalInits
(
std
::
move
(
D
)),
Function
(
nullptr
),
RawFunc
(
nullptr
)
{}
EmitterWorkItem
::
EmitterWorkItem
(
uint32_t
Seq
,
std
::
unique_ptr
<
Assembler
>
A
)
:
Sequence
(
Seq
),
Kind
(
WI_Asm
),
GlobalInits
(
nullptr
),
Function
(
std
::
move
(
A
)),
RawFunc
(
nullptr
)
{}
EmitterWorkItem
::
EmitterWorkItem
(
uint32_t
Seq
,
Assembler
*
A
)
:
Sequence
(
Seq
),
Kind
(
WI_Asm
),
GlobalInits
(
nullptr
),
Function
(
A
),
RawFunc
(
nullptr
)
{}
EmitterWorkItem
::
EmitterWorkItem
(
uint32_t
Seq
,
Cfg
*
F
)
EmitterWorkItem
::
EmitterWorkItem
(
uint32_t
Seq
,
std
::
unique_ptr
<
Cfg
>
F
)
:
Sequence
(
Seq
),
Kind
(
WI_Cfg
),
GlobalInits
(
nullptr
),
Function
(
nullptr
),
RawFunc
(
F
)
{}
RawFunc
(
std
::
move
(
F
)
)
{}
void
EmitterWorkItem
::
setGlobalInits
(
std
::
unique_ptr
<
VariableDeclarationList
>
GloblInits
)
{
...
...
src/IceThreading.h
View file @
bd2e2315
...
...
@@ -18,7 +18,9 @@
#include "IceDefs.h"
#include <condition_variable>
#include <memory>
#include <mutex>
#include <utility>
namespace
Ice
{
...
...
@@ -55,18 +57,18 @@ class BoundedProducerConsumerQueue {
public
:
BoundedProducerConsumerQueue
(
bool
Sequential
,
size_t
MaxSize
=
MaxStaticSize
)
:
MaxSize
(
std
::
min
(
MaxSize
,
MaxStaticSize
)),
Sequential
(
Sequential
)
{}
void
blockingPush
(
T
*
Item
)
{
void
blockingPush
(
std
::
unique_ptr
<
T
>
Item
)
{
{
std
::
unique_lock
<
GlobalLockType
>
L
(
Lock
);
// If the work queue is already "full", wait for a consumer to grab an
// element and shrink the queue.
Shrunk
.
wait
(
L
,
[
this
]
{
return
size
()
<
MaxSize
||
Sequential
;
});
push
(
Item
);
push
(
std
::
move
(
Item
)
);
}
GrewOrEnded
.
notify_one
();
}
T
*
blockingPop
()
{
T
*
Item
=
nullptr
;
std
::
unique_ptr
<
T
>
blockingPop
()
{
std
::
unique_ptr
<
T
>
Item
;
bool
ShouldNotifyProducer
=
false
;
{
std
::
unique_lock
<
GlobalLockType
>
L
(
Lock
);
...
...
@@ -95,7 +97,7 @@ private:
ICE_CACHELINE_BOUNDARY
;
/// WorkItems and Lock are read/written by all.
T
*
WorkItems
[
MaxStaticSize
];
std
::
unique_ptr
<
T
>
WorkItems
[
MaxStaticSize
];
ICE_CACHELINE_BOUNDARY
;
/// Lock guards access to WorkItems, Front, Back, and IsEnded.
GlobalLockType
Lock
;
...
...
@@ -131,13 +133,13 @@ private:
/// The lock must be held when the following methods are called.
bool
empty
()
const
{
return
Front
==
Back
;
}
size_t
size
()
const
{
return
Back
-
Front
;
}
void
push
(
T
*
Item
)
{
WorkItems
[
Back
++
&
MaxStaticSizeMask
]
=
Item
;
void
push
(
std
::
unique_ptr
<
T
>
Item
)
{
WorkItems
[
Back
++
&
MaxStaticSizeMask
]
=
std
::
move
(
Item
)
;
assert
(
size
()
<=
MaxStaticSize
);
}
T
*
pop
()
{
std
::
unique_ptr
<
T
>
pop
()
{
assert
(
!
empty
());
return
WorkItems
[
Front
++
&
MaxStaticSizeMask
]
;
return
std
::
move
(
WorkItems
[
Front
++
&
MaxStaticSizeMask
])
;
}
};
...
...
@@ -174,11 +176,11 @@ public:
/// Constructor for a WI_Nop work item.
explicit
EmitterWorkItem
(
uint32_t
Seq
);
/// Constructor for a WI_GlobalInits work item.
EmitterWorkItem
(
uint32_t
Seq
,
VariableDeclarationList
*
D
);
EmitterWorkItem
(
uint32_t
Seq
,
std
::
unique_ptr
<
VariableDeclarationList
>
D
);
/// Constructor for a WI_Asm work item.
EmitterWorkItem
(
uint32_t
Seq
,
Assembler
*
A
);
EmitterWorkItem
(
uint32_t
Seq
,
std
::
unique_ptr
<
Assembler
>
A
);
/// Constructor for a WI_Cfg work item.
EmitterWorkItem
(
uint32_t
Seq
,
Cfg
*
F
);
EmitterWorkItem
(
uint32_t
Seq
,
std
::
unique_ptr
<
Cfg
>
F
);
uint32_t
getSequenceNumber
()
const
{
return
Sequence
;
}
ItemKind
getKind
()
const
{
return
Kind
;
}
void
setGlobalInits
(
std
::
unique_ptr
<
VariableDeclarationList
>
GloblInits
);
...
...
src/IceTranslator.cpp
View file @
bd2e2315
...
...
@@ -14,13 +14,15 @@
#include "IceTranslator.h"
#include "IceDefs.h"
#include "IceCfg.h"
#include "IceClFlags.h"
#include "IceDefs.h"
#include "IceGlobalInits.h"
#include "IceTargetLowering.h"
using
namespace
Ice
;
#include <utility>
namespace
Ice
{
Translator
::
Translator
(
GlobalContext
*
Ctx
)
:
Ctx
(
Ctx
),
NextSequenceNumber
(
GlobalContext
::
getFirstSequenceNumber
()),
...
...
@@ -58,7 +60,8 @@ void Translator::translateFcn(std::unique_ptr<Cfg> Func) {
void
Translator
::
lowerGlobals
(
std
::
unique_ptr
<
VariableDeclarationList
>
VariableDeclarations
)
{
EmitterWorkItem
*
Item
=
new
EmitterWorkItem
(
getNextSequenceNumber
(),
VariableDeclarations
.
release
());
Ctx
->
emitQueueBlockingPush
(
Item
);
Ctx
->
emitQueueBlockingPush
(
makeUnique
<
EmitterWorkItem
>
(
getNextSequenceNumber
(),
std
::
move
(
VariableDeclarations
)));
}
}
// end of namespace Ice
src/IceTranslator.h
View file @
bd2e2315
...
...
@@ -19,6 +19,8 @@
#include "IceDefs.h"
#include "IceGlobalContext.h"
#include <memory>
namespace
llvm
{
class
Module
;
}
// end of namespace llvm
...
...
@@ -48,8 +50,7 @@ public:
const
ClFlags
&
getFlags
()
const
{
return
Ctx
->
getFlags
();
}
/// Translates the constructed ICE function Fcn to machine code. Takes
/// ownership of Func.
/// Translates the constructed ICE function Func to machine code.
void
translateFcn
(
std
::
unique_ptr
<
Cfg
>
Func
);
/// Lowers the given list of global addresses to target. Generates list of
...
...
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