aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler
Commit message (Collapse)AuthorAgeFilesLines
* spirv: compute push constant access offset & rangeLionel Landwerlin2017-01-041-13/+65
| | | | | | | | v2: Move relative push constant relative offset computation down to _vtn_load_store_tail() (Jason) Signed-off-by: Lionel Landwerlin <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]>
* spirv: move block_size() definitionLionel Landwerlin2017-01-041-48/+48
| | | | | Signed-off-by: Lionel Landwerlin <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]>
* nir: fix loop iteration count calculation for floatsTimothy Arceri2017-01-041-2/+2
| | | | | | | | | | | | Fixes performance regression in SynMark PSPom caused by loops with float counters not always unrolling. For example: for (float i = 0.02; i < 0.9; i += 0.11) ... Reviewed-by: Jason Ekstrand <[email protected]>
* glsl: Update ES 3.2 shader output restrictions.Kenneth Graunke2017-01-021-11/+37
| | | | | | | | | | | | | | | | | This disallows fancy varyings in tessellation and geometry shaders, as required by ES 3.2. Fixes: dEQP-GLES31.functional.tessellation.user_defined_io.negative.per_patch_array_of_structs dEQP-GLES31.functional.tessellation.user_defined_io.negative.per_patch_structs_containing_arrays (Not a candidate for stable branches as it only disallows things which should be working as desktop GL allows them.) v2: Update error messages to not say "vertex shader" (caught by Iago). Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Iago Toral Quiroga <[email protected]>
* glsl/mesa: add reference to gl_shader_program_data from gl_programTimothy Arceri2016-12-313-0/+16
| | | | | | | | | We also add the stubs for the standalone compiler in this change. By adding a reference here we can now refactor some code to use gl_program where we were previously awkwardly using gl_shader_program. Reviewed-by: Eric Anholt <[email protected]>
* nir/split_var_copies: Use a nir_shader rather than a void *mem_ctxJason Ekstrand2016-12-301-3/+3
| | | | | Reviewed-by: Eduardo Lima Mitev <[email protected]> Reviewed-by: Jordan Justen <[email protected]>
* nir/opt_peephole_select: Pass around the actual nir_shaderJason Ekstrand2016-12-301-4/+5
| | | | | Reviewed-by: Eduardo Lima Mitev <[email protected]> Reviewed-by: Jordan Justen <[email protected]>
* nir/conditional_if: Properly use the builderJason Ekstrand2016-12-301-11/+10
| | | | | | | | | | We were passing around a void *mem_ctx and using that to initialize the builder which was wrong since that pointed to ralloc_parent(impl) which is the shader but the builder is supposed to be initialized with the nir_function_impl. Reviewed-by: Eduardo Lima Mitev <[email protected]> Reviewed-by: Jordan Justen <[email protected]>
* nir/lower_var_copies: Use a shader rather than a void *mem_ctxJason Ekstrand2016-12-302-9/+10
| | | | | Reviewed-by: Eduardo Lima Mitev <[email protected]> Reviewed-by: Jordan Justen <[email protected]>
* nir/lower_io: Use the builder instead of carrying a mem_ctxJason Ekstrand2016-12-301-8/+8
| | | | | Reviewed-by: Eduardo Lima Mitev <[email protected]> Reviewed-by: Jordan Justen <[email protected]>
* nir/from_ssa: Use nir_builder for emit_copyJason Ekstrand2016-12-301-13/+13
| | | | | | | | This lets us get rid of the void *mem_ctx parameter and make things a bit more type safe. Reviewed-by: Eduardo Lima Mitev <[email protected]> Reviewed-by: Jordan Justen <[email protected]>
* nir: Make nir_copy_deref follow the "clone" patternJason Ekstrand2016-12-3012-63/+50
| | | | | | | | | We rename it to nir_deref_clone, re-order the sources to match the other clone functions, and expose nir_deref_var_clone. This past part, in particular, lets us get rid of quite a few lines since we no longer have to call nir_copy_deref and wrap it in deref_as_var. Reviewed-by: Jordan Justen <[email protected]>
* spirv: always expose SpvCapabilityStorageImageExtendedFormatsIlia Mirkin2016-12-292-4/+1
| | | | | | | | | | I forgot to do this in commit 76b97d544e ("anv: enable storage image extended formats"). Since both drivers support this now, no need for the conditional enable. Signed-off-by: Ilia Mirkin <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]> Reviewed-by: Dave Airlie <[email protected]>
* nir: Rewrite lower_regs_to_ssa to use the phi builderJason Ekstrand2016-12-291-421/+174
| | | | | This keeps some of Connor's original code. However, while I was at it, I updated this very old pass to a bit more modern NIR.
* nir/phi-builder: Set the value in the block when creating a phiJason Ekstrand2016-12-291-1/+1
| | | | | | | | | After we figure out the value that we are going to return, we have a loop that walks up the dominance tree and sets the value in each of the blocks that doesn't have one yet. In the case of the phi, the def is set to NEEDS_PHI not NULL, so the last one where the phi node actually goes never gets filled out. This can lead to duplicating the phi node unnecessarily.
* nir: Add foreach_register helper macrosJason Ekstrand2016-12-291-0/+5
|
* nir: Rename convert_to_ssa lower_regs_to_ssaJason Ekstrand2016-12-296-10/+9
| | | | This matches the naming of nir_lower_vars_to_ssa, the other to-SSA pass.
* mesa/glsl/i965: remove Driver.NewShader()Timothy Arceri2016-12-305-19/+2
| | | | | | | | | After removing brw_shader in the previous commit this is no longer needed. V2: remove use in src/compiler/glsl/test_optpass.cpp Reviewed-by: Eric Anholt <[email protected]>
* mesa/glsl: move BlendSupport bitfield to gl_programTimothy Arceri2016-12-303-5/+5
| | | | | | | | | | | | This will let us to make _CurrentFragmentProgram a gl_program pointer allowing for simpilifications to be made. We also need to add a field to gl_shader to hold it during parsing. In gl_program we put it inside a union in anticipation of moving more fields here that can be only fs or vertex stage fields. Reviewed-by: Eric Anholt <[email protected]>
* mesa/glsl: move LinkedTransformFeedback from gl_shader_program to gl_programTimothy Arceri2016-12-302-26/+37
| | | | | | | | | | | | This will help allow us to store gl_program in the CurrentProgram array rather than gl_shader_program which will allow a bunch of simplifications. Note that we make LinkedTransformFeedback a pointer so we don't waste memory creating a struct for each stage. We also store a pointer to the gl_program that will contain the pointer in gl_shader_program so we can get easy access to the correct stage. Reviewed-by: Eric Anholt <[email protected]>
* mesa: move _Used to gl_programTimothy Arceri2016-12-301-1/+0
| | | | | | We no longer need to initialise it because gl_program is never reused. Reviewed-by: Eric Anholt <[email protected]>
* mesa/compiler: add local_size_variable to shader_infoTimothy Arceri2016-12-301-0/+2
| | | | | | | | This will be used in api_validate.c in a following patch when we switch to using gl_program pointers for the pipelines CurrentProgram array. Reviewed-by: Eric Anholt <[email protected]>
* glsl/mesa: set separate_shader directly in shader_infoTimothy Arceri2016-12-301-1/+0
| | | | Reviewed-by: Eric Anholt <[email protected]>
* mesa/glsl: move subroutine metadata to gl_programTimothy Arceri2016-12-302-56/+57
| | | | | | | | This will allow us to store gl_program rather than gl_shader_program as the current program perstage which allows us to simplify code that makes use of the CurrentProgram list. Reviewed-by: Eric Anholt <[email protected]>
* mesa/compiler: add stage to shader_infoTimothy Arceri2016-12-301-0/+3
| | | | | | | | | | | | This will allow us to simplify the current program logic for SSO. Also since we aim to detach shader_info from nir_shader this will come in handy avoiding passing nir_shader around just to keep track of the stage we are dealing with. V2: set stage for arb asm programs also. Reviewed-by: Eric Anholt <[email protected]>
* nir: stop gcc warning about uninitialised variablesTimothy Arceri2016-12-291-1/+1
| | | | Reviewed-by: Jason Ekstrand <[email protected]>
* spirv: add interface for drivers to define support extensions.Dave Airlie2016-12-284-3/+23
| | | | | | | | | | | I expect over time the struct contents will change as all drivers support stuff etc, but for now this should be a good starting point. Reviewed-by: Edward O'Callaghan <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]> Acked-by: Jason Ekstrand <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
* nir/algebraic: Add optimizations for "a == a && a CMP b"Jason Ekstrand2016-12-221-0/+8
| | | | | | | | This sequence shows up The Talos Principal, at least under Vulkan, and prevents loop analysis from properly computing trip counts in a few loops. Reviewed-by: Ian Romanick <[email protected]>
* nir: Add a pass for moving SPIR-V continue blocks to the ends of loopsJason Ekstrand2016-12-223-0/+259
| | | | | | | | | | | | | | | When shaders come in from SPIR-V, we handle continue blocks by placing the contents of the continue inside of a "if (!first_iteration)". We do this so that we can properly handle the fact that continues in SPIR-V jump to the continue block at the end of the loop rather than jumping directly to the top of the loop like they do in NIR. In particular, the increment step of a simple for loop ends up in the continue block. This pass looks for this case in loops that don't actually have any continues and moves the continue contents to the end of the loop instead. We need this because loop unrolling doesn't work if the increment is inside of a condition. Reviewed-by: Timothy Arceri <[email protected]>
* nir: Add an optimization pass to remove trivial continuesJason Ekstrand2016-12-223-0/+140
| | | | Reviewed-by: Timothy Arceri <[email protected]>
* nir: Correctly handle blocks in cf_node_cf_tree_nextJason Ekstrand2016-12-221-1/+1
| | | | Reviewed-by: Timothy Arceri <[email protected]>
* nir: update nir_lower_returns to only predicate instructions when neededTimothy Arceri2016-12-231-6/+41
| | | | | | | | | | | | | | Unless an if statement contains nested returns we can simply add any following instructions to the branch without the return. V2: fix handling if_nested_return value when there is a sibling if/loop that doesn't contain a return. (Spotted by Ken) V3: - add a better comment to the new variable - remove instructions after if when both branches return Reviewed-by: Jason Ekstrand <[email protected]>
* nir: add a loop unrolling passTimothy Arceri2016-12-233-0/+578
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | V2: - tidy ups suggested by Connor. - tidy up cloning logic and handle copy propagation based of suggestion by Connor. - use nir_ssa_def_rewrite_uses to fix up lcssa phis suggested by Connor. - add support for complex loop unrolling (two terminators) - handle case were the ssa defs use outside the loop is already a phi - support unrolling loops with multiple terminators when trip count is know for each terminator V3: - set correct num_components when creating phi in complex unroll - rewrite update remap table based on Jasons suggestions. - remove unrequired extract_loop_body() helper as suggested by Jason. - simplify the lcssa phi fix up code for simple loops as per Jasons suggestions. - use mem context to keep track of hash table memory as suggested by Jason. - move is_{complex,simple}_loop helpers to the unroll code - require nir_metadata_block_index - partially rewrote complex unroll to be simpler and easier to follow. V4: - use rzalloc() when creating nir_phi_src but not setting pred right away fixes regression cause by ralloc() no longer zeroing memory. V5: - simplify calling of complex_unroll() - use new loop terminator fields to get the break/continue from blocks and simplify loop unrolling code - handle slightly less trivial loop terminators. if branches can now have instructions but can only contain a single block. - use nir print type IR snippets in unroll function descriptions - add better explanation and variable for why we need to clone additional times when the second terminator it the limiting terminator. - partially convert out of ssa before unrolling loops (suggested by Jason) v6: - remove unused nir_builder - use Jasons new from ssa helper - tidy/fixup cursor use - unroll terminators that contain control flow correctly - unroll complex loops with control flow before the terminators correctly Reviewed-by: Jason Ekstrand <[email protected]>
* nir: add helper for cloning nir_cf_listTimothy Arceri2016-12-232-9/+56
| | | | | | | | | V2: - updated to create a generic list clone helper nir_cf_list_clone() - continue to assert on clone when fallback flag not set as suggested by Jason. Reviewed-by: Jason Ekstrand <[email protected]>
* nir: update fixup_phi_srcs() to handle registersTimothy Arceri2016-12-231-4/+9
| | | | | | | We need to do this because we partially get out of SSA when unrolling and cloning loops. Reviewed-by: Jason Ekstrand <[email protected]>
* nir: create helper for fixing phi srcs when cloningTimothy Arceri2016-12-231-15/+21
| | | | | | | This will be useful for fixing phi srcs when cloning a loop body during loop unrolling. Reviewed-by: Jason Ekstrand <[email protected]>
* nir: Add a LCSAA-passThomas Helland2016-12-233-0/+206
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | V2: Do a "depth first search" to convert to LCSSA V3: Small comment fixup V4: Rebase, adapt to removal of function overloads V5: Rebase, adapt to relocation of nir to compiler/nir Still need to adapt to potential if-uses Work around nir_validate issue V6 (Timothy): - tidy lcssa and stop leaking memory - dont rewrite the src for the lcssa phi node - validate lcssa phi srcs to avoid postvalidate assert - don't add new phi if one already exists - more lcssa phi validation fixes - Rather than marking ssa defs inside a loop just mark blocks inside a loop. This is simpler and fixes lcssa for intrinsics which do not have a destination. - don't create LCSSA phis for loops we won't unroll - require loop metadata for lcssa pass - handle case were the ssa defs use outside the loop is already a phi V7: (Timothy) - pass indirect mask to metadata call v8: (Timothy) - make convert to lcssa a helper function rather than a nir pass - replace inside loop bitset with on the fly block index logic. - remove lcssa phi validation special cases - inline code from useless helpers, suggested by Jason. - always do lcssa on loops, suggested by Jason. - stop making lcssa phis special. Add as many source as the block has predecessors, suggested by Jason. V9: (Timothy) - fix regression with the is_lcssa_phi field not being initialised to false now that ralloc() doesn't zero out memory. V10: (Timothy) - remove extra braces in SSA example, pointed out by Topi V11: (Timothy) - add missing support for LCSSA phis in if conditions. V12: (Timothy) - small tidy up suggested by Jason. - always create lcssa phi even if it just points to an lcssa phi from an inner loop Reviewed-by: Jason Ekstrand <[email protected]>
* nir: Add a loop analysis passThomas Helland2016-12-236-3/+986
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This pass detects induction variables and calculates the trip count of loops to be used for loop unrolling. V2: Rebase, adapt to removal of function overloads V3: (Timothy Arceri) - don't try to find trip count if loop terminator conditional is a phi - fix trip count for do-while loops - replace conditional type != alu assert with return - disable unrolling of loops with continues - multiple fixes to memory allocation, stop leaking and don't destroy structs we want to use for unrolling. - fix iteration count bugs when induction var not on RHS of condition - add FIXME for && conditions - calculate trip count for unsigned induction/limit vars V4: (Timothy Arceri) - count instructions in a loop - set the limiting_terminator even if we can't find the trip count for all terminators. This is needed for complex unrolling where we handle 2 terminators and the trip count is unknown for one of them. - restruct structs so we don't keep information not required after analysis and remove dead fields. - force unrolling in some cases as per the rules in the GLSL IR pass V5: (Timothy Arceri) - fix metadata mask value 0x10 vs 0x16 V6: (Timothy Arceri) - merge loop_variable and nir_loop_variable structs and lists suggested by Jason - remove induction var hash table and store pointer to induction information in the loop_variable suggested by Jason. - use lowercase list_addtail() suggested by Jason. - tidy up init_loop_block() as per Jasons suggestions. - replace switch with nir_op_infos[alu->op].num_inputs == 2 in is_var_basic_induction_var() as suggested by Jason. - use nir_block_last_instr() in and rename foreach_cf_node_ex_loop() as suggested by Jason. - fix else check for is_trivial_loop_terminator() as per Connors suggetions. - simplify offset for induction valiables incremented before the exit conditions is checked. - replace nir_op_isub check with assert() as it should have been lowered away. V7: (Timothy Arceri) - use rzalloc() on nir_loop struct creation. Worked previously because ralloc() was broken and always zeroed the struct. - fix cf_node_find_loop_jumps() to find jumps when loops contain nested if statements. Code is tidier as a result. V8: (Timothy Arceri) - move is_trivial_loop_terminator() to nir.h so we can use it to assert is the loop unroll pass - fix analysis to not bail when looking for terminator when the break is in the else rather then the if - added new loop terminator fields: break_block, continue_from_block and continue_from_then so we don't have to gather these when doing unrolling. - get correct array length when forcing unrolling of variables indexed arrays that are the same size as the iteration count - add support for induction variables of type float - update trival loop terminator check to allow an if containing instructions as long as both branches contain only a single block. V9: (Timothy) - bunch of tidy ups and simplifications suggested by Jason. - rewrote trivial terminator detection, now the only restriction is there must be no nested jumps, anything else goes. - rewrote the iteration test to use nir_eval_const_opcode(). - count instruction properly even when forcing an unroll. - bunch of other tidy ups and simplifications. V10: (Timothy) - some trivial tidy ups suggested by Jason. - conditional fix for break inside continue branch by Jason. Reviewed-by: Jason Ekstrand <[email protected]>
* nir: Add a couple quick-and-dirty out-of-SSA helpersJason Ekstrand2016-12-232-12/+180
| | | | | | | | | | | These are designed for use within an optimization pass when SSA becomes more pain than it's worth. They're very naive and don't generate anything close to optimal register-based NIR. Also, they may result in shaders which do not validate because of, for instance, registers in phi sources. However, the register-based into-SSA pass should be pretty efficient at cleaning up the mess. Reviewed-by: Timothy Arceri <[email protected]>
* glsl: Eliminate the open-coded version of process_block_array_leafIan Romanick2016-12-211-31/+9
| | | | | Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Timothy Arceri <[email protected]>
* glsl: Use ir_var_temporary when generating inline functions.Kenneth Graunke2016-12-201-1/+1
| | | | | | | | | | | | | | | | | | | | | | | We were using ir_var_auto for the inlined function parameter variables, which is wrong, as it suggests that those are real variables declared by the program. Normally this doesn't matter. However, if you called built-ins at global scope, it would pollute the global variable namespace with these new parameter temporaries. If the shader already had variables with those names, the linker might see contradictory global variable declarations and raise an error. Making them temporaries indicates that these are just things generated by the compiler internally. This avoids confusing the linker. Fixes a new Piglit test: glsl-fs-multiple-builtins. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99154 Reported-by: Niels Ole Salscheider <[email protected]> Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Ilia Mirkin <[email protected]> Reviewed-by: Iago Toral Quiroga <[email protected]>
* glsl: allow invariant on fragment shader outputs.Dave Airlie2016-12-201-2/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | From page 27 (page 33 of the PDF) of the GLSL 1.20 spec: " Only variables output from a vertex shader can be candidates for invariance." But this later changes to: From page 37 (page 43 of the PDF) of the GLSL 1.30 spec: " Only variables output from a shader can be candidates for invariance." We can also find: From page 37 (page 43 of the PDF) of the GLSL 1.30 spec: " Initially, by default, all output variables are allowed to be variant. To force all output variables to be invariant, use the pragma #pragma STDGL invariant(all) before all declarations in a shader. If this pragma is used after the declaration of any variables or functions, then the set of outputs that behave as invariant is undefined. It is an error to use this pragma in a fragment shader." But this needs to be corrected and it is being addressed at: https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16140 Fixes GL45-CTS.shading_language_420pack.qualifier_order. Signed-off-by: Dave Airlie <[email protected]> Reviewed-by: Andres Gomez <[email protected]>
* nir: Trivial clean ups in the generated nir_constant_expressions.cIan Romanick2016-12-191-6/+5
| | | | | Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
* nir: Silence unused parameter warnings in nir_constant_expression.cIan Romanick2016-12-191-2/+2
| | | | | | | | | | | | | | | | | | | | nir/nir_constant_expressions.c:290:25: warning: unused parameter 'num_components' [-Wunused-parameter] evaluate_ball3(unsigned num_components, nir_const_value *_src) ^ nir/nir_constant_expressions.c: In function 'evaluate_fddx': nir/nir_constant_expressions.c:1282:57: warning: unused parameter '_src' [-Wunused-parameter] evaluate_fddx(unsigned num_components, nir_const_value *_src) ^ v2: Unconditionally mark the parameters as MAYBE_UNUSED instead of conditionally adding (void) casts to keep the generator simple. Suggested by Jason. Number of total warnings in my build reduced from 1575 to 1485 (reduction of 89). Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
* nir: Silence missing field initializer warnings for vectors in ↵Ian Romanick2016-12-191-0/+3
| | | | | | | | | | | | | | | | | | | | | nir_constant_expressions nir/nir_constant_expressions.c: In function 'evaluate_ball2': nir/nir_constant_expressions.c:279:7: warning: missing initializer for field 'z' of 'struct bool_vec' [-Wmissing-field-initializers] }; ^ nir/nir_constant_expressions.c:234:10: note: 'z' declared here bool z; ^ Number of total warnings in my build reduced from 2532 to 2304 (reduction of 228). v2: Initialize bool vectors with 0 instead of false to keep the generator simpler. Suggested by Ken. Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Silence "unused parameter" warnings in ast_type.cppIan Romanick2016-12-191-6/+4
| | | | | | | | | | | | | | glsl/ast_type.cpp: In function ‘bool validate_point_mode(YYLTYPE*, _mesa_glsl_parse_state*, const ast_type_qualifier&, const ast_type_qualifier&)’: glsl/ast_type.cpp:173:30: warning: unused parameter ‘loc’ [-Wunused-parameter] validate_point_mode(YYLTYPE *loc, ^~~ glsl/ast_type.cpp:174:45: warning: unused parameter ‘state’ [-Wunused-parameter] _mesa_glsl_parse_state *state, ^~~~~ Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Andres Gomez <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Trivial whitespace fixes in link_uniforms.cppIan Romanick2016-12-191-3/+4
| | | | | Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Silence unused parameter warning in propagate_invariance.cppIan Romanick2016-12-191-1/+1
| | | | | | | | | | glsl/propagate_invariance.cpp: In member function ‘virtual ir_visitor_status {anonymous}::ir_invariance_propagation_visitor::visit_leave(ir_assignment*)’: glsl/propagate_invariance.cpp:86:63: warning: unused parameter ‘ir’ [-Wunused-parameter] ir_invariance_propagation_visitor::visit_leave(ir_assignment *ir) ^~ Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Minor formatting fixes in link_uniform_blocks.cppIan Romanick2016-12-191-37/+42
| | | | | Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Fix all the whitespace errors in link_uniform_block_active_visitor.cppIan Romanick2016-12-191-25/+21
| | | | | Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>