| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
| |
There was no reason to treat array types and record types differently.
Unifying them saves a bunch of code and saves a few bytes in every
ir_constant.
Signed-off-by: Ian Romanick <[email protected]>
Reviewed-by: Alejandro Piñeiro <[email protected]>
Reviewed-by: Elie Tournier <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
The next patch will unify ::array_elements and ::components, so the
name ::array_elements wouldn't be appropriate. A lot of things use
the names array_elements and components, so grepping for either is
pretty useless.
Signed-off-by: Ian Romanick <[email protected]>
Reviewed-by: Alejandro Piñeiro <[email protected]>
Reviewed-by: Elie Tournier <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
glsl/ast_type.cpp: In function ‘void merge_bindless_qualifier(YYLTYPE*, _mesa_glsl_parse_state*, const ast_type_qualifier&, const ast_type_qualifier&)’:
glsl/ast_type.cpp:189:35: warning: unused parameter ‘loc’ [-Wunused-parameter]
merge_bindless_qualifier(YYLTYPE *loc,
^~~
glsl/ast_type.cpp:191:52: warning: unused parameter ‘qualifier’ [-Wunused-parameter]
const ast_type_qualifier &qualifier,
^~~~~~~~~
glsl/ast_type.cpp:192:52: warning: unused parameter ‘new_qualifier’ [-Wunused-parameter]
const ast_type_qualifier &new_qualifier)
^~~~~~~~~~~~~
glsl/ir_constant_expression.cpp: In member function ‘virtual ir_constant* ir_rvalue::constant_expression_value(void*, hash_table*)’:
glsl/ir_constant_expression.cpp:512:44: warning: unused parameter ‘mem_ctx’ [-Wunused-parameter]
ir_rvalue::constant_expression_value(void *mem_ctx, struct hash_table *)
^~~~~~~
glsl/ir_constant_expression.cpp: In member function ‘virtual ir_constant* ir_texture::constant_expression_value(void*, hash_table*)’:
glsl/ir_constant_expression.cpp:705:45: warning: unused parameter ‘mem_ctx’ [-Wunused-parameter]
ir_texture::constant_expression_value(void *mem_ctx, struct hash_table *)
^~~~~~~
glsl/ir_constant_expression.cpp: In member function ‘virtual ir_constant* ir_assignment::constant_expression_value(void*, hash_table*)’:
glsl/ir_constant_expression.cpp:851:48: warning: unused parameter ‘mem_ctx’ [-Wunused-parameter]
ir_assignment::constant_expression_value(void *mem_ctx, struct hash_table *)
^~~~~~~
glsl/ir_constant_expression.cpp: In member function ‘virtual ir_constant* ir_constant::constant_expression_value(void*, hash_table*)’:
glsl/ir_constant_expression.cpp:859:46: warning: unused parameter ‘mem_ctx’ [-Wunused-parameter]
ir_constant::constant_expression_value(void *mem_ctx, struct hash_table *)
^~~~~~~
glsl/linker.cpp: In function ‘void link_xfb_stride_layout_qualifiers(gl_context*, gl_shader_program*, gl_linked_shader*, gl_shader**, unsigned int)’:
glsl/linker.cpp:1655:60: warning: unused parameter ‘linked_shader’ [-Wunused-parameter]
struct gl_linked_shader *linked_shader,
^~~~~~~~~~~~~
glsl/linker.cpp: In function ‘void link_bindless_layout_qualifiers(gl_shader_program*, gl_program*, gl_shader**, unsigned int)’:
glsl/linker.cpp:1693:52: warning: unused parameter ‘gl_prog’ [-Wunused-parameter]
struct gl_program *gl_prog,
^~~~~~~
glsl/lower_distance.cpp: In member function ‘virtual void {anonymous}::lower_distance_visitor_counter::handle_rvalue(ir_rvalue**)’:
glsl/lower_distance.cpp:652:59: warning: unused parameter ‘rv’ [-Wunused-parameter]
lower_distance_visitor_counter::handle_rvalue(ir_rvalue **rv)
^~
glsl/opt_array_splitting.cpp: In member function ‘virtual ir_visitor_status {anonymous}::ir_array_reference_visitor::visit_leave(ir_assignment*)’:
glsl/opt_array_splitting.cpp:198:56: warning: unused parameter ‘ir’ [-Wunused-parameter]
ir_array_reference_visitor::visit_leave(ir_assignment *ir)
^~
glsl/glsl_parser_extras.cpp: In function ‘void assign_subroutine_indexes(gl_shader*, _mesa_glsl_parse_state*)’:
glsl/glsl_parser_extras.cpp:1869:45: warning: unused parameter ‘sh’ [-Wunused-parameter]
assign_subroutine_indexes(struct gl_shader *sh,
^~
Signed-off-by: Ian Romanick <[email protected]>
Reviewed-by: Alejandro Piñeiro <[email protected]>
Reviewed-by: Elie Tournier <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In GLSL ES 3.10 session 4.9 [Memory Access Qualifiers], it has the
following description:
"A variable could be qualified as both readonly and writeonly,
disallowing both read and write, but still be passed to
imageSize() to have the size queried.".
This is for image variable, but not for buffer variables.
According to https://github.com/KhronosGroup/OpenGL-API/issues/7 Khronos
intent is to allow both readonly and writeonly in buffer variables, and
as such it will update the GLSL specification.
This commit address this issue, and fixes:
KHR-GL{43,44,45}.shader_storage_buffer_object.basic-readonly-writeonly
KHR-GLES31.core.shader_storage_buffer_object.basic-readonly-writeonly
v2: set correctly fields[i] memory flags (Samuel Pitoiset).
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
|
|
| |
Suggested-by: Nicolai Hähnle <[email protected]>
Signed-off-by: Eric Engestrom <[email protected]>
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
After get_variable_being_redeclared() has been called, it is no longer
safe to access the original variable pointer, since its memory might have
been freed.
Since callers of this function should only be accessing the variable pointer
returned by the function, avoid potential bugs by re-assigning the
original variable pointer to the result of the function call,
making it impossible for the remaining code to access an invalid variable
pointer.
Reviewed-by: Nicolai Hähnle <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
get_variable_being_redeclared() can delete the original variable
in a specific scenario. The code sets it to NULL after this so other
code in that same function doesn't try to access trashed memory after
the fact, however, the copy of that variable in the caller code
won't see any of this making it very easy to overlook.
Make the function a bit safer by taking a pointer to the original
variable so we can also make NULL the caller's pointer to the variable
if this function deletes it.
Reviewed-by: Nicolai Hähnle <[email protected]>
|
|
|
|
|
|
|
|
|
| |
Since the original 'var' might have been deleted from this point forward.
Bugzila: https://bugs.freedesktop.org/show_bug.cgi?id=102685
Fixes: 51bf007d2c27fba (glsl: Disallow unsized array of atomic_uint)
Reviewed-by: Nicolai Hähnle <[email protected]>
|
|
|
|
|
|
|
|
|
| |
The function is only called from one place, which is hidden behind
the same `#ifdef DEBUG`.
Fixes: ca73c3358c91434e68ab "glsl: Mark functions static"
Signed-off-by: Eric Engestrom <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
Instead of setting based on set/unset, allow users to use boolean values.
In the docs and tests, use `DISABLE=true` instead of `DISABLE=1` as it's
clearer IMO.
Signed-off-by: Eric Engestrom <[email protected]>
Reviewed-by: Timothy Arceri <[email protected]>
Reviewed-by: Emil Velikov <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
This was a bugfix to the spec addressed in OpenGL 4.5 (revision
7 of the spec) and there is a CTS test to check this.
Fixes:
KHR-GL45.shader_atomic_counters.negative-unsized-array
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a conditional branch has the same labels in the "if" part and in the
"else" part, then we have the same cfg block, and it must be handled
once.
v2: handle it the same way as OpBranch (Jason).
Fixes:
dEQP-VK.spirv_assembly.instruction.compute.conditional_branch.same_labels*
dEQP-VK.spirv_assembly.instruction.graphics.conditional_branch.same_labels*
Reviewed-by: Jason Ekstrand <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently we support 32-bit indexes/offsets all over the driver, so we
convert them to that bit size.
Fixes dEQP-VK.spirv_assembly.instruction.*.indexing.*
v2: Use u2u32 instead (Jason).
Signed-off-by: Samuel Iglesias Gonsálvez <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
This being declared bool means it won't get merged with the previous
bitfields, this seems like an oversight rather than deliberate.
Noticed when running pahole.
Reviewed-by: Jason Ekstrand <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
|
|
|
|
|
|
|
|
| |
I have no idea how this got missed but it's been missing since forever.
Cc: [email protected]
Reviewed-by: Samuel Iglesias Gonsálvez <[email protected]>
Reviewed-by: Ian Romanick <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Otherwise clang warns:
glsl/glsl_lexer.cpp:3507:16: warning: function 'yyinput' is not needed
and will not be emitted [-Wunneeded-internal-declaration]
static int yyinput (yyscan_t yyscanner)
^
Reviewed-by: Emil Velikov <[email protected]>
Reviewed-by: Eric Engestrom <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Clang warns:
warning: absolute value function 'fabsf' given an argument of type
'const float64_t' (aka 'const double') but has parameter of type 'float'
which may cause truncation of value [-Wabsolute-value]
float64_t dst = bit_size == 64 ? fabs(src0) : fabsf(src0);
The type of the ternary expression will be the common type of fabs() and
fabsf(): double. So fabsf(src0) will be implicitly converted to double.
We may as well just convert src0 to double before a call to fabs() and
remove the needless complexity, à la
float64_t dst = fabs(src0);
Reviewed-by: Emil Velikov <[email protected]>
Reviewed-by: Eric Engestrom <[email protected]>
|
|
|
|
|
|
|
|
| |
Quiets a number of uninitialized variable warnings in clang.
Reviewed-by: Jordan Justen <[email protected]>
Reviewed-by: Emil Velikov <[email protected]>
Reviewed-by: Eric Engestrom <[email protected]>
|
|
|
|
|
|
|
| |
nir_intrinsics.h does this a lot, causing lots of warnings from clang.
Reviewed-by: Emil Velikov <[email protected]>
Reviewed-by: Eric Engestrom <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The functionality is used by glsl and mesa. With the latter already
depending on the former.
With this in place the src/util/ static library libmesautil.la no longer
has a C++ dependency. Thus objects which use it (like libEGL) don't need
the C++ link.
Cc: "17.2" <[email protected]>
Fixes: 02cc35937277 ("egl/wayland: Use linux-dmabuf interface for buffers")
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101851
Signed-off-by: Emil Velikov <[email protected]>
Suggested-by: Jason Ekstrand <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Tested-by: Mike Lothian <[email protected]>
Tested-by: James Harvey <[email protected]>
|
|
|
|
|
|
|
| |
A couple of the cases were backwards
Reviewed-by: Matt Turner <[email protected]>
Cc: [email protected]
|
|
|
|
|
|
| |
Somehow tabs got in there...
Reviewed-by: Matt Turner <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
The argument to count_attribute_slots should only be set to true for
vertex inputs, not for all vertex shader varyings.
Fixes KHR-GL45.enhanced_layouts.varying_locations
Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Timothy Arceri <[email protected]>
Reviewed-by: Nicolai Hähnle <[email protected]>
Cc: [email protected]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Found by address sanitizer:
==22621==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61400000cbd8 at pc 0x7f561610a4ff bp 0x7ffca85f9d50 sp 0x7ffca85f94f8
READ of size 344 at 0x61400000cbd8 thread T0
#0 0x7f561610a4fe (/usr/lib/x86_64-linux-gnu/libasan.so.3+0x5f4fe)
#1 0x7f560bb305a5 in memcpy /usr/include/x86_64-linux-gnu/bits/string3.h:53
#2 0x7f560bb305a5 in blob_write_bytes ../../../mesa-src/src/compiler/glsl/blob.c:136
#3 0x7f560be7d7ff in encode_type_to_blob ../../../mesa-src/src/compiler/glsl/shader_cache.cpp:153
#4 0x7f560be81222 in write_program_resource_data ../../../mesa-src/src/compiler/glsl/shader_cache.cpp:950
#5 0x7f560be81222 in write_program_resource_list ../../../mesa-src/src/compiler/glsl/shader_cache.cpp:1118
#6 0x7f560be81222 in shader_cache_write_program_metadata(gl_context*, gl_shader_program*) ../../../mesa-src/src/compiler/glsl/shader_cache.cpp:1407
#7 0x7f560b825fdb in link_program ../../../mesa-src/src/mesa/main/shaderapi.c:1163
Fixes: 073a84ff60db ("glsl: stop adding pointers from glsl_struct_field to the cache")
Reviewed-by: Timothy Arceri <[email protected]>
|
|
|
|
|
|
|
| |
We don't actually write them to disk here. That will happen in the
following commit.
Reviewed-by: Nicolai Hähnle <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Steam is already analysing cache items, unfortunatly we did not
introduce a versioning mechanism for identifying structural changes
to cache entries earlier so the only way to do so is to rename the
cache directory.
Since we are renaming it we take the opportunity to give the directory
a more meaningful name.
Adding a version field to the header of cache entries will help us to
avoid having to rename the directory in future. Please note this is
versioning for the internal structure of the entries as defined in
disk_cache.{c,h} as opposed to the structure of the data provided to
the disk cache by the GLSL compiler and the various driver backends.
Reviewed-by: Nicolai Hähnle <[email protected]>
|
|
|
|
|
|
|
| |
This is so we always create reproducible cache entries. Consistency
is required for verification of any third party distributed shaders.
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
|
|
|
| |
This is so we always create reproducible cache entries. Consistency
is required for verification of any third party distributed shaders.
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
|
|
|
| |
This will allow us to easily skip them when writting the struct
to disk cache.
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
|
|
|
|
|
| |
In the following patch we will stop writing the pointer to cache.
Unfortunately adding empty strings to that cache seems to be the
only thing we can do here once we no longer have the pointers.
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
|
|
|
| |
This is so we always create reproducible cache entries. Consistency
is required for verification of any third party distributed shaders.
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
| |
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
|
|
|
| |
This is so we always create reproducible cache entries. Consistency
is required for verification of any third party distributed shaders.
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
|
|
|
| |
This is so we always create reproducible cache entries. Consistency
is required for verification of any third party distributed shaders.
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
|
|
| |
This will be used by the following commit.
Reviewed-by: Samuel Pitoiset <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
copy_constant_to_storage, set_uniform_initializer,
populate_consumer_input_sets, and get_matching_input are all used by
tests in src/compiler/glsl/tests:
glsl/tests/varyings_test.o: In function `link_varyings_single_simple_input_Test::TestBody()':
src/compiler/glsl/tests/varyings_test.cpp:131: undefined reference to `linker::populate_consumer_input_sets(void*, exec_list*, hash_table*, hash_table*, ir_variable**)'
glsl/tests/varyings_test.o: In function `link_varyings_gl_ClipDistance_Test::TestBody()':
src/compiler/glsl/tests/varyings_test.cpp:159: undefined reference to `linker::populate_consumer_input_sets(void*, exec_list*, hash_table*, hash_table*, ir_variable**)'
glsl/tests/varyings_test.o: In function `link_varyings_gl_CullDistance_Test::TestBody()':
src/compiler/glsl/tests/varyings_test.cpp:186: undefined reference to `linker::populate_consumer_input_sets(void*, exec_list*, hash_table*, hash_table*, ir_variable**)'
glsl/tests/varyings_test.o: In function `link_varyings_single_interface_input_Test::TestBody()':
src/compiler/glsl/tests/varyings_test.cpp:208: undefined reference to `linker::populate_consumer_input_sets(void*, exec_list*, hash_table*, hash_table*, ir_variable**)'
glsl/tests/varyings_test.o: In function `link_varyings_one_interface_and_one_simple_input_Test::TestBody()':
src/compiler/glsl/tests/varyings_test.cpp:241: undefined reference to `linker::populate_consumer_input_sets(void*, exec_list*, hash_table*, hash_table*, ir_variable**)'
glsl/tests/varyings_test.o:src/compiler/glsl/tests/varyings_test.cpp:272: more undefined references to `linker::populate_consumer_input_sets(void*, exec_list*, hash_table*, hash_table*, ir_variable**)' follow
glsl/tests/varyings_test.o: In function `link_varyings_interface_field_doesnt_match_noninterface_Test::TestBody()':
src/compiler/glsl/tests/varyings_test.cpp:289: undefined reference to `linker::get_matching_input(void*, ir_variable const*, hash_table*, hash_table*, ir_variable**)'
glsl/tests/varyings_test.o: In function `link_varyings_interface_field_doesnt_match_noninterface_vice_versa_Test::TestBody()':
src/compiler/glsl/tests/varyings_test.cpp:314: undefined reference to `linker::populate_consumer_input_sets(void*, exec_list*, hash_table*, hash_table*, ir_variable**)'
src/compiler/glsl/tests/varyings_test.cpp:328: undefined reference to `linker::get_matching_input(void*, ir_variable const*, hash_table*, hash_table*, ir_variable**)'
Fixes: ca73c3358c91 ("glsl: Mark functions static")
Signed-off-by: Ian Romanick <[email protected]>
Reviewed-by: Timothy Arceri <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
|
|
|
|
|
|
|
| |
Here we also make use of the UseSTD430AsDefaultPacking constant
and call the new get_internal_ifc_packing() helper.
Reviewed-by: Marek Olšák <[email protected]>
|
|
|
|
|
|
|
| |
This is used to avoid code duplication when selecting the
packing type for shared and packed layouts.
Reviewed-by: Marek Olšák <[email protected]>
|
|
|
|
| |
Reviewed-by: Jordan Justen <[email protected]>
|
|
|
|
|
|
| |
Cuts 3224 bytes of .text
Reviewed-by: Jordan Justen <[email protected]>
|
|
|
|
| |
Reviewed-by: Jordan Justen <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
Fixes KHR-GL45.shader_ballot_tests.ShaderBallotAvailability, which
causes some silly swizzles to appear, triggering this optimization to
get hit.
Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Dave Airlie <[email protected]>
Cc: [email protected]
|
|
|
|
|
|
|
|
|
| |
This fixes an assert during IR validation in LLVMpipe.
Fixes: e2e2c5abd279 (glsl: calculate number of operands in an expression once)
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102274
Reviewed-by: Brian Paul <[email protected]>
Tested-by: Brian Paul <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We continue in the code to do some more things with the rhs, including
setting a constant initializer. If the type is wrong, this causes some
confusion down the line, leading to assertions. This makes sure that the
rhs processing continues to flow as-if the type was correct to start
with (even though the state has been marked as an error state).
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101766
Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Cc: [email protected]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The cloning was introduced in f81ede469910d to fix a problem with
shaders including IR that was owned by builtins.
However the approach of cloning the whole function each time we
reference a builtin lead to a significant reduction in the GLSL
IR compilers performance.
The previous patch fixes the ownership problem in a more precise
way. So we can now remove this cloning.
Testing on a Ryzen 7 1800X shows a ~15% decreases in compiling the
Deus Ex: Mankind Divided shaders on radeonsi (which take 5min+ on
some machines). Looking just at the GLSL IR compiler the speed up
is ~40%.
Tested-by: Dieter Nützel <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Reviewed-by: Nicolai Hähnle <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The main motivation for this is that threaded compilation can fall
over if we were to allocate IR inside constant_expression_value()
when calling it on a builtin. This is because builtins are shared
across the whole OpenGL context.
f81ede469910d worked around the problem by cloning the entire
builtin before constant_expression_value() could be called on
it. However cloning the whole function each time we referenced
it lead to a significant reduction in the GLSL IR compiler
performance. This change along with the following patch
helps fix that performance regression.
Other advantages are that we reduce the number of calls to
ralloc_parent(), and for loop unrolling we free constants after
they are used rather than leaving them hanging around.
Reviewed-by: Kenneth Graunke <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The Deus Ex: Mankind Divided shaders go from spending ~20 seconds
in the GLSL IR compilers front-end down to ~18.5 seconds on a
Ryzen 1800X.
Tested by compiling once with shader-db then deleting the index file
from the shader cache and compiling again.
v2:
- fix rebasing issue in v1
Reviewed-by: Thomas Helland <[email protected]>
|
|
|
|
|
| |
Reviewed-by: Thomas Helland <[email protected]>
Tested-by: Dieter Nützel <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
We are currently copying the name for each member dereference
but we can just share a single instance of the string provided
by the type.
This change also stops us recalculating the field index
repeatedly.
Reviewed-by: Thomas Helland <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
Also add a comment that this should only be used by the ir_reader
interface for testing purposes.
v2:
- fix grammar in comment
- use unreachable rather than assert
Reviewed-by: Thomas Helland <[email protected]>
|