diff mbox series

[testsuite] Fix caching of tests for multiple variant runs and update existing target-supports tests.

Message ID 20180926134838.GA15583@arm.com
State New
Headers show
Series [testsuite] Fix caching of tests for multiple variant runs and update existing target-supports tests. | expand

Commit Message

Tamar Christina Sept. 26, 2018, 1:48 p.m. UTC
Hi All,

Currently some target supports checks such as vect_int cache their
results in a manner that would cause them not to be rechecked when
running the same tests against a different variant in a multi variant
run.  This causes tests to be skipped or run when they shouldn't be.

there is already an existing caching mechanism in place that does the
caching correctly, but presumably these weren't used because some of these
tests originally only contained static data. e.g. only checked if the target is
aarch64*-*-* etc.

This patch changes every function that needs to do any caching at all to use
check_cached_effective_target which will cache per variant instead of globally.

For those tests that already parameterize over et_index I have created
check_cached_effective_target_indexed to handle this common case by creating a list
containing the property name and the current value of et_index.

These changes result in a much simpler implementation for most tests and a large
reduction in lines for target-supports.exp.

Regtested on
  aarch64-none-elf
  x86_64-pc-linux-gnu
  powerpc64-unknown-linux-gnu
  arm-none-eabi

and no testsuite errors. Difference would depend on your site.exp.
On arm we get about 4500 new testcases and on aarch64 the low 10s.
On PowerPC and x86_64 no changes as expected since the default exp for these
just test the default configuration.

What this means for new target checks is that they should always use either
check_cached_effective_target or check_cached_effective_target_indexed if the
result of the check is to be cached.

As an example the new vect_int looks like

proc check_effective_target_vect_int { } {
    return [check_cached_effective_target_indexed <name> {
      expr {
         <condition>
	}}]
}

The debug information that was once there is now all hidden in
check_cached_effective_target, (called from check_cached_effective_target_indexed)
and so the only thing you are required to do is give it a unique cache name and a condition.

The condition doesn't need to be an if statement so simple boolean expressions are enough here:

         [istarget i?86-*-*] || [istarget x86_64-*-*]
         || ([istarget powerpc*-*-*]
	     && ![istarget powerpc-*-linux*paired*])
         || ...

The expr may not be required as check_cached_effective_target forces evaluation, but I have
left these here just to be sure (TCL semantics is confusing at times.).


Ok for trunk?

Thank,
Tamar

gcc/testsuite/

2018-09-26  Tamar Christina  <tamar.christina@arm.com>

	* lib/target-supports.exp (check_cached_effective_target_indexed): New.
	(check_cached_effective_target, clear_effective_target_cache): Cleanup.
	(check_compile): Support values already Boolean.
	(check_alias_available, check_gc_sections_available,
	check_profiling_available, check_effective_target_vect_cmdline_needed,
	check_effective_target_vect_int,
	check_effective_target_vect_intfloat_cvt,
	check_effective_target_vect_doubleint_cvt,
	check_effective_target_vect_intdouble_cvt,
	check_effective_target_vect_uintfloat_cvt,
	check_effective_target_vect_floatint_cvt,
	check_effective_target_vect_floatuint_cvt,
	check_effective_target_vect_peeling_profitable,
	check_effective_target_vect_simd_clones,
	check_effective_target_vect_peeling_profitable,
	check_effective_target_vect_simd_clones,
	check_effective_target_vect_shift,
	check_effective_target_vect_bswap,
	check_effective_target_vect_shift_char,
	check_effective_target_vect_float,
	check_effective_target_vect_double,
	check_effective_target_vect_long_long,
	check_effective_target_vect_no_int_min_max,
	check_effective_target_vect_no_int_add,
	check_effective_target_vect_no_bitwise,
	check_effective_target_vect_perm,
	check_effective_target_vect_perm_byte,
	check_effective_target_vect_perm_short,
	check_effective_target_xorsign,
	check_effective_target_vect_widen_sum_hi_to_si_pattern,
	check_effective_target_vect_widen_sum_hi_to_si,
	check_effective_target_vect_widen_sum_qi_to_hi,
	check_effective_target_vect_widen_sum_qi_to_si,
	check_effective_target_vect_widen_mult_qi_to_hi,
	check_effective_target_vect_widen_mult_hi_to_si,
	check_effective_target_vect_widen_mult_qi_to_hi_pattern,
	check_effective_target_vect_widen_mult_hi_to_si_pattern,
	check_effective_target_vect_widen_mult_si_to_di_pattern,
	check_effective_target_vect_widen_shift,
	check_effective_target_vect_sdot_qi,
	check_effective_target_vect_udot_qi,
	check_effective_target_vect_sdot_hi,
	check_effective_target_vect_udot_hi,
	check_effective_target_vect_usad_char,
	check_effective_target_vect_pack_trunc,
	check_effective_target_vect_unpack,
	check_effective_target_unaligned_stack,
	check_effective_target_vect_no_align,
	check_effective_target_vect_hw_misalign,
	check_effective_target_natural_alignment_32,
	check_effective_target_natural_alignment_64,
	check_effective_target_vect_element_align,
	check_effective_target_vect_load_lanes **,
	check_effective_target_vect_condition,
	check_effective_target_vect_cond_mixed,
	check_effective_target_vect_char_mult,
	check_effective_target_vect_short_mult,
	check_effective_target_vect_int_mult,
	check_effective_target_vect_extract_even_odd,
	check_effective_target_vect_interleave,
	check_effective_target_vect_stridedN,
	check_effective_target_vect_call_copysignf,
	check_effective_target_sqrt_insn,
	check_effective_target_vect_call_sqrtf,
	check_effective_target_vect_call_btrunc,
	check_effective_target_vect_call_btruncf,
	check_effective_target_vect_call_ceil,
	check_effective_target_vect_call_ceilf,
	check_effective_target_vect_call_floor,
	check_effective_target_vect_call_floorf,
	check_effective_target_vect_call_lceil,
	check_effective_target_vect_call_lfloor,
	check_effective_target_vect_call_nearbyint,
	check_effective_target_vect_call_nearbyintf,
	check_effective_target_vect_call_round,
	check_effective_target_vect_call_roundf,
	check_effective_target_section_anchors,
	check_effective_target_bswap,
	check_effective_target_sync_int_long,
	check_effective_target_sync_char_short,
	check_effective_target_tiny,
	check_effective_target_pie_copyreloc,
	check_effective_target_got32x_reloc,
	check_effective_target_tls_get_addr_via_got): Use new caching.

--

Comments

Richard Sandiford Sept. 27, 2018, 8:40 a.m. UTC | #1
Tamar Christina <tamar.christina@arm.com> writes:
> Hi All,
>
> Currently some target supports checks such as vect_int cache their
> results in a manner that would cause them not to be rechecked when
> running the same tests against a different variant in a multi variant
> run.  This causes tests to be skipped or run when they shouldn't be.
>
> there is already an existing caching mechanism in place that does the
> caching correctly, but presumably these weren't used because some of
> these tests originally only contained static data. e.g. only checked
> if the target is aarch64*-*-* etc.
>
> This patch changes every function that needs to do any caching at all
> to use check_cached_effective_target which will cache per variant
> instead of globally.

Thanks for doing this!

> For those tests that already parameterize over et_index I have created
> check_cached_effective_target_indexed to handle this common case by
> creating a list containing the property name and the current value of
> et_index.
>
> These changes result in a much simpler implementation for most tests
> and a large reduction in lines for target-supports.exp.
>
> Regtested on
>   aarch64-none-elf
>   x86_64-pc-linux-gnu
>   powerpc64-unknown-linux-gnu
>   arm-none-eabi
>
> and no testsuite errors. Difference would depend on your site.exp.
> On arm we get about 4500 new testcases and on aarch64 the low 10s.
> On PowerPC and x86_64 no changes as expected since the default exp for these
> just test the default configuration.

Would be good to try --target_board unix{,-m32} on x86_64.

> What this means for new target checks is that they should always use either
> check_cached_effective_target or check_cached_effective_target_indexed if the
> result of the check is to be cached.
>
> As an example the new vect_int looks like
>
> proc check_effective_target_vect_int { } {
>     return [check_cached_effective_target_indexed <name> {
>       expr {
>          <condition>
> 	}}]
> }
>
> The debug information that was once there is now all hidden in
> check_cached_effective_target, (called from
> check_cached_effective_target_indexed) and so the only thing you are
> required to do is give it a unique cache name and a condition.
>
> The condition doesn't need to be an if statement so simple boolean expressions are enough here:
>
>          [istarget i?86-*-*] || [istarget x86_64-*-*]
>          || ([istarget powerpc*-*-*]
> 	     && ![istarget powerpc-*-linux*paired*])
>          || ...
>
> The expr may not be required as check_cached_effective_target forces
> evaluation, but I have left these here just to be sure (TCL semantics
> is confusing at times.).

It's required, since "eval" just runs a tcl script (which can give back
an arbitrary string) while "expr" evaluates the string as an expression.

This means that the caching (as written) should work for arbitrary strings,
such as command-line flags or the default value of -march.

