Merge pull request #216 from Qining/fix-non-const-array-size-from-spec-const

SPV: Generate OpSpecConstantOp for all subtrees indicated by the AST.
This commit is contained in:
John Kessenich 2016-04-06 13:14:11 -06:00
commit a8d9faba1f
6 changed files with 162 additions and 137 deletions

View file

@ -66,6 +66,27 @@ namespace {
// or a different instruction sequence to do something gets used). // or a different instruction sequence to do something gets used).
const int GeneratorVersion = 1; const int GeneratorVersion = 1;
namespace {
class SpecConstantOpModeGuard {
public:
SpecConstantOpModeGuard(spv::Builder* builder)
: builder_(builder) {
previous_flag_ = builder->isInSpecConstCodeGenMode();
}
~SpecConstantOpModeGuard() {
previous_flag_ ? builder_->setToSpecConstCodeGenMode()
: builder_->setToNormalCodeGenMode();
}
void turnOnSpecConstantOpMode() {
builder_->setToSpecConstCodeGenMode();
}
private:
spv::Builder* builder_;
bool previous_flag_;
};
}
// //
// The main holder of information for translating glslang to SPIR-V. // The main holder of information for translating glslang to SPIR-V.
// //
@ -757,6 +778,10 @@ TGlslangToSpvTraverser::~TGlslangToSpvTraverser()
// //
void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
{ {
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
if (symbol->getType().getQualifier().isSpecConstant())
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
// getSymbolId() will set up all the IO decorations on the first call. // getSymbolId() will set up all the IO decorations on the first call.
// Formal function parameters were mapped during makeFunctions(). // Formal function parameters were mapped during makeFunctions().
spv::Id id = getSymbolId(symbol); spv::Id id = getSymbolId(symbol);
@ -794,6 +819,10 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node) bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
{ {
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
if (node->getType().getQualifier().isSpecConstant())
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
// First, handle special cases // First, handle special cases
switch (node->getOp()) { switch (node->getOp()) {
case glslang::EOpAssign: case glslang::EOpAssign:
@ -966,6 +995,10 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node) bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node)
{ {
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
if (node->getType().getQualifier().isSpecConstant())
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
spv::Id result = spv::NoResult; spv::Id result = spv::NoResult;
// try texturing first // try texturing first
@ -1927,6 +1960,7 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra
glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim); glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim);
if (specNode != nullptr) { if (specNode != nullptr) {
builder.clearAccessChain(); builder.clearAccessChain();
// SpecConstantOpModeGuard set_to_spec_const_mode(&builder);
specNode->traverse(this); specNode->traverse(this);
return accessChainLoad(specNode->getAsTyped()->getType()); return accessChainLoad(specNode->getAsTyped()->getType());
} }
@ -3868,25 +3902,6 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
return builder.makeCompositeConstant(typeId, spvConsts); return builder.makeCompositeConstant(typeId, spvConsts);
} }
namespace {
class SpecConstantOpModeGuard {
public:
SpecConstantOpModeGuard(spv::Builder* builder)
: builder_(builder) {
previous_flag_ = builder->isInSpecConstCodeGenMode();
builder->setToSpecConstCodeGenMode();
}
~SpecConstantOpModeGuard() {
previous_flag_ ? builder_->setToSpecConstCodeGenMode()
: builder_->setToNormalCodeGenMode();
}
private:
spv::Builder* builder_;
bool previous_flag_;
};
}
// Create constant ID from const initializer sub tree. // Create constant ID from const initializer sub tree.
spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstSubTree( spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstSubTree(
glslang::TIntermTyped* subTree) glslang::TIntermTyped* subTree)
@ -3919,22 +3934,12 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstSubTree(
} else if (glslang::TIntermBinary* bn = subTree->getAsBinaryNode()) { } else if (glslang::TIntermBinary* bn = subTree->getAsBinaryNode()) {
// Binary operation node, we should generate OpSpecConstantOp <binary op> // Binary operation node, we should generate OpSpecConstantOp <binary op>
// This case should only happen when Specialization Constants are involved. // This case should only happen when Specialization Constants are involved.
// Spec constants defined with binary operations and other constants requires
// OpSpecConstantOp instruction.
SpecConstantOpModeGuard set_to_spec_const_mode(&builder);
bn->traverse(this); bn->traverse(this);
return accessChainLoad(bn->getType()); return accessChainLoad(bn->getType());
} else if (glslang::TIntermUnary* un = subTree->getAsUnaryNode()) { } else if (glslang::TIntermUnary* un = subTree->getAsUnaryNode()) {
// Unary operation node, similar to binary operation node, should only // Unary operation node, similar to binary operation node, should only
// happen when specialization constants are involved. // happen when specialization constants are involved.
// Spec constants defined with unary operations and other constants requires
// OpSpecConstantOp instruction.
SpecConstantOpModeGuard set_to_spec_const_mode(&builder);
un->traverse(this); un->traverse(this);
return accessChainLoad(un->getType()); return accessChainLoad(un->getType());

View file

@ -39,16 +39,16 @@ Linked compute stage:
15: TypeVector 6(int) 3 15: TypeVector 6(int) 3
16: 15(ivec3) SpecConstantComposite 12 13 14 16: 15(ivec3) SpecConstantComposite 12 13 14
17: 6(int) Constant 0 17: 6(int) Constant 0
18: 6(int) SpecConstantOp 81 16 0
19: 6(int) Constant 1 19: 6(int) Constant 1
20: 6(int) SpecConstantOp 81 16 1(GLSL.std.450)
21: 6(int) SpecConstantOp 132 18 20
22: 6(int) Constant 2 22: 6(int) Constant 2
23: 6(int) SpecConstantOp 81 16 2
24: 6(int) SpecConstantOp 132 21 23
25: TypePointer Uniform 6(int) 25: TypePointer Uniform 6(int)
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
18: 6(int) CompositeExtract 16 0
20: 6(int) CompositeExtract 16 1
21: 6(int) IMul 18 20
23: 6(int) CompositeExtract 16 2
24: 6(int) IMul 21 23
26: 25(ptr) AccessChain 9(bi) 11 26: 25(ptr) AccessChain 9(bi) 11
Store 26 24 Store 26 24
Return Return

View file

@ -58,17 +58,25 @@ Linked vertex stage:
30: 29(bool) SpecConstantTrue 30: 29(bool) SpecConstantTrue
33: TypeInt 32 0 33: TypeInt 32 0
34: 33(int) SpecConstant 2 34: 33(int) SpecConstant 2
35: 6(float) SpecConstantOp 112 34
38: TypeFloat 64 38: TypeFloat 64
39: 38(float) SpecConstant 1413754136 1074340347 39: 38(float) SpecConstant 1413754136 1074340347
40: 6(float) SpecConstant 1078523331 40: 6(float) SpecConstant 1078523331
41: 38(float) SpecConstantOp 115 40
42: 38(float) SpecConstantOp 136 39 41
43: 6(float) SpecConstantOp 115 42
50: 8(int) SpecConstant 12 50: 8(int) SpecConstant 12
51: TypeArray 7(fvec4) 50 51: TypeArray 7(fvec4) 50
52: TypePointer Input 51 52: TypePointer Input 51
53(dupUcol): 52(ptr) Variable Input 53(dupUcol): 52(ptr) Variable Input
60: 29(bool) SpecConstantTrue 60: 29(bool) SpecConstantTrue
63: 33(int) SpecConstant 2 63: 33(int) SpecConstant 2
64: 6(float) SpecConstantOp 112 63
67: 38(float) SpecConstant 1413754136 1074340347 67: 38(float) SpecConstant 1413754136 1074340347
68: 6(float) SpecConstant 1078523331 68: 6(float) SpecConstant 1078523331
69: 38(float) SpecConstantOp 115 68
70: 38(float) SpecConstantOp 136 67 69
71: 6(float) SpecConstantOp 115 70
75: TypePointer Function 8(int) 75: TypePointer Function 8(int)
77: 8(int) SpecConstant 8 77: 8(int) SpecConstant 8
4(main): 2 Function None 3 4(main): 2 Function None 3
@ -81,15 +89,11 @@ Linked vertex stage:
SelectionMerge 32 None SelectionMerge 32 None
BranchConditional 30 31 32 BranchConditional 30 31 32
31: Label 31: Label
35: 6(float) ConvertUToF 34
36: 7(fvec4) Load 20(color) 36: 7(fvec4) Load 20(color)
37: 7(fvec4) VectorTimesScalar 36 35 37: 7(fvec4) VectorTimesScalar 36 35
Store 20(color) 37 Store 20(color) 37
Branch 32 Branch 32
32: Label 32: Label
41: 38(float) FConvert 40
42: 38(float) FDiv 39 41
43: 6(float) FConvert 42
44: 7(fvec4) Load 20(color) 44: 7(fvec4) Load 20(color)
45: 7(fvec4) CompositeConstruct 43 43 43 43 45: 7(fvec4) CompositeConstruct 43 43 43 43
46: 7(fvec4) FAdd 44 45 46: 7(fvec4) FAdd 44 45
@ -113,15 +117,11 @@ Linked vertex stage:
SelectionMerge 62 None SelectionMerge 62 None
BranchConditional 60 61 62 BranchConditional 60 61 62
61: Label 61: Label
64: 6(float) ConvertUToF 63
65: 7(fvec4) Load 20(color) 65: 7(fvec4) Load 20(color)
66: 7(fvec4) VectorTimesScalar 65 64 66: 7(fvec4) VectorTimesScalar 65 64
Store 20(color) 66 Store 20(color) 66
Branch 62 Branch 62
62: Label 62: Label
69: 38(float) FConvert 68
70: 38(float) FDiv 67 69
71: 6(float) FConvert 70
72: 7(fvec4) Load 20(color) 72: 7(fvec4) Load 20(color)
73: 7(fvec4) CompositeConstruct 71 71 71 71 73: 7(fvec4) CompositeConstruct 71 71 71 71
74: 7(fvec4) FAdd 72 73 74: 7(fvec4) FAdd 72 73

View file

@ -51,6 +51,7 @@ Linked vertex stage:
26: TypePointer Output 25(fvec4) 26: TypePointer Output 25(fvec4)
27(color): 26(ptr) Variable Output 27(color): 26(ptr) Variable Output
28: 14(int) SpecConstant 3 28: 14(int) SpecConstant 3
29: 24(float) SpecConstantOp 111 28
32: 24(float) SpecConstant 1078523331 32: 24(float) SpecConstant 1078523331
33: 25(fvec4) SpecConstantComposite 32 32 32 32 33: 25(fvec4) SpecConstantComposite 32 32 32 32
36: 24(float) Constant 1133908460 36: 24(float) Constant 1133908460
@ -76,6 +77,7 @@ Linked vertex stage:
70: 68 SpecConstantComposite 28 28 63 46 69 70: 68 SpecConstantComposite 28 28 63 46 69
71: TypePointer Function 68 71: TypePointer Function 68
73: TypePointer Function 14(int) 73: TypePointer Function 14(int)
79: 24(float) SpecConstantOp 111 78
87: 24(float) Constant 1106321080 87: 24(float) Constant 1106321080
88:41(flat_struct) SpecConstantComposite 69 87 43 21 88:41(flat_struct) SpecConstantComposite 69 87 43 21
89: 14(int) Constant 10 89: 14(int) Constant 10
@ -99,7 +101,6 @@ Linked vertex stage:
SelectionMerge 23 None SelectionMerge 23 None
BranchConditional 21 22 23 BranchConditional 21 22 23
22: Label 22: Label
29: 24(float) ConvertSToF 28
30: 25(fvec4) Load 27(color) 30: 25(fvec4) Load 27(color)
31: 25(fvec4) VectorTimesScalar 30 29 31: 25(fvec4) VectorTimesScalar 30 29
Store 27(color) 31 Store 27(color) 31
@ -146,7 +147,6 @@ Linked vertex stage:
Store 76(indexable) 70 Store 76(indexable) 70
77: 73(ptr) AccessChain 76(indexable) 75 77: 73(ptr) AccessChain 76(indexable) 75
78: 14(int) Load 77 78: 14(int) Load 77
79: 24(float) ConvertSToF 78
80: 25(fvec4) Load 27(color) 80: 25(fvec4) Load 27(color)
81: 25(fvec4) CompositeConstruct 79 79 79 79 81: 25(fvec4) CompositeConstruct 79 79 79 79
82: 25(fvec4) FDiv 80 81 82: 25(fvec4) FDiv 80 81

View file

@ -7,7 +7,7 @@ Linked vertex stage:
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 94 // Id's are bound by 107
Capability Shader Capability Shader
Capability Float64 Capability Float64
@ -16,101 +16,116 @@ Linked vertex stage:
EntryPoint Vertex 4 "main" EntryPoint Vertex 4 "main"
Source GLSL 450 Source GLSL 450
Name 4 "main" Name 4 "main"
Decorate 7 SpecId 200 Name 8 "non_const_array_size_from_spec_const("
Decorate 9 SpecId 201 Name 15 "array"
Decorate 11 SpecId 202 Decorate 10 SpecId 201
Decorate 12 SpecId 203 Decorate 24 SpecId 200
Decorate 26 SpecId 202
Decorate 27 SpecId 203
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeInt 32 1
7: 6(float) SpecConstant 1078530010 7: TypeFunction 6(int)
8: TypeInt 32 1 10: 6(int) SpecConstant 10
9: 8(int) SpecConstant 10 11: 6(int) Constant 2
10: TypeInt 32 0 12: 6(int) SpecConstantOp 128 10 11
11: 10(int) SpecConstant 100 13: TypeArray 6(int) 12
12: 8(int) SpecConstant 4294967286 14: TypePointer Function 13
13: TypeFloat 64 16: 6(int) Constant 1
14: 13(float) SpecConstantOp 115 7 17: 6(int) SpecConstantOp 128 10 16
15: 6(float) SpecConstantOp 115 14 18: TypePointer Function 6(int)
16: 8(int) SpecConstantOp 126 9 23: TypeFloat 32
17: 8(int) SpecConstantOp 200 9 24: 23(float) SpecConstant 1078530010
18: 8(int) Constant 2 25: TypeInt 32 0
19: 8(int) SpecConstantOp 128 9 18 26: 25(int) SpecConstant 100
20: 8(int) SpecConstantOp 128 9 18 27: 6(int) SpecConstant 4294967286
21: 8(int) Constant 3 28: TypeFloat 64
22: 8(int) SpecConstantOp 130 20 21 29: 28(float) SpecConstantOp 115 24
23: 8(int) Constant 4 30: 23(float) SpecConstantOp 115 29
24: 8(int) SpecConstantOp 130 19 23 31: 6(int) SpecConstantOp 126 10
25: 8(int) SpecConstantOp 132 12 18 32: 6(int) SpecConstantOp 200 10
26: 10(int) Constant 2 33: 6(int) SpecConstantOp 128 10 11
27: 10(int) SpecConstantOp 132 11 26 34: 6(int) SpecConstantOp 128 10 11
28: 8(int) Constant 5 35: 6(int) Constant 3
29: 8(int) SpecConstantOp 135 25 28 36: 6(int) SpecConstantOp 130 34 35
30: 10(int) Constant 5 37: 6(int) Constant 4
31: 10(int) SpecConstantOp 134 27 30 38: 6(int) SpecConstantOp 130 33 37
32: 8(int) SpecConstantOp 139 12 23 39: 6(int) SpecConstantOp 132 27 11
33: 10(int) Constant 4 40: 25(int) Constant 2
34: 10(int) SpecConstantOp 137 11 33 41: 25(int) SpecConstantOp 132 26 40
35: 8(int) SpecConstantOp 132 12 21 42: 6(int) Constant 5
36: 8(int) SpecConstantOp 135 35 28 43: 6(int) SpecConstantOp 135 39 42
37: 8(int) Constant 10 44: 25(int) Constant 5
38: 8(int) SpecConstantOp 195 12 37 45: 25(int) SpecConstantOp 134 41 44
39: 8(int) Constant 20 46: 6(int) SpecConstantOp 139 27 37
40: 10(int) SpecConstantOp 194 11 39 47: 25(int) Constant 4
41: 8(int) Constant 1 48: 25(int) SpecConstantOp 137 26 47
42: 8(int) SpecConstantOp 196 12 41 49: 6(int) SpecConstantOp 132 27 35
43: 10(int) SpecConstantOp 196 11 18 50: 6(int) SpecConstantOp 135 49 42
44: 8(int) Constant 256 51: 6(int) Constant 10
45: 8(int) SpecConstantOp 197 12 44 52: 6(int) SpecConstantOp 195 27 51
46: 10(int) Constant 512 53: 6(int) Constant 20
47: 10(int) SpecConstantOp 198 11 46 54: 25(int) SpecConstantOp 194 26 53
48: TypeBool 55: 6(int) SpecConstantOp 196 27 16
49: 48(bool) SpecConstantOp 177 9 12 56: 25(int) SpecConstantOp 196 26 11
50: 48(bool) SpecConstantOp 170 11 11 57: 6(int) Constant 256
51: 48(bool) SpecConstantOp 173 9 12 58: 6(int) SpecConstantOp 197 27 57
52: TypeVector 8(int) 4 59: 25(int) Constant 512
53: 8(int) Constant 30 60: 25(int) SpecConstantOp 198 26 59
54: 52(ivec4) SpecConstantComposite 39 53 9 9 61: TypeBool
55: TypeVector 10(int) 4 62: 61(bool) SpecConstantOp 177 10 27
56: 10(int) Constant 4294967295 63: 61(bool) SpecConstantOp 170 26 26
57: 10(int) Constant 4294967294 64: 61(bool) SpecConstantOp 173 10 27
58: 55(ivec4) SpecConstantComposite 11 11 56 57 65: TypeVector 6(int) 4
59: TypeVector 6(float) 4 66: 6(int) Constant 30
60: 6(float) Constant 1067450368 67: 65(ivec4) SpecConstantComposite 53 66 10 10
61: 59(fvec4) SpecConstantComposite 7 60 7 60 68: TypeVector 25(int) 4
62: TypeVector 13(float) 4 69: 25(int) Constant 4294967295
63: 62(fvec4) SpecConstantOp 115 61 70: 25(int) Constant 4294967294
64: 59(fvec4) SpecConstantOp 115 63 71: 68(ivec4) SpecConstantComposite 26 26 69 70
65: 52(ivec4) SpecConstantOp 200 54 72: TypeVector 23(float) 4
66: 52(ivec4) SpecConstantOp 126 54 73: 23(float) Constant 1067450368
67: 52(ivec4) ConstantComposite 18 18 18 18 74: 72(fvec4) SpecConstantComposite 24 73 24 73
68: 52(ivec4) SpecConstantOp 128 54 67 75: TypeVector 28(float) 4
69: 52(ivec4) SpecConstantOp 128 54 67 76: 75(fvec4) SpecConstantOp 115 74
70: 52(ivec4) ConstantComposite 21 21 21 21 77: 72(fvec4) SpecConstantOp 115 76
71: 52(ivec4) SpecConstantOp 130 69 70 78: 65(ivec4) SpecConstantOp 200 67
72: 52(ivec4) ConstantComposite 23 23 23 23 79: 65(ivec4) SpecConstantOp 126 67
73: 52(ivec4) SpecConstantOp 130 71 72 80: 65(ivec4) ConstantComposite 11 11 11 11
74: 52(ivec4) SpecConstantOp 132 54 67 81: 65(ivec4) SpecConstantOp 128 67 80
75: 52(ivec4) ConstantComposite 28 28 28 28 82: 65(ivec4) SpecConstantOp 128 67 80
76: 52(ivec4) SpecConstantOp 135 74 75 83: 65(ivec4) ConstantComposite 35 35 35 35
77: 52(ivec4) SpecConstantOp 139 54 72 84: 65(ivec4) SpecConstantOp 130 82 83
78: 52(ivec4) ConstantComposite 37 37 37 37 85: 65(ivec4) ConstantComposite 37 37 37 37
79: 52(ivec4) SpecConstantOp 195 54 78 86: 65(ivec4) SpecConstantOp 130 84 85
80: 52(ivec4) SpecConstantOp 196 54 67 87: 65(ivec4) SpecConstantOp 132 67 80
81: 8(int) Constant 1024 88: 65(ivec4) ConstantComposite 42 42 42 42
82: 52(ivec4) ConstantComposite 81 81 81 81 89: 65(ivec4) SpecConstantOp 135 87 88
83: 52(ivec4) SpecConstantOp 197 54 82 90: 65(ivec4) SpecConstantOp 139 67 85
84: 10(int) Constant 2048 91: 65(ivec4) ConstantComposite 51 51 51 51
85: 55(ivec4) ConstantComposite 84 84 84 84 92: 65(ivec4) SpecConstantOp 195 67 91
86: 55(ivec4) SpecConstantOp 198 58 85 93: 65(ivec4) SpecConstantOp 196 67 80
87: 10(int) Constant 0 94: 6(int) Constant 1024
88: 8(int) SpecConstantOp 81 54 0 95: 65(ivec4) ConstantComposite 94 94 94 94
89: TypeVector 8(int) 2 96: 65(ivec4) SpecConstantOp 197 67 95
90: 89(ivec2) SpecConstantOp 79 54 54 1(GLSL.std.450) 0 97: 25(int) Constant 2048
91: TypeVector 8(int) 3 98: 68(ivec4) ConstantComposite 97 97 97 97
92: 91(ivec3) SpecConstantOp 79 54 54 2 1(GLSL.std.450) 0 99: 68(ivec4) SpecConstantOp 198 71 98
93: 52(ivec4) SpecConstantOp 79 54 54 1(GLSL.std.450) 2 0 3 100: 25(int) Constant 0
101: 6(int) SpecConstantOp 81 67 0
102: TypeVector 6(int) 2
103: 102(ivec2) SpecConstantOp 79 67 67 1(GLSL.std.450) 0
104: TypeVector 6(int) 3
105: 104(ivec3) SpecConstantOp 79 67 67 2 1(GLSL.std.450) 0
106: 65(ivec4) SpecConstantOp 79 67 67 1(GLSL.std.450) 2 0 3
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
Return Return
FunctionEnd FunctionEnd
8(non_const_array_size_from_spec_const(): 6(int) Function None 7
9: Label
15(array): 14(ptr) Variable Function
19: 18(ptr) AccessChain 15(array) 17
20: 6(int) Load 19
ReturnValue 20
FunctionEnd

View file

@ -86,5 +86,10 @@ const ivec2 iv_yx = iv.yx;
const ivec3 iv_zyx = iv.zyx; const ivec3 iv_zyx = iv.zyx;
const ivec4 iv_yzxw = iv.yzxw; const ivec4 iv_yzxw = iv.yzxw;
int non_const_array_size_from_spec_const() {
int array[sp_int + 2];
return array[sp_int + 1];
}
void main() {} void main() {}