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
811d9f4c
Commit
811d9f4c
authored
Aug 17, 2016
by
steve-lunarg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP: SPIRV remapper: allow 64 bit literals in OperandVariableLiteralId class iteration
parent
057c01ef
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
129 additions
and
53 deletions
+129
-53
SPVRemapper.cpp
SPIRV/SPVRemapper.cpp
+111
-41
SPVRemapper.h
SPIRV/SPVRemapper.h
+18
-12
No files found.
SPIRV/SPVRemapper.cpp
View file @
811d9f4c
...
@@ -127,6 +127,33 @@ namespace spv {
...
@@ -127,6 +127,33 @@ 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
:
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
auto
tid_it
=
idTypeSizeMap
.
find
(
id
);
if
(
tid_it
==
idTypeSizeMap
.
end
())
error
(
"type size for ID not found"
);
return
tid_it
->
second
;
}
// Is this an opcode we should remove when using --strip?
// Is this an opcode we should remove when using --strip?
bool
spirvbin_t
::
isStripOp
(
spv
::
Op
opCode
)
const
bool
spirvbin_t
::
isStripOp
(
spv
::
Op
opCode
)
const
{
{
...
@@ -140,6 +167,7 @@ namespace spv {
...
@@ -140,6 +167,7 @@ namespace spv {
}
}
}
}
// Return true if this opcode is flow control
bool
spirvbin_t
::
isFlowCtrl
(
spv
::
Op
opCode
)
const
bool
spirvbin_t
::
isFlowCtrl
(
spv
::
Op
opCode
)
const
{
{
switch
(
opCode
)
{
switch
(
opCode
)
{
...
@@ -155,6 +183,7 @@ namespace spv {
...
@@ -155,6 +183,7 @@ namespace spv {
}
}
}
}
// Return true if this opcode defines a type
bool
spirvbin_t
::
isTypeOp
(
spv
::
Op
opCode
)
const
bool
spirvbin_t
::
isTypeOp
(
spv
::
Op
opCode
)
const
{
{
switch
(
opCode
)
{
switch
(
opCode
)
{
...
@@ -182,6 +211,7 @@ namespace spv {
...
@@ -182,6 +211,7 @@ namespace spv {
}
}
}
}
// Return true if this opcode defines a constant
bool
spirvbin_t
::
isConstOp
(
spv
::
Op
opCode
)
const
bool
spirvbin_t
::
isConstOp
(
spv
::
Op
opCode
)
const
{
{
switch
(
opCode
)
{
switch
(
opCode
)
{
...
@@ -324,7 +354,7 @@ namespace spv {
...
@@ -324,7 +354,7 @@ namespace spv {
fnPosDCE
.
clear
();
fnPosDCE
.
clear
();
fnCalls
.
clear
();
fnCalls
.
clear
();
typeConstPos
.
clear
();
typeConstPos
.
clear
();
typeConst
PosR
.
clear
();
id
PosR
.
clear
();
entryPoint
=
spv
::
NoResult
;
entryPoint
=
spv
::
NoResult
;
largestNewId
=
0
;
largestNewId
=
0
;
...
@@ -340,6 +370,25 @@ namespace spv {
...
@@ -340,6 +370,25 @@ namespace spv {
if
((
options
&
STRIP
)
&&
isStripOp
(
opCode
))
if
((
options
&
STRIP
)
&&
isStripOp
(
opCode
))
stripInst
(
start
);
stripInst
(
start
);
unsigned
word
=
start
+
1
;
spv
::
Id
typeId
=
spv
::
NoResult
;
if
(
spv
::
InstructionDesc
[
opCode
].
hasType
())
typeId
=
asId
(
word
++
);
// If there's a result ID, remember the size of its type
if
(
spv
::
InstructionDesc
[
opCode
].
hasResult
())
{
const
spv
::
Id
resultId
=
asId
(
word
++
);
idPosR
[
resultId
]
=
start
;
if
(
typeId
!=
spv
::
NoResult
)
{
const
unsigned
idTypeSize
=
typeSizeInWords
(
typeId
);
if
(
idTypeSize
!=
0
)
idTypeSizeMap
[
resultId
]
=
idTypeSize
;
}
}
if
(
opCode
==
spv
::
Op
::
OpName
)
{
if
(
opCode
==
spv
::
Op
::
OpName
)
{
const
spv
::
Id
target
=
asId
(
start
+
1
);
const
spv
::
Id
target
=
asId
(
start
+
1
);
const
std
::
string
name
=
literalString
(
start
+
2
);
const
std
::
string
name
=
literalString
(
start
+
2
);
...
@@ -363,11 +412,9 @@ namespace spv {
...
@@ -363,11 +412,9 @@ namespace spv {
}
else
if
(
isConstOp
(
opCode
))
{
}
else
if
(
isConstOp
(
opCode
))
{
assert
(
asId
(
start
+
2
)
!=
spv
::
NoResult
);
assert
(
asId
(
start
+
2
)
!=
spv
::
NoResult
);
typeConstPos
.
insert
(
start
);
typeConstPos
.
insert
(
start
);
typeConstPosR
[
asId
(
start
+
2
)]
=
start
;
}
else
if
(
isTypeOp
(
opCode
))
{
}
else
if
(
isTypeOp
(
opCode
))
{
assert
(
asId
(
start
+
1
)
!=
spv
::
NoResult
);
assert
(
asId
(
start
+
1
)
!=
spv
::
NoResult
);
typeConstPos
.
insert
(
start
);
typeConstPos
.
insert
(
start
);
typeConstPosR
[
asId
(
start
+
1
)]
=
start
;
}
}
return
false
;
return
false
;
...
@@ -436,12 +483,19 @@ namespace spv {
...
@@ -436,12 +483,19 @@ namespace spv {
return
nextInst
;
return
nextInst
;
}
}
// Circular buffer so we can look back at previous unmapped values during the mapping pass.
static
const
unsigned
idBufferSize
=
4
;
spv
::
Id
idBuffer
[
idBufferSize
];
unsigned
idBufferPos
=
0
;
// Store IDs from instruction in our map
// Store IDs from instruction in our map
for
(
int
op
=
0
;
numOperands
>
0
;
++
op
,
--
numOperands
)
{
for
(
int
op
=
0
;
numOperands
>
0
;
++
op
,
--
numOperands
)
{
switch
(
spv
::
InstructionDesc
[
opCode
].
operands
.
getClass
(
op
))
{
switch
(
spv
::
InstructionDesc
[
opCode
].
operands
.
getClass
(
op
))
{
case
spv
:
:
OperandId
:
case
spv
:
:
OperandId
:
case
spv
:
:
OperandScope
:
case
spv
:
:
OperandScope
:
case
spv
:
:
OperandMemorySemantics
:
case
spv
:
:
OperandMemorySemantics
:
idBuffer
[
idBufferPos
]
=
asId
(
word
);
idBufferPos
=
(
idBufferPos
+
1
)
%
idBufferSize
;
idFn
(
asId
(
word
++
));
idFn
(
asId
(
word
++
));
break
;
break
;
...
@@ -459,13 +513,25 @@ namespace spv {
...
@@ -459,13 +513,25 @@ namespace spv {
// word += numOperands;
// word += numOperands;
return
nextInst
;
return
nextInst
;
case
spv
:
:
OperandVariableLiteralId
:
case
spv
:
:
OperandVariableLiteralId
:
{
while
(
numOperands
>
0
)
{
if
(
opCode
==
OpSwitch
)
{
++
word
;
// immediate
// word-2 is the position of the selector ID. OpSwitch Literals match its type.
idFn
(
asId
(
word
++
));
// ID
// In case the IDs are currently being remapped, we get the word[-2] ID from
numOperands
-=
2
;
// the circular idBuffer.
const
unsigned
literalSizePos
=
(
idBufferPos
+
idBufferSize
-
2
)
%
idBufferSize
;
const
unsigned
literalSize
=
idTypeSizeInWords
(
idBuffer
[
literalSizePos
]);
const
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
;
return
nextInst
;
}
case
spv
:
:
OperandLiteralString
:
{
case
spv
:
:
OperandLiteralString
:
{
const
int
stringWordCount
=
literalStringWords
(
literalString
(
word
));
const
int
stringWordCount
=
literalStringWords
(
literalString
(
word
));
...
@@ -966,23 +1032,27 @@ namespace spv {
...
@@ -966,23 +1032,27 @@ namespace spv {
std
::
unordered_map
<
spv
::
Id
,
int
>
typeUseCount
;
std
::
unordered_map
<
spv
::
Id
,
int
>
typeUseCount
;
// Count total type usage
// This is not the most efficient algorithm, but this is an offline tool, and
process
(
inst_fn_nop
,
// it's easy to write this way. Can be improved opportunistically if needed.
[
&
](
spv
::
Id
&
id
)
{
if
(
isType
[
id
])
++
typeUseCount
[
id
];
}
bool
changed
=
true
;
);
while
(
changed
)
{
changed
=
false
;
strip
();
typeUseCount
.
clear
();
// Remove types from deleted code
// Count total type usage
for
(
const
auto
&
fn
:
fnPosDCE
)
process
(
inst_fn_nop
,
process
(
inst_fn_nop
,
[
&
](
spv
::
Id
&
id
)
{
if
(
isType
[
id
])
--
typeUseCount
[
id
];
},
[
&
](
spv
::
Id
&
id
)
{
if
(
isType
[
id
])
++
typeUseCount
[
id
];
}
fn
.
second
.
first
,
fn
.
second
.
second
);
);
// Remove single reference types
// Remove single reference types
for
(
const
auto
typeStart
:
typeConstPos
)
{
for
(
const
auto
typeStart
:
typeConstPos
)
{
const
spv
::
Id
typeId
=
asTypeConstId
(
typeStart
);
const
spv
::
Id
typeId
=
asTypeConstId
(
typeStart
);
if
(
typeUseCount
[
typeId
]
==
1
)
{
if
(
typeUseCount
[
typeId
]
==
1
)
{
--
typeUseCount
[
typeId
];
changed
=
true
;
stripInst
(
typeStart
);
--
typeUseCount
[
typeId
];
stripInst
(
typeStart
);
}
}
}
}
}
}
}
...
@@ -1060,12 +1130,12 @@ namespace spv {
...
@@ -1060,12 +1130,12 @@ namespace spv {
}
}
#endif // NOTDEF
#endif // NOTDEF
// Return start position in SPV of given
type
. error if not found.
// Return start position in SPV of given
Id
. error if not found.
unsigned
spirvbin_t
::
type
Pos
(
spv
::
Id
id
)
const
unsigned
spirvbin_t
::
id
Pos
(
spv
::
Id
id
)
const
{
{
const
auto
tid_it
=
typeConst
PosR
.
find
(
id
);
const
auto
tid_it
=
id
PosR
.
find
(
id
);
if
(
tid_it
==
typeConst
PosR
.
end
())
if
(
tid_it
==
id
PosR
.
end
())
error
(
"
type
ID not found"
);
error
(
"ID not found"
);
return
tid_it
->
second
;
return
tid_it
->
second
;
}
}
...
@@ -1083,11 +1153,11 @@ namespace spv {
...
@@ -1083,11 +1153,11 @@ namespace spv {
case
spv
:
:
OpTypeInt
:
return
3
+
(
spv
[
typeStart
+
3
]);
case
spv
:
:
OpTypeInt
:
return
3
+
(
spv
[
typeStart
+
3
]);
case
spv
:
:
OpTypeFloat
:
return
5
;
case
spv
:
:
OpTypeFloat
:
return
5
;
case
spv
:
:
OpTypeVector
:
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
:
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
:
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
+
3
]
+
// dimensionality
spv
[
typeStart
+
4
]
*
8
*
16
+
// depth
spv
[
typeStart
+
4
]
*
8
*
16
+
// depth
spv
[
typeStart
+
5
]
*
4
*
16
+
// arrayed
spv
[
typeStart
+
5
]
*
4
*
16
+
// arrayed
...
@@ -1098,24 +1168,24 @@ namespace spv {
...
@@ -1098,24 +1168,24 @@ namespace spv {
case
spv
:
:
OpTypeSampledImage
:
case
spv
:
:
OpTypeSampledImage
:
return
502
;
return
502
;
case
spv
:
:
OpTypeArray
:
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
:
case
spv
:
:
OpTypeRuntimeArray
:
return
5000
+
hashType
(
type
Pos
(
spv
[
typeStart
+
2
]));
return
5000
+
hashType
(
id
Pos
(
spv
[
typeStart
+
2
]));
case
spv
:
:
OpTypeStruct
:
case
spv
:
:
OpTypeStruct
:
{
{
std
::
uint32_t
hash
=
10000
;
std
::
uint32_t
hash
=
10000
;
for
(
unsigned
w
=
2
;
w
<
wordCount
;
++
w
)
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
;
return
hash
;
}
}
case
spv
:
:
OpTypeOpaque
:
return
6000
+
spv
[
typeStart
+
2
];
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
:
case
spv
:
:
OpTypeFunction
:
{
{
std
::
uint32_t
hash
=
200000
;
std
::
uint32_t
hash
=
200000
;
for
(
unsigned
w
=
2
;
w
<
wordCount
;
++
w
)
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
;
return
hash
;
}
}
...
@@ -1132,14 +1202,14 @@ namespace spv {
...
@@ -1132,14 +1202,14 @@ namespace spv {
case
spv
:
:
OpConstantFalse
:
return
300008
;
case
spv
:
:
OpConstantFalse
:
return
300008
;
case
spv
:
:
OpConstantComposite
:
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
)
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
;
return
hash
;
}
}
case
spv
:
:
OpConstant
:
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
)
for
(
unsigned
w
=
3
;
w
<
wordCount
;
++
w
)
hash
+=
w
*
spv
[
typeStart
+
w
];
hash
+=
w
*
spv
[
typeStart
+
w
];
return
hash
;
return
hash
;
...
@@ -1212,19 +1282,19 @@ namespace spv {
...
@@ -1212,19 +1282,19 @@ namespace spv {
msg
(
3
,
4
,
std
::
string
(
"ID bound: "
)
+
std
::
to_string
(
bound
()));
msg
(
3
,
4
,
std
::
string
(
"ID bound: "
)
+
std
::
to_string
(
bound
()));
strip
();
// strip out data we decided to eliminate
strip
();
// strip out data we decided to eliminate
if
(
options
&
OPT_LOADSTORE
)
optLoadStore
();
if
(
options
&
OPT_LOADSTORE
)
optLoadStore
();
if
(
options
&
OPT_FWD_LS
)
forwardLoadStores
();
if
(
options
&
OPT_FWD_LS
)
forwardLoadStores
();
if
(
options
&
DCE_FUNCS
)
dceFuncs
();
if
(
options
&
DCE_FUNCS
)
dceFuncs
();
if
(
options
&
DCE_VARS
)
dceVars
();
if
(
options
&
DCE_VARS
)
dceVars
();
if
(
options
&
DCE_TYPES
)
dceTypes
();
if
(
options
&
DCE_TYPES
)
dceTypes
();
strip
();
// strip out data we decided to eliminate
if
(
options
&
MAP_TYPES
)
mapTypeConst
();
if
(
options
&
MAP_TYPES
)
mapTypeConst
();
if
(
options
&
MAP_NAMES
)
mapNames
();
if
(
options
&
MAP_NAMES
)
mapNames
();
if
(
options
&
MAP_FUNCS
)
mapFnBodies
();
if
(
options
&
MAP_FUNCS
)
mapFnBodies
();
mapRemainder
();
// map any unmapped IDs
mapRemainder
();
// map any unmapped IDs
applyMap
();
// Now remap each shader to the new IDs we've come up with
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
// remap from a memory image
...
...
SPIRV/SPVRemapper.h
View file @
811d9f4c
...
@@ -159,16 +159,21 @@ private:
...
@@ -159,16 +159,21 @@ private:
typedef
std
::
set
<
int
>
posmap_t
;
typedef
std
::
set
<
int
>
posmap_t
;
typedef
std
::
unordered_map
<
spv
::
Id
,
int
>
posmap_rev_t
;
typedef
std
::
unordered_map
<
spv
::
Id
,
int
>
posmap_rev_t
;
// Maps and ID to the size of its base type, if known.
typedef
std
::
unordered_map
<
spv
::
Id
,
unsigned
>
typesize_map_t
;
// handle error
// handle error
void
error
(
const
std
::
string
&
txt
)
const
{
errorHandler
(
txt
);
}
void
error
(
const
std
::
string
&
txt
)
const
{
errorHandler
(
txt
);
}
bool
isConstOp
(
spv
::
Op
opCode
)
const
;
bool
isConstOp
(
spv
::
Op
opCode
)
const
;
bool
isTypeOp
(
spv
::
Op
opCode
)
const
;
bool
isTypeOp
(
spv
::
Op
opCode
)
const
;
bool
isStripOp
(
spv
::
Op
opCode
)
const
;
bool
isStripOp
(
spv
::
Op
opCode
)
const
;
bool
isFlowCtrl
(
spv
::
Op
opCode
)
const
;
bool
isFlowCtrl
(
spv
::
Op
opCode
)
const
;
range_t
literalRange
(
spv
::
Op
opCode
)
const
;
range_t
literalRange
(
spv
::
Op
opCode
)
const
;
range_t
typeRange
(
spv
::
Op
opCode
)
const
;
range_t
typeRange
(
spv
::
Op
opCode
)
const
;
range_t
constRange
(
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
];
}
spv
::
Id
&
asId
(
unsigned
word
)
{
return
spv
[
word
];
}
const
spv
::
Id
&
asId
(
unsigned
word
)
const
{
return
spv
[
word
];
}
const
spv
::
Id
&
asId
(
unsigned
word
)
const
{
return
spv
[
word
];
}
...
@@ -177,10 +182,10 @@ private:
...
@@ -177,10 +182,10 @@ private:
spv
::
Decoration
asDecoration
(
unsigned
word
)
const
{
return
spv
::
Decoration
(
spv
[
word
]);
}
spv
::
Decoration
asDecoration
(
unsigned
word
)
const
{
return
spv
::
Decoration
(
spv
[
word
]);
}
unsigned
asWordCount
(
unsigned
word
)
const
{
return
opWordCount
(
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
));
}
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
unsigned
opWordCount
(
spirword_t
data
)
{
return
data
>>
spv
::
WordCountShift
;
}
static
spv
::
Op
opOpCode
(
spirword_t
data
)
{
return
spv
::
Op
(
data
&
spv
::
OpCodeMask
);
}
static
spv
::
Op
opOpCode
(
spirword_t
data
)
{
return
spv
::
Op
(
data
&
spv
::
OpCodeMask
);
}
// Header access & set methods
// Header access & set methods
spirword_t
magic
()
const
{
return
spv
[
0
];
}
// return magic number
spirword_t
magic
()
const
{
return
spv
[
0
];
}
// return magic number
...
@@ -263,8 +268,9 @@ private:
...
@@ -263,8 +268,9 @@ private:
// Which functions are called, anywhere in the module, with a call count
// Which functions are called, anywhere in the module, with a call count
std
::
unordered_map
<
spv
::
Id
,
int
>
fnCalls
;
std
::
unordered_map
<
spv
::
Id
,
int
>
fnCalls
;
posmap_t
typeConstPos
;
// word positions that define types & consts (ordered)
posmap_t
typeConstPos
;
// word positions that define types & consts (ordered)
posmap_rev_t
typeConstPosR
;
// reverse map from IDs to positions
posmap_rev_t
idPosR
;
// reverse map from IDs to positions
typesize_map_t
idTypeSizeMap
;
// maps each ID to its type size, if known.
std
::
vector
<
spv
::
Id
>
idMapL
;
// ID {M}ap from {L}ocal to {G}lobal IDs
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