Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
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
glslang
Commits
ad08b30f
Commit
ad08b30f
authored
Aug 12, 2016
by
John Kessenich
Committed by
GitHub
Aug 12, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #456 from steve-lunarg/remapper-literal64
SPIRV: Remapper: allow 64 bit literals in OperandVariableLiteralId iteration
parents
28660bb5
b249f2fc
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
108 additions
and
53 deletions
+108
-53
SPVRemapper.cpp
SPIRV/SPVRemapper.cpp
+94
-41
SPVRemapper.h
SPIRV/SPVRemapper.h
+14
-12
No files found.
SPIRV/SPVRemapper.cpp
View file @
ad08b30f
...
...
@@ -127,6 +127,37 @@ namespace spv {
}
}
// Return the size of a type in 32-bit words. This currently only
// handles ints and floats, and is only invoked by queries which must be
// integer types. If ever needed, it can be generalized.
unsigned
spirvbin_t
::
typeSizeInWords
(
spv
::
Id
id
)
const
{
const
unsigned
typeStart
=
idPos
(
id
);
const
spv
::
Op
opCode
=
asOpCode
(
typeStart
);
switch
(
opCode
)
{
case
spv
:
:
OpTypeInt
:
// fall through...
case
spv
:
:
OpTypeFloat
:
return
(
spv
[
typeStart
+
2
]
+
31
)
/
32
;
default
:
error
(
"unimplemented type size request"
);
return
0
;
}
}
// Looks up the type of a given const or variable ID, and
// returns its size in 32-bit words.
unsigned
spirvbin_t
::
idTypeSizeInWords
(
spv
::
Id
id
)
const
{
const
unsigned
idStart
=
idPos
(
id
);
const
spv
::
Op
opCode
=
asOpCode
(
idStart
);
if
(
spv
::
InstructionDesc
[
opCode
].
hasType
())
return
typeSizeInWords
(
asId
(
idStart
+
1
));
error
(
"asked for type of typeless ID"
);
return
0
;
}
// Is this an opcode we should remove when using --strip?
bool
spirvbin_t
::
isStripOp
(
spv
::
Op
opCode
)
const
{
...
...
@@ -140,6 +171,7 @@ namespace spv {
}
}
// Return true if this opcode is flow control
bool
spirvbin_t
::
isFlowCtrl
(
spv
::
Op
opCode
)
const
{
switch
(
opCode
)
{
...
...
@@ -155,6 +187,7 @@ namespace spv {
}
}
// Return true if this opcode defines a type
bool
spirvbin_t
::
isTypeOp
(
spv
::
Op
opCode
)
const
{
switch
(
opCode
)
{
...
...
@@ -182,6 +215,7 @@ namespace spv {
}
}
// Return true if this opcode defines a constant
bool
spirvbin_t
::
isConstOp
(
spv
::
Op
opCode
)
const
{
switch
(
opCode
)
{
...
...
@@ -324,7 +358,7 @@ namespace spv {
fnPosDCE
.
clear
();
fnCalls
.
clear
();
typeConstPos
.
clear
();
typeConst
PosR
.
clear
();
id
PosR
.
clear
();
entryPoint
=
spv
::
NoResult
;
largestNewId
=
0
;
...
...
@@ -340,6 +374,14 @@ namespace spv {
if
((
options
&
STRIP
)
&&
isStripOp
(
opCode
))
stripInst
(
start
);
unsigned
word
=
start
+
1
;
if
(
spv
::
InstructionDesc
[
opCode
].
hasType
())
word
++
;
if
(
spv
::
InstructionDesc
[
opCode
].
hasResult
())
idPosR
[
asId
(
word
++
)]
=
start
;
if
(
opCode
==
spv
::
Op
::
OpName
)
{
const
spv
::
Id
target
=
asId
(
start
+
1
);
const
std
::
string
name
=
literalString
(
start
+
2
);
...
...
@@ -363,11 +405,9 @@ namespace spv {
}
else
if
(
isConstOp
(
opCode
))
{
assert
(
asId
(
start
+
2
)
!=
spv
::
NoResult
);
typeConstPos
.
insert
(
start
);
typeConstPosR
[
asId
(
start
+
2
)]
=
start
;
}
else
if
(
isTypeOp
(
opCode
))
{
assert
(
asId
(
start
+
1
)
!=
spv
::
NoResult
);
typeConstPos
.
insert
(
start
);
typeConstPosR
[
asId
(
start
+
1
)]
=
start
;
}
return
false
;
...
...
@@ -459,13 +499,22 @@ namespace spv {
// word += numOperands;
return
nextInst
;
case
spv
:
:
OperandVariableLiteralId
:
while
(
numOperands
>
0
)
{
++
word
;
// immediate
idFn
(
asId
(
word
++
));
// ID
numOperands
-=
2
;
case
spv
:
:
OperandVariableLiteralId
:
{
if
(
opCode
==
OpSwitch
)
{
// word-2 is the position of the selector ID. Literals match its type.
const
unsigned
literalSize
=
idTypeSizeInWords
(
asId
(
word
-
2
));
unsigned
numLiteralIdPairs
=
(
nextInst
-
word
)
/
(
1
+
literalSize
);
for
(
unsigned
arg
=
0
;
arg
<
numLiteralIdPairs
;
++
arg
)
{
word
+=
literalSize
;
// literal
idFn
(
asId
(
word
++
));
// label
}
}
else
{
assert
(
0
);
// currentely, only OpSwitch uses OperandVariableLiteralId
}
return
nextInst
;
}
case
spv
:
:
OperandLiteralString
:
{
const
int
stringWordCount
=
literalStringWords
(
literalString
(
word
));
...
...
@@ -966,23 +1015,27 @@ namespace spv {
std
::
unordered_map
<
spv
::
Id
,
int
>
typeUseCount
;
// Count total type usage
process
(
inst_fn_nop
,
[
&
](
spv
::
Id
&
id
)
{
if
(
isType
[
id
])
++
typeUseCount
[
id
];
}
);
// This is not the most efficient algorithm, but this is an offline tool, and
// it's easy to write this way. Can be improved opportunistically if needed.
bool
changed
=
true
;
while
(
changed
)
{
changed
=
false
;
strip
();
typeUseCount
.
clear
();
// Remove types from deleted code
for
(
const
auto
&
fn
:
fnPosDCE
)
// Count total type usage
process
(
inst_fn_nop
,
[
&
](
spv
::
Id
&
id
)
{
if
(
isType
[
id
])
--
typeUseCount
[
id
];
},
fn
.
second
.
first
,
fn
.
second
.
second
);
// Remove single reference types
for
(
const
auto
typeStart
:
typeConstPos
)
{
const
spv
::
Id
typeId
=
asTypeConstId
(
typeStart
);
if
(
typeUseCount
[
typeId
]
==
1
)
{
--
typeUseCount
[
typeId
];
stripInst
(
typeStart
);
[
&
](
spv
::
Id
&
id
)
{
if
(
isType
[
id
])
++
typeUseCount
[
id
];
}
);
// Remove single reference types
for
(
const
auto
typeStart
:
typeConstPos
)
{
const
spv
::
Id
typeId
=
asTypeConstId
(
typeStart
);
if
(
typeUseCount
[
typeId
]
==
1
)
{
changed
=
true
;
--
typeUseCount
[
typeId
];
stripInst
(
typeStart
);
}
}
}
}
...
...
@@ -1060,12 +1113,12 @@ namespace spv {
}
#endif // NOTDEF
// Return start position in SPV of given
type
. error if not found.
unsigned
spirvbin_t
::
type
Pos
(
spv
::
Id
id
)
const
// Return start position in SPV of given
Id
. error if not found.
unsigned
spirvbin_t
::
id
Pos
(
spv
::
Id
id
)
const
{
const
auto
tid_it
=
typeConst
PosR
.
find
(
id
);
if
(
tid_it
==
typeConst
PosR
.
end
())
error
(
"
type
ID not found"
);
const
auto
tid_it
=
id
PosR
.
find
(
id
);
if
(
tid_it
==
id
PosR
.
end
())
error
(
"ID not found"
);
return
tid_it
->
second
;
}
...
...
@@ -1083,11 +1136,11 @@ namespace spv {
case
spv
:
:
OpTypeInt
:
return
3
+
(
spv
[
typeStart
+
3
]);
case
spv
:
:
OpTypeFloat
:
return
5
;
case
spv
:
:
OpTypeVector
:
return
6
+
hashType
(
type
Pos
(
spv
[
typeStart
+
2
]))
*
(
spv
[
typeStart
+
3
]
-
1
);
return
6
+
hashType
(
id
Pos
(
spv
[
typeStart
+
2
]))
*
(
spv
[
typeStart
+
3
]
-
1
);
case
spv
:
:
OpTypeMatrix
:
return
30
+
hashType
(
type
Pos
(
spv
[
typeStart
+
2
]))
*
(
spv
[
typeStart
+
3
]
-
1
);
return
30
+
hashType
(
id
Pos
(
spv
[
typeStart
+
2
]))
*
(
spv
[
typeStart
+
3
]
-
1
);
case
spv
:
:
OpTypeImage
:
return
120
+
hashType
(
type
Pos
(
spv
[
typeStart
+
2
]))
+
return
120
+
hashType
(
id
Pos
(
spv
[
typeStart
+
2
]))
+
spv
[
typeStart
+
3
]
+
// dimensionality
spv
[
typeStart
+
4
]
*
8
*
16
+
// depth
spv
[
typeStart
+
5
]
*
4
*
16
+
// arrayed
...
...
@@ -1098,24 +1151,24 @@ namespace spv {
case
spv
:
:
OpTypeSampledImage
:
return
502
;
case
spv
:
:
OpTypeArray
:
return
501
+
hashType
(
type
Pos
(
spv
[
typeStart
+
2
]))
*
spv
[
typeStart
+
3
];
return
501
+
hashType
(
id
Pos
(
spv
[
typeStart
+
2
]))
*
spv
[
typeStart
+
3
];
case
spv
:
:
OpTypeRuntimeArray
:
return
5000
+
hashType
(
type
Pos
(
spv
[
typeStart
+
2
]));
return
5000
+
hashType
(
id
Pos
(
spv
[
typeStart
+
2
]));
case
spv
:
:
OpTypeStruct
:
{
std
::
uint32_t
hash
=
10000
;
for
(
unsigned
w
=
2
;
w
<
wordCount
;
++
w
)
hash
+=
w
*
hashType
(
type
Pos
(
spv
[
typeStart
+
w
]));
hash
+=
w
*
hashType
(
id
Pos
(
spv
[
typeStart
+
w
]));
return
hash
;
}
case
spv
:
:
OpTypeOpaque
:
return
6000
+
spv
[
typeStart
+
2
];
case
spv
:
:
OpTypePointer
:
return
100000
+
hashType
(
type
Pos
(
spv
[
typeStart
+
3
]));
case
spv
:
:
OpTypePointer
:
return
100000
+
hashType
(
id
Pos
(
spv
[
typeStart
+
3
]));
case
spv
:
:
OpTypeFunction
:
{
std
::
uint32_t
hash
=
200000
;
for
(
unsigned
w
=
2
;
w
<
wordCount
;
++
w
)
hash
+=
w
*
hashType
(
type
Pos
(
spv
[
typeStart
+
w
]));
hash
+=
w
*
hashType
(
id
Pos
(
spv
[
typeStart
+
w
]));
return
hash
;
}
...
...
@@ -1132,14 +1185,14 @@ namespace spv {
case
spv
:
:
OpConstantFalse
:
return
300008
;
case
spv
:
:
OpConstantComposite
:
{
std
::
uint32_t
hash
=
300011
+
hashType
(
type
Pos
(
spv
[
typeStart
+
1
]));
std
::
uint32_t
hash
=
300011
+
hashType
(
id
Pos
(
spv
[
typeStart
+
1
]));
for
(
unsigned
w
=
3
;
w
<
wordCount
;
++
w
)
hash
+=
w
*
hashType
(
type
Pos
(
spv
[
typeStart
+
w
]));
hash
+=
w
*
hashType
(
id
Pos
(
spv
[
typeStart
+
w
]));
return
hash
;
}
case
spv
:
:
OpConstant
:
{
std
::
uint32_t
hash
=
400011
+
hashType
(
type
Pos
(
spv
[
typeStart
+
1
]));
std
::
uint32_t
hash
=
400011
+
hashType
(
id
Pos
(
spv
[
typeStart
+
1
]));
for
(
unsigned
w
=
3
;
w
<
wordCount
;
++
w
)
hash
+=
w
*
spv
[
typeStart
+
w
];
return
hash
;
...
...
@@ -1212,19 +1265,19 @@ namespace spv {
msg
(
3
,
4
,
std
::
string
(
"ID bound: "
)
+
std
::
to_string
(
bound
()));
strip
();
// strip out data we decided to eliminate
if
(
options
&
OPT_LOADSTORE
)
optLoadStore
();
if
(
options
&
OPT_FWD_LS
)
forwardLoadStores
();
if
(
options
&
DCE_FUNCS
)
dceFuncs
();
if
(
options
&
DCE_VARS
)
dceVars
();
if
(
options
&
DCE_TYPES
)
dceTypes
();
strip
();
// strip out data we decided to eliminate
if
(
options
&
MAP_TYPES
)
mapTypeConst
();
if
(
options
&
MAP_NAMES
)
mapNames
();
if
(
options
&
MAP_FUNCS
)
mapFnBodies
();
mapRemainder
();
// map any unmapped IDs
applyMap
();
// Now remap each shader to the new IDs we've come up with
strip
();
// strip out data we decided to eliminate
}
// remap from a memory image
...
...
SPIRV/SPVRemapper.h
View file @
ad08b30f
...
...
@@ -162,13 +162,15 @@ private:
// handle error
void
error
(
const
std
::
string
&
txt
)
const
{
errorHandler
(
txt
);
}
bool
isConstOp
(
spv
::
Op
opCode
)
const
;
bool
isTypeOp
(
spv
::
Op
opCode
)
const
;
bool
isStripOp
(
spv
::
Op
opCode
)
const
;
bool
isFlowCtrl
(
spv
::
Op
opCode
)
const
;
range_t
literalRange
(
spv
::
Op
opCode
)
const
;
range_t
typeRange
(
spv
::
Op
opCode
)
const
;
range_t
constRange
(
spv
::
Op
opCode
)
const
;
bool
isConstOp
(
spv
::
Op
opCode
)
const
;
bool
isTypeOp
(
spv
::
Op
opCode
)
const
;
bool
isStripOp
(
spv
::
Op
opCode
)
const
;
bool
isFlowCtrl
(
spv
::
Op
opCode
)
const
;
range_t
literalRange
(
spv
::
Op
opCode
)
const
;
range_t
typeRange
(
spv
::
Op
opCode
)
const
;
range_t
constRange
(
spv
::
Op
opCode
)
const
;
unsigned
typeSizeInWords
(
spv
::
Id
id
)
const
;
unsigned
idTypeSizeInWords
(
spv
::
Id
id
)
const
;
spv
::
Id
&
asId
(
unsigned
word
)
{
return
spv
[
word
];
}
const
spv
::
Id
&
asId
(
unsigned
word
)
const
{
return
spv
[
word
];
}
...
...
@@ -177,10 +179,10 @@ private:
spv
::
Decoration
asDecoration
(
unsigned
word
)
const
{
return
spv
::
Decoration
(
spv
[
word
]);
}
unsigned
asWordCount
(
unsigned
word
)
const
{
return
opWordCount
(
spv
[
word
]);
}
spv
::
Id
asTypeConstId
(
unsigned
word
)
const
{
return
asId
(
word
+
(
isTypeOp
(
asOpCode
(
word
))
?
1
:
2
));
}
unsigned
typePos
(
spv
::
Id
id
)
const
;
unsigned
idPos
(
spv
::
Id
id
)
const
;
static
unsigned
opWordCount
(
spirword_t
data
)
{
return
data
>>
spv
::
WordCountShift
;
}
static
spv
::
Op
opOpCode
(
spirword_t
data
)
{
return
spv
::
Op
(
data
&
spv
::
OpCodeMask
);
}
static
unsigned
opWordCount
(
spirword_t
data
)
{
return
data
>>
spv
::
WordCountShift
;
}
static
spv
::
Op
opOpCode
(
spirword_t
data
)
{
return
spv
::
Op
(
data
&
spv
::
OpCodeMask
);
}
// Header access & set methods
spirword_t
magic
()
const
{
return
spv
[
0
];
}
// return magic number
...
...
@@ -263,8 +265,8 @@ private:
// Which functions are called, anywhere in the module, with a call count
std
::
unordered_map
<
spv
::
Id
,
int
>
fnCalls
;
posmap_t
typeConstPos
;
// word positions that define types & consts (ordered)
posmap_rev_t
typeConstPosR
;
// reverse map from IDs to positions
posmap_t
typeConstPos
;
// word positions that define types & consts (ordered)
posmap_rev_t
idPosR
;
// reverse map from IDs to positions
std
::
vector
<
spv
::
Id
>
idMapL
;
// ID {M}ap from {L}ocal to {G}lobal IDs
...
...
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