> @@ -120,22 +121,41 @@ proc check_cached_effective_target { prop args } {
>      global et_prop_list
> 
>      set target [current_target_name]
> -    if {![info exists et_cache($prop,target)]
> -	|| $et_cache($prop,target) != $target} {
> +    if {![info exists et_cache($prop,$target)]} {
>  	verbose "check_cached_effective_target $prop: checking $target" 2
> -	set et_cache($prop,target) $target
> -	set et_cache($prop,value) [uplevel eval $args]
> +	if {[string is true -strict $args] || [string is false -strict $args]} {
> +	    set et_cache($prop,$target) $args
> +	} else {
> +	    set et_cache($prop,$target) [uplevel eval $args]
> +	}

Why are the checks for true and false needed?  We shouldn't be
using this function for something that's already true or false.

> +# Implements a version of check_cached_effective_target that also takes et_index
> +# into account when creating the key for the cache.
> +proc check_cached_effective_target_indexed { prop args } {
> +    global et_index
> +    set key "$et_index $prop"
> +    verbose "check_cached_effective_target_index $prop: returning $key" 2
> +
> +    # Force the evaluation at this level since check_cached_effective_target
> +    # may no longer be able to.
> +    if {[string is true -strict $args] || [string is false -strict $args]} {
> +	set value $args
> +    } else {
> +	set value [uplevel eval $args]
> +    }
> +    return [check_cached_effective_target $key $value]
> +}

This defeats the point of the cache, since we'll evaluate the expression
every time before passing it to check_cached_effective_target.

How about:

  return [check_cached_effective_target $key [list uplevel eval $args]]

> @@ -149,11 +169,13 @@ proc clear_effective_target_cache { } {
>      global et_cache
>      global et_prop_list
> 
> +    set target [current_target_name]
>      if {[info exists et_prop_list]} {
>  	verbose "clear_effective_target_cache: $et_prop_list" 2
>  	foreach prop $et_prop_list {
> -	    unset et_cache($prop,value)
> -	    unset et_cache($prop,target)
> +	    if {[info exists et_cache($prop,$target)]} {
> +		unset et_cache($prop,$target)
> +            }

Looks a bit odd that we now have to make this conditional.  Maybe we
should maintain an et_prop_list for each target.  I.e.:

 	if {![info exists et_prop_list]
 	    || [lsearch $et_prop_list $prop] < 0} {
 	    lappend et_prop_list $prop
 	}

in check_cached_effective_target would become an unconditional:

	lappend et_prop_list($target) $prop

(since $prop should already be in the cache for $target if it's
already in the list) and clear_effective_target_cache would then use:

     if {[info exists et_prop_list($target)]} {
 	verbose "clear_effective_target_cache: $et_prop_list($target)" 2
 	foreach prop $et_prop_list($target) {
	    unset et_cache($prop,$target)
 	}
 	unset et_prop_list($target)
     }

...That said, I'm not sure what the point of et_prop_list actually is.
The comment above clear_effective_target_cache says:

  # Clear effective-target cache. This is useful after testing
  # effective-target features and overriding TEST_ALWAYS_FLAGS and/or
  # ALWAYS_CXXFLAGS.
  # If one changes ALWAYS_CXXFLAGS or TEST_ALWAYS_FLAGS then they should
  # do a clear_effective_target_cache at the end as the target cache can
  # make decisions based upon the flags, and those decisions need to be
  # redone when the flags change. An example of this is the
  # asan_init/asan_finish pair.

so at first I thought it was to avoid removing entries from before
TEST_ALWAYS_FLAGS & co. had been changed, since those entries should
still be valid after the flags have been reset.  But that would only
happen if something cleared et_prop_list before changing TEST_ALWAYS_FLAGS
(so that et_prop_list only contains entries that postdate the change),
and AFAICT nothing does.

So I think we should simply remove et_prop_list and use an unconditional:

    array unset et_cache

in clear_effective_target_cache.

> @@ -380,12 +402,9 @@ proc check_visibility_available { what_kind } {
>  # be determined.
> 
>  proc check_alias_available { } {
> -    global alias_available_saved
>      global tool
> 
> -    if [info exists alias_available_saved] {
> -        verbose "check_alias_available  returning saved $alias_available_saved" 2
> -    } else {
> +    return [check_cached_effective_target alias_available {
>  	set src alias[pid].c
>  	set obj alias[pid].o
>          verbose "check_alias_available  compiling testfile $src" 2
> @@ -402,7 +421,7 @@ proc check_alias_available { } {
> 
>  	if [string match "" $lines] then {
>  	    # No error messages, everything is OK.
> -	    set alias_available_saved 2
> +	    return 2
>  	} else {
>  	    if [regexp "alias definitions not supported" $lines] {
>  		verbose "check_alias_available  target does not support aliases" 2
> @@ -411,24 +430,20 @@ proc check_alias_available { } {
> 
>  		if { $objformat == "elf" } {
>  		    verbose "check_alias_available  but target uses ELF format, so it ought to" 2
> -		    set alias_available_saved -1
> +		    return -1
>  		} else {
> -		    set alias_available_saved 0
> +		    return 0
>  		}
>  	    } else {
>  		if [regexp "only weak aliases are supported" $lines] {
>  		verbose "check_alias_available  target supports only weak aliases" 2
> -		set alias_available_saved 1
> +		    return 1
>  		} else {
> -		    set alias_available_saved -1
> +		    return -1
>  		}
>  	    }
>  	}
> -
> -	verbose "check_alias_available  returning $alias_available_saved" 2
> -    }
> -
> -    return $alias_available_saved
> +    }]
>  }

As it stands, these should be "expr" rather than "return".
"return" will make check_cached_effective_target return at the point of
the uplevel eval, bypassing the actual caching.

If instead you want to support "return" (would be nice IMO), you could
use something like:

    set code [catch {uplevel eval $args} result options]
    if {$code != 0 && $code != 2} {
	return -code $code $result
    }
    set et_cache($prop,$target) $result

Thanks,
Richard
Richard Sandiford Sept. 27, 2018, 8:49 a.m. UTC | #2
Richard Sandiford <richard.sandiford@arm.com> writes:
> If instead you want to support "return" (would be nice IMO), you could
> use something like:
>
>     set code [catch {uplevel eval $args} result options]
>     if {$code != 0 && $code != 2} {
> 	return -code $code $result
>     }
>     set et_cache($prop,$target) $result

Sorry, drop the "options" argument to "catch".  I was experimenting
with whether -code $code or -options $options gave better backtraces
for errors, but -code $code seemed better.

Richard
Tamar Christina Sept. 27, 2018, 10:23 a.m. UTC | #3
Hi Richard,

Thanks for the review!

The 09/27/2018 09:40, Richard Sandiford wrote:
> Tamar Christina <tamar.christina@arm.com> writes:
> >
> > and no testsuite errors. Difference would depend on your site.exp.
> > On arm we get about 4500 new testcases and on aarch64 the low 10s.
> > On PowerPC and x86_64 no changes as expected since the default exp for these
> > just test the default configuration.
> 
> Would be good to try --target_board unix{,-m32} on x86_64.
> 

Running now.

> > What this means for new target checks is that they should always use either
> > check_cached_effective_target or check_cached_effective_target_indexed if the
> > result of the check is to be cached.
> >
> > As an example the new vect_int looks like
> >
> > proc check_effective_target_vect_int { } {
> >     return [check_cached_effective_target_indexed <name> {
> >       expr {
> >          <condition>
> > 	}}]
> > }
> >
> > The debug information that was once there is now all hidden in
> > check_cached_effective_target, (called from
> > check_cached_effective_target_indexed) and so the only thing you are
> > required to do is give it a unique cache name and a condition.
> >
> > The condition doesn't need to be an if statement so simple boolean expressions are enough here:
> >
> >          [istarget i?86-*-*] || [istarget x86_64-*-*]
> >          || ([istarget powerpc*-*-*]
> > 	     && ![istarget powerpc-*-linux*paired*])
> >          || ...
> >
> > The expr may not be required as check_cached_effective_target forces
> > evaluation, but I have left these here just to be sure (TCL semantics
> > is confusing at times.).
> 
> It's required, since "eval" just runs a tcl script (which can give back
> an arbitrary string) while "expr" evaluates the string as an expression.
> 
> This means that the caching (as written) should work for arbitrary strings,
> such as command-line flags or the default value of -march.
> 

Ah ok, got it,

> > @@ -120,22 +121,41 @@ proc check_cached_effective_target { prop args } {
> >      global et_prop_list
> > 
> >      set target [current_target_name]
> > -    if {![info exists et_cache($prop,target)]
> > -	|| $et_cache($prop,target) != $target} {
> > +    if {![info exists et_cache($prop,$target)]} {
> >  	verbose "check_cached_effective_target $prop: checking $target" 2
> > -	set et_cache($prop,target) $target
> > -	set et_cache($prop,value) [uplevel eval $args]
> > +	if {[string is true -strict $args] || [string is false -strict $args]} {
> > +	    set et_cache($prop,$target) $args
> > +	} else {
> > +	    set et_cache($prop,$target) [uplevel eval $args]
> > +	}
> 
> Why are the checks for true and false needed?  We shouldn't be
> using this function for something that's already true or false.
> 

I had wanted to be a bit lenient here in accepting it if you have a function that already
fully evaluated the expr before passing it to check_cached_effective_target.

i.e. something like

 proc check_effective_target_vect_int { } {
     return [check_cached_effective_target_indexed <name> [
       expr {
          <condition>
     }]]
 }

The error you would get if you do this is very confusing so I thought since it didn't matter
much for the regexp only target triple tests that just accepting this would be fine.

Should I drop it or keep it?

Thanks,
Tamar.

> > +# Implements a version of check_cached_effective_target that also takes et_index
> > +# into account when creating the key for the cache.
> > +proc check_cached_effective_target_indexed { prop args } {
> > +    global et_index
> > +    set key "$et_index $prop"
> > +    verbose "check_cached_effective_target_index $prop: returning $key" 2
> > +
> > +    # Force the evaluation at this level since check_cached_effective_target
> > +    # may no longer be able to.
> > +    if {[string is true -strict $args] || [string is false -strict $args]} {
> > +	set value $args
> > +    } else {
> > +	set value [uplevel eval $args]
> > +    }
> > +    return [check_cached_effective_target $key $value]
> > +}
> 
> This defeats the point of the cache, since we'll evaluate the expression
> every time before passing it to check_cached_effective_target.
> 
> How about:
> 
>   return [check_cached_effective_target $key [list uplevel eval $args]]
> 
> > @@ -149,11 +169,13 @@ proc clear_effective_target_cache { } {
> >      global et_cache
> >      global et_prop_list
> > 
> > +    set target [current_target_name]
> >      if {[info exists et_prop_list]} {
> >  	verbose "clear_effective_target_cache: $et_prop_list" 2
> >  	foreach prop $et_prop_list {
> > -	    unset et_cache($prop,value)
> > -	    unset et_cache($prop,target)
> > +	    if {[info exists et_cache($prop,$target)]} {
> > +		unset et_cache($prop,$target)
> > +            }
> 
> Looks a bit odd that we now have to make this conditional.  Maybe we
> should maintain an et_prop_list for each target.  I.e.:
> 
>  	if {![info exists et_prop_list]
>  	    || [lsearch $et_prop_list $prop] < 0} {
>  	    lappend et_prop_list $prop
>  	}
> 
> in check_cached_effective_target would become an unconditional:
> 
> 	lappend et_prop_list($target) $prop
> 
> (since $prop should already be in the cache for $target if it's
> already in the list) and clear_effective_target_cache would then use:
> 
>      if {[info exists et_prop_list($target)]} {
>  	verbose "clear_effective_target_cache: $et_prop_list($target)" 2
>  	foreach prop $et_prop_list($target) {
> 	    unset et_cache($prop,$target)
>  	}
>  	unset et_prop_list($target)
>      }
> 
> ...That said, I'm not sure what the point of et_prop_list actually is.
> The comment above clear_effective_target_cache says:
> 
>   # Clear effective-target cache. This is useful after testing
>   # effective-target features and overriding TEST_ALWAYS_FLAGS and/or
>   # ALWAYS_CXXFLAGS.
>   # If one changes ALWAYS_CXXFLAGS or TEST_ALWAYS_FLAGS then they should
>   # do a clear_effective_target_cache at the end as the target cache can
>   # make decisions based upon the flags, and those decisions need to be
>   # redone when the flags change. An example of this is the
>   # asan_init/asan_finish pair.
> 
> so at first I thought it was to avoid removing entries from before
> TEST_ALWAYS_FLAGS & co. had been changed, since those entries should
> still be valid after the flags have been reset.  But that would only
> happen if something cleared et_prop_list before changing TEST_ALWAYS_FLAGS
> (so that et_prop_list only contains entries that postdate the change),
> and AFAICT nothing does.
> 
> So I think we should simply remove et_prop_list and use an unconditional:
> 
>     array unset et_cache
> 
> in clear_effective_target_cache.
> 
> > @@ -380,12 +402,9 @@ proc check_visibility_available { what_kind } {
> >  # be determined.
> > 
> >  proc check_alias_available { } {
> > -    global alias_available_saved
> >      global tool
> > 
> > -    if [info exists alias_available_saved] {
> > -        verbose "check_alias_available  returning saved $alias_available_saved" 2
> > -    } else {
> > +    return [check_cached_effective_target alias_available {
> >  	set src alias[pid].c
> >  	set obj alias[pid].o
> >          verbose "check_alias_available  compiling testfile $src" 2
> > @@ -402,7 +421,7 @@ proc check_alias_available { } {
> > 
> >  	if [string match "" $lines] then {
> >  	    # No error messages, everything is OK.
> > -	    set alias_available_saved 2
> > +	    return 2
> >  	} else {
> >  	    if [regexp "alias definitions not supported" $lines] {
> >  		verbose "check_alias_available  target does not support aliases" 2
> > @@ -411,24 +430,20 @@ proc check_alias_available { } {
> > 
> >  		if { $objformat == "elf" } {
> >  		    verbose "check_alias_available  but target uses ELF format, so it ought to" 2
> > -		    set alias_available_saved -1
> > +		    return -1
> >  		} else {
> > -		    set alias_available_saved 0
> > +		    return 0
> >  		}
> >  	    } else {
> >  		if [regexp "only weak aliases are supported" $lines] {
> >  		verbose "check_alias_available  target supports only weak aliases" 2
> > -		set alias_available_saved 1
> > +		    return 1
> >  		} else {
> > -		    set alias_available_saved -1
> > +		    return -1
> >  		}
> >  	    }
> >  	}
> > -
> > -	verbose "check_alias_available  returning $alias_available_saved" 2
> > -    }
> > -
> > -    return $alias_available_saved
> > +    }]
> >  }
> 
> As it stands, these should be "expr" rather than "return".
> "return" will make check_cached_effective_target return at the point of
> the uplevel eval, bypassing the actual caching.
> 
> If instead you want to support "return" (would be nice IMO), you could
> use something like:
> 
>     set code [catch {uplevel eval $args} result options]
>     if {$code != 0 && $code != 2} {
> 	return -code $code $result
>     }
>     set et_cache($prop,$target) $result
> 
> Thanks,
> Richard

--
Richard Sandiford Sept. 27, 2018, 11:19 a.m. UTC | #4
Tamar Christina <Tamar.Christina@arm.com> writes:
> The 09/27/2018 09:40, Richard Sandiford wrote:
>> Tamar Christina <tamar.christina@arm.com> writes:
>> > @@ -120,22 +121,41 @@ proc check_cached_effective_target { prop args } {
>> >      global et_prop_list
>> > 
>> >      set target [current_target_name]
>> > -    if {![info exists et_cache($prop,target)]
>> > -	|| $et_cache($prop,target) != $target} {
>> > +    if {![info exists et_cache($prop,$target)]} {
>> >  	verbose "check_cached_effective_target $prop: checking $target" 2
>> > -	set et_cache($prop,target) $target
>> > -	set et_cache($prop,value) [uplevel eval $args]
>> > +	if {[string is true -strict $args] || [string is false -strict $args]} {
>> > +	    set et_cache($prop,$target) $args
>> > +	} else {
>> > +	    set et_cache($prop,$target) [uplevel eval $args]
>> > +	}
>> 
>> Why are the checks for true and false needed?  We shouldn't be
>> using this function for something that's already true or false.
>> 
>
> I had wanted to be a bit lenient here in accepting it if you have a
> function that already fully evaluated the expr before passing it to
> check_cached_effective_target.
>
> i.e. something like
>
>  proc check_effective_target_vect_int { } {
>      return [check_cached_effective_target_indexed <name> [
>        expr {
>           <condition>
>      }]]
>  }
>
> The error you would get if you do this is very confusing so I thought
> since it didn't matter much for the regexp only target triple tests
> that just accepting this would be fine.

Seems a good thing that that's a noisy failure; the function should
make up its mind whether it wants to cache (use curly braces) or not
(just return the expr directly).

> Should I drop it or keep it?

Think we should either drop it or make it into a more user-friendly
error, e.g.:

	if {[string is true -strict $args] || [string is false -strict $args]} {
	    error {check_cached_effective_target condition already evaluated; did you pass [...] instead of the expected {...}?}
	} else {
	    set et_cache($prop,$target) [uplevel eval $args]
	}

Thanks,
Richard
Tamar Christina Sept. 27, 2018, 2:13 p.m. UTC | #5
> >
> > The error you would get if you do this is very confusing so I thought
> > since it didn't matter much for the regexp only target triple tests
> > that just accepting this would be fine.
> 
> Seems a good thing that that's a noisy failure; the function should
> make up its mind whether it wants to cache (use curly braces) or not
> (just return the expr directly).
> 
> > Should I drop it or keep it?
> 
> Think we should either drop it or make it into a more user-friendly
> error, e.g.:
> 
> 	if {[string is true -strict $args] || [string is false -strict $args]} {
> 	    error {check_cached_effective_target condition already evaluated; did you pass [...] instead of the expected {...}?}
> 	} else {
> 	    set et_cache($prop,$target) [uplevel eval $args]
> 	}
>

Done, I have also ran a regression test on x86_64 with unix{,-m32} and no fallouts, testsuite is clean.

Attached updated patch with feedback processed.

Ok for trunk?

Thanks,
Tamar
 
> Thanks,
> Richard

--
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index c2d814cf8c692e5939ec71c43a50c5bd52554b2b..b70536503f87fe4e8b3bd27a0c25c5317f8bf9c8 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -37,6 +37,7 @@
 # and "// Go" for Go
 # If the tool is ObjC/ObjC++ then we overide the extension to .m/.mm to 
 # allow for ObjC/ObjC++ specific flags.
+
 proc check_compile {basename type contents args} {
     global tool
     verbose "check_compile tool: $tool for $basename" 
@@ -117,25 +118,36 @@ proc current_target_name { } {
 
 proc check_cached_effective_target { prop args } {
     global et_cache
-    global et_prop_list
 
     set target [current_target_name]
-    if {![info exists et_cache($prop,target)]
-	|| $et_cache($prop,target) != $target} {
+    if {![info exists et_cache($prop,$target)]} {
 	verbose "check_cached_effective_target $prop: checking $target" 2
-	set et_cache($prop,target) $target
-	set et_cache($prop,value) [uplevel eval $args]
-	if {![info exists et_prop_list]
-	    || [lsearch $et_prop_list $prop] < 0} {
-	    lappend et_prop_list $prop
+	if {[string is true -strict $args] || [string is false -strict $args]} {
+	    error {check_cached_effective_target condition already evaluated;\
+		   did you pass [...] instead of the expected {...}?}
+	} else {
+	    set code [catch {uplevel eval $args} result]
+	    if {$code != 0 && $code != 2} {
+		return -code $code $result
+	    }
+	    set et_cache($prop,$target) $result
 	}
-	verbose "check_cached_effective_target cached list is now: $et_prop_list" 2
     }
-    set value $et_cache($prop,value)
+    set value $et_cache($prop,$target)
     verbose "check_cached_effective_target $prop: returning $value for $target" 2
     return $value
 }
 
+# Implements a version of check_cached_effective_target that also takes et_index
+# into account when creating the key for the cache.
+proc check_cached_effective_target_indexed { prop args } {
+    global et_index
+    set key "$et_index $prop"
+    verbose "check_cached_effective_target_index $prop: returning $key" 2
+
+    return [check_cached_effective_target $key [list uplevel eval $args]]
+}
+
 # Clear effective-target cache. This is useful after testing
 # effective-target features and overriding TEST_ALWAYS_FLAGS and/or
 # ALWAYS_CXXFLAGS.
@@ -147,16 +159,7 @@ proc check_cached_effective_target { prop args } {
 
 proc clear_effective_target_cache { } {
     global et_cache
-    global et_prop_list
-
-    if {[info exists et_prop_list]} {
-	verbose "clear_effective_target_cache: $et_prop_list" 2
-	foreach prop $et_prop_list {
-	    unset et_cache($prop,value)
-	    unset et_cache($prop,target)
-	}
-	unset et_prop_list
-    }
+    array unset et_cache
 }
 
 # Like check_compile, but delete the output file and return true if the
@@ -380,12 +383,9 @@ proc check_visibility_available { what_kind } {
 # be determined.
 
 proc check_alias_available { } {
-    global alias_available_saved
     global tool
 
-    if [info exists alias_available_saved] {
-        verbose "check_alias_available  returning saved $alias_available_saved" 2
-    } else {
+    return [check_cached_effective_target alias_available {
 	set src alias[pid].c
 	set obj alias[pid].o
         verbose "check_alias_available  compiling testfile $src" 2
@@ -402,7 +402,7 @@ proc check_alias_available { } {
 
 	if [string match "" $lines] then {
 	    # No error messages, everything is OK.
-	    set alias_available_saved 2
+	    return 2
 	} else {
 	    if [regexp "alias definitions not supported" $lines] {
 		verbose "check_alias_available  target does not support aliases" 2
@@ -411,24 +411,20 @@ proc check_alias_available { } {
 
 		if { $objformat == "elf" } {
 		    verbose "check_alias_available  but target uses ELF format, so it ought to" 2
-		    set alias_available_saved -1
+		    return -1
 		} else {
-		    set alias_available_saved 0
+		    return 0
 		}
 	    } else {
 		if [regexp "only weak aliases are supported" $lines] {
 		verbose "check_alias_available  target supports only weak aliases" 2
-		set alias_available_saved 1
+		    return 1
 		} else {
-		    set alias_available_saved -1
+		    return -1
 		}
 	    }
 	}
-
-	verbose "check_alias_available  returning $alias_available_saved" 2
-    }
-
-    return $alias_available_saved
+    }]
 }
 
 # Returns 1 if the target toolchain supports strong aliases, 0 otherwise.
@@ -461,15 +457,13 @@ proc check_ifunc_available { } {
 # Returns true if --gc-sections is supported on the target.
 
 proc check_gc_sections_available { } {
-    global gc_sections_available_saved
     global tool
 
-    if {![info exists gc_sections_available_saved]} {
+    return [check_cached_effective_target gc_sections_available {
 	# Some targets don't support gc-sections despite whatever's
 	# advertised by ld's options.
 	if { [istarget alpha*-*-*]
 	     || [istarget ia64-*-*] } {
-	    set gc_sections_available_saved 0
 	    return 0
 	}
 
@@ -477,7 +471,6 @@ proc check_gc_sections_available { } {
 	# --gc-sections.
 	if { [board_info target exists ldflags]
 	     && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
-	    set gc_sections_available_saved 0
 	    return 0
 	}
 
@@ -485,7 +478,6 @@ proc check_gc_sections_available { } {
 	# while RTP executables are linked with -q (--emit-relocs).
 	# Both of these options are incompatible with --gc-sections.
 	if { [istarget *-*-vxworks*] } {
-	    set gc_sections_available_saved 0
 	    return 0
 	}
 
@@ -493,12 +485,11 @@ proc check_gc_sections_available { } {
 	set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=ld" "" "none" ""] 0]
 	set ld_output [remote_exec host "$gcc_ld" "--help"]
 	if { [ string first "--gc-sections" $ld_output ] >= 0 } {
-	    set gc_sections_available_saved 1
+	    return 1
 	} else {
-	    set gc_sections_available_saved 0
+	    return 0
 	}
-    }
-    return $gc_sections_available_saved
+    }]
 }
 
 # Return 1 if according to target_info struct and explicit target list
@@ -581,8 +572,6 @@ proc profopt-perf-wrapper { } {
 # Return true if profiling is supported on the target.
 
 proc check_profiling_available { test_what } {
-    global profiling_available_saved
-
     verbose "Profiling argument is <$test_what>" 1
 
     # These conditions depend on the argument so examine them before
@@ -657,7 +646,8 @@ proc check_profiling_available { test_what } {
     }
 
     # Now examine the cache variable.
-    if {![info exists profiling_available_saved]} {
+    set profiling_working \
+       [expr {[check_cached_effective_target profiling_available {
 	# Some targets don't have any implementation of __bb_init_func or are
 	# missing other needed machinery.
 	if {[istarget aarch64*-*-elf]
@@ -692,16 +682,15 @@ proc check_profiling_available { test_what } {
 	     || [istarget xtensa*-*-elf]
 	     || [istarget *-*-rtems*]
 	     || [istarget *-*-vxworks*] } {
-	    set profiling_available_saved 0
+	    return 0
 	} else {
-	    set profiling_available_saved 1
+	    return 1
 	}
-    }
+    }]}]
 
     # -pg link test result can't be cached since it may change between
     # runs.
-    set profiling_working $profiling_available_saved
-    if { $profiling_available_saved == 1
+    if { $profiling_working == 1
          && ![check_no_compiler_messages_nocache profiling executable {
 	      int main() { return 0; } } "-pg"] } {
 	set profiling_working 0
@@ -3039,7 +3028,6 @@ proc check_effective_target_ucn { } {
 # instruction set.
 
 proc check_effective_target_vect_cmdline_needed { } {
-    global et_vect_cmdline_needed_saved
     global et_vect_cmdline_needed_target_name
 
     if { ![info exists et_vect_cmdline_needed_target_name] } {
@@ -3057,10 +3045,7 @@ proc check_effective_target_vect_cmdline_needed { } {
 	}
     }
 
-    if [info exists et_vect_cmdline_needed_saved] {
-	verbose "check_effective_target_vect_cmdline_needed: using cached result" 2
-    } else {
-	set et_vect_cmdline_needed_saved 1
+    return [check_cached_effective_target vect_cmdline_needed {
 	if { [istarget alpha*-*-*]
 	     || [istarget ia64-*-*]
 	     || (([istarget i?86-*-*] || [istarget x86_64-*-*])
@@ -3072,12 +3057,10 @@ proc check_effective_target_vect_cmdline_needed { } {
              || [istarget spu-*-*]
 	     || ([istarget arm*-*-*] && [check_effective_target_arm_neon])
 	     || [istarget aarch64*-*-*] } {
-	   set et_vect_cmdline_needed_saved 0
-	}
-    }
-
-    verbose "check_effective_target_vect_cmdline_needed: returning $et_vect_cmdline_needed_saved" 2
-    return $et_vect_cmdline_needed_saved
+		return 0
+	} else {
+		return 1
+	}}]
 }
 
 # Return 1 if the target supports hardware vectors of int, 0 otherwise.
@@ -3085,106 +3068,62 @@ proc check_effective_target_vect_cmdline_needed { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_int { } {
-    global et_vect_int_saved
-    global et_index
-
-    if [info exists et_vect_int_saved($et_index)] {
-	verbose "check_effective_target_vect_int: using cached result" 2
-    } else {
-	set et_vect_int_saved($et_index) 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
-             || ([istarget powerpc*-*-*]
-		 && ![istarget powerpc-*-linux*paired*])
-	     || [istarget spu-*-*]
-	     || [istarget sparc*-*-*]
-	     || [istarget alpha*-*-*]
-	     || [istarget ia64-*-*] 
-	     || [istarget aarch64*-*-*]
-	     || [is-effective-target arm_neon]
-	     || ([istarget mips*-*-*]
-		 && ([et-is-effective-target mips_loongson]
-		     || [et-is-effective-target mips_msa]))
-	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_int_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_int:\
-	     returning $et_vect_int_saved($et_index)" 2
-    return $et_vect_int_saved($et_index)
+    return [check_cached_effective_target_indexed vect_int {
+      expr {
+         [istarget i?86-*-*] || [istarget x86_64-*-*]
+         || ([istarget powerpc*-*-*]
+	     && ![istarget powerpc-*-linux*paired*])
+	 || [istarget spu-*-*]
+	 || [istarget sparc*-*-*]
+	 || [istarget alpha*-*-*]
+	 || [istarget ia64-*-*]
+	 || [istarget aarch64*-*-*]
+	 || [is-effective-target arm_neon]
+	 || ([istarget mips*-*-*]
+	     && ([et-is-effective-target mips_loongson]
+	     || [et-is-effective-target mips_msa]))
+	 || ([istarget s390*-*-*]
+	     && [check_effective_target_s390_vx])
+	}}]
 }
 
 # Return 1 if the target supports signed int->float conversion 
 #
 
 proc check_effective_target_vect_intfloat_cvt { } {
-    global et_vect_intfloat_cvt_saved
-    global et_index
-
-    if [info exists et_vect_intfloat_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_intfloat_cvt:\
-		 using cached result" 2
-    } else {
-	set et_vect_intfloat_cvt_saved($et_index) 0
-        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_intfloat_cvt {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget powerpc*-*-*]
 		 && ![istarget powerpc-*-linux*paired*])
 	     || [is-effective-target arm_neon]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_intfloat_cvt_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_intfloat_cvt:\
-	     returning $et_vect_intfloat_cvt_saved($et_index)" 2
-    return $et_vect_intfloat_cvt_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target supports signed double->int conversion
 #
 
 proc check_effective_target_vect_doubleint_cvt { } {
-    global et_vect_doubleint_cvt_saved
-    global et_index
-
-    if [info exists et_vect_doubleint_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_doubleint_cvt: using cached result" 2
-    } else {
-	set et_vect_doubleint_cvt_saved($et_index) 0
-	if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
-	      && [check_no_compiler_messages vect_doubleint_cvt assembly {
-		  #ifdef __tune_atom__
-		  # error No double vectorizer support.
-		  #endif
+    return [check_cached_effective_target_indexed vect_doubleint_cvt {
+      expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+	       && [check_no_compiler_messages vect_doubleint_cvt assembly {
+		   #ifdef __tune_atom__
+		   # error No double vectorizer support.
+		   #endif
 	      }])
-	     || [istarget aarch64*-*-*]
-	     || [istarget spu-*-*]
-	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
-	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_doubleint_cvt_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_doubleint_cvt:\
-	     returning $et_vect_doubleint_cvt_saved($et_index)" 2
-    return $et_vect_doubleint_cvt_saved($et_index)
+	    || [istarget aarch64*-*-*]
+	    || [istarget spu-*-*]
+	    || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
+	    || ([istarget mips*-*-*]
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target supports signed int->double conversion
 #
 
 proc check_effective_target_vect_intdouble_cvt { } {
-    global et_vect_intdouble_cvt_saved
-    global et_index
-
-    if [info exists et_vect_intdouble_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_intdouble_cvt: using cached result" 2
-    } else {
-	set et_vect_intdouble_cvt_saved($et_index) 0
-	if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+    return [check_cached_effective_target_indexed vect_intdouble_cvt {
+      expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
 	      && [check_no_compiler_messages vect_intdouble_cvt assembly {
 		  #ifdef __tune_atom__
 		  # error No double vectorizer support.
@@ -3194,14 +3133,7 @@ proc check_effective_target_vect_intdouble_cvt { } {
 	     || [istarget spu-*-*]
 	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_intdouble_cvt_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_intdouble_cvt:\
-	     returning $et_vect_intdouble_cvt_saved($et_index)" 2
-    return $et_vect_intdouble_cvt_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 #Return 1 if we're supporting __int128 for target, 0 otherwise.
@@ -3222,28 +3154,14 @@ proc check_effective_target_int128 { } {
 #
 
 proc check_effective_target_vect_uintfloat_cvt { } {
-    global et_vect_uintfloat_cvt_saved
-    global et_index
-
-    if [info exists et_vect_uintfloat_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_uintfloat_cvt:\
-		 using cached result" 2
-    } else {
-	set et_vect_uintfloat_cvt_saved($et_index) 0
-        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_uintfloat_cvt {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget powerpc*-*-*]
 		 && ![istarget powerpc-*-linux*paired*])
 	     || [istarget aarch64*-*-*]
 	     || [is-effective-target arm_neon]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_uintfloat_cvt_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_uintfloat_cvt:\
-	     returning $et_vect_uintfloat_cvt_saved($et_index)" 2
-    return $et_vect_uintfloat_cvt_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 
@@ -3251,76 +3169,35 @@ proc check_effective_target_vect_uintfloat_cvt { } {
 #
 
 proc check_effective_target_vect_floatint_cvt { } {
-    global et_vect_floatint_cvt_saved
-    global et_index
-
-    if [info exists et_vect_floatint_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_floatint_cvt:\
-		 using cached result" 2
-    } else {
-	set et_vect_floatint_cvt_saved($et_index) 0
-        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_floatint_cvt {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget powerpc*-*-*]
 		 && ![istarget powerpc-*-linux*paired*])
 	     || [is-effective-target arm_neon]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_floatint_cvt_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_floatint_cvt:\
-	     returning $et_vect_floatint_cvt_saved($et_index)" 2
-    return $et_vect_floatint_cvt_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target supports unsigned float->int conversion
 #
 
 proc check_effective_target_vect_floatuint_cvt { } {
-    global et_vect_floatuint_cvt_saved
-    global et_index
-
-    if [info exists et_vect_floatuint_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_floatuint_cvt:\
-		 using cached result" 2
-    } else {
-	set et_vect_floatuint_cvt_saved($et_index) 0
-        if { ([istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_floatuint_cvt {
+      expr { ([istarget powerpc*-*-*]
 	      && ![istarget powerpc-*-linux*paired*])
 	    || [is-effective-target arm_neon]
 	    || ([istarget mips*-*-*]
-		&& [et-is-effective-target mips_msa]) } {
-	   set et_vect_floatuint_cvt_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_floatuint_cvt:\
-	     returning $et_vect_floatuint_cvt_saved($et_index)" 2
-    return $et_vect_floatuint_cvt_saved($et_index)
+		&& [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if peeling for alignment might be profitable on the target
 #
 
 proc check_effective_target_vect_peeling_profitable { } {
-    global et_vect_peeling_profitable_saved
-    global et_index
-
-    if [info exists et_vect_peeling_profitable_saved($et_index)] {
-	verbose "check_effective_target_vect_peeling_profitable: using cached result" 2
-    } else {
-	set et_vect_peeling_profitable_saved($et_index) 1
-        if { ([istarget s390*-*-*]
+    return [check_cached_effective_target_indexed vect_peeling_profitable {
+      expr { ([istarget s390*-*-*]
 	      && [check_effective_target_s390_vx])
-	     || [check_effective_target_vect_element_align_preferred] } {
-	    set et_vect_peeling_profitable_saved($et_index) 0
-        }
-    }
-
-    verbose "check_effective_target_vect_peeling_profitable:\
-	     returning $et_vect_peeling_profitable_saved($et_index)" 2
-    return $et_vect_peeling_profitable_saved($et_index)
+	    || [check_effective_target_vect_element_align_preferred] }}]
 }
 
 # Return 1 if the target supports #pragma omp declare simd, 0 otherwise.
@@ -3328,26 +3205,13 @@ proc check_effective_target_vect_peeling_profitable { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_simd_clones { } {
-    global et_vect_simd_clones_saved
-    global et_index
-
-    if [info exists et_vect_simd_clones_saved($et_index)] {
-	verbose "check_effective_target_vect_simd_clones: using cached result" 2
-    } else {
-	set et_vect_simd_clones_saved($et_index) 0
-	# On i?86/x86_64 #pragma omp declare simd builds a sse2, avx,
-	# avx2 and avx512f clone.  Only the right clone for the
-	# specified arch will be chosen, but still we need to at least
-	# be able to assemble avx512f.
-	if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
-	      && [check_effective_target_avx512f]) } {
-	    set et_vect_simd_clones_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_simd_clones:\
-	     returning $et_vect_simd_clones_saved($et_index)" 2
-    return $et_vect_simd_clones_saved($et_index)
+    # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx,
+    # avx2 and avx512f clone.  Only the right clone for the
+    # specified arch will be chosen, but still we need to at least
+    # be able to assemble avx512f.
+    return [check_cached_effective_target_indexed vect_simd_clones {
+      expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+	      && [check_effective_target_avx512f]) }}]
 }
 
 # Return 1 if this is a AArch64 target supporting big endian
@@ -5433,14 +5297,8 @@ proc check_effective_target_sparc_vis { } {
 # Return 1 if the target supports hardware vector shift operation.
 
 proc check_effective_target_vect_shift { } {
-    global et_vect_shift_saved
-    global et_index
-
-    if [info exists et_vect_shift_saved($et_index)] {
-	verbose "check_effective_target_vect_shift: using cached result" 2
-    } else {
-	set et_vect_shift_saved($et_index) 0
-	if { ([istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_shift {
+      expr {([istarget powerpc*-*-*]
 	      && ![istarget powerpc-*-linux*paired*])
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
@@ -5450,14 +5308,7 @@ proc check_effective_target_vect_shift { } {
 		 && ([et-is-effective-target mips_msa]
 		     || [et-is-effective-target mips_loongson]))
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_shift_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_shift:\
-	     returning $et_vect_shift_saved($et_index)" 2
-    return $et_vect_shift_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 proc check_effective_target_whole_vector_shift { } {
@@ -5483,49 +5334,21 @@ proc check_effective_target_whole_vector_shift { } {
 # Return 1 if the target supports vector bswap operations.
 
 proc check_effective_target_vect_bswap { } {
-    global et_vect_bswap_saved
-    global et_index
-
-    if [info exists et_vect_bswap_saved($et_index)] {
-	verbose "check_effective_target_vect_bswap: using cached result" 2
-    } else {
-	set et_vect_bswap_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
-             || [is-effective-target arm_neon]
-	   } {
-	   set et_vect_bswap_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_bswap:\
-	     returning $et_vect_bswap_saved($et_index)" 2
-    return $et_vect_bswap_saved($et_index)
+    return [check_cached_effective_target_indexed vect_bswap {
+      expr { [istarget aarch64*-*-*] || [is-effective-target arm_neon] }}]
 }
 
 # Return 1 if the target supports hardware vector shift operation for char.
 
 proc check_effective_target_vect_shift_char { } {
-    global et_vect_shift_char_saved
-    global et_index
-
-    if [info exists et_vect_shift_char_saved($et_index)] {
-	verbose "check_effective_target_vect_shift_char: using cached result" 2
-    } else {
-	set et_vect_shift_char_saved($et_index) 0
-	if { ([istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_shift_char {
+      expr { ([istarget powerpc*-*-*]
              && ![istarget powerpc-*-linux*paired*])
 	     || [is-effective-target arm_neon]
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_shift_char_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_shift_char:\
-	     returning $et_vect_shift_char_saved($et_index)" 2
-    return $et_vect_shift_char_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports hardware vectors of long, 0 otherwise.
@@ -5559,14 +5382,8 @@ proc check_effective_target_vect_long { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_float { } {
-    global et_vect_float_saved
-    global et_index
-
-    if [info exists et_vect_float_saved($et_index)] {
-	verbose "check_effective_target_vect_float: using cached result" 2
-    } else {
-	set et_vect_float_saved($et_index) 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_float {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget powerpc*-*-*]
 	     || [istarget spu-*-*]
 	     || [istarget mips-sde-elf]
@@ -5577,14 +5394,7 @@ proc check_effective_target_vect_float { } {
 		 && [et-is-effective-target mips_msa])
 	     || [is-effective-target arm_neon]
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vxe]) } {
-	    set et_vect_float_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_float:\
-	     returning $et_vect_float_saved($et_index)" 2
-    return $et_vect_float_saved($et_index)
+		 && [check_effective_target_s390_vxe]) }}]
 }
 
 # Return 1 if the target supports hardware vectors of float without
@@ -5600,33 +5410,20 @@ proc check_effective_target_vect_float_strict { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_double { } {
-    global et_vect_double_saved
-    global et_index
-
-    if [info exists et_vect_double_saved($et_index)] {
-	verbose "check_effective_target_vect_double: using cached result" 2
-    } else {
-	set et_vect_double_saved($et_index) 0
-	if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
-	      && [check_no_compiler_messages vect_double assembly {
+    return [check_cached_effective_target_indexed vect_double {
+        expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+	         && [check_no_compiler_messages vect_double assembly {
 		  #ifdef __tune_atom__
 		  # error No double vectorizer support.
 		  #endif
-	      }])
+		}])
 	     || [istarget aarch64*-*-*]
 	     || [istarget spu-*-*]
 	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_double_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_double:\
-	     returning $et_vect_double_saved($et_index)" 2
-    return $et_vect_double_saved($et_index)
+		 && [check_effective_target_s390_vx])} }]
 }
 
 # Return 1 if the target supports conditional addition, subtraction,
@@ -5642,25 +5439,12 @@ proc check_effective_target_vect_double_cond_arith { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_long_long { } {
-    global et_vect_long_long_saved
-    global et_index
-
-    if [info exists et_vect_long_long_saved($et_index)] {
-        verbose "check_effective_target_vect_long_long: using cached result" 2
-    } else {
-	set et_vect_long_long_saved($et_index) 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_long_long {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_long_long_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_long_long:\
-	     returning $et_vect_long_long_saved($et_index)" 2
-    return $et_vect_long_long_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 
@@ -5670,25 +5454,12 @@ proc check_effective_target_vect_long_long { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_no_int_min_max { } {
-    global et_vect_no_int_min_max_saved
-    global et_index
-
-    if [info exists et_vect_no_int_min_max_saved($et_index)] {
-	verbose "check_effective_target_vect_no_int_min_max:\
-		 using cached result" 2
-    } else {
-	set et_vect_no_int_min_max_saved($et_index) 0
-	if { [istarget sparc*-*-*]
+    return [check_cached_effective_target_indexed vect_no_int_min_max {
+      expr { [istarget sparc*-*-*]
 	     || [istarget spu-*-*]
 	     || [istarget alpha*-*-*]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_loongson]) } {
-	    set et_vect_no_int_min_max_saved($et_index) 1
-	}
-    }
-    verbose "check_effective_target_vect_no_int_min_max:\
-	     returning $et_vect_no_int_min_max_saved($et_index)" 2
-    return $et_vect_no_int_min_max_saved($et_index)
+		 && [et-is-effective-target mips_loongson]) }}]
 }
 
 # Return 1 if the target plus current options does not support a vector
@@ -5697,21 +5468,9 @@ proc check_effective_target_vect_no_int_min_max { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_no_int_add { } {
-    global et_vect_no_int_add_saved
-    global et_index
-
-    if [info exists et_vect_no_int_add_saved($et_index)] {
-	verbose "check_effective_target_vect_no_int_add: using cached result" 2
-    } else {
-	set et_vect_no_int_add_saved($et_index) 0
-	# Alpha only supports vector add on V8QI and V4HI.
-	if { [istarget alpha*-*-*] } {
-	    set et_vect_no_int_add_saved($et_index) 1
-	}
-    }
-    verbose "check_effective_target_vect_no_int_add:\
-	     returning $et_vect_no_int_add_saved($et_index)" 2
-    return $et_vect_no_int_add_saved($et_index)
+    # Alpha only supports vector add on V8QI and V4HI.
+    return [check_cached_effective_target_indexed vect_no_int_add {
+      expr { [istarget alpha*-*-*] }}]
 }
 
 # Return 1 if the target plus current options does not support vector
@@ -5720,17 +5479,7 @@ proc check_effective_target_vect_no_int_add { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_no_bitwise { } {
-    global et_vect_no_bitwise_saved
-    global et_index
-
-    if [info exists et_vect_no_bitwise_saved($et_index)] {
-	verbose "check_effective_target_vect_no_bitwise: using cached result" 2
-    } else {
-	set et_vect_no_bitwise_saved($et_index) 0
-    }
-    verbose "check_effective_target_vect_no_bitwise:\
-	     returning $et_vect_no_bitwise_saved($et_index)" 2
-    return $et_vect_no_bitwise_saved($et_index)
+    return [check_cached_effective_target_indexed vect_no_bitwise { expr 0 }]
 }
 
 # Return 1 if the target plus current options supports vector permutation,
@@ -5739,14 +5488,8 @@ proc check_effective_target_vect_no_bitwise { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_perm { } {
-    global et_vect_perm_saved
-    global et_index
-
-    if [info exists et_vect_perm_saved($et_index)] {
-        verbose "check_effective_target_vect_perm: using cached result" 2
-    } else {
-	set et_vect_perm_saved($et_index) 0
-        if { [is-effective-target arm_neon]
+    return [check_cached_effective_target_indexed vect_perm {
+      expr { [is-effective-target arm_neon]
 	     || ([istarget aarch64*-*-*]
 		 && ![check_effective_target_vect_variable_length])
 	     || [istarget powerpc*-*-*]
@@ -5756,13 +5499,7 @@ proc check_effective_target_vect_perm { } {
 		 && ([et-is-effective-target mpaired_single]
 		     || [et-is-effective-target mips_msa]))
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_perm_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_perm:\
-	     returning $et_vect_perm_saved($et_index)" 2
-    return $et_vect_perm_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if, for some VF:
@@ -5843,14 +5580,8 @@ proc check_effective_target_vect_perm3_int { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_perm_byte { } {
-    global et_vect_perm_byte_saved
-    global et_index
-
-    if [info exists et_vect_perm_byte_saved($et_index)] {
-        verbose "check_effective_target_vect_perm_byte: using cached result" 2
-    } else {
-	set et_vect_perm_byte_saved($et_index) 0
-        if { ([is-effective-target arm_neon]
+    return [check_cached_effective_target_indexed vect_perm_byte {
+      expr { ([is-effective-target arm_neon]
 	      && [is-effective-target arm_little_endian])
 	     || ([istarget aarch64*-*-*]
 		 && [is-effective-target aarch64_little_endian]
@@ -5860,13 +5591,7 @@ proc check_effective_target_vect_perm_byte { } {
 	     || ([istarget mips-*.*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_perm_byte_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_perm_byte:\
-	     returning $et_vect_perm_byte_saved($et_index)" 2
-    return $et_vect_perm_byte_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports SLP permutation of 3 vectors when each
@@ -5883,14 +5608,8 @@ proc check_effective_target_vect_perm3_byte { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_perm_short { } {
-    global et_vect_perm_short_saved
-    global et_index
-
-    if [info exists et_vect_perm_short_saved($et_index)] {
-        verbose "check_effective_target_vect_perm_short: using cached result" 2
-    } else {
-	set et_vect_perm_short_saved($et_index) 0
-        if { ([is-effective-target arm_neon]
+    return [check_cached_effective_target_indexed vect_perm_short {
+      expr { ([is-effective-target arm_neon]
 	      && [is-effective-target arm_little_endian])
 	     || ([istarget aarch64*-*-*]
 		 && [is-effective-target aarch64_little_endian]
@@ -5902,13 +5621,7 @@ proc check_effective_target_vect_perm_short { } {
 	     || ([istarget mips*-*-*]
 		  && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_perm_short_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_perm_short:\
-	     returning $et_vect_perm_short_saved($et_index)" 2
-    return $et_vect_perm_short_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports SLP permutation of 3 vectors when each
@@ -5925,20 +5638,8 @@ proc check_effective_target_vect_perm3_short { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_xorsign { } {
-    global et_xorsign_saved
-    global et_index
-
-    if [info exists et_xorsign_saved($et_index)] {
-        verbose "check_effective_target_xorsign: using cached result" 2
-    } else {
-	set et_xorsign_saved($et_index) 0
-        if { [istarget aarch64*-*-*] || [istarget arm*-*-*] } {
-	    set et_xorsign_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_xorsign:\
-	     returning $et_xorsign_saved($et_index)" 2
-    return $et_xorsign_saved($et_index)
+    return [check_cached_effective_target_indexed xorsign {
+      expr { [istarget aarch64*-*-*] || [istarget arm*-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -5947,25 +5648,12 @@ proc check_effective_target_xorsign { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
-    global et_vect_widen_sum_hi_to_si_pattern_saved
-    global et_index
-
-    if [info exists et_vect_widen_sum_hi_to_si_pattern_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_sum_hi_to_si_pattern_saved($et_index) 0
-        if { [istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si_pattern {
+      expr { [istarget powerpc*-*-*]
              || ([istarget aarch64*-*-*]
 		 && ![check_effective_target_aarch64_sve])
 	     || [is-effective-target arm_neon]
-             || [istarget ia64-*-*] } {
-	    set et_vect_widen_sum_hi_to_si_pattern_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern:\
-	     returning $et_vect_widen_sum_hi_to_si_pattern_saved($et_index)" 2
-    return $et_vect_widen_sum_hi_to_si_pattern_saved($et_index)
+             || [istarget ia64-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -5974,25 +5662,12 @@ proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
 # promotion (unpacking) from shorts to ints.
 #
 # This won't change for different subtargets so cache the result.
-                                                                                                
-proc check_effective_target_vect_widen_sum_hi_to_si { } {
-    global et_vect_widen_sum_hi_to_si_saved
-    global et_index
 
-    if [info exists et_vect_widen_sum_hi_to_si_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_sum_hi_to_si:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_sum_hi_to_si_saved($et_index) \
-	    [check_effective_target_vect_unpack]
-        if { [istarget powerpc*-*-*] 
-	     || [istarget ia64-*-*] } {
-	    set et_vect_widen_sum_hi_to_si_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_sum_hi_to_si:\
-	     returning $et_vect_widen_sum_hi_to_si_saved($et_index)" 2
-    return $et_vect_widen_sum_hi_to_si_saved($et_index)
+proc check_effective_target_vect_widen_sum_hi_to_si { } {
+    return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si {
+      expr { [check_effective_target_vect_unpack]
+             || [istarget powerpc*-*-*]
+	     || [istarget ia64-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6003,23 +5678,10 @@ proc check_effective_target_vect_widen_sum_hi_to_si { } {
 # This won't change for different subtargets so cache the result.
                                                                                                 
 proc check_effective_target_vect_widen_sum_qi_to_hi { } {
-    global et_vect_widen_sum_qi_to_hi_saved
-    global et_index
-
-    if [info exists et_vect_widen_sum_qi_to_hi_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_sum_qi_to_hi:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_sum_qi_to_hi_saved($et_index) 0
-	if { [check_effective_target_vect_unpack] 
+    return [check_cached_effective_target_indexed vect_widen_sum_qi_to_hi {
+      expr { [check_effective_target_vect_unpack]
 	     || [is-effective-target arm_neon]
-	     || [istarget ia64-*-*] } {
-	    set et_vect_widen_sum_qi_to_hi_saved($et_index) 1
-	}
-    }
-    verbose "check_effective_target_vect_widen_sum_qi_to_hi:\
-	     returning $et_vect_widen_sum_qi_to_hi_saved($et_index)" 2
-    return $et_vect_widen_sum_qi_to_hi_saved($et_index)
+	     || [istarget ia64-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6028,21 +5690,8 @@ proc check_effective_target_vect_widen_sum_qi_to_hi { } {
 # This won't change for different subtargets so cache the result.
                                                                                                 
 proc check_effective_target_vect_widen_sum_qi_to_si { } {
-    global et_vect_widen_sum_qi_to_si_saved
-    global et_index
-
-    if [info exists et_vect_widen_sum_qi_to_si_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_sum_qi_to_si:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_sum_qi_to_si_saved($et_index) 0
-        if { [istarget powerpc*-*-*] } {
-	    set et_vect_widen_sum_qi_to_si_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_sum_qi_to_si:\
-	     returning $et_vect_widen_sum_qi_to_si_saved($et_index)" 2
-    return $et_vect_widen_sum_qi_to_si_saved($et_index)
+    return [check_cached_effective_target_indexed vect_widen_sum_qi_to_si {
+      expr { [istarget powerpc*-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6055,31 +5704,15 @@ proc check_effective_target_vect_widen_sum_qi_to_si { } {
 
 
 proc check_effective_target_vect_widen_mult_qi_to_hi { } {
-    global et_vect_widen_mult_qi_to_hi_saved
-    global et_index
-
-    if [info exists et_vect_widen_mult_qi_to_hi_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_mult_qi_to_hi:\
-		 using cached result" 2
-    } else {
-	if { [check_effective_target_vect_unpack]
-	     && [check_effective_target_vect_short_mult] } {
-	    set et_vect_widen_mult_qi_to_hi_saved($et_index) 1
-	} else {
-	    set et_vect_widen_mult_qi_to_hi_saved($et_index) 0
-	}
-        if { [istarget powerpc*-*-*]
-              || ([istarget aarch64*-*-*]
-		  && ![check_effective_target_aarch64_sve])
-              || [is-effective-target arm_neon]
-	      || ([istarget s390*-*-*]
-		  && [check_effective_target_s390_vx]) } {
-	    set et_vect_widen_mult_qi_to_hi_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_mult_qi_to_hi:\
-	     returning $et_vect_widen_mult_qi_to_hi_saved($et_index)" 2
-    return $et_vect_widen_mult_qi_to_hi_saved($et_index)
+    return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi {
+      expr { ([check_effective_target_vect_unpack]
+	       && [check_effective_target_vect_short_mult])
+	      || ([istarget powerpc*-*-*]
+		  || ([istarget aarch64*-*-*]
+		      && ![check_effective_target_aarch64_sve])
+		  || [is-effective-target arm_neon]
+		  || ([istarget s390*-*-*]
+		      && [check_effective_target_s390_vx])) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6092,34 +5725,18 @@ proc check_effective_target_vect_widen_mult_qi_to_hi { } {
 
 
 proc check_effective_target_vect_widen_mult_hi_to_si { } {
-    global et_vect_widen_mult_hi_to_si_saved
-    global et_index
-
-    if [info exists et_vect_widen_mult_hi_to_si_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_mult_hi_to_si:\
-		 using cached result" 2
-    } else {
-        if { [check_effective_target_vect_unpack]
-             && [check_effective_target_vect_int_mult] } {
-	  set et_vect_widen_mult_hi_to_si_saved($et_index) 1
-        } else {
-	  set et_vect_widen_mult_hi_to_si_saved($et_index) 0
-        }
-        if { [istarget powerpc*-*-*]
-	     || [istarget spu-*-*]
-	     || [istarget ia64-*-*]
-	     || ([istarget aarch64*-*-*]
-		 && ![check_effective_target_aarch64_sve])
-	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
-	     || [is-effective-target arm_neon]
-	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_widen_mult_hi_to_si_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_mult_hi_to_si:\
-	     returning $et_vect_widen_mult_hi_to_si_saved($et_index)" 2
-    return $et_vect_widen_mult_hi_to_si_saved($et_index)
+    return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si {
+      expr { ([check_effective_target_vect_unpack]
+              && [check_effective_target_vect_int_mult])
+	     || ([istarget powerpc*-*-*]
+		 || [istarget spu-*-*]
+		 || [istarget ia64-*-*]
+		 || ([istarget aarch64*-*-*]
+		     && ![check_effective_target_aarch64_sve])
+		 || [istarget i?86-*-*] || [istarget x86_64-*-*]
+		 || [is-effective-target arm_neon]
+		 || ([istarget s390*-*-*]
+		     && [check_effective_target_s390_vx])) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6128,25 +5745,12 @@ proc check_effective_target_vect_widen_mult_hi_to_si { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
-    global et_vect_widen_mult_qi_to_hi_pattern_saved
-    global et_index
-
-    if [info exists et_vect_widen_mult_qi_to_hi_pattern_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_mult_qi_to_hi_pattern_saved($et_index) 0
-        if { [istarget powerpc*-*-*]
-              || ([is-effective-target arm_neon]
-		  && [check_effective_target_arm_little_endian])
-	      || ([istarget s390*-*-*]
-		  && [check_effective_target_s390_vx]) } {
-	    set et_vect_widen_mult_qi_to_hi_pattern_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern:\
-	     returning $et_vect_widen_mult_qi_to_hi_pattern_saved($et_index)" 2
-    return $et_vect_widen_mult_qi_to_hi_pattern_saved($et_index)
+    return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi_pattern {
+      expr { [istarget powerpc*-*-*]
+             || ([is-effective-target arm_neon]
+		 && [check_effective_target_arm_little_endian])
+	     || ([istarget s390*-*-*]
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6155,28 +5759,15 @@ proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
-    global et_vect_widen_mult_hi_to_si_pattern_saved
-    global et_index
-
-    if [info exists et_vect_widen_mult_hi_to_si_pattern_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_mult_hi_to_si_pattern_saved($et_index) 0
-        if { [istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si_pattern {
+      expr { [istarget powerpc*-*-*]
 	     || [istarget spu-*-*]
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([is-effective-target arm_neon]
 		 && [check_effective_target_arm_little_endian])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_widen_mult_hi_to_si_pattern_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern:\
-	     returning $et_vect_widen_mult_hi_to_si_pattern_saved($et_index)" 2
-    return $et_vect_widen_mult_hi_to_si_pattern_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6185,25 +5776,12 @@ proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_widen_mult_si_to_di_pattern { } {
-    global et_vect_widen_mult_si_to_di_pattern_saved
-    global et_index
-
-    if [info exists et_vect_widen_mult_si_to_di_pattern_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_mult_si_to_di_pattern:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_mult_si_to_di_pattern_saved($et_index) 0
-        if {[istarget ia64-*-*]
-	    || [istarget i?86-*-*] || [istarget x86_64-*-*]
-	    || ([istarget s390*-*-*]
-		&& [check_effective_target_s390_vx]) } {
-	    set et_vect_widen_mult_si_to_di_pattern_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_mult_si_to_di_pattern:\
-	     returning $et_vect_widen_mult_si_to_di_pattern_saved($et_index)" 2
-    return $et_vect_widen_mult_si_to_di_pattern_saved($et_index)
-}
+    return [check_cached_effective_target_indexed vect_widen_mult_si_to_di_pattern {
+      expr { [istarget ia64-*-*]
+	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
+	     || ([istarget s390*-*-*]
+		 && [check_effective_target_s390_vx]) }}]
+}
 
 # Return 1 if the target plus current options supports a vector
 # widening shift, 0 otherwise.
@@ -6211,20 +5789,8 @@ proc check_effective_target_vect_widen_mult_si_to_di_pattern { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_widen_shift { } {
-    global et_vect_widen_shift_saved
-    global et_index
-
-    if [info exists et_vect_shift_saved($et_index)] {
-        verbose "check_effective_target_vect_widen_shift: using cached result" 2
-    } else {
-	set et_vect_widen_shift_saved($et_index) 0
-        if { [is-effective-target arm_neon] } {
-	    set et_vect_widen_shift_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_shift:\
-	     returning $et_vect_widen_shift_saved($et_index)" 2
-    return $et_vect_widen_shift_saved($et_index)
+    return [check_cached_effective_target_indexed vect_widen_shift {
+      expr { [is-effective-target arm_neon] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6233,24 +5799,12 @@ proc check_effective_target_vect_widen_shift { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_sdot_qi { } {
-    global et_vect_sdot_qi_saved
-    global et_index
-
-    if [info exists et_vect_sdot_qi_saved($et_index)] {
-        verbose "check_effective_target_vect_sdot_qi: using cached result" 2
-    } else {
-	set et_vect_sdot_qi_saved($et_index) 0
-	if { [istarget ia64-*-*]
+    return [check_cached_effective_target_indexed vect_sdot_qi {
+      expr { [istarget ia64-*-*]
 	     || [istarget aarch64*-*-*]
 	     || [istarget arm*-*-*]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-            set et_vect_udot_qi_saved 1
-        }
-    }
-    verbose "check_effective_target_vect_sdot_qi:\
-	     returning $et_vect_sdot_qi_saved($et_index)" 2
-    return $et_vect_sdot_qi_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6259,25 +5813,13 @@ proc check_effective_target_vect_sdot_qi { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_udot_qi { } {
-    global et_vect_udot_qi_saved
-    global et_index
-
-    if [info exists et_vect_udot_qi_saved($et_index)] {
-        verbose "check_effective_target_vect_udot_qi: using cached result" 2
-    } else {
-	set et_vect_udot_qi_saved($et_index) 0
-        if { [istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_udot_qi {
+      expr { [istarget powerpc*-*-*]
 	     || [istarget aarch64*-*-*]
 	     || [istarget arm*-*-*]
 	     || [istarget ia64-*-*]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_udot_qi_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_udot_qi:\
-	     returning $et_vect_udot_qi_saved($et_index)" 2
-    return $et_vect_udot_qi_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6286,24 +5828,12 @@ proc check_effective_target_vect_udot_qi { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_sdot_hi { } {
-    global et_vect_sdot_hi_saved
-    global et_index
-
-    if [info exists et_vect_sdot_hi_saved($et_index)] {
-        verbose "check_effective_target_vect_sdot_hi: using cached result" 2
-    } else {
-	set et_vect_sdot_hi_saved($et_index) 0
-        if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
+    return [check_cached_effective_target_indexed vect_sdot_hi {
+      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_sdot_hi_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_sdot_hi:\
-	     returning $et_vect_sdot_hi_saved($et_index)" 2
-    return $et_vect_sdot_hi_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6312,22 +5842,10 @@ proc check_effective_target_vect_sdot_hi { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_udot_hi { } {
-    global et_vect_udot_hi_saved
-    global et_index
-
-    if [info exists et_vect_udot_hi_saved($et_index)] {
-        verbose "check_effective_target_vect_udot_hi: using cached result" 2
-    } else {
-	set et_vect_udot_hi_saved($et_index) 0
-	if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
+    return [check_cached_effective_target_indexed vect_udot_hi {
+      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_udot_hi_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_udot_hi:\
-	     returning $et_vect_udot_hi_saved($et_index)" 2
-    return $et_vect_udot_hi_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6336,20 +5854,8 @@ proc check_effective_target_vect_udot_hi { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_usad_char { } {
-    global et_vect_usad_char_saved
-    global et_index
-
-    if [info exists et_vect_usad_char_saved($et_index)] {
-        verbose "check_effective_target_vect_usad_char: using cached result" 2
-    } else {
-	set et_vect_usad_char_saved($et_index) 0
-        if { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
-	    set et_vect_usad_char_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_usad_char:\
-	     returning $et_vect_usad_char_saved($et_index)" 2
-    return $et_vect_usad_char_saved($et_index)
+    return [check_cached_effective_target_indexed vect_usad_char {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports both signed
@@ -6367,14 +5873,8 @@ proc check_effective_target_vect_avg_qi {} {
 # This won't change for different subtargets so cache the result.
                                                                                 
 proc check_effective_target_vect_pack_trunc { } {
-    global et_vect_pack_trunc_saved
-    global et_index
-                                                                                
-    if [info exists et_vect_pack_trunc_saved($et_index)] {
-        verbose "check_effective_target_vect_pack_trunc: using cached result" 2
-    } else {
-	set et_vect_pack_trunc_saved($et_index) 0
-        if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
+    return [check_cached_effective_target_indexed vect_pack_trunc {
+      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
              || [istarget i?86-*-*] || [istarget x86_64-*-*]
              || [istarget aarch64*-*-*]
              || [istarget spu-*-*]
@@ -6383,13 +5883,7 @@ proc check_effective_target_vect_pack_trunc { } {
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_pack_trunc_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_pack_trunc:\
-	     returning $et_vect_pack_trunc_saved($et_index)" 2
-    return $et_vect_pack_trunc_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6398,15 +5892,9 @@ proc check_effective_target_vect_pack_trunc { } {
 # This won't change for different subtargets so cache the result.
                                    
 proc check_effective_target_vect_unpack { } {
-    global et_vect_unpack_saved
-    global et_index
-                                        
-    if [info exists et_vect_unpack_saved($et_index)] {
-        verbose "check_effective_target_vect_unpack: using cached result" 2
-    } else {
-	set et_vect_unpack_saved($et_index) 0
-        if { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
-             || [istarget i?86-*-*] || [istarget x86_64-*-*] 
+    return [check_cached_effective_target_indexed vect_unpack {
+      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
+             || [istarget i?86-*-*] || [istarget x86_64-*-*]
              || [istarget spu-*-*]
              || [istarget ia64-*-*]
              || [istarget aarch64*-*-*]
@@ -6415,13 +5903,7 @@ proc check_effective_target_vect_unpack { } {
              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
 		 && [check_effective_target_arm_little_endian])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_unpack_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_unpack:\
-	     returning $et_vect_unpack_saved($et_index)" 2
-    return $et_vect_unpack_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target plus current options does not guarantee
@@ -6430,15 +5912,7 @@ proc check_effective_target_vect_unpack { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_unaligned_stack { } {
-    global et_unaligned_stack_saved
-
-    if [info exists et_unaligned_stack_saved] {
-        verbose "check_effective_target_unaligned_stack: using cached result" 2
-    } else {
-        set et_unaligned_stack_saved 0
-    }
-    verbose "check_effective_target_unaligned_stack: returning $et_unaligned_stack_saved" 2
-    return $et_unaligned_stack_saved
+    return [check_cached_effective_target_indexed unaligned_stack { expr 0 }]
 }
 
 # Return 1 if the target plus current options does not support a vector
@@ -6447,27 +5921,15 @@ proc check_effective_target_unaligned_stack { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_no_align { } {
-    global et_vect_no_align_saved
-    global et_index
-
-    if [info exists et_vect_no_align_saved($et_index)] {
-	verbose "check_effective_target_vect_no_align: using cached result" 2
-    } else {
-	set et_vect_no_align_saved($et_index) 0
-	if { [istarget mipsisa64*-*-*]
+    return [check_cached_effective_target_indexed vect_no_align {
+      expr { [istarget mipsisa64*-*-*]
 	     || [istarget mips-sde-elf]
 	     || [istarget sparc*-*-*]
 	     || [istarget ia64-*-*]
 	     || [check_effective_target_arm_vect_no_misalign]
 	     || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_loongson]) } {
-	    set et_vect_no_align_saved($et_index) 1
-	}
-    }
-    verbose "check_effective_target_vect_no_align:\
-	     returning $et_vect_no_align_saved($et_index)" 2
-    return $et_vect_no_align_saved($et_index)
+		 && [et-is-effective-target mips_loongson]) }}]
 }
 
 # Return 1 if the target supports a vector misalign access, 0 otherwise.
@@ -6475,28 +5937,21 @@ proc check_effective_target_vect_no_align { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_hw_misalign { } {
-    global et_vect_hw_misalign_saved
-    global et_index
-
-    if [info exists et_vect_hw_misalign_saved($et_index)] {
-        verbose "check_effective_target_vect_hw_misalign: using cached result" 2
-    } else {
-	set et_vect_hw_misalign_saved($et_index) 0
+    return [check_cached_effective_target_indexed vect_hw_misalign {
 	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
 	     || [istarget aarch64*-*-*]
 	     || ([istarget mips*-*-*] && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
 		 && [check_effective_target_s390_vx]) } {
-	  set et_vect_hw_misalign_saved($et_index) 1
+	  return 1
 	}
-	if { [istarget arm*-*-*] } {
-	    set et_vect_hw_misalign_saved($et_index) [expr ![check_effective_target_arm_vect_no_misalign]]
+	if { [istarget arm*-*-*]
+	     && ![check_effective_target_arm_vect_no_misalign] } {
+	  return 1
 	}
-    }
-    verbose "check_effective_target_vect_hw_misalign:\
-	     returning $et_vect_hw_misalign_saved($et_index)" 2
-    return $et_vect_hw_misalign_saved($et_index)
+        return 0
+    }]
 }
 
 
@@ -6523,20 +5978,15 @@ proc check_effective_target_vect_aligned_arrays { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_natural_alignment_32 { } {
-    global et_natural_alignment_32
-
-    if [info exists et_natural_alignment_32_saved] {
-        verbose "check_effective_target_natural_alignment_32: using cached result" 2
-    } else {
-        # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
-        set et_natural_alignment_32_saved 1
-        if { ([istarget *-*-darwin*] && [is-effective-target lp64])
-             || [istarget avr-*-*] } {
-            set et_natural_alignment_32_saved 0
-        }
-    }
-    verbose "check_effective_target_natural_alignment_32: returning $et_natural_alignment_32_saved" 2
-    return $et_natural_alignment_32_saved
+    # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
+    return [check_cached_effective_target_indexed natural_alignment_32 {
+	    if { ([istarget *-*-darwin*] && [is-effective-target lp64])
+		  || [istarget avr-*-*] } {
+		return 0
+	    } else {
+		return 1
+	    }
+    }]
 }
 
 # Return 1 if types of size 64 bit or less are naturally aligned (aligned to their
@@ -6545,19 +5995,10 @@ proc check_effective_target_natural_alignment_32 { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_natural_alignment_64 { } {
-    global et_natural_alignment_64
-
-    if [info exists et_natural_alignment_64_saved] {
-        verbose "check_effective_target_natural_alignment_64: using cached result" 2
-    } else {
-        set et_natural_alignment_64_saved 0
-        if { ([is-effective-target lp64] && ![istarget *-*-darwin*])
-             || [istarget spu-*-*] } {
-            set et_natural_alignment_64_saved 1
-        }
-    }
-    verbose "check_effective_target_natural_alignment_64: returning $et_natural_alignment_64_saved" 2
-    return $et_natural_alignment_64_saved
+    return [check_cached_effective_target_indexed natural_alignment_64 {
+	    expr { ([is-effective-target lp64] && ![istarget *-*-darwin*])
+		  || [istarget spu-*-*] }
+    }]
 }
 
 # Return 1 if all vector types are naturally aligned (aligned to their
@@ -6627,24 +6068,10 @@ proc check_effective_target_vector_alignment_reachable_for_64bit { } {
 # Return 1 if the target only requires element alignment for vector accesses
 
 proc check_effective_target_vect_element_align { } {
-    global et_vect_element_align
-    global et_index
-
-    if [info exists et_vect_element_align($et_index)] {
-	verbose "check_effective_target_vect_element_align:\
-		 using cached result" 2
-    } else {
-	set et_vect_element_align($et_index) 0
-	if { ([istarget arm*-*-*]
+    return [check_cached_effective_target_indexed vect_element_align {
+      expr { ([istarget arm*-*-*]
 	      && ![check_effective_target_arm_vect_no_misalign])
-	     || [check_effective_target_vect_hw_misalign] } {
-	   set et_vect_element_align($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_element_align:\
-	     returning $et_vect_element_align($et_index)" 2
-    return $et_vect_element_align($et_index)
+	     || [check_effective_target_vect_hw_misalign] }}]
 }
 
 # Return 1 if we expect to see unaligned accesses in at least some
@@ -6659,21 +6086,10 @@ proc check_effective_target_vect_unaligned_possible { } {
 # Return 1 if the target supports vector LOAD_LANES operations, 0 otherwise.
 
 proc check_effective_target_vect_load_lanes { } {
-    global et_vect_load_lanes
-
-    if [info exists et_vect_load_lanes] {
-	verbose "check_effective_target_vect_load_lanes: using cached result" 2
-    } else {
-	set et_vect_load_lanes 0
-	# We don't support load_lanes correctly on big-endian arm.
-	if { ([check_effective_target_arm_little_endian] && [check_effective_target_arm_neon_ok])
-	     || [istarget aarch64*-*-*] } {
-	    set et_vect_load_lanes 1
-	}
-    }
-
-    verbose "check_effective_target_vect_load_lanes: returning $et_vect_load_lanes" 2
-    return $et_vect_load_lanes
+    # We don't support load_lanes correctly on big-endian arm.
+    return [check_cached_effective_target vect_load_lanes {
+      expr { ([check_effective_target_arm_little_endian] && [check_effective_target_arm_neon_ok])
+	     || [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector masked stores.
@@ -6691,14 +6107,8 @@ proc check_effective_target_vect_scatter_store { } {
 # Return 1 if the target supports vector conditional operations, 0 otherwise.
 
 proc check_effective_target_vect_condition { } {
-    global et_vect_cond_saved
-    global et_index
-
-    if [info exists et_vect_cond_saved($et_index)] {
-	verbose "check_effective_target_vect_cond: using cached result" 2
-    } else {
-	set et_vect_cond_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target_indexed vect_condition {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget powerpc*-*-*]
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
@@ -6708,54 +6118,28 @@ proc check_effective_target_vect_condition { } {
 	     || ([istarget arm*-*-*]
 		 && [check_effective_target_arm_neon_ok])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_cond_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_cond:\
-	     returning $et_vect_cond_saved($et_index)" 2
-    return $et_vect_cond_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector conditional operations where
 # the comparison has different type from the lhs, 0 otherwise.
 
 proc check_effective_target_vect_cond_mixed { } {
-    global et_vect_cond_mixed_saved
-    global et_index
-
-    if [info exists et_vect_cond_mixed_saved($et_index)] {
-	verbose "check_effective_target_vect_cond_mixed: using cached result" 2
-    } else {
-	set et_vect_cond_mixed_saved($et_index) 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_cond_mixed {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget aarch64*-*-*]
 	     || [istarget powerpc*-*-*] 
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_cond_mixed_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_cond_mixed:\
-	     returning $et_vect_cond_mixed_saved($et_index)" 2
-    return $et_vect_cond_mixed_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector char multiplication, 0 otherwise.
 
 proc check_effective_target_vect_char_mult { } {
-    global et_vect_char_mult_saved
-    global et_index
-
-    if [info exists et_vect_char_mult_saved($et_index)] {
-	verbose "check_effective_target_vect_char_mult: using cached result" 2
-    } else {
-	set et_vect_char_mult_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target_indexed vect_char_mult {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [check_effective_target_arm32]
@@ -6763,27 +6147,14 @@ proc check_effective_target_vect_char_mult { } {
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_char_mult_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_char_mult:\
-	     returning $et_vect_char_mult_saved($et_index)" 2
-    return $et_vect_char_mult_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector short multiplication, 0 otherwise.
 
 proc check_effective_target_vect_short_mult { } {
-    global et_vect_short_mult_saved
-    global et_index
-
-    if [info exists et_vect_short_mult_saved($et_index)] {
-	verbose "check_effective_target_vect_short_mult: using cached result" 2
-    } else {
-	set et_vect_short_mult_saved($et_index) 0
-	if { [istarget ia64-*-*]
+    return [check_cached_effective_target_indexed vect_short_mult {
+      expr { [istarget ia64-*-*]
 	     || [istarget spu-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget powerpc*-*-*]
@@ -6793,27 +6164,14 @@ proc check_effective_target_vect_short_mult { } {
 		 && ([et-is-effective-target mips_msa]
 		     || [et-is-effective-target mips_loongson]))
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_short_mult_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_short_mult:\
-	     returning $et_vect_short_mult_saved($et_index)" 2
-    return $et_vect_short_mult_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector int multiplication, 0 otherwise.
 
 proc check_effective_target_vect_int_mult { } {
-    global et_vect_int_mult_saved
-    global et_index
-
-    if [info exists et_vect_int_mult_saved($et_index)] {
-	verbose "check_effective_target_vect_int_mult: using cached result" 2
-    } else {
-	set et_vect_int_mult_saved($et_index) 0
-	if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
+    return [check_cached_effective_target_indexed vect_int_mult {
+      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
 	     || [istarget spu-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget ia64-*-*]
@@ -6822,14 +6180,7 @@ proc check_effective_target_vect_int_mult { } {
 		 && [et-is-effective-target mips_msa])
 	     || [check_effective_target_arm32]
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_int_mult_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_int_mult:\
-	     returning $et_vect_int_mult_saved($et_index)" 2
-    return $et_vect_int_mult_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports 64 bit hardware vector
@@ -6859,15 +6210,8 @@ proc check_effective_target_vect_long_mult { } {
 # Return 1 if the target supports vector even/odd elements extraction, 0 otherwise.
 
 proc check_effective_target_vect_extract_even_odd { } {
-    global et_vect_extract_even_odd_saved
-    global et_index
-    
-    if [info exists et_vect_extract_even_odd_saved($et_index)] {
-	verbose "check_effective_target_vect_extract_even_odd:\
-		 using cached result" 2
-    } else {
-	set et_vect_extract_even_odd_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target_indexed extract_even_odd {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget powerpc*-*-*]
 	     || [is-effective-target arm_neon]
              || [istarget i?86-*-*] || [istarget x86_64-*-*]
@@ -6877,27 +6221,14 @@ proc check_effective_target_vect_extract_even_odd { } {
 		 && ([et-is-effective-target mips_msa]
 		     || [et-is-effective-target mpaired_single]))
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_extract_even_odd_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_extract_even_odd:\
-	     returning $et_vect_extract_even_odd_saved($et_index)" 2
-    return $et_vect_extract_even_odd_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector interleaving, 0 otherwise.
 
 proc check_effective_target_vect_interleave { } {
-    global et_vect_interleave_saved
-    global et_index
-    
-    if [info exists et_vect_interleave_saved($et_index)] {
-        verbose "check_effective_target_vect_interleave: using cached result" 2
-    } else {
-	set et_vect_interleave_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target_indexed vect_interleave {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget powerpc*-*-*]
 	     || [is-effective-target arm_neon]
              || [istarget i?86-*-*] || [istarget x86_64-*-*]
@@ -6907,42 +6238,25 @@ proc check_effective_target_vect_interleave { } {
 		 && ([et-is-effective-target mpaired_single]
 		     || [et-is-effective-target mips_msa]))
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_interleave_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_interleave:\
-	     returning $et_vect_interleave_saved($et_index)" 2
-    return $et_vect_interleave_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 foreach N {2 3 4 8} {
     eval [string map [list N $N] {
 	# Return 1 if the target supports 2-vector interleaving
 	proc check_effective_target_vect_stridedN { } {
-	    global et_vect_stridedN_saved
-	    global et_index
-
-	    if [info exists et_vect_stridedN_saved($et_index)] {
-		verbose "check_effective_target_vect_stridedN:\
-			 using cached result" 2
-	    } else {
-		set et_vect_stridedN_saved($et_index) 0
+	    return [check_cached_effective_target_indexed vect_stridedN {
 		if { (N & -N) == N
 		     && [check_effective_target_vect_interleave]
 		     && [check_effective_target_vect_extract_even_odd] } {
-		    set et_vect_stridedN_saved($et_index) 1
+		    return 1
 		}
 		if { ([istarget arm*-*-*]
 		      || [istarget aarch64*-*-*]) && N >= 2 && N <= 4 } {
-		    set et_vect_stridedN_saved($et_index) 1
+		    return 1
 		}
-	    }
-
-	    verbose "check_effective_target_vect_stridedN:\
-		     returning $et_vect_stridedN_saved($et_index)" 2
-	    return $et_vect_stridedN_saved($et_index)
+		return 0
+	    }]
 	}
     }]
 }
@@ -6993,71 +6307,33 @@ proc check_effective_target_vect64 { } {
 # Return 1 if the target supports vector copysignf calls.
 
 proc check_effective_target_vect_call_copysignf { } {
-    global et_vect_call_copysignf_saved
-    global et_index
-
-    if [info exists et_vect_call_copysignf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_copysignf:\
-		 using cached result" 2
-    } else {
-	set et_vect_call_copysignf_saved($et_index) 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_call_copysignf {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget powerpc*-*-*]
-	     || [istarget aarch64*-*-*] } {
-	   set et_vect_call_copysignf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_copysignf:\
-	     returning $et_vect_call_copysignf_saved($et_index)" 2
-    return $et_vect_call_copysignf_saved($et_index)
+	     || [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports hardware square root instructions.
 
 proc check_effective_target_sqrt_insn { } {
-    global et_sqrt_insn_saved
-
-    if [info exists et_sqrt_insn_saved] {
-	verbose "check_effective_target_hw_sqrt: using cached result" 2
-    } else {
-	set et_sqrt_insn_saved 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target sqrt_insn {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget powerpc*-*-*]
 	     || [istarget aarch64*-*-*]
 	     || ([istarget arm*-*-*] && [check_effective_target_arm_vfp_ok])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_sqrt_insn_saved 1
-	}
-    }
-
-    verbose "check_effective_target_hw_sqrt: returning et_sqrt_insn_saved" 2
-    return $et_sqrt_insn_saved
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector sqrtf calls.
 
 proc check_effective_target_vect_call_sqrtf { } {
-    global et_vect_call_sqrtf_saved
-    global et_index
-
-    if [info exists et_vect_call_sqrtf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_sqrtf: using cached result" 2
-    } else {
-	set et_vect_call_sqrtf_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target_indexed vect_call_sqrtf {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_call_sqrtf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_sqrtf:\
-	     returning $et_vect_call_sqrtf_saved($et_index)" 2
-    return $et_vect_call_sqrtf_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector lrint calls.
@@ -7076,244 +6352,85 @@ proc check_effective_target_vect_call_lrint { } {
 # Return 1 if the target supports vector btrunc calls.
 
 proc check_effective_target_vect_call_btrunc { } {
-    global et_vect_call_btrunc_saved
-    global et_index
-
-    if [info exists et_vect_call_btrunc_saved($et_index)] {
-	verbose "check_effective_target_vect_call_btrunc:\
-		 using cached result" 2
-    } else {
-	set et_vect_call_btrunc_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_btrunc_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_btrunc:\
-	     returning $et_vect_call_btrunc_saved($et_index)" 2
-    return $et_vect_call_btrunc_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_btrunc {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector btruncf calls.
 
 proc check_effective_target_vect_call_btruncf { } {
-    global et_vect_call_btruncf_saved
-    global et_index
-
-    if [info exists et_vect_call_btruncf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_btruncf:\
-		 using cached result" 2
-    } else {
-	set et_vect_call_btruncf_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_btruncf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_btruncf:\
-	     returning $et_vect_call_btruncf_saved($et_index)" 2
-    return $et_vect_call_btruncf_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_btruncf {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector ceil calls.
 
 proc check_effective_target_vect_call_ceil { } {
-    global et_vect_call_ceil_saved
-    global et_index
-
-    if [info exists et_vect_call_ceil_saved($et_index)] {
-	verbose "check_effective_target_vect_call_ceil: using cached result" 2
-    } else {
-	set et_vect_call_ceil_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_ceil_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_ceil:\
-	     returning $et_vect_call_ceil_saved($et_index)" 2
-    return $et_vect_call_ceil_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_ceil {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector ceilf calls.
 
 proc check_effective_target_vect_call_ceilf { } {
-    global et_vect_call_ceilf_saved
-    global et_index
-
-    if [info exists et_vect_call_ceilf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_ceilf: using cached result" 2
-    } else {
-	set et_vect_call_ceilf_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_ceilf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_ceilf:\
-	     returning $et_vect_call_ceilf_saved($et_index)" 2
-    return $et_vect_call_ceilf_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_ceilf {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector floor calls.
 
 proc check_effective_target_vect_call_floor { } {
-    global et_vect_call_floor_saved
-    global et_index
-
-    if [info exists et_vect_call_floor_saved($et_index)] {
-	verbose "check_effective_target_vect_call_floor: using cached result" 2
-    } else {
-	set et_vect_call_floor_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_floor_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_floor:\
-	     returning $et_vect_call_floor_saved($et_index)" 2
-    return $et_vect_call_floor_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_floor {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector floorf calls.
 
 proc check_effective_target_vect_call_floorf { } {
-    global et_vect_call_floorf_saved
-    global et_index
-
-    if [info exists et_vect_call_floorf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_floorf: using cached result" 2
-    } else {
-	set et_vect_call_floorf_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_floorf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_floorf:\
-	     returning $et_vect_call_floorf_saved($et_index)" 2
-    return $et_vect_call_floorf_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_floorf {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector lceil calls.
 
 proc check_effective_target_vect_call_lceil { } {
-    global et_vect_call_lceil_saved
-    global et_index
-
-    if [info exists et_vect_call_lceil_saved($et_index)] {
-	verbose "check_effective_target_vect_call_lceil: using cached result" 2
-    } else {
-	set et_vect_call_lceil_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_lceil_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_lceil:\
-	     returning $et_vect_call_lceil_saved($et_index)" 2
-    return $et_vect_call_lceil_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_lceil {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector lfloor calls.
 
 proc check_effective_target_vect_call_lfloor { } {
-    global et_vect_call_lfloor_saved
-    global et_index
-
-    if [info exists et_vect_call_lfloor_saved($et_index)] {
-	verbose "check_effective_target_vect_call_lfloor: using cached result" 2
-    } else {
-	set et_vect_call_lfloor_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_lfloor_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_lfloor:\
-	     returning $et_vect_call_lfloor_saved($et_index)" 2
-    return $et_vect_call_lfloor_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_lfloor {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector nearbyint calls.
 
 proc check_effective_target_vect_call_nearbyint { } {
-    global et_vect_call_nearbyint_saved
-    global et_index
-
-    if [info exists et_vect_call_nearbyint_saved($et_index)] {
-	verbose "check_effective_target_vect_call_nearbyint: using cached result" 2
-    } else {
-	set et_vect_call_nearbyint_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_nearbyint_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_nearbyint:\
-	     returning $et_vect_call_nearbyint_saved($et_index)" 2
-    return $et_vect_call_nearbyint_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_nearbyint {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector nearbyintf calls.
 
 proc check_effective_target_vect_call_nearbyintf { } {
-    global et_vect_call_nearbyintf_saved
-    global et_index
-
-    if [info exists et_vect_call_nearbyintf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_nearbyintf:\
-		 using cached result" 2
-    } else {
-	set et_vect_call_nearbyintf_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_nearbyintf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_nearbyintf:\
-	     returning $et_vect_call_nearbyintf_saved($et_index)" 2
-    return $et_vect_call_nearbyintf_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_nearbyintf {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector round calls.
 
 proc check_effective_target_vect_call_round { } {
-    global et_vect_call_round_saved
-    global et_index
-
-    if [info exists et_vect_call_round_saved($et_index)] {
-	verbose "check_effective_target_vect_call_round: using cached result" 2
-    } else {
-	set et_vect_call_round_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_round_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_round:\
-	     returning $et_vect_call_round_saved($et_index)" 2
-    return $et_vect_call_round_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_round {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector roundf calls.
 
 proc check_effective_target_vect_call_roundf { } {
-    global et_vect_call_roundf_saved
-    global et_index
-
-    if [info exists et_vect_call_roundf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_roundf: using cached result" 2
-    } else {
-	set et_vect_call_roundf_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_roundf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_roundf:\
-	     returning $et_vect_call_roundf_saved($et_index)" 2
-    return $et_vect_call_roundf_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_roundf {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports AND, OR and XOR reduction.
@@ -7331,21 +6448,10 @@ proc check_effective_target_vect_fold_extract_last { } {
 # Return 1 if the target supports section-anchors
 
 proc check_effective_target_section_anchors { } {
-    global et_section_anchors_saved
-
-    if [info exists et_section_anchors_saved] {
-        verbose "check_effective_target_section_anchors: using cached result" 2
-    } else {
-        set et_section_anchors_saved 0
-        if { [istarget powerpc*-*-*]
-	      || [istarget arm*-*-*] 
-	      || [istarget aarch64*-*-*] } {
-           set et_section_anchors_saved 1
-        }
-    }
-
-    verbose "check_effective_target_section_anchors: returning $et_section_anchors_saved" 2
-    return $et_section_anchors_saved
+    return [check_cached_effective_target section_anchors {
+      expr { [istarget powerpc*-*-*]
+	     || [istarget arm*-*-*]
+	     || [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports atomic operations on "int_128" values.
@@ -7441,13 +6547,8 @@ proc check_effective_target_sync_long_long_runtime { } {
 # Return 1 if the target supports byte swap instructions.
 
 proc check_effective_target_bswap { } {
-    global et_bswap_saved
-
-    if [info exists et_bswap_saved] {
-        verbose "check_effective_target_bswap: using cached result" 2
-    } else {
-	set et_bswap_saved 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target bswap {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget alpha*-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget m68k-*-*]
@@ -7460,27 +6561,16 @@ proc check_effective_target_bswap { } {
 		     #error not armv6 or later
 		     #endif
 		     int i;
-		 } ""]) } {
-		set et_bswap_saved 1
-	}
-    }
-
-    verbose "check_effective_target_bswap: returning $et_bswap_saved" 2
-    return $et_bswap_saved
+		 } ""]) }}]
 }
 
 # Return 1 if the target supports atomic operations on "int" and "long".
 
 proc check_effective_target_sync_int_long { } {
-    global et_sync_int_long_saved
-
-    if [info exists et_sync_int_long_saved] {
-        verbose "check_effective_target_sync_int_long: using cached result" 2
-    } else {
-        set et_sync_int_long_saved 0
 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
 # load-reserved/store-conditional instructions.
-        if { [istarget ia64-*-*]
+    return [check_cached_effective_target sync_int_long {
+      expr { [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget aarch64*-*-*]
 	     || [istarget alpha*-*-*] 
@@ -7495,27 +6585,16 @@ proc check_effective_target_sync_int_long { } {
 	     || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
 	     || [istarget spu-*-*]
 	     || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
-	     || [check_effective_target_mips_llsc] } {
-           set et_sync_int_long_saved 1
-        }
-    }
-
-    verbose "check_effective_target_sync_int_long: returning $et_sync_int_long_saved" 2
-    return $et_sync_int_long_saved
+	     || [check_effective_target_mips_llsc] }}]
 }
 
 # Return 1 if the target supports atomic operations on "char" and "short".
 
 proc check_effective_target_sync_char_short { } {
-    global et_sync_char_short_saved
-
-    if [info exists et_sync_char_short_saved] {
-        verbose "check_effective_target_sync_char_short: using cached result" 2
-    } else {
-        set et_sync_char_short_saved 0
 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
 # load-reserved/store-conditional instructions.
-        if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target sync_char_short {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget alpha*-*-*] 
@@ -7529,13 +6608,7 @@ proc check_effective_target_sync_char_short { } {
 	     || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
 	     || [istarget spu-*-*]
 	     || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
-	     || [check_effective_target_mips_llsc] } {
-           set et_sync_char_short_saved 1
-        }
-    }
-
-    verbose "check_effective_target_sync_char_short: returning $et_sync_char_short_saved" 2
-    return $et_sync_char_short_saved
+	     || [check_effective_target_mips_llsc] }}]
 }
 
 # Return 1 if the target uses a ColdFire FPU.
@@ -7687,8 +6760,17 @@ proc is-effective-target { arg } {
 	  default          { error "unknown effective target keyword `$arg'" }
 	}
     }
+
     verbose "is-effective-target: $arg $selected" 2
-    return $selected
+    if {[string is true -strict $selected]
+	|| [string is false -strict $selected]} {
+	set result $selected
+    } else {
+	set result [uplevel eval $selected]
+	verbose "is-effective-target forced eval: $arg $result" 2
+    }
+
+    return $result
 }
 
 # Return 1 if the argument is an effective-target keyword, 0 otherwise.
@@ -8817,23 +7899,17 @@ proc check_effective_target_fenv_exceptions {} {
 }
 
 proc check_effective_target_tiny {} {
-    global et_target_tiny_saved
-
-    if [info exists et_target_tiny_saved] {
-      verbose "check_effective_target_tiny: using cached result" 2
-    } else {
-       set et_target_tiny_saved 0
-       if { [istarget aarch64*-*-*]
-             && [check_effective_target_aarch64_tiny] } {
-         set et_target_tiny_saved 1
-       }
-       if { [istarget avr-*-*]
-             && [check_effective_target_avr_tiny] } {
-         set et_target_tiny_saved 1
-       }
-    }
-
-    return $et_target_tiny_saved
+    return [check_cached_effective_target tiny {
+	    if { [istarget aarch64*-*-*]
+		 && [check_effective_target_aarch64_tiny] } {
+	      return 1
+	    }
+	    if { [istarget avr-*-*]
+		 && [check_effective_target_avr_tiny] } {
+	      return 1
+	    }
+	    return 0
+    }]
 }
 
 # Return 1 if LOGICAL_OP_NON_SHORT_CIRCUIT is set to 0 for the current target.
@@ -8911,7 +7987,6 @@ proc scan-ltrans-tree-dump-dem-not_required_options {} {
 # otherwise.  Cache the result.
 
 proc check_effective_target_pie_copyreloc { } {
-    global pie_copyreloc_available_saved
     global tool
     global GCC_UNDER_TEST
 
@@ -8924,9 +7999,7 @@ proc check_effective_target_pie_copyreloc { } {
 	return 0
     }
 
-    if [info exists pie_copyreloc_available_saved] {
-	verbose "check_effective_target_pie_copyreloc returning saved $pie_copyreloc_available_saved" 2
-    } else {
+    return [check_cached_effective_target pie_copyreloc {
 	# Set up and compile to see if linker supports PIE with copy
 	# reloc.  Include the current process ID in the file names to
 	# prevent conflicts with invocations for multiple testsuites.
@@ -8949,21 +8022,18 @@ proc check_effective_target_pie_copyreloc { } {
 
 	if [string match "" $lines] then {
 	    verbose "check_effective_target_pie_copyreloc testfile compilation passed" 2
-	    set pie_copyreloc_available_saved 1
+	    return 1
 	} else {
 	    verbose "check_effective_target_pie_copyreloc testfile compilation failed" 2
-	    set pie_copyreloc_available_saved 0
+	    return 0
 	}
-    }
-
-    return $pie_copyreloc_available_saved
+    }]
 }
 
 # Return 1 if the x86 target supports R_386_GOT32X relocation, 0
 # otherwise.  Cache the result.
 
 proc check_effective_target_got32x_reloc { } {
-    global got32x_reloc_available_saved
     global tool
     global GCC_UNDER_TEST
 
@@ -8976,9 +8046,7 @@ proc check_effective_target_got32x_reloc { } {
 	return 0
     }
 
-    if [info exists got32x_reloc_available_saved] {
-	verbose "check_effective_target_got32x_reloc returning saved $got32x_reloc_available_saved" 2
-    } else {
+    return [check_cached_effective_target got32x_reloc {
 	# Include the current process ID in the file names to prevent
 	# conflicts with invocations for multiple testsuites.
 
@@ -9000,12 +8068,12 @@ proc check_effective_target_got32x_reloc { } {
 
 	if [string match "" $lines] then {
 	    verbose "check_effective_target_got32x_reloc testfile compilation passed" 2
-	    set got32x_reloc_available_saved 1
+	    return 1
 	} else {
 	    verbose "check_effective_target_got32x_reloc testfile compilation failed" 2
-	    set got32x_reloc_available_saved 0
+	    return 0
 	}
-    }
+    }]
 
     return $got32x_reloc_available_saved
 }
@@ -9014,7 +8082,6 @@ proc check_effective_target_got32x_reloc { } {
 # 0 otherwise.  Cache the result.
 
 proc check_effective_target_tls_get_addr_via_got { } {
-    global tls_get_addr_via_got_available_saved
     global tool
     global GCC_UNDER_TEST
 
@@ -9027,9 +8094,7 @@ proc check_effective_target_tls_get_addr_via_got { } {
 	return 0
     }
 
-    if [info exists tls_get_addr_via_got_available_saved] {
-	verbose "check_effective_target_tls_get_addr_via_got returning saved $tls_get_addr_via_got_available_saved" 2
-    } else {
+    return [check_cached_effective_target tls_get_addr_via_got {
 	# Include the current process ID in the file names to prevent
 	# conflicts with invocations for multiple testsuites.
 
@@ -9051,14 +8116,12 @@ proc check_effective_target_tls_get_addr_via_got { } {
 
 	if [string match "" $lines] then {
 	    verbose "check_effective_target_tls_get_addr_via_got testfile compilation passed" 2
-	    set tls_get_addr_via_got_available_saved 1
+	    return 1
 	} else {
 	    verbose "check_effective_target_tls_get_addr_via_got testfile compilation failed" 2
-	    set tls_get_addr_via_got_available_saved 0
+	    return 0
 	}
-    }
-
-    return $tls_get_addr_via_got_available_saved
+    }]
 }
 
 # Return 1 if the target uses comdat groups.
Richard Sandiford Sept. 27, 2018, 4:05 p.m. UTC | #6
Tamar Christina <Tamar.Christina@arm.com> writes:
>> >
>> > The error you would get if you do this is very confusing so I thought
>> > since it didn't matter much for the regexp only target triple tests
>> > that just accepting this would be fine.
>> 
>> Seems a good thing that that's a noisy failure; the function should
>> make up its mind whether it wants to cache (use curly braces) or not
>> (just return the expr directly).
>> 
>> > Should I drop it or keep it?
>> 
>> Think we should either drop it or make it into a more user-friendly
>> error, e.g.:
>> 
>> 	if {[string is true -strict $args] || [string is false -strict $args]} {
>> 	    error {check_cached_effective_target condition already evaluated; did you pass [...] instead of the expected {...}?}
>> 	} else {
>> 	    set et_cache($prop,$target) [uplevel eval $args]
>> 	}
>>
>
> Done, I have also ran a regression test on x86_64 with unix{,-m32} and
> no fallouts, testsuite is clean.
>
> Attached updated patch with feedback processed.
>
> Ok for trunk?

Looks good, some minor things below.

> @@ -117,25 +118,36 @@ proc current_target_name { } {
> 
>  proc check_cached_effective_target { prop args } {
>      global et_cache
> -    global et_prop_list
> 
>      set target [current_target_name]
> -    if {![info exists et_cache($prop,target)]
> -	|| $et_cache($prop,target) != $target} {
> +    if {![info exists et_cache($prop,$target)]} {
>  	verbose "check_cached_effective_target $prop: checking $target" 2
> -	set et_cache($prop,target) $target
> -	set et_cache($prop,value) [uplevel eval $args]
> -	if {![info exists et_prop_list]
> -	    || [lsearch $et_prop_list $prop] < 0} {
> -	    lappend et_prop_list $prop
> +	if {[string is true -strict $args] || [string is false -strict $args]} {
> +	    error {check_cached_effective_target condition already evaluated;\
> +		   did you pass [...] instead of the expected {...}?}

Should be no line break here, since the extra spaces will be part of the
error message.

> @@ -657,7 +646,8 @@ proc check_profiling_available { test_what } {
>      }
 
>      # Now examine the cache variable.
> -    if {![info exists profiling_available_saved]} {
> +    set profiling_working \
> +       [expr {[check_cached_effective_target profiling_available {
>  	# Some targets don't have any implementation of __bb_init_func or are
>  	# missing other needed machinery.
>  	if {[istarget aarch64*-*-elf]

No need for this [expr {...}] wrapper, can just use
[check_cached_effective_target profiling_available ...] directly.

> @@ -3072,12 +3057,10 @@ proc check_effective_target_vect_cmdline_needed { } {
>               || [istarget spu-*-*]
>  	     || ([istarget arm*-*-*] && [check_effective_target_arm_neon])
>  	     || [istarget aarch64*-*-*] } {
> -	   set et_vect_cmdline_needed_saved 0
> -	}
> -    }
> -
> -    verbose "check_effective_target_vect_cmdline_needed: returning $et_vect_cmdline_needed_saved" 2
> -    return $et_vect_cmdline_needed_saved
> +		return 0
> +	} else {
> +		return 1
> +	}}]
>  }

Returns indented too far.

> @@ -5720,17 +5479,7 @@ proc check_effective_target_vect_no_int_add { } {
>  # This won't change for different subtargets so cache the result.
 
>  proc check_effective_target_vect_no_bitwise { } {
> -    global et_vect_no_bitwise_saved
> -    global et_index
> -
> -    if [info exists et_vect_no_bitwise_saved($et_index)] {
> -	verbose "check_effective_target_vect_no_bitwise: using cached result" 2
> -    } else {
> -	set et_vect_no_bitwise_saved($et_index) 0
> -    }
> -    verbose "check_effective_target_vect_no_bitwise:\
> -	     returning $et_vect_no_bitwise_saved($et_index)" 2
> -    return $et_vect_no_bitwise_saved($et_index)
> +    return [check_cached_effective_target_indexed vect_no_bitwise { expr 0 }]
>  }

Might as well just return 0 here.  But OK if you want to keep it.

> @@ -6523,20 +5978,15 @@ proc check_effective_target_vect_aligned_arrays { } {
>  # This won't change for different subtargets so cache the result.
> 
>  proc check_effective_target_natural_alignment_32 { } {
> -    global et_natural_alignment_32
> -
> -    if [info exists et_natural_alignment_32_saved] {
> -        verbose "check_effective_target_natural_alignment_32: using cached result" 2
> -    } else {
> -        # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
> -        set et_natural_alignment_32_saved 1
> -        if { ([istarget *-*-darwin*] && [is-effective-target lp64])
> -             || [istarget avr-*-*] } {
> -            set et_natural_alignment_32_saved 0
> -        }
> -    }
> -    verbose "check_effective_target_natural_alignment_32: returning $et_natural_alignment_32_saved" 2
> -    return $et_natural_alignment_32_saved
> +    # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
> +    return [check_cached_effective_target_indexed natural_alignment_32 {
> +	    if { ([istarget *-*-darwin*] && [is-effective-target lp64])
> +		  || [istarget avr-*-*] } {
> +		return 0
> +	    } else {
> +		return 1
> +	    }
> +    }]
>  }
 
Excess indentation of { ... } body.

>  # Return 1 if types of size 64 bit or less are naturally aligned (aligned to their
> @@ -6545,19 +5995,10 @@ proc check_effective_target_natural_alignment_32 { } {
>  # This won't change for different subtargets so cache the result.
 
>  proc check_effective_target_natural_alignment_64 { } {
> -    global et_natural_alignment_64
> -
> -    if [info exists et_natural_alignment_64_saved] {
> -        verbose "check_effective_target_natural_alignment_64: using cached result" 2
> -    } else {
> -        set et_natural_alignment_64_saved 0
> -        if { ([is-effective-target lp64] && ![istarget *-*-darwin*])
> -             || [istarget spu-*-*] } {
> -            set et_natural_alignment_64_saved 1
> -        }
> -    }
> -    verbose "check_effective_target_natural_alignment_64: returning $et_natural_alignment_64_saved" 2
> -    return $et_natural_alignment_64_saved
> +    return [check_cached_effective_target_indexed natural_alignment_64 {
> +	    expr { ([is-effective-target lp64] && ![istarget *-*-darwin*])
> +		  || [istarget spu-*-*] }
> +    }]
>  }

Same here.

> @@ -6659,21 +6086,10 @@ proc check_effective_target_vect_unaligned_possible { } {
>  # Return 1 if the target supports vector LOAD_LANES operations, 0 otherwise.
 
>  proc check_effective_target_vect_load_lanes { } {
> -    global et_vect_load_lanes
> -
> -    if [info exists et_vect_load_lanes] {
> -	verbose "check_effective_target_vect_load_lanes: using cached result" 2
> -    } else {
> -	set et_vect_load_lanes 0
> -	# We don't support load_lanes correctly on big-endian arm.
> -	if { ([check_effective_target_arm_little_endian] && [check_effective_target_arm_neon_ok])
> -	     || [istarget aarch64*-*-*] } {
> -	    set et_vect_load_lanes 1
> -	}
> -    }
> -
> -    verbose "check_effective_target_vect_load_lanes: returning $et_vect_load_lanes" 2
> -    return $et_vect_load_lanes
> +    # We don't support load_lanes correctly on big-endian arm.
> +    return [check_cached_effective_target vect_load_lanes {
> +      expr { ([check_effective_target_arm_little_endian] && [check_effective_target_arm_neon_ok])
> +	     || [istarget aarch64*-*-*] }}]
>  }

Long line.
 
> @@ -7687,8 +6760,17 @@ proc is-effective-target { arg } {
>  	  default          { error "unknown effective target keyword `$arg'" }
>  	}
>      }
> +
>      verbose "is-effective-target: $arg $selected" 2
> -    return $selected
> +    if {[string is true -strict $selected]
> +	|| [string is false -strict $selected]} {
> +	set result $selected
> +    } else {
> +	set result [uplevel eval $selected]
> +	verbose "is-effective-target forced eval: $arg $result" 2
> +    }
> +
> +    return $result
>  }

Is this necessary?  $selected is set by things like:

	  "vmx_hw"         { set selected [check_vmx_hw_available] }

so should already be correct.

> @@ -8817,23 +7899,17 @@ proc check_effective_target_fenv_exceptions {} {
>  }
 
>  proc check_effective_target_tiny {} {
> -    global et_target_tiny_saved
> -
> -    if [info exists et_target_tiny_saved] {
> -      verbose "check_effective_target_tiny: using cached result" 2
> -    } else {
> -       set et_target_tiny_saved 0
> -       if { [istarget aarch64*-*-*]
> -             && [check_effective_target_aarch64_tiny] } {
> -         set et_target_tiny_saved 1
> -       }
> -       if { [istarget avr-*-*]
> -             && [check_effective_target_avr_tiny] } {
> -         set et_target_tiny_saved 1
> -       }
> -    }
> -
> -    return $et_target_tiny_saved
> +    return [check_cached_effective_target tiny {
> +	    if { [istarget aarch64*-*-*]
> +		 && [check_effective_target_aarch64_tiny] } {
> +	      return 1
> +	    }
> +	    if { [istarget avr-*-*]
> +		 && [check_effective_target_avr_tiny] } {
> +	      return 1
> +	    }
> +	    return 0
> +    }]
>  }

Over-indented { ... } body.
 
OK with those changes if you can drop the is-effective-target hunk above.

Thanks,
Richard
Jeff Law Oct. 12, 2018, 3:17 a.m. UTC | #7
On 9/27/18 8:13 AM, Tamar Christina wrote:
>>> The error you would get if you do this is very confusing so I thought
>>> since it didn't matter much for the regexp only target triple tests
>>> that just accepting this would be fine.
>> Seems a good thing that that's a noisy failure; the function should
>> make up its mind whether it wants to cache (use curly braces) or not
>> (just return the expr directly).
>>
>>> Should I drop it or keep it?
>> Think we should either drop it or make it into a more user-friendly
>> error, e.g.:
>>
>> 	if {[string is true -strict $args] || [string is false -strict $args]} {
>> 	    error {check_cached_effective_target condition already evaluated; did you pass [...] instead of the expected {...}?}
>> 	} else {
>> 	    set et_cache($prop,$target) [uplevel eval $args]
>> 	}
>>
> Done, I have also ran a regression test on x86_64 with unix{,-m32} and no fallouts, testsuite is clean.
> 
> Attached updated patch with feedback processed.
> 
> Ok for trunk?
I don't think this ever got a final approval.  If it did I certainly
missed it.

OK for the trunk.

Jeff

ps.  You're mighty brave heading into that tcl nonsense...  Be careful
you don't get good at it and end up owning it!
diff mbox series

Patch

diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index c2d814cf8c692e5939ec71c43a50c5bd52554b2b..52f74ecd217061ae645385f636b61786e04812d7 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -37,6 +37,7 @@ 
 # and "// Go" for Go
 # If the tool is ObjC/ObjC++ then we overide the extension to .m/.mm to 
 # allow for ObjC/ObjC++ specific flags.
+
 proc check_compile {basename type contents args} {
     global tool
     verbose "check_compile tool: $tool for $basename" 
@@ -120,22 +121,41 @@  proc check_cached_effective_target { prop args } {
     global et_prop_list
 
     set target [current_target_name]
-    if {![info exists et_cache($prop,target)]
-	|| $et_cache($prop,target) != $target} {
+    if {![info exists et_cache($prop,$target)]} {
 	verbose "check_cached_effective_target $prop: checking $target" 2
-	set et_cache($prop,target) $target
-	set et_cache($prop,value) [uplevel eval $args]
+	if {[string is true -strict $args] || [string is false -strict $args]} {
+	    set et_cache($prop,$target) $args
+	} else {
+	    set et_cache($prop,$target) [uplevel eval $args]
+	}
 	if {![info exists et_prop_list]
 	    || [lsearch $et_prop_list $prop] < 0} {
 	    lappend et_prop_list $prop
 	}
 	verbose "check_cached_effective_target cached list is now: $et_prop_list" 2
     }
-    set value $et_cache($prop,value)
+    set value $et_cache($prop,$target)
     verbose "check_cached_effective_target $prop: returning $value for $target" 2
     return $value
 }
 
+# Implements a version of check_cached_effective_target that also takes et_index
+# into account when creating the key for the cache.
+proc check_cached_effective_target_indexed { prop args } {
+    global et_index
+    set key "$et_index $prop"
+    verbose "check_cached_effective_target_index $prop: returning $key" 2
+
+    # Force the evaluation at this level since check_cached_effective_target
+    # may no longer be able to.
+    if {[string is true -strict $args] || [string is false -strict $args]} {
+	set value $args
+    } else {
+	set value [uplevel eval $args]
+    }
+    return [check_cached_effective_target $key $value]
+}
+
 # Clear effective-target cache. This is useful after testing
 # effective-target features and overriding TEST_ALWAYS_FLAGS and/or
 # ALWAYS_CXXFLAGS.
@@ -149,11 +169,13 @@  proc clear_effective_target_cache { } {
     global et_cache
     global et_prop_list
 
+    set target [current_target_name]
     if {[info exists et_prop_list]} {
 	verbose "clear_effective_target_cache: $et_prop_list" 2
 	foreach prop $et_prop_list {
-	    unset et_cache($prop,value)
-	    unset et_cache($prop,target)
+	    if {[info exists et_cache($prop,$target)]} {
+		unset et_cache($prop,$target)
+            }
 	}
 	unset et_prop_list
     }
@@ -380,12 +402,9 @@  proc check_visibility_available { what_kind } {
 # be determined.
 
 proc check_alias_available { } {
-    global alias_available_saved
     global tool
 
-    if [info exists alias_available_saved] {
-        verbose "check_alias_available  returning saved $alias_available_saved" 2
-    } else {
+    return [check_cached_effective_target alias_available {
 	set src alias[pid].c
 	set obj alias[pid].o
         verbose "check_alias_available  compiling testfile $src" 2
@@ -402,7 +421,7 @@  proc check_alias_available { } {
 
 	if [string match "" $lines] then {
 	    # No error messages, everything is OK.
-	    set alias_available_saved 2
+	    return 2
 	} else {
 	    if [regexp "alias definitions not supported" $lines] {
 		verbose "check_alias_available  target does not support aliases" 2
@@ -411,24 +430,20 @@  proc check_alias_available { } {
 
 		if { $objformat == "elf" } {
 		    verbose "check_alias_available  but target uses ELF format, so it ought to" 2
-		    set alias_available_saved -1
+		    return -1
 		} else {
-		    set alias_available_saved 0
+		    return 0
 		}
 	    } else {
 		if [regexp "only weak aliases are supported" $lines] {
 		verbose "check_alias_available  target supports only weak aliases" 2
-		set alias_available_saved 1
+		    return 1
 		} else {
-		    set alias_available_saved -1
+		    return -1
 		}
 	    }
 	}
-
-	verbose "check_alias_available  returning $alias_available_saved" 2
-    }
-
-    return $alias_available_saved
+    }]
 }
 
 # Returns 1 if the target toolchain supports strong aliases, 0 otherwise.
@@ -461,15 +476,13 @@  proc check_ifunc_available { } {
 # Returns true if --gc-sections is supported on the target.
 
 proc check_gc_sections_available { } {
-    global gc_sections_available_saved
     global tool
 
-    if {![info exists gc_sections_available_saved]} {
+    return [check_cached_effective_target gc_sections_available {
 	# Some targets don't support gc-sections despite whatever's
 	# advertised by ld's options.
 	if { [istarget alpha*-*-*]
 	     || [istarget ia64-*-*] } {
-	    set gc_sections_available_saved 0
 	    return 0
 	}
 
@@ -477,7 +490,6 @@  proc check_gc_sections_available { } {
 	# --gc-sections.
 	if { [board_info target exists ldflags]
 	     && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
-	    set gc_sections_available_saved 0
 	    return 0
 	}
 
@@ -485,7 +497,6 @@  proc check_gc_sections_available { } {
 	# while RTP executables are linked with -q (--emit-relocs).
 	# Both of these options are incompatible with --gc-sections.
 	if { [istarget *-*-vxworks*] } {
-	    set gc_sections_available_saved 0
 	    return 0
 	}
 
@@ -493,12 +504,11 @@  proc check_gc_sections_available { } {
 	set gcc_ld [lindex [${tool}_target_compile "-print-prog-name=ld" "" "none" ""] 0]
 	set ld_output [remote_exec host "$gcc_ld" "--help"]
 	if { [ string first "--gc-sections" $ld_output ] >= 0 } {
-	    set gc_sections_available_saved 1
+	    return 1
 	} else {
-	    set gc_sections_available_saved 0
+	    return 0
 	}
-    }
-    return $gc_sections_available_saved
+    }]
 }
 
 # Return 1 if according to target_info struct and explicit target list
@@ -581,8 +591,6 @@  proc profopt-perf-wrapper { } {
 # Return true if profiling is supported on the target.
 
 proc check_profiling_available { test_what } {
-    global profiling_available_saved
-
     verbose "Profiling argument is <$test_what>" 1
 
     # These conditions depend on the argument so examine them before
@@ -657,7 +665,8 @@  proc check_profiling_available { test_what } {
     }
 
     # Now examine the cache variable.
-    if {![info exists profiling_available_saved]} {
+    set profiling_working \
+       [expr {[check_cached_effective_target profiling_available {
 	# Some targets don't have any implementation of __bb_init_func or are
 	# missing other needed machinery.
 	if {[istarget aarch64*-*-elf]
@@ -692,16 +701,15 @@  proc check_profiling_available { test_what } {
 	     || [istarget xtensa*-*-elf]
 	     || [istarget *-*-rtems*]
 	     || [istarget *-*-vxworks*] } {
-	    set profiling_available_saved 0
+	    return 0
 	} else {
-	    set profiling_available_saved 1
+	    return 1
 	}
-    }
+    }]}]
 
     # -pg link test result can't be cached since it may change between
     # runs.
-    set profiling_working $profiling_available_saved
-    if { $profiling_available_saved == 1
+    if { $profiling_working == 1
          && ![check_no_compiler_messages_nocache profiling executable {
 	      int main() { return 0; } } "-pg"] } {
 	set profiling_working 0
@@ -3039,7 +3047,6 @@  proc check_effective_target_ucn { } {
 # instruction set.
 
 proc check_effective_target_vect_cmdline_needed { } {
-    global et_vect_cmdline_needed_saved
     global et_vect_cmdline_needed_target_name
 
     if { ![info exists et_vect_cmdline_needed_target_name] } {
@@ -3057,10 +3064,7 @@  proc check_effective_target_vect_cmdline_needed { } {
 	}
     }
 
-    if [info exists et_vect_cmdline_needed_saved] {
-	verbose "check_effective_target_vect_cmdline_needed: using cached result" 2
-    } else {
-	set et_vect_cmdline_needed_saved 1
+    return [check_cached_effective_target vect_cmdline_needed {
 	if { [istarget alpha*-*-*]
 	     || [istarget ia64-*-*]
 	     || (([istarget i?86-*-*] || [istarget x86_64-*-*])
@@ -3072,12 +3076,10 @@  proc check_effective_target_vect_cmdline_needed { } {
              || [istarget spu-*-*]
 	     || ([istarget arm*-*-*] && [check_effective_target_arm_neon])
 	     || [istarget aarch64*-*-*] } {
-	   set et_vect_cmdline_needed_saved 0
-	}
-    }
-
-    verbose "check_effective_target_vect_cmdline_needed: returning $et_vect_cmdline_needed_saved" 2
-    return $et_vect_cmdline_needed_saved
+		return 0
+	} else {
+		return 1
+	}}]
 }
 
 # Return 1 if the target supports hardware vectors of int, 0 otherwise.
@@ -3085,106 +3087,62 @@  proc check_effective_target_vect_cmdline_needed { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_int { } {
-    global et_vect_int_saved
-    global et_index
-
-    if [info exists et_vect_int_saved($et_index)] {
-	verbose "check_effective_target_vect_int: using cached result" 2
-    } else {
-	set et_vect_int_saved($et_index) 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
-             || ([istarget powerpc*-*-*]
-		 && ![istarget powerpc-*-linux*paired*])
-	     || [istarget spu-*-*]
-	     || [istarget sparc*-*-*]
-	     || [istarget alpha*-*-*]
-	     || [istarget ia64-*-*] 
-	     || [istarget aarch64*-*-*]
-	     || [is-effective-target arm_neon]
-	     || ([istarget mips*-*-*]
-		 && ([et-is-effective-target mips_loongson]
-		     || [et-is-effective-target mips_msa]))
-	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_int_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_int:\
-	     returning $et_vect_int_saved($et_index)" 2
-    return $et_vect_int_saved($et_index)
+    return [check_cached_effective_target_indexed vect_int {
+      expr {
+         [istarget i?86-*-*] || [istarget x86_64-*-*]
+         || ([istarget powerpc*-*-*]
+	     && ![istarget powerpc-*-linux*paired*])
+	 || [istarget spu-*-*]
+	 || [istarget sparc*-*-*]
+	 || [istarget alpha*-*-*]
+	 || [istarget ia64-*-*]
+	 || [istarget aarch64*-*-*]
+	 || [is-effective-target arm_neon]
+	 || ([istarget mips*-*-*]
+	     && ([et-is-effective-target mips_loongson]
+	     || [et-is-effective-target mips_msa]))
+	 || ([istarget s390*-*-*]
+	     && [check_effective_target_s390_vx])
+	}}]
 }
 
 # Return 1 if the target supports signed int->float conversion 
 #
 
 proc check_effective_target_vect_intfloat_cvt { } {
-    global et_vect_intfloat_cvt_saved
-    global et_index
-
-    if [info exists et_vect_intfloat_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_intfloat_cvt:\
-		 using cached result" 2
-    } else {
-	set et_vect_intfloat_cvt_saved($et_index) 0
-        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_intfloat_cvt {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget powerpc*-*-*]
 		 && ![istarget powerpc-*-linux*paired*])
 	     || [is-effective-target arm_neon]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_intfloat_cvt_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_intfloat_cvt:\
-	     returning $et_vect_intfloat_cvt_saved($et_index)" 2
-    return $et_vect_intfloat_cvt_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target supports signed double->int conversion
 #
 
 proc check_effective_target_vect_doubleint_cvt { } {
-    global et_vect_doubleint_cvt_saved
-    global et_index
-
-    if [info exists et_vect_doubleint_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_doubleint_cvt: using cached result" 2
-    } else {
-	set et_vect_doubleint_cvt_saved($et_index) 0
-	if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
-	      && [check_no_compiler_messages vect_doubleint_cvt assembly {
-		  #ifdef __tune_atom__
-		  # error No double vectorizer support.
-		  #endif
+    return [check_cached_effective_target_indexed vect_doubleint_cvt {
+      expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+	       && [check_no_compiler_messages vect_doubleint_cvt assembly {
+		   #ifdef __tune_atom__
+		   # error No double vectorizer support.
+		   #endif
 	      }])
-	     || [istarget aarch64*-*-*]
-	     || [istarget spu-*-*]
-	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
-	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_doubleint_cvt_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_doubleint_cvt:\
-	     returning $et_vect_doubleint_cvt_saved($et_index)" 2
-    return $et_vect_doubleint_cvt_saved($et_index)
+	    || [istarget aarch64*-*-*]
+	    || [istarget spu-*-*]
+	    || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
+	    || ([istarget mips*-*-*]
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target supports signed int->double conversion
 #
 
 proc check_effective_target_vect_intdouble_cvt { } {
-    global et_vect_intdouble_cvt_saved
-    global et_index
-
-    if [info exists et_vect_intdouble_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_intdouble_cvt: using cached result" 2
-    } else {
-	set et_vect_intdouble_cvt_saved($et_index) 0
-	if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+    return [check_cached_effective_target_indexed vect_intdouble_cvt {
+      expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
 	      && [check_no_compiler_messages vect_intdouble_cvt assembly {
 		  #ifdef __tune_atom__
 		  # error No double vectorizer support.
@@ -3194,14 +3152,7 @@  proc check_effective_target_vect_intdouble_cvt { } {
 	     || [istarget spu-*-*]
 	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_intdouble_cvt_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_intdouble_cvt:\
-	     returning $et_vect_intdouble_cvt_saved($et_index)" 2
-    return $et_vect_intdouble_cvt_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 #Return 1 if we're supporting __int128 for target, 0 otherwise.
@@ -3222,28 +3173,14 @@  proc check_effective_target_int128 { } {
 #
 
 proc check_effective_target_vect_uintfloat_cvt { } {
-    global et_vect_uintfloat_cvt_saved
-    global et_index
-
-    if [info exists et_vect_uintfloat_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_uintfloat_cvt:\
-		 using cached result" 2
-    } else {
-	set et_vect_uintfloat_cvt_saved($et_index) 0
-        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_uintfloat_cvt {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget powerpc*-*-*]
 		 && ![istarget powerpc-*-linux*paired*])
 	     || [istarget aarch64*-*-*]
 	     || [is-effective-target arm_neon]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_uintfloat_cvt_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_uintfloat_cvt:\
-	     returning $et_vect_uintfloat_cvt_saved($et_index)" 2
-    return $et_vect_uintfloat_cvt_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 
@@ -3251,76 +3188,35 @@  proc check_effective_target_vect_uintfloat_cvt { } {
 #
 
 proc check_effective_target_vect_floatint_cvt { } {
-    global et_vect_floatint_cvt_saved
-    global et_index
-
-    if [info exists et_vect_floatint_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_floatint_cvt:\
-		 using cached result" 2
-    } else {
-	set et_vect_floatint_cvt_saved($et_index) 0
-        if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_floatint_cvt {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget powerpc*-*-*]
 		 && ![istarget powerpc-*-linux*paired*])
 	     || [is-effective-target arm_neon]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_floatint_cvt_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_floatint_cvt:\
-	     returning $et_vect_floatint_cvt_saved($et_index)" 2
-    return $et_vect_floatint_cvt_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target supports unsigned float->int conversion
 #
 
 proc check_effective_target_vect_floatuint_cvt { } {
-    global et_vect_floatuint_cvt_saved
-    global et_index
-
-    if [info exists et_vect_floatuint_cvt_saved($et_index)] {
-	verbose "check_effective_target_vect_floatuint_cvt:\
-		 using cached result" 2
-    } else {
-	set et_vect_floatuint_cvt_saved($et_index) 0
-        if { ([istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_floatuint_cvt {
+      expr { ([istarget powerpc*-*-*]
 	      && ![istarget powerpc-*-linux*paired*])
 	    || [is-effective-target arm_neon]
 	    || ([istarget mips*-*-*]
-		&& [et-is-effective-target mips_msa]) } {
-	   set et_vect_floatuint_cvt_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_floatuint_cvt:\
-	     returning $et_vect_floatuint_cvt_saved($et_index)" 2
-    return $et_vect_floatuint_cvt_saved($et_index)
+		&& [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if peeling for alignment might be profitable on the target
 #
 
 proc check_effective_target_vect_peeling_profitable { } {
-    global et_vect_peeling_profitable_saved
-    global et_index
-
-    if [info exists et_vect_peeling_profitable_saved($et_index)] {
-	verbose "check_effective_target_vect_peeling_profitable: using cached result" 2
-    } else {
-	set et_vect_peeling_profitable_saved($et_index) 1
-        if { ([istarget s390*-*-*]
+    return [check_cached_effective_target_indexed vect_peeling_profitable {
+      expr { ([istarget s390*-*-*]
 	      && [check_effective_target_s390_vx])
-	     || [check_effective_target_vect_element_align_preferred] } {
-	    set et_vect_peeling_profitable_saved($et_index) 0
-        }
-    }
-
-    verbose "check_effective_target_vect_peeling_profitable:\
-	     returning $et_vect_peeling_profitable_saved($et_index)" 2
-    return $et_vect_peeling_profitable_saved($et_index)
+	    || [check_effective_target_vect_element_align_preferred] }}]
 }
 
 # Return 1 if the target supports #pragma omp declare simd, 0 otherwise.
@@ -3328,26 +3224,13 @@  proc check_effective_target_vect_peeling_profitable { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_simd_clones { } {
-    global et_vect_simd_clones_saved
-    global et_index
-
-    if [info exists et_vect_simd_clones_saved($et_index)] {
-	verbose "check_effective_target_vect_simd_clones: using cached result" 2
-    } else {
-	set et_vect_simd_clones_saved($et_index) 0
-	# On i?86/x86_64 #pragma omp declare simd builds a sse2, avx,
-	# avx2 and avx512f clone.  Only the right clone for the
-	# specified arch will be chosen, but still we need to at least
-	# be able to assemble avx512f.
-	if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
-	      && [check_effective_target_avx512f]) } {
-	    set et_vect_simd_clones_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_simd_clones:\
-	     returning $et_vect_simd_clones_saved($et_index)" 2
-    return $et_vect_simd_clones_saved($et_index)
+    # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx,
+    # avx2 and avx512f clone.  Only the right clone for the
+    # specified arch will be chosen, but still we need to at least
+    # be able to assemble avx512f.
+    return [check_cached_effective_target_indexed vect_simd_clones {
+      expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+	      && [check_effective_target_avx512f]) }}]
 }
 
 # Return 1 if this is a AArch64 target supporting big endian
@@ -5433,14 +5316,8 @@  proc check_effective_target_sparc_vis { } {
 # Return 1 if the target supports hardware vector shift operation.
 
 proc check_effective_target_vect_shift { } {
-    global et_vect_shift_saved
-    global et_index
-
-    if [info exists et_vect_shift_saved($et_index)] {
-	verbose "check_effective_target_vect_shift: using cached result" 2
-    } else {
-	set et_vect_shift_saved($et_index) 0
-	if { ([istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_shift {
+      expr {([istarget powerpc*-*-*]
 	      && ![istarget powerpc-*-linux*paired*])
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
@@ -5450,14 +5327,7 @@  proc check_effective_target_vect_shift { } {
 		 && ([et-is-effective-target mips_msa]
 		     || [et-is-effective-target mips_loongson]))
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_shift_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_shift:\
-	     returning $et_vect_shift_saved($et_index)" 2
-    return $et_vect_shift_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 proc check_effective_target_whole_vector_shift { } {
@@ -5483,49 +5353,21 @@  proc check_effective_target_whole_vector_shift { } {
 # Return 1 if the target supports vector bswap operations.
 
 proc check_effective_target_vect_bswap { } {
-    global et_vect_bswap_saved
-    global et_index
-
-    if [info exists et_vect_bswap_saved($et_index)] {
-	verbose "check_effective_target_vect_bswap: using cached result" 2
-    } else {
-	set et_vect_bswap_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
-             || [is-effective-target arm_neon]
-	   } {
-	   set et_vect_bswap_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_bswap:\
-	     returning $et_vect_bswap_saved($et_index)" 2
-    return $et_vect_bswap_saved($et_index)
+    return [check_cached_effective_target_indexed vect_bswap {
+      expr { [istarget aarch64*-*-*] || [is-effective-target arm_neon] }}]
 }
 
 # Return 1 if the target supports hardware vector shift operation for char.
 
 proc check_effective_target_vect_shift_char { } {
-    global et_vect_shift_char_saved
-    global et_index
-
-    if [info exists et_vect_shift_char_saved($et_index)] {
-	verbose "check_effective_target_vect_shift_char: using cached result" 2
-    } else {
-	set et_vect_shift_char_saved($et_index) 0
-	if { ([istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_shift_char {
+      expr { ([istarget powerpc*-*-*]
              && ![istarget powerpc-*-linux*paired*])
 	     || [is-effective-target arm_neon]
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_shift_char_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_shift_char:\
-	     returning $et_vect_shift_char_saved($et_index)" 2
-    return $et_vect_shift_char_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports hardware vectors of long, 0 otherwise.
@@ -5559,14 +5401,8 @@  proc check_effective_target_vect_long { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_float { } {
-    global et_vect_float_saved
-    global et_index
-
-    if [info exists et_vect_float_saved($et_index)] {
-	verbose "check_effective_target_vect_float: using cached result" 2
-    } else {
-	set et_vect_float_saved($et_index) 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_float {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget powerpc*-*-*]
 	     || [istarget spu-*-*]
 	     || [istarget mips-sde-elf]
@@ -5577,14 +5413,7 @@  proc check_effective_target_vect_float { } {
 		 && [et-is-effective-target mips_msa])
 	     || [is-effective-target arm_neon]
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vxe]) } {
-	    set et_vect_float_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_float:\
-	     returning $et_vect_float_saved($et_index)" 2
-    return $et_vect_float_saved($et_index)
+		 && [check_effective_target_s390_vxe]) }}]
 }
 
 # Return 1 if the target supports hardware vectors of float without
@@ -5600,33 +5429,20 @@  proc check_effective_target_vect_float_strict { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_double { } {
-    global et_vect_double_saved
-    global et_index
-
-    if [info exists et_vect_double_saved($et_index)] {
-	verbose "check_effective_target_vect_double: using cached result" 2
-    } else {
-	set et_vect_double_saved($et_index) 0
-	if { (([istarget i?86-*-*] || [istarget x86_64-*-*])
-	      && [check_no_compiler_messages vect_double assembly {
+    return [check_cached_effective_target_indexed vect_double {
+        expr { (([istarget i?86-*-*] || [istarget x86_64-*-*])
+	         && [check_no_compiler_messages vect_double assembly {
 		  #ifdef __tune_atom__
 		  # error No double vectorizer support.
 		  #endif
-	      }])
+		}])
 	     || [istarget aarch64*-*-*]
 	     || [istarget spu-*-*]
 	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_double_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_double:\
-	     returning $et_vect_double_saved($et_index)" 2
-    return $et_vect_double_saved($et_index)
+		 && [check_effective_target_s390_vx])} }]
 }
 
 # Return 1 if the target supports conditional addition, subtraction,
@@ -5642,25 +5458,12 @@  proc check_effective_target_vect_double_cond_arith { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_long_long { } {
-    global et_vect_long_long_saved
-    global et_index
-
-    if [info exists et_vect_long_long_saved($et_index)] {
-        verbose "check_effective_target_vect_long_long: using cached result" 2
-    } else {
-	set et_vect_long_long_saved($et_index) 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_long_long {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_long_long_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_long_long:\
-	     returning $et_vect_long_long_saved($et_index)" 2
-    return $et_vect_long_long_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 
@@ -5670,25 +5473,12 @@  proc check_effective_target_vect_long_long { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_no_int_min_max { } {
-    global et_vect_no_int_min_max_saved
-    global et_index
-
-    if [info exists et_vect_no_int_min_max_saved($et_index)] {
-	verbose "check_effective_target_vect_no_int_min_max:\
-		 using cached result" 2
-    } else {
-	set et_vect_no_int_min_max_saved($et_index) 0
-	if { [istarget sparc*-*-*]
+    return [check_cached_effective_target_indexed vect_no_int_min_max {
+      expr { [istarget sparc*-*-*]
 	     || [istarget spu-*-*]
 	     || [istarget alpha*-*-*]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_loongson]) } {
-	    set et_vect_no_int_min_max_saved($et_index) 1
-	}
-    }
-    verbose "check_effective_target_vect_no_int_min_max:\
-	     returning $et_vect_no_int_min_max_saved($et_index)" 2
-    return $et_vect_no_int_min_max_saved($et_index)
+		 && [et-is-effective-target mips_loongson]) }}]
 }
 
 # Return 1 if the target plus current options does not support a vector
@@ -5697,21 +5487,9 @@  proc check_effective_target_vect_no_int_min_max { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_no_int_add { } {
-    global et_vect_no_int_add_saved
-    global et_index
-
-    if [info exists et_vect_no_int_add_saved($et_index)] {
-	verbose "check_effective_target_vect_no_int_add: using cached result" 2
-    } else {
-	set et_vect_no_int_add_saved($et_index) 0
-	# Alpha only supports vector add on V8QI and V4HI.
-	if { [istarget alpha*-*-*] } {
-	    set et_vect_no_int_add_saved($et_index) 1
-	}
-    }
-    verbose "check_effective_target_vect_no_int_add:\
-	     returning $et_vect_no_int_add_saved($et_index)" 2
-    return $et_vect_no_int_add_saved($et_index)
+    # Alpha only supports vector add on V8QI and V4HI.
+    return [check_cached_effective_target_indexed vect_no_int_add {
+      expr { [istarget alpha*-*-*] }}]
 }
 
 # Return 1 if the target plus current options does not support vector
@@ -5720,17 +5498,7 @@  proc check_effective_target_vect_no_int_add { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_no_bitwise { } {
-    global et_vect_no_bitwise_saved
-    global et_index
-
-    if [info exists et_vect_no_bitwise_saved($et_index)] {
-	verbose "check_effective_target_vect_no_bitwise: using cached result" 2
-    } else {
-	set et_vect_no_bitwise_saved($et_index) 0
-    }
-    verbose "check_effective_target_vect_no_bitwise:\
-	     returning $et_vect_no_bitwise_saved($et_index)" 2
-    return $et_vect_no_bitwise_saved($et_index)
+    return [check_cached_effective_target_indexed vect_no_bitwise { expr 0 }]
 }
 
 # Return 1 if the target plus current options supports vector permutation,
@@ -5739,14 +5507,8 @@  proc check_effective_target_vect_no_bitwise { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_perm { } {
-    global et_vect_perm_saved
-    global et_index
-
-    if [info exists et_vect_perm_saved($et_index)] {
-        verbose "check_effective_target_vect_perm: using cached result" 2
-    } else {
-	set et_vect_perm_saved($et_index) 0
-        if { [is-effective-target arm_neon]
+    return [check_cached_effective_target_indexed vect_perm {
+      expr { [is-effective-target arm_neon]
 	     || ([istarget aarch64*-*-*]
 		 && ![check_effective_target_vect_variable_length])
 	     || [istarget powerpc*-*-*]
@@ -5756,13 +5518,7 @@  proc check_effective_target_vect_perm { } {
 		 && ([et-is-effective-target mpaired_single]
 		     || [et-is-effective-target mips_msa]))
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_perm_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_perm:\
-	     returning $et_vect_perm_saved($et_index)" 2
-    return $et_vect_perm_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if, for some VF:
@@ -5843,14 +5599,8 @@  proc check_effective_target_vect_perm3_int { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_perm_byte { } {
-    global et_vect_perm_byte_saved
-    global et_index
-
-    if [info exists et_vect_perm_byte_saved($et_index)] {
-        verbose "check_effective_target_vect_perm_byte: using cached result" 2
-    } else {
-	set et_vect_perm_byte_saved($et_index) 0
-        if { ([is-effective-target arm_neon]
+    return [check_cached_effective_target_indexed vect_perm_byte {
+      expr { ([is-effective-target arm_neon]
 	      && [is-effective-target arm_little_endian])
 	     || ([istarget aarch64*-*-*]
 		 && [is-effective-target aarch64_little_endian]
@@ -5860,13 +5610,7 @@  proc check_effective_target_vect_perm_byte { } {
 	     || ([istarget mips-*.*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_perm_byte_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_perm_byte:\
-	     returning $et_vect_perm_byte_saved($et_index)" 2
-    return $et_vect_perm_byte_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports SLP permutation of 3 vectors when each
@@ -5883,14 +5627,8 @@  proc check_effective_target_vect_perm3_byte { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_perm_short { } {
-    global et_vect_perm_short_saved
-    global et_index
-
-    if [info exists et_vect_perm_short_saved($et_index)] {
-        verbose "check_effective_target_vect_perm_short: using cached result" 2
-    } else {
-	set et_vect_perm_short_saved($et_index) 0
-        if { ([is-effective-target arm_neon]
+    return [check_cached_effective_target_indexed vect_perm_short {
+      expr { ([is-effective-target arm_neon]
 	      && [is-effective-target arm_little_endian])
 	     || ([istarget aarch64*-*-*]
 		 && [is-effective-target aarch64_little_endian]
@@ -5902,13 +5640,7 @@  proc check_effective_target_vect_perm_short { } {
 	     || ([istarget mips*-*-*]
 		  && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_perm_short_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_perm_short:\
-	     returning $et_vect_perm_short_saved($et_index)" 2
-    return $et_vect_perm_short_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports SLP permutation of 3 vectors when each
@@ -5925,20 +5657,8 @@  proc check_effective_target_vect_perm3_short { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_xorsign { } {
-    global et_xorsign_saved
-    global et_index
-
-    if [info exists et_xorsign_saved($et_index)] {
-        verbose "check_effective_target_xorsign: using cached result" 2
-    } else {
-	set et_xorsign_saved($et_index) 0
-        if { [istarget aarch64*-*-*] || [istarget arm*-*-*] } {
-	    set et_xorsign_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_xorsign:\
-	     returning $et_xorsign_saved($et_index)" 2
-    return $et_xorsign_saved($et_index)
+    return [check_cached_effective_target_indexed xorsign {
+      expr { [istarget aarch64*-*-*] || [istarget arm*-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -5947,25 +5667,12 @@  proc check_effective_target_xorsign { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
-    global et_vect_widen_sum_hi_to_si_pattern_saved
-    global et_index
-
-    if [info exists et_vect_widen_sum_hi_to_si_pattern_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_sum_hi_to_si_pattern_saved($et_index) 0
-        if { [istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si_pattern {
+      expr { [istarget powerpc*-*-*]
              || ([istarget aarch64*-*-*]
 		 && ![check_effective_target_aarch64_sve])
 	     || [is-effective-target arm_neon]
-             || [istarget ia64-*-*] } {
-	    set et_vect_widen_sum_hi_to_si_pattern_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_sum_hi_to_si_pattern:\
-	     returning $et_vect_widen_sum_hi_to_si_pattern_saved($et_index)" 2
-    return $et_vect_widen_sum_hi_to_si_pattern_saved($et_index)
+             || [istarget ia64-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -5974,25 +5681,12 @@  proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } {
 # promotion (unpacking) from shorts to ints.
 #
 # This won't change for different subtargets so cache the result.
-                                                                                                
-proc check_effective_target_vect_widen_sum_hi_to_si { } {
-    global et_vect_widen_sum_hi_to_si_saved
-    global et_index
 
-    if [info exists et_vect_widen_sum_hi_to_si_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_sum_hi_to_si:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_sum_hi_to_si_saved($et_index) \
-	    [check_effective_target_vect_unpack]
-        if { [istarget powerpc*-*-*] 
-	     || [istarget ia64-*-*] } {
-	    set et_vect_widen_sum_hi_to_si_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_sum_hi_to_si:\
-	     returning $et_vect_widen_sum_hi_to_si_saved($et_index)" 2
-    return $et_vect_widen_sum_hi_to_si_saved($et_index)
+proc check_effective_target_vect_widen_sum_hi_to_si { } {
+    return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si {
+      expr { [check_effective_target_vect_unpack]
+             || [istarget powerpc*-*-*]
+	     || [istarget ia64-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6003,23 +5697,10 @@  proc check_effective_target_vect_widen_sum_hi_to_si { } {
 # This won't change for different subtargets so cache the result.
                                                                                                 
 proc check_effective_target_vect_widen_sum_qi_to_hi { } {
-    global et_vect_widen_sum_qi_to_hi_saved
-    global et_index
-
-    if [info exists et_vect_widen_sum_qi_to_hi_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_sum_qi_to_hi:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_sum_qi_to_hi_saved($et_index) 0
-	if { [check_effective_target_vect_unpack] 
+    return [check_cached_effective_target_indexed vect_widen_sum_qi_to_hi {
+      expr { [check_effective_target_vect_unpack]
 	     || [is-effective-target arm_neon]
-	     || [istarget ia64-*-*] } {
-	    set et_vect_widen_sum_qi_to_hi_saved($et_index) 1
-	}
-    }
-    verbose "check_effective_target_vect_widen_sum_qi_to_hi:\
-	     returning $et_vect_widen_sum_qi_to_hi_saved($et_index)" 2
-    return $et_vect_widen_sum_qi_to_hi_saved($et_index)
+	     || [istarget ia64-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6028,21 +5709,8 @@  proc check_effective_target_vect_widen_sum_qi_to_hi { } {
 # This won't change for different subtargets so cache the result.
                                                                                                 
 proc check_effective_target_vect_widen_sum_qi_to_si { } {
-    global et_vect_widen_sum_qi_to_si_saved
-    global et_index
-
-    if [info exists et_vect_widen_sum_qi_to_si_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_sum_qi_to_si:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_sum_qi_to_si_saved($et_index) 0
-        if { [istarget powerpc*-*-*] } {
-	    set et_vect_widen_sum_qi_to_si_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_sum_qi_to_si:\
-	     returning $et_vect_widen_sum_qi_to_si_saved($et_index)" 2
-    return $et_vect_widen_sum_qi_to_si_saved($et_index)
+    return [check_cached_effective_target_indexed vect_widen_sum_qi_to_si {
+      expr { [istarget powerpc*-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6055,31 +5723,15 @@  proc check_effective_target_vect_widen_sum_qi_to_si { } {
 
 
 proc check_effective_target_vect_widen_mult_qi_to_hi { } {
-    global et_vect_widen_mult_qi_to_hi_saved
-    global et_index
-
-    if [info exists et_vect_widen_mult_qi_to_hi_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_mult_qi_to_hi:\
-		 using cached result" 2
-    } else {
-	if { [check_effective_target_vect_unpack]
-	     && [check_effective_target_vect_short_mult] } {
-	    set et_vect_widen_mult_qi_to_hi_saved($et_index) 1
-	} else {
-	    set et_vect_widen_mult_qi_to_hi_saved($et_index) 0
-	}
-        if { [istarget powerpc*-*-*]
-              || ([istarget aarch64*-*-*]
-		  && ![check_effective_target_aarch64_sve])
-              || [is-effective-target arm_neon]
-	      || ([istarget s390*-*-*]
-		  && [check_effective_target_s390_vx]) } {
-	    set et_vect_widen_mult_qi_to_hi_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_mult_qi_to_hi:\
-	     returning $et_vect_widen_mult_qi_to_hi_saved($et_index)" 2
-    return $et_vect_widen_mult_qi_to_hi_saved($et_index)
+    return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi {
+      expr { ([check_effective_target_vect_unpack]
+	       && [check_effective_target_vect_short_mult])
+	      || ([istarget powerpc*-*-*]
+		  || ([istarget aarch64*-*-*]
+		      && ![check_effective_target_aarch64_sve])
+		  || [is-effective-target arm_neon]
+		  || ([istarget s390*-*-*]
+		      && [check_effective_target_s390_vx])) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6092,34 +5744,18 @@  proc check_effective_target_vect_widen_mult_qi_to_hi { } {
 
 
 proc check_effective_target_vect_widen_mult_hi_to_si { } {
-    global et_vect_widen_mult_hi_to_si_saved
-    global et_index
-
-    if [info exists et_vect_widen_mult_hi_to_si_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_mult_hi_to_si:\
-		 using cached result" 2
-    } else {
-        if { [check_effective_target_vect_unpack]
-             && [check_effective_target_vect_int_mult] } {
-	  set et_vect_widen_mult_hi_to_si_saved($et_index) 1
-        } else {
-	  set et_vect_widen_mult_hi_to_si_saved($et_index) 0
-        }
-        if { [istarget powerpc*-*-*]
-	     || [istarget spu-*-*]
-	     || [istarget ia64-*-*]
-	     || ([istarget aarch64*-*-*]
-		 && ![check_effective_target_aarch64_sve])
-	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
-	     || [is-effective-target arm_neon]
-	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_widen_mult_hi_to_si_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_mult_hi_to_si:\
-	     returning $et_vect_widen_mult_hi_to_si_saved($et_index)" 2
-    return $et_vect_widen_mult_hi_to_si_saved($et_index)
+    return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si {
+      expr { ([check_effective_target_vect_unpack]
+              && [check_effective_target_vect_int_mult])
+	     || ([istarget powerpc*-*-*]
+		 || [istarget spu-*-*]
+		 || [istarget ia64-*-*]
+		 || ([istarget aarch64*-*-*]
+		     && ![check_effective_target_aarch64_sve])
+		 || [istarget i?86-*-*] || [istarget x86_64-*-*]
+		 || [is-effective-target arm_neon]
+		 || ([istarget s390*-*-*]
+		     && [check_effective_target_s390_vx])) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6128,25 +5764,12 @@  proc check_effective_target_vect_widen_mult_hi_to_si { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
-    global et_vect_widen_mult_qi_to_hi_pattern_saved
-    global et_index
-
-    if [info exists et_vect_widen_mult_qi_to_hi_pattern_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_mult_qi_to_hi_pattern_saved($et_index) 0
-        if { [istarget powerpc*-*-*]
-              || ([is-effective-target arm_neon]
-		  && [check_effective_target_arm_little_endian])
-	      || ([istarget s390*-*-*]
-		  && [check_effective_target_s390_vx]) } {
-	    set et_vect_widen_mult_qi_to_hi_pattern_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern:\
-	     returning $et_vect_widen_mult_qi_to_hi_pattern_saved($et_index)" 2
-    return $et_vect_widen_mult_qi_to_hi_pattern_saved($et_index)
+    return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi_pattern {
+      expr { [istarget powerpc*-*-*]
+             || ([is-effective-target arm_neon]
+		 && [check_effective_target_arm_little_endian])
+	     || ([istarget s390*-*-*]
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6155,28 +5778,15 @@  proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
-    global et_vect_widen_mult_hi_to_si_pattern_saved
-    global et_index
-
-    if [info exists et_vect_widen_mult_hi_to_si_pattern_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_mult_hi_to_si_pattern_saved($et_index) 0
-        if { [istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si_pattern {
+      expr { [istarget powerpc*-*-*]
 	     || [istarget spu-*-*]
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([is-effective-target arm_neon]
 		 && [check_effective_target_arm_little_endian])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_widen_mult_hi_to_si_pattern_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern:\
-	     returning $et_vect_widen_mult_hi_to_si_pattern_saved($et_index)" 2
-    return $et_vect_widen_mult_hi_to_si_pattern_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6185,25 +5795,12 @@  proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_widen_mult_si_to_di_pattern { } {
-    global et_vect_widen_mult_si_to_di_pattern_saved
-    global et_index
-
-    if [info exists et_vect_widen_mult_si_to_di_pattern_saved($et_index)] {
-	verbose "check_effective_target_vect_widen_mult_si_to_di_pattern:\
-		 using cached result" 2
-    } else {
-	set et_vect_widen_mult_si_to_di_pattern_saved($et_index) 0
-        if {[istarget ia64-*-*]
-	    || [istarget i?86-*-*] || [istarget x86_64-*-*]
-	    || ([istarget s390*-*-*]
-		&& [check_effective_target_s390_vx]) } {
-	    set et_vect_widen_mult_si_to_di_pattern_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_mult_si_to_di_pattern:\
-	     returning $et_vect_widen_mult_si_to_di_pattern_saved($et_index)" 2
-    return $et_vect_widen_mult_si_to_di_pattern_saved($et_index)
-}
+    return [check_cached_effective_target_indexed vect_widen_mult_si_to_di_pattern {
+      expr { [istarget ia64-*-*]
+	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
+	     || ([istarget s390*-*-*]
+		 && [check_effective_target_s390_vx]) }}]
+}
 
 # Return 1 if the target plus current options supports a vector
 # widening shift, 0 otherwise.
@@ -6211,20 +5808,8 @@  proc check_effective_target_vect_widen_mult_si_to_di_pattern { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_widen_shift { } {
-    global et_vect_widen_shift_saved
-    global et_index
-
-    if [info exists et_vect_shift_saved($et_index)] {
-        verbose "check_effective_target_vect_widen_shift: using cached result" 2
-    } else {
-	set et_vect_widen_shift_saved($et_index) 0
-        if { [is-effective-target arm_neon] } {
-	    set et_vect_widen_shift_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_widen_shift:\
-	     returning $et_vect_widen_shift_saved($et_index)" 2
-    return $et_vect_widen_shift_saved($et_index)
+    return [check_cached_effective_target_indexed vect_widen_shift {
+      expr { [is-effective-target arm_neon] }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6233,24 +5818,12 @@  proc check_effective_target_vect_widen_shift { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_sdot_qi { } {
-    global et_vect_sdot_qi_saved
-    global et_index
-
-    if [info exists et_vect_sdot_qi_saved($et_index)] {
-        verbose "check_effective_target_vect_sdot_qi: using cached result" 2
-    } else {
-	set et_vect_sdot_qi_saved($et_index) 0
-	if { [istarget ia64-*-*]
+    return [check_cached_effective_target_indexed vect_sdot_qi {
+      expr { [istarget ia64-*-*]
 	     || [istarget aarch64*-*-*]
 	     || [istarget arm*-*-*]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-            set et_vect_udot_qi_saved 1
-        }
-    }
-    verbose "check_effective_target_vect_sdot_qi:\
-	     returning $et_vect_sdot_qi_saved($et_index)" 2
-    return $et_vect_sdot_qi_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6259,25 +5832,13 @@  proc check_effective_target_vect_sdot_qi { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_udot_qi { } {
-    global et_vect_udot_qi_saved
-    global et_index
-
-    if [info exists et_vect_udot_qi_saved($et_index)] {
-        verbose "check_effective_target_vect_udot_qi: using cached result" 2
-    } else {
-	set et_vect_udot_qi_saved($et_index) 0
-        if { [istarget powerpc*-*-*]
+    return [check_cached_effective_target_indexed vect_udot_qi {
+      expr { [istarget powerpc*-*-*]
 	     || [istarget aarch64*-*-*]
 	     || [istarget arm*-*-*]
 	     || [istarget ia64-*-*]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_udot_qi_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_udot_qi:\
-	     returning $et_vect_udot_qi_saved($et_index)" 2
-    return $et_vect_udot_qi_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6286,24 +5847,12 @@  proc check_effective_target_vect_udot_qi { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_sdot_hi { } {
-    global et_vect_sdot_hi_saved
-    global et_index
-
-    if [info exists et_vect_sdot_hi_saved($et_index)] {
-        verbose "check_effective_target_vect_sdot_hi: using cached result" 2
-    } else {
-	set et_vect_sdot_hi_saved($et_index) 0
-        if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
+    return [check_cached_effective_target_indexed vect_sdot_hi {
+      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_sdot_hi_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_sdot_hi:\
-	     returning $et_vect_sdot_hi_saved($et_index)" 2
-    return $et_vect_sdot_hi_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6312,22 +5861,10 @@  proc check_effective_target_vect_sdot_hi { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_udot_hi { } {
-    global et_vect_udot_hi_saved
-    global et_index
-
-    if [info exists et_vect_udot_hi_saved($et_index)] {
-        verbose "check_effective_target_vect_udot_hi: using cached result" 2
-    } else {
-	set et_vect_udot_hi_saved($et_index) 0
-	if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
+    return [check_cached_effective_target_indexed vect_udot_hi {
+      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_msa]) } {
-	    set et_vect_udot_hi_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_udot_hi:\
-	     returning $et_vect_udot_hi_saved($et_index)" 2
-    return $et_vect_udot_hi_saved($et_index)
+		 && [et-is-effective-target mips_msa]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6336,20 +5873,8 @@  proc check_effective_target_vect_udot_hi { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_usad_char { } {
-    global et_vect_usad_char_saved
-    global et_index
-
-    if [info exists et_vect_usad_char_saved($et_index)] {
-        verbose "check_effective_target_vect_usad_char: using cached result" 2
-    } else {
-	set et_vect_usad_char_saved($et_index) 0
-        if { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
-	    set et_vect_usad_char_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_usad_char:\
-	     returning $et_vect_usad_char_saved($et_index)" 2
-    return $et_vect_usad_char_saved($et_index)
+    return [check_cached_effective_target_indexed vect_usad_char {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*] }}]
 }
 
 # Return 1 if the target plus current options supports both signed
@@ -6367,14 +5892,8 @@  proc check_effective_target_vect_avg_qi {} {
 # This won't change for different subtargets so cache the result.
                                                                                 
 proc check_effective_target_vect_pack_trunc { } {
-    global et_vect_pack_trunc_saved
-    global et_index
-                                                                                
-    if [info exists et_vect_pack_trunc_saved($et_index)] {
-        verbose "check_effective_target_vect_pack_trunc: using cached result" 2
-    } else {
-	set et_vect_pack_trunc_saved($et_index) 0
-        if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
+    return [check_cached_effective_target_indexed vect_pack_trunc {
+      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
              || [istarget i?86-*-*] || [istarget x86_64-*-*]
              || [istarget aarch64*-*-*]
              || [istarget spu-*-*]
@@ -6383,13 +5902,7 @@  proc check_effective_target_vect_pack_trunc { } {
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_pack_trunc_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_pack_trunc:\
-	     returning $et_vect_pack_trunc_saved($et_index)" 2
-    return $et_vect_pack_trunc_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target plus current options supports a vector
@@ -6398,15 +5911,9 @@  proc check_effective_target_vect_pack_trunc { } {
 # This won't change for different subtargets so cache the result.
                                    
 proc check_effective_target_vect_unpack { } {
-    global et_vect_unpack_saved
-    global et_index
-                                        
-    if [info exists et_vect_unpack_saved($et_index)] {
-        verbose "check_effective_target_vect_unpack: using cached result" 2
-    } else {
-	set et_vect_unpack_saved($et_index) 0
-        if { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
-             || [istarget i?86-*-*] || [istarget x86_64-*-*] 
+    return [check_cached_effective_target_indexed vect_unpack {
+      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
+             || [istarget i?86-*-*] || [istarget x86_64-*-*]
              || [istarget spu-*-*]
              || [istarget ia64-*-*]
              || [istarget aarch64*-*-*]
@@ -6415,13 +5922,7 @@  proc check_effective_target_vect_unpack { } {
              || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]
 		 && [check_effective_target_arm_little_endian])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_unpack_saved($et_index) 1
-        }
-    }
-    verbose "check_effective_target_vect_unpack:\
-	     returning $et_vect_unpack_saved($et_index)" 2
-    return $et_vect_unpack_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target plus current options does not guarantee
@@ -6430,15 +5931,7 @@  proc check_effective_target_vect_unpack { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_unaligned_stack { } {
-    global et_unaligned_stack_saved
-
-    if [info exists et_unaligned_stack_saved] {
-        verbose "check_effective_target_unaligned_stack: using cached result" 2
-    } else {
-        set et_unaligned_stack_saved 0
-    }
-    verbose "check_effective_target_unaligned_stack: returning $et_unaligned_stack_saved" 2
-    return $et_unaligned_stack_saved
+    return [check_cached_effective_target_indexed unaligned_stack { expr 0 }]
 }
 
 # Return 1 if the target plus current options does not support a vector
@@ -6447,27 +5940,15 @@  proc check_effective_target_unaligned_stack { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_no_align { } {
-    global et_vect_no_align_saved
-    global et_index
-
-    if [info exists et_vect_no_align_saved($et_index)] {
-	verbose "check_effective_target_vect_no_align: using cached result" 2
-    } else {
-	set et_vect_no_align_saved($et_index) 0
-	if { [istarget mipsisa64*-*-*]
+    return [check_cached_effective_target_indexed vect_no_align {
+      expr { [istarget mipsisa64*-*-*]
 	     || [istarget mips-sde-elf]
 	     || [istarget sparc*-*-*]
 	     || [istarget ia64-*-*]
 	     || [check_effective_target_arm_vect_no_misalign]
 	     || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
 	     || ([istarget mips*-*-*]
-		 && [et-is-effective-target mips_loongson]) } {
-	    set et_vect_no_align_saved($et_index) 1
-	}
-    }
-    verbose "check_effective_target_vect_no_align:\
-	     returning $et_vect_no_align_saved($et_index)" 2
-    return $et_vect_no_align_saved($et_index)
+		 && [et-is-effective-target mips_loongson]) }}]
 }
 
 # Return 1 if the target supports a vector misalign access, 0 otherwise.
@@ -6475,28 +5956,21 @@  proc check_effective_target_vect_no_align { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_vect_hw_misalign { } {
-    global et_vect_hw_misalign_saved
-    global et_index
-
-    if [info exists et_vect_hw_misalign_saved($et_index)] {
-        verbose "check_effective_target_vect_hw_misalign: using cached result" 2
-    } else {
-	set et_vect_hw_misalign_saved($et_index) 0
+    return [check_cached_effective_target_indexed vect_hw_misalign {
 	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget powerpc*-*-*] && [check_p8vector_hw_available])
 	     || [istarget aarch64*-*-*]
 	     || ([istarget mips*-*-*] && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
 		 && [check_effective_target_s390_vx]) } {
-	  set et_vect_hw_misalign_saved($et_index) 1
+	  return 1
 	}
-	if { [istarget arm*-*-*] } {
-	    set et_vect_hw_misalign_saved($et_index) [expr ![check_effective_target_arm_vect_no_misalign]]
+	if { [istarget arm*-*-*]
+	     && ![check_effective_target_arm_vect_no_misalign] } {
+	  return 1
 	}
-    }
-    verbose "check_effective_target_vect_hw_misalign:\
-	     returning $et_vect_hw_misalign_saved($et_index)" 2
-    return $et_vect_hw_misalign_saved($et_index)
+        return 0
+    }]
 }
 
 
@@ -6523,20 +5997,15 @@  proc check_effective_target_vect_aligned_arrays { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_natural_alignment_32 { } {
-    global et_natural_alignment_32
-
-    if [info exists et_natural_alignment_32_saved] {
-        verbose "check_effective_target_natural_alignment_32: using cached result" 2
-    } else {
-        # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
-        set et_natural_alignment_32_saved 1
-        if { ([istarget *-*-darwin*] && [is-effective-target lp64])
-             || [istarget avr-*-*] } {
-            set et_natural_alignment_32_saved 0
-        }
-    }
-    verbose "check_effective_target_natural_alignment_32: returning $et_natural_alignment_32_saved" 2
-    return $et_natural_alignment_32_saved
+    # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
+    return [check_cached_effective_target_indexed natural_alignment_32 {
+	    if { ([istarget *-*-darwin*] && [is-effective-target lp64])
+		  || [istarget avr-*-*] } {
+		return 0
+	    } else {
+		return 1
+	    }
+    }]
 }
 
 # Return 1 if types of size 64 bit or less are naturally aligned (aligned to their
@@ -6545,19 +6014,10 @@  proc check_effective_target_natural_alignment_32 { } {
 # This won't change for different subtargets so cache the result.
 
 proc check_effective_target_natural_alignment_64 { } {
-    global et_natural_alignment_64
-
-    if [info exists et_natural_alignment_64_saved] {
-        verbose "check_effective_target_natural_alignment_64: using cached result" 2
-    } else {
-        set et_natural_alignment_64_saved 0
-        if { ([is-effective-target lp64] && ![istarget *-*-darwin*])
-             || [istarget spu-*-*] } {
-            set et_natural_alignment_64_saved 1
-        }
-    }
-    verbose "check_effective_target_natural_alignment_64: returning $et_natural_alignment_64_saved" 2
-    return $et_natural_alignment_64_saved
+    return [check_cached_effective_target_indexed natural_alignment_64 {
+	    expr { ([is-effective-target lp64] && ![istarget *-*-darwin*])
+		  || [istarget spu-*-*] }
+    }]
 }
 
 # Return 1 if all vector types are naturally aligned (aligned to their
@@ -6627,24 +6087,10 @@  proc check_effective_target_vector_alignment_reachable_for_64bit { } {
 # Return 1 if the target only requires element alignment for vector accesses
 
 proc check_effective_target_vect_element_align { } {
-    global et_vect_element_align
-    global et_index
-
-    if [info exists et_vect_element_align($et_index)] {
-	verbose "check_effective_target_vect_element_align:\
-		 using cached result" 2
-    } else {
-	set et_vect_element_align($et_index) 0
-	if { ([istarget arm*-*-*]
+    return [check_cached_effective_target_indexed vect_element_align {
+      expr { ([istarget arm*-*-*]
 	      && ![check_effective_target_arm_vect_no_misalign])
-	     || [check_effective_target_vect_hw_misalign] } {
-	   set et_vect_element_align($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_element_align:\
-	     returning $et_vect_element_align($et_index)" 2
-    return $et_vect_element_align($et_index)
+	     || [check_effective_target_vect_hw_misalign] }}]
 }
 
 # Return 1 if we expect to see unaligned accesses in at least some
@@ -6659,21 +6105,10 @@  proc check_effective_target_vect_unaligned_possible { } {
 # Return 1 if the target supports vector LOAD_LANES operations, 0 otherwise.
 
 proc check_effective_target_vect_load_lanes { } {
-    global et_vect_load_lanes
-
-    if [info exists et_vect_load_lanes] {
-	verbose "check_effective_target_vect_load_lanes: using cached result" 2
-    } else {
-	set et_vect_load_lanes 0
-	# We don't support load_lanes correctly on big-endian arm.
-	if { ([check_effective_target_arm_little_endian] && [check_effective_target_arm_neon_ok])
-	     || [istarget aarch64*-*-*] } {
-	    set et_vect_load_lanes 1
-	}
-    }
-
-    verbose "check_effective_target_vect_load_lanes: returning $et_vect_load_lanes" 2
-    return $et_vect_load_lanes
+    # We don't support load_lanes correctly on big-endian arm.
+    return [check_cached_effective_target vect_load_lanes {
+      expr { ([check_effective_target_arm_little_endian] && [check_effective_target_arm_neon_ok])
+	     || [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector masked stores.
@@ -6691,14 +6126,8 @@  proc check_effective_target_vect_scatter_store { } {
 # Return 1 if the target supports vector conditional operations, 0 otherwise.
 
 proc check_effective_target_vect_condition { } {
-    global et_vect_cond_saved
-    global et_index
-
-    if [info exists et_vect_cond_saved($et_index)] {
-	verbose "check_effective_target_vect_cond: using cached result" 2
-    } else {
-	set et_vect_cond_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target_indexed vect_condition {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget powerpc*-*-*]
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
@@ -6708,54 +6137,28 @@  proc check_effective_target_vect_condition { } {
 	     || ([istarget arm*-*-*]
 		 && [check_effective_target_arm_neon_ok])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_cond_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_cond:\
-	     returning $et_vect_cond_saved($et_index)" 2
-    return $et_vect_cond_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector conditional operations where
 # the comparison has different type from the lhs, 0 otherwise.
 
 proc check_effective_target_vect_cond_mixed { } {
-    global et_vect_cond_mixed_saved
-    global et_index
-
-    if [info exists et_vect_cond_mixed_saved($et_index)] {
-	verbose "check_effective_target_vect_cond_mixed: using cached result" 2
-    } else {
-	set et_vect_cond_mixed_saved($et_index) 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_cond_mixed {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget aarch64*-*-*]
 	     || [istarget powerpc*-*-*] 
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_cond_mixed_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_cond_mixed:\
-	     returning $et_vect_cond_mixed_saved($et_index)" 2
-    return $et_vect_cond_mixed_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector char multiplication, 0 otherwise.
 
 proc check_effective_target_vect_char_mult { } {
-    global et_vect_char_mult_saved
-    global et_index
-
-    if [info exists et_vect_char_mult_saved($et_index)] {
-	verbose "check_effective_target_vect_char_mult: using cached result" 2
-    } else {
-	set et_vect_char_mult_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target_indexed vect_char_mult {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [check_effective_target_arm32]
@@ -6763,27 +6166,14 @@  proc check_effective_target_vect_char_mult { } {
 	     || ([istarget mips*-*-*]
 		 && [et-is-effective-target mips_msa])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_char_mult_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_char_mult:\
-	     returning $et_vect_char_mult_saved($et_index)" 2
-    return $et_vect_char_mult_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector short multiplication, 0 otherwise.
 
 proc check_effective_target_vect_short_mult { } {
-    global et_vect_short_mult_saved
-    global et_index
-
-    if [info exists et_vect_short_mult_saved($et_index)] {
-	verbose "check_effective_target_vect_short_mult: using cached result" 2
-    } else {
-	set et_vect_short_mult_saved($et_index) 0
-	if { [istarget ia64-*-*]
+    return [check_cached_effective_target_indexed vect_short_mult {
+      expr { [istarget ia64-*-*]
 	     || [istarget spu-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget powerpc*-*-*]
@@ -6793,27 +6183,14 @@  proc check_effective_target_vect_short_mult { } {
 		 && ([et-is-effective-target mips_msa]
 		     || [et-is-effective-target mips_loongson]))
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_short_mult_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_short_mult:\
-	     returning $et_vect_short_mult_saved($et_index)" 2
-    return $et_vect_short_mult_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector int multiplication, 0 otherwise.
 
 proc check_effective_target_vect_int_mult { } {
-    global et_vect_int_mult_saved
-    global et_index
-
-    if [info exists et_vect_int_mult_saved($et_index)] {
-	verbose "check_effective_target_vect_int_mult: using cached result" 2
-    } else {
-	set et_vect_int_mult_saved($et_index) 0
-	if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
+    return [check_cached_effective_target_indexed vect_int_mult {
+      expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
 	     || [istarget spu-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget ia64-*-*]
@@ -6822,14 +6199,7 @@  proc check_effective_target_vect_int_mult { } {
 		 && [et-is-effective-target mips_msa])
 	     || [check_effective_target_arm32]
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_vect_int_mult_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_int_mult:\
-	     returning $et_vect_int_mult_saved($et_index)" 2
-    return $et_vect_int_mult_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports 64 bit hardware vector
@@ -6859,15 +6229,8 @@  proc check_effective_target_vect_long_mult { } {
 # Return 1 if the target supports vector even/odd elements extraction, 0 otherwise.
 
 proc check_effective_target_vect_extract_even_odd { } {
-    global et_vect_extract_even_odd_saved
-    global et_index
-    
-    if [info exists et_vect_extract_even_odd_saved($et_index)] {
-	verbose "check_effective_target_vect_extract_even_odd:\
-		 using cached result" 2
-    } else {
-	set et_vect_extract_even_odd_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target_indexed extract_even_odd {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget powerpc*-*-*]
 	     || [is-effective-target arm_neon]
              || [istarget i?86-*-*] || [istarget x86_64-*-*]
@@ -6877,27 +6240,14 @@  proc check_effective_target_vect_extract_even_odd { } {
 		 && ([et-is-effective-target mips_msa]
 		     || [et-is-effective-target mpaired_single]))
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_extract_even_odd_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_extract_even_odd:\
-	     returning $et_vect_extract_even_odd_saved($et_index)" 2
-    return $et_vect_extract_even_odd_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector interleaving, 0 otherwise.
 
 proc check_effective_target_vect_interleave { } {
-    global et_vect_interleave_saved
-    global et_index
-    
-    if [info exists et_vect_interleave_saved($et_index)] {
-        verbose "check_effective_target_vect_interleave: using cached result" 2
-    } else {
-	set et_vect_interleave_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target_indexed vect_interleave {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget powerpc*-*-*]
 	     || [is-effective-target arm_neon]
              || [istarget i?86-*-*] || [istarget x86_64-*-*]
@@ -6907,42 +6257,25 @@  proc check_effective_target_vect_interleave { } {
 		 && ([et-is-effective-target mpaired_single]
 		     || [et-is-effective-target mips_msa]))
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_interleave_saved($et_index) 1
-        }
-    }
-
-    verbose "check_effective_target_vect_interleave:\
-	     returning $et_vect_interleave_saved($et_index)" 2
-    return $et_vect_interleave_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 foreach N {2 3 4 8} {
     eval [string map [list N $N] {
 	# Return 1 if the target supports 2-vector interleaving
 	proc check_effective_target_vect_stridedN { } {
-	    global et_vect_stridedN_saved
-	    global et_index
-
-	    if [info exists et_vect_stridedN_saved($et_index)] {
-		verbose "check_effective_target_vect_stridedN:\
-			 using cached result" 2
-	    } else {
-		set et_vect_stridedN_saved($et_index) 0
+	    return [check_cached_effective_target_indexed vect_stridedN {
 		if { (N & -N) == N
 		     && [check_effective_target_vect_interleave]
 		     && [check_effective_target_vect_extract_even_odd] } {
-		    set et_vect_stridedN_saved($et_index) 1
+		    return 1
 		}
 		if { ([istarget arm*-*-*]
 		      || [istarget aarch64*-*-*]) && N >= 2 && N <= 4 } {
-		    set et_vect_stridedN_saved($et_index) 1
+		    return 1
 		}
-	    }
-
-	    verbose "check_effective_target_vect_stridedN:\
-		     returning $et_vect_stridedN_saved($et_index)" 2
-	    return $et_vect_stridedN_saved($et_index)
+		return 0
+	    }]
 	}
     }]
 }
@@ -6993,71 +6326,33 @@  proc check_effective_target_vect64 { } {
 # Return 1 if the target supports vector copysignf calls.
 
 proc check_effective_target_vect_call_copysignf { } {
-    global et_vect_call_copysignf_saved
-    global et_index
-
-    if [info exists et_vect_call_copysignf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_copysignf:\
-		 using cached result" 2
-    } else {
-	set et_vect_call_copysignf_saved($et_index) 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target_indexed vect_call_copysignf {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget powerpc*-*-*]
-	     || [istarget aarch64*-*-*] } {
-	   set et_vect_call_copysignf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_copysignf:\
-	     returning $et_vect_call_copysignf_saved($et_index)" 2
-    return $et_vect_call_copysignf_saved($et_index)
+	     || [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports hardware square root instructions.
 
 proc check_effective_target_sqrt_insn { } {
-    global et_sqrt_insn_saved
-
-    if [info exists et_sqrt_insn_saved] {
-	verbose "check_effective_target_hw_sqrt: using cached result" 2
-    } else {
-	set et_sqrt_insn_saved 0
-	if { [istarget i?86-*-*] || [istarget x86_64-*-*]
+    return [check_cached_effective_target sqrt_insn {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget powerpc*-*-*]
 	     || [istarget aarch64*-*-*]
 	     || ([istarget arm*-*-*] && [check_effective_target_arm_vfp_ok])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	   set et_sqrt_insn_saved 1
-	}
-    }
-
-    verbose "check_effective_target_hw_sqrt: returning et_sqrt_insn_saved" 2
-    return $et_sqrt_insn_saved
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector sqrtf calls.
 
 proc check_effective_target_vect_call_sqrtf { } {
-    global et_vect_call_sqrtf_saved
-    global et_index
-
-    if [info exists et_vect_call_sqrtf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_sqrtf: using cached result" 2
-    } else {
-	set et_vect_call_sqrtf_saved($et_index) 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target_indexed vect_call_sqrtf {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || ([istarget powerpc*-*-*] && [check_vsx_hw_available])
 	     || ([istarget s390*-*-*]
-		 && [check_effective_target_s390_vx]) } {
-	    set et_vect_call_sqrtf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_sqrtf:\
-	     returning $et_vect_call_sqrtf_saved($et_index)" 2
-    return $et_vect_call_sqrtf_saved($et_index)
+		 && [check_effective_target_s390_vx]) }}]
 }
 
 # Return 1 if the target supports vector lrint calls.
@@ -7076,244 +6371,85 @@  proc check_effective_target_vect_call_lrint { } {
 # Return 1 if the target supports vector btrunc calls.
 
 proc check_effective_target_vect_call_btrunc { } {
-    global et_vect_call_btrunc_saved
-    global et_index
-
-    if [info exists et_vect_call_btrunc_saved($et_index)] {
-	verbose "check_effective_target_vect_call_btrunc:\
-		 using cached result" 2
-    } else {
-	set et_vect_call_btrunc_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_btrunc_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_btrunc:\
-	     returning $et_vect_call_btrunc_saved($et_index)" 2
-    return $et_vect_call_btrunc_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_btrunc {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector btruncf calls.
 
 proc check_effective_target_vect_call_btruncf { } {
-    global et_vect_call_btruncf_saved
-    global et_index
-
-    if [info exists et_vect_call_btruncf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_btruncf:\
-		 using cached result" 2
-    } else {
-	set et_vect_call_btruncf_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_btruncf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_btruncf:\
-	     returning $et_vect_call_btruncf_saved($et_index)" 2
-    return $et_vect_call_btruncf_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_btruncf {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector ceil calls.
 
 proc check_effective_target_vect_call_ceil { } {
-    global et_vect_call_ceil_saved
-    global et_index
-
-    if [info exists et_vect_call_ceil_saved($et_index)] {
-	verbose "check_effective_target_vect_call_ceil: using cached result" 2
-    } else {
-	set et_vect_call_ceil_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_ceil_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_ceil:\
-	     returning $et_vect_call_ceil_saved($et_index)" 2
-    return $et_vect_call_ceil_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_ceil {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector ceilf calls.
 
 proc check_effective_target_vect_call_ceilf { } {
-    global et_vect_call_ceilf_saved
-    global et_index
-
-    if [info exists et_vect_call_ceilf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_ceilf: using cached result" 2
-    } else {
-	set et_vect_call_ceilf_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_ceilf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_ceilf:\
-	     returning $et_vect_call_ceilf_saved($et_index)" 2
-    return $et_vect_call_ceilf_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_ceilf {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector floor calls.
 
 proc check_effective_target_vect_call_floor { } {
-    global et_vect_call_floor_saved
-    global et_index
-
-    if [info exists et_vect_call_floor_saved($et_index)] {
-	verbose "check_effective_target_vect_call_floor: using cached result" 2
-    } else {
-	set et_vect_call_floor_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_floor_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_floor:\
-	     returning $et_vect_call_floor_saved($et_index)" 2
-    return $et_vect_call_floor_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_floor {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector floorf calls.
 
 proc check_effective_target_vect_call_floorf { } {
-    global et_vect_call_floorf_saved
-    global et_index
-
-    if [info exists et_vect_call_floorf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_floorf: using cached result" 2
-    } else {
-	set et_vect_call_floorf_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_floorf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_floorf:\
-	     returning $et_vect_call_floorf_saved($et_index)" 2
-    return $et_vect_call_floorf_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_floorf {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector lceil calls.
 
 proc check_effective_target_vect_call_lceil { } {
-    global et_vect_call_lceil_saved
-    global et_index
-
-    if [info exists et_vect_call_lceil_saved($et_index)] {
-	verbose "check_effective_target_vect_call_lceil: using cached result" 2
-    } else {
-	set et_vect_call_lceil_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_lceil_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_lceil:\
-	     returning $et_vect_call_lceil_saved($et_index)" 2
-    return $et_vect_call_lceil_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_lceil {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector lfloor calls.
 
 proc check_effective_target_vect_call_lfloor { } {
-    global et_vect_call_lfloor_saved
-    global et_index
-
-    if [info exists et_vect_call_lfloor_saved($et_index)] {
-	verbose "check_effective_target_vect_call_lfloor: using cached result" 2
-    } else {
-	set et_vect_call_lfloor_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_lfloor_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_lfloor:\
-	     returning $et_vect_call_lfloor_saved($et_index)" 2
-    return $et_vect_call_lfloor_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_lfloor {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector nearbyint calls.
 
 proc check_effective_target_vect_call_nearbyint { } {
-    global et_vect_call_nearbyint_saved
-    global et_index
-
-    if [info exists et_vect_call_nearbyint_saved($et_index)] {
-	verbose "check_effective_target_vect_call_nearbyint: using cached result" 2
-    } else {
-	set et_vect_call_nearbyint_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_nearbyint_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_nearbyint:\
-	     returning $et_vect_call_nearbyint_saved($et_index)" 2
-    return $et_vect_call_nearbyint_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_nearbyint {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector nearbyintf calls.
 
 proc check_effective_target_vect_call_nearbyintf { } {
-    global et_vect_call_nearbyintf_saved
-    global et_index
-
-    if [info exists et_vect_call_nearbyintf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_nearbyintf:\
-		 using cached result" 2
-    } else {
-	set et_vect_call_nearbyintf_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_nearbyintf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_nearbyintf:\
-	     returning $et_vect_call_nearbyintf_saved($et_index)" 2
-    return $et_vect_call_nearbyintf_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_nearbyintf {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector round calls.
 
 proc check_effective_target_vect_call_round { } {
-    global et_vect_call_round_saved
-    global et_index
-
-    if [info exists et_vect_call_round_saved($et_index)] {
-	verbose "check_effective_target_vect_call_round: using cached result" 2
-    } else {
-	set et_vect_call_round_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_round_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_round:\
-	     returning $et_vect_call_round_saved($et_index)" 2
-    return $et_vect_call_round_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_round {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports vector roundf calls.
 
 proc check_effective_target_vect_call_roundf { } {
-    global et_vect_call_roundf_saved
-    global et_index
-
-    if [info exists et_vect_call_roundf_saved($et_index)] {
-	verbose "check_effective_target_vect_call_roundf: using cached result" 2
-    } else {
-	set et_vect_call_roundf_saved($et_index) 0
-	if { [istarget aarch64*-*-*] } {
-	  set et_vect_call_roundf_saved($et_index) 1
-	}
-    }
-
-    verbose "check_effective_target_vect_call_roundf:\
-	     returning $et_vect_call_roundf_saved($et_index)" 2
-    return $et_vect_call_roundf_saved($et_index)
+    return [check_cached_effective_target_indexed vect_call_roundf {
+      expr { [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports AND, OR and XOR reduction.
@@ -7331,21 +6467,10 @@  proc check_effective_target_vect_fold_extract_last { } {
 # Return 1 if the target supports section-anchors
 
 proc check_effective_target_section_anchors { } {
-    global et_section_anchors_saved
-
-    if [info exists et_section_anchors_saved] {
-        verbose "check_effective_target_section_anchors: using cached result" 2
-    } else {
-        set et_section_anchors_saved 0
-        if { [istarget powerpc*-*-*]
-	      || [istarget arm*-*-*] 
-	      || [istarget aarch64*-*-*] } {
-           set et_section_anchors_saved 1
-        }
-    }
-
-    verbose "check_effective_target_section_anchors: returning $et_section_anchors_saved" 2
-    return $et_section_anchors_saved
+    return [check_cached_effective_target section_anchors {
+      expr { [istarget powerpc*-*-*]
+	     || [istarget arm*-*-*]
+	     || [istarget aarch64*-*-*] }}]
 }
 
 # Return 1 if the target supports atomic operations on "int_128" values.
@@ -7441,13 +6566,8 @@  proc check_effective_target_sync_long_long_runtime { } {
 # Return 1 if the target supports byte swap instructions.
 
 proc check_effective_target_bswap { } {
-    global et_bswap_saved
-
-    if [info exists et_bswap_saved] {
-        verbose "check_effective_target_bswap: using cached result" 2
-    } else {
-	set et_bswap_saved 0
-	if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target bswap {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget alpha*-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget m68k-*-*]
@@ -7460,27 +6580,16 @@  proc check_effective_target_bswap { } {
 		     #error not armv6 or later
 		     #endif
 		     int i;
-		 } ""]) } {
-		set et_bswap_saved 1
-	}
-    }
-
-    verbose "check_effective_target_bswap: returning $et_bswap_saved" 2
-    return $et_bswap_saved
+		 } ""]) }}]
 }
 
 # Return 1 if the target supports atomic operations on "int" and "long".
 
 proc check_effective_target_sync_int_long { } {
-    global et_sync_int_long_saved
-
-    if [info exists et_sync_int_long_saved] {
-        verbose "check_effective_target_sync_int_long: using cached result" 2
-    } else {
-        set et_sync_int_long_saved 0
 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
 # load-reserved/store-conditional instructions.
-        if { [istarget ia64-*-*]
+    return [check_cached_effective_target sync_int_long {
+      expr { [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget aarch64*-*-*]
 	     || [istarget alpha*-*-*] 
@@ -7495,27 +6604,16 @@  proc check_effective_target_sync_int_long { } {
 	     || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
 	     || [istarget spu-*-*]
 	     || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
-	     || [check_effective_target_mips_llsc] } {
-           set et_sync_int_long_saved 1
-        }
-    }
-
-    verbose "check_effective_target_sync_int_long: returning $et_sync_int_long_saved" 2
-    return $et_sync_int_long_saved
+	     || [check_effective_target_mips_llsc] }}]
 }
 
 # Return 1 if the target supports atomic operations on "char" and "short".
 
 proc check_effective_target_sync_char_short { } {
-    global et_sync_char_short_saved
-
-    if [info exists et_sync_char_short_saved] {
-        verbose "check_effective_target_sync_char_short: using cached result" 2
-    } else {
-        set et_sync_char_short_saved 0
 # This is intentionally powerpc but not rs6000, rs6000 doesn't have the
 # load-reserved/store-conditional instructions.
-        if { [istarget aarch64*-*-*]
+    return [check_cached_effective_target sync_char_short {
+      expr { [istarget aarch64*-*-*]
 	     || [istarget ia64-*-*]
 	     || [istarget i?86-*-*] || [istarget x86_64-*-*]
 	     || [istarget alpha*-*-*] 
@@ -7529,13 +6627,7 @@  proc check_effective_target_sync_char_short { } {
 	     || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9])
 	     || [istarget spu-*-*]
 	     || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
-	     || [check_effective_target_mips_llsc] } {
-           set et_sync_char_short_saved 1
-        }
-    }
-
-    verbose "check_effective_target_sync_char_short: returning $et_sync_char_short_saved" 2
-    return $et_sync_char_short_saved
+	     || [check_effective_target_mips_llsc] }}]
 }
 
 # Return 1 if the target uses a ColdFire FPU.
@@ -7687,8 +6779,17 @@  proc is-effective-target { arg } {
 	  default          { error "unknown effective target keyword `$arg'" }
 	}
     }
+
     verbose "is-effective-target: $arg $selected" 2
-    return $selected
+    if {[string is true -strict $selected]
+	|| [string is false -strict $selected]} {
+	set result $selected
+    } else {
+	set result [uplevel eval $selected]
+	verbose "is-effective-target forced eval: $arg $result" 2
+    }
+
+    return $result
 }
 
 # Return 1 if the argument is an effective-target keyword, 0 otherwise.
@@ -8817,23 +7918,17 @@  proc check_effective_target_fenv_exceptions {} {
 }
 
 proc check_effective_target_tiny {} {
-    global et_target_tiny_saved
-
-    if [info exists et_target_tiny_saved] {
-      verbose "check_effective_target_tiny: using cached result" 2
-    } else {
-       set et_target_tiny_saved 0
-       if { [istarget aarch64*-*-*]
-             && [check_effective_target_aarch64_tiny] } {
-         set et_target_tiny_saved 1
-       }
-       if { [istarget avr-*-*]
-             && [check_effective_target_avr_tiny] } {
-         set et_target_tiny_saved 1
-       }
-    }
-
-    return $et_target_tiny_saved
+    return [check_cached_effective_target tiny {
+	    if { [istarget aarch64*-*-*]
+		 && [check_effective_target_aarch64_tiny] } {
+	      return 1
+	    }
+	    if { [istarget avr-*-*]
+		 && [check_effective_target_avr_tiny] } {
+	      return 1
+	    }
+	    return 0
+    }]
 }
 
 # Return 1 if LOGICAL_OP_NON_SHORT_CIRCUIT is set to 0 for the current target.
@@ -8911,7 +8006,6 @@  proc scan-ltrans-tree-dump-dem-not_required_options {} {
 # otherwise.  Cache the result.
 
 proc check_effective_target_pie_copyreloc { } {
-    global pie_copyreloc_available_saved
     global tool
     global GCC_UNDER_TEST
 
@@ -8924,9 +8018,7 @@  proc check_effective_target_pie_copyreloc { } {
 	return 0
     }
 
-    if [info exists pie_copyreloc_available_saved] {
-	verbose "check_effective_target_pie_copyreloc returning saved $pie_copyreloc_available_saved" 2
-    } else {
+    return [check_cached_effective_target pie_copyreloc {
 	# Set up and compile to see if linker supports PIE with copy
 	# reloc.  Include the current process ID in the file names to
 	# prevent conflicts with invocations for multiple testsuites.
@@ -8949,21 +8041,18 @@  proc check_effective_target_pie_copyreloc { } {
 
 	if [string match "" $lines] then {
 	    verbose "check_effective_target_pie_copyreloc testfile compilation passed" 2
-	    set pie_copyreloc_available_saved 1
+	    return 1
 	} else {
 	    verbose "check_effective_target_pie_copyreloc testfile compilation failed" 2
-	    set pie_copyreloc_available_saved 0
+	    return 0
 	}
-    }
-
-    return $pie_copyreloc_available_saved
+    }]
 }
 
 # Return 1 if the x86 target supports R_386_GOT32X relocation, 0
 # otherwise.  Cache the result.
 
 proc check_effective_target_got32x_reloc { } {
-    global got32x_reloc_available_saved
     global tool
     global GCC_UNDER_TEST
 
@@ -8976,9 +8065,7 @@  proc check_effective_target_got32x_reloc { } {
 	return 0
     }
 
-    if [info exists got32x_reloc_available_saved] {
-	verbose "check_effective_target_got32x_reloc returning saved $got32x_reloc_available_saved" 2
-    } else {
+    return [check_cached_effective_target got32x_reloc {
 	# Include the current process ID in the file names to prevent
 	# conflicts with invocations for multiple testsuites.
 
@@ -9000,12 +8087,12 @@  proc check_effective_target_got32x_reloc { } {
 
 	if [string match "" $lines] then {
 	    verbose "check_effective_target_got32x_reloc testfile compilation passed" 2
-	    set got32x_reloc_available_saved 1
+	    return 1
 	} else {
 	    verbose "check_effective_target_got32x_reloc testfile compilation failed" 2
-	    set got32x_reloc_available_saved 0
+	    return 0
 	}
-    }
+    }]
 
     return $got32x_reloc_available_saved
 }
@@ -9014,7 +8101,6 @@  proc check_effective_target_got32x_reloc { } {
 # 0 otherwise.  Cache the result.
 
 proc check_effective_target_tls_get_addr_via_got { } {
-    global tls_get_addr_via_got_available_saved
     global tool
     global GCC_UNDER_TEST
 
@@ -9027,9 +8113,7 @@  proc check_effective_target_tls_get_addr_via_got { } {
 	return 0
     }
 
-    if [info exists tls_get_addr_via_got_available_saved] {
-	verbose "check_effective_target_tls_get_addr_via_got returning saved $tls_get_addr_via_got_available_saved" 2
-    } else {
+    return [check_cached_effective_target tls_get_addr_via_got {
 	# Include the current process ID in the file names to prevent
 	# conflicts with invocations for multiple testsuites.
 
@@ -9051,14 +8135,12 @@  proc check_effective_target_tls_get_addr_via_got { } {
 
 	if [string match "" $lines] then {
 	    verbose "check_effective_target_tls_get_addr_via_got testfile compilation passed" 2
-	    set tls_get_addr_via_got_available_saved 1
+	    return 1
 	} else {
 	    verbose "check_effective_target_tls_get_addr_via_got testfile compilation failed" 2
-	    set tls_get_addr_via_got_available_saved 0
+	    return 0
 	}
-    }
-
-    return $tls_get_addr_via_got_available_saved
+    }]
 }
 
 # Return 1 if the target uses comdat groups.