diff mbox series

[libstdc++.exp] Update the usage of cached result, rebuild nlocale wrapper for each variant.

Message ID 3782a899-c556-b090-af4d-6f472d45decd@foss.arm.com
State New
Headers show
Series [libstdc++.exp] Update the usage of cached result, rebuild nlocale wrapper for each variant. | expand

Commit Message

Renlin Li Nov. 16, 2018, 10:42 a.m. UTC
Hi all,

Tejas noticed that libstdc++.exp currently builds nlocale driver (libstc++.exp:check_v3_target_namedlocale())
once for a test run. This is done irrespective of the number of variants in the site.exp file.
For eg. if we have more than one variant for different target profiles i.e.

     <board>/-mthumb/-march=armv8-a/-mfpu=crypto-neon-fp-armv8/-mfloat-abi=hard
     <board>/-mthumb/-mcpu=cortex-m0

nlocale<id>.cpp is built once and is reused for all the variants.
This is incorrect as the same binary may not work on all target profiles - eg. nlocale<id>.x built for arm A-profile
may not work on M-profile targets. nlocale<id> needs to be rebuilt for each variant in site.exp. This patch fixes that.

Meanwhile, it updates all the usage of cached value with the new method.
This is similar to the recent change in gcc/testsuite/lib/target-support.exp
A global dictionary is used to store a property for a particular target, instead of the target check and update approach.
This factors the common code out of each procedure, reduce the length of libstdc++.exp file.


Tested on arm-none-eabi with the following variants in site.exp:

     <board>/-marm/-march=armv7-a/-mfpu=vfpv3-d16/-mfloat-abi=softfp
     <board>/-mthumb/-march=armv8-a/-mfpu=crypto-neon-fp-armv8/-mfloat-abi=hard
     <board>/-mthumb/-mcpu=cortex-m0
     <board>/-mthumb/-mcpu=cortex-m3
     <board>/-mthumb/-mcpu=cortex-m4
     <board>/-mthumb/-mcpu=cortex-m7
     <board>/-mthumb/-mcpu=cortex-m23
     <board>/-mthumb/-march=armv8-m.main


Tested on native x86_64,

    make check-target-libstdc++-v3

with default unix variant. There is no change on the result.


Okay to commit?

Regards,
Renlin


gcc/libstdc++-v3/:
2018-11-16  Renlin Li  <renlin.li@arm.com>
	    Tejas Belagod  <tejas.belagod@arm.com>

         testsuite/lib/libstdc++.exp (check_v3_target_prop_cached): New proc.
         (check_v3_target): Use the check_v3_target_prop_cached.

Comments

Jonathan Wakely Nov. 16, 2018, 1:20 p.m. UTC | #1
On 16/11/18 10:42 +0000, Renlin Li wrote:
>Hi all,

Please remember that all patches for libstdc++ must be sent to the
libstdc++ list, as documented at https://gcc.gnu.org/lists.html
Just CCing me is not enough.

>Tejas noticed that libstdc++.exp currently builds nlocale driver (libstc++.exp:check_v3_target_namedlocale())
>once for a test run. This is done irrespective of the number of variants in the site.exp file.
>For eg. if we have more than one variant for different target profiles i.e.
>
>    <board>/-mthumb/-march=armv8-a/-mfpu=crypto-neon-fp-armv8/-mfloat-abi=hard
>    <board>/-mthumb/-mcpu=cortex-m0
>
>nlocale<id>.cpp is built once and is reused for all the variants.
>This is incorrect as the same binary may not work on all target profiles - eg. nlocale<id>.x built for arm A-profile
>may not work on M-profile targets. nlocale<id> needs to be rebuilt for each variant in site.exp. This patch fixes that.
>
>Meanwhile, it updates all the usage of cached value with the new method.
>This is similar to the recent change in gcc/testsuite/lib/target-support.exp
>A global dictionary is used to store a property for a particular target, instead of the target check and update approach.
>This factors the common code out of each procedure, reduce the length of libstdc++.exp file.

This is great, thanks!

>Tested on arm-none-eabi with the following variants in site.exp:
>
>    <board>/-marm/-march=armv7-a/-mfpu=vfpv3-d16/-mfloat-abi=softfp
>    <board>/-mthumb/-march=armv8-a/-mfpu=crypto-neon-fp-armv8/-mfloat-abi=hard
>    <board>/-mthumb/-mcpu=cortex-m0
>    <board>/-mthumb/-mcpu=cortex-m3
>    <board>/-mthumb/-mcpu=cortex-m4
>    <board>/-mthumb/-mcpu=cortex-m7
>    <board>/-mthumb/-mcpu=cortex-m23
>    <board>/-mthumb/-march=armv8-m.main
>
>
>Tested on native x86_64,
>
>   make check-target-libstdc++-v3
>
>with default unix variant. There is no change on the result.
>
>
>Okay to commit?

OK, thanks.
Renlin Li Nov. 16, 2018, 2:37 p.m. UTC | #2
On 11/16/2018 01:20 PM, Jonathan Wakely wrote:
> On 16/11/18 10:42 +0000, Renlin Li wrote:
>> Hi all,
> 
> Please remember that all patches for libstdc++ must be sent to the
> libstdc++ list, as documented at https://gcc.gnu.org/lists.html
> Just CCing me is not enough.

Hi Jonathan,

I knew I missed something!
Thanks, committed.

Regards,
Renlin
Jonathan Wakely March 11, 2019, 11:54 a.m. UTC | #3
Hi, I've just noticed this in your r266209 change from November:

On 16/11/18 10:42 +0000, Renlin Li wrote:
>+    return [check_v3_target_prop_cached et_parallel_mode {
>+	global cxxflags
>+	global v3-libgomp
> 	# If 'make check-parallel' is running the test succeeds.
> 	if { ${v3-libgomp} == 1 && [regexp "libgomp" $cxxflags] } {
>-	    set et_parallel_mode 1
>+	    return1 1

Is this a typo? It should be "return 1" not "return1 1" right?
Jonathan Wakely April 10, 2019, 2:46 p.m. UTC | #4
On 11/03/19 11:54 +0000, Jonathan Wakely wrote:
>Hi, I've just noticed this in your r266209 change from November:
>
>On 16/11/18 10:42 +0000, Renlin Li wrote:
>>+    return [check_v3_target_prop_cached et_parallel_mode {
>>+	global cxxflags
>>+	global v3-libgomp
>>	# If 'make check-parallel' is running the test succeeds.
>>	if { ${v3-libgomp} == 1 && [regexp "libgomp" $cxxflags] } {
>>-	    set et_parallel_mode 1
>>+	    return1 1
>
>Is this a typo? It should be "return 1" not "return1 1" right?


I've committed this fix to trunk.
commit 116f85727b49103ff3c8d4fb152c7a6047eb3546
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Apr 10 15:44:35 2019 +0100

    Fix typo in effective-target check
    
            * testsuite/lib/libstdc++.exp (check_v3_target_parallel_mode): Fix
            typo.

diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 5a12ac0242d..d0efc90a1ba 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -1048,7 +1048,7 @@ proc check_v3_target_parallel_mode { } {
 	global v3-libgomp
 	# If 'make check-parallel' is running the test succeeds.
 	if { ${v3-libgomp} == 1 && [regexp "libgomp" $cxxflags] } {
-	    return1 1
+	    return 1
 	}
 	return 0
     }]
diff mbox series

Patch

diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 79d8e0130dcefdd8ccb67ad45f81ff12a3703600..7047b8f7b2233911445abaed54337bc46b37b7e5 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -688,31 +688,38 @@  proc v3-build_support { } {
     }
 }
 
-proc check_v3_target_fileio { } {
-    global et_fileio_saved
-    global et_fileio_target_name
-    global tool
-    global srcdir
+# Implement an target check for property PROP by invoking
+# the Tcl command ARGS and seeing if it returns true.
 
-    if { ![info exists et_fileio_target_name] } {
-	set et_fileio_target_name ""
-    }
+proc check_v3_target_prop_cached { prop args } {
+    global et_cache
 
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_fileio_target_name } {
-	verbose "check_v3_target_fileio: `$et_fileio_target_name'" 2
-	set et_fileio_target_name $current_target
-	if [info exists et_fileio_saved] {
-	    verbose "check_v3_target_fileio: removing cached result" 2
-	    unset et_fileio_saved
+    set target [current_target_name]
+    if {![info exists et_cache($prop,$target)]} {
+	verbose "check_v3_target_prop_cached $prop: checking $target" 2
+	if {[string is true -strict $args] || [string is false -strict $args]} {
+	    error {check_v3_target_prop_cached condition already evaluated; did you pass [...] instead of the expected {...}?}
+	} else {
+	    set code [catch {uplevel eval $args} result]
+	    if {$code != 0 && $code != 2} {
+		verbose "check_v3_target_prop_cached $prop: evaluation failed for $target" 2
+		return -code $code $result
+	    }
+	    set et_cache($prop,$target) $result
 	}
+    } else {
+	verbose "check_v3_target_prop_cached $prop $target: using cached result" 2
     }
 
-    if [info exists et_fileio_saved] {
-	verbose "check_v3_target_fileio: using cached result" 2
-    } else {
-	set et_fileio_saved 0
+    set value $et_cache($prop,$target)
+    verbose "check_v3_target_prop_cached $prop: returning $value for $target" 2
+    return $value
+}
+
+proc check_v3_target_fileio { } {
+    return [check_v3_target_prop_cached et_fileio {
+	global tool
+	global srcdir
 
 	# Set up, compile, and execute a C++ test program that tries to use
 	# the file functions
@@ -766,41 +773,19 @@  proc check_v3_target_fileio { } {
 	    verbose "check_v3_target_fileio: status is <$status>" 2
 
 	    if { $status == "pass" } {
-		set et_fileio_saved 1
+		return 1
 	    }
 	} else {
 	    verbose "check_v3_target_fileio: compilation failed" 2
 	}
-    }
-    return $et_fileio_saved
+	return 0
+    }]
 }
 
 # Eventually we want C90/C99 determining and switching from this.
 proc check_v3_target_c_std { } {
-    global et_c_std_saved
-    global et_c_std_target_name
-    global tool
-
-    if { ![info exists et_c_std_target_name] } {
-	set et_c_std_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_c_std_target_name } {
-	verbose "check_v3_target_c_std: `$et_c_std_target_name'" 2
-	set et_c_std_target_name $current_target
-	if [info exists et_c_std_saved] {
-	    verbose "check_v3_target_c_std: removing cached result" 2
-	    unset et_c_std_saved
-	}
-    }
-
-    if [info exists et_c_std_saved] {
-	verbose "check_v3_target_c_std: using cached result" 2
-    } else {
-	set et_c_std_saved 0
-
+    return [check_v3_target_prop_cached et_c_std {
+	global tool
 	# Set up, compile, and execute a C++ test program that tries to use
 	# C99 functionality.
 	# For math bits, could use check_effective_target_c99_math.
@@ -832,13 +817,13 @@  proc check_v3_target_c_std { } {
 	    verbose "check_v3_target_c_std: status is <$status>" 2
 
 	    if { $status == "pass" } {
-		set et_c_std_saved 1
+		return 1
 	    }
 	} else {
 	    verbose "check_v3_target_c_std: compilation failed" 2
 	}
-    }
-    return $et_c_std_saved
+	return 0
+    }]
 }
 
 proc check_v3_target_sharedlib { } {
@@ -847,30 +832,8 @@  proc check_v3_target_sharedlib { } {
 }
 
 proc check_v3_target_time { } {
-    global et_time_saved
-    global et_time_target_name
-    global tool
-
-    if { ![info exists et_time_target_name] } {
-	set et_time_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_time_target_name } {
-	verbose "check_v3_target_time: `$et_time_target_name'" 2
-	set et_time_target_name $current_target
-	if [info exists et_time_saved] {
-	    verbose "check_v3_target_time: removing cached result" 2
-	    unset et_time_saved
-	}
-    }
-
-    if [info exists et_time_saved] {
-	verbose "check_v3_target_time: using cached result" 2
-    } else {
-	set et_time_saved 0
-
+    return [check_v3_target_prop_cached et_target_time {
+	global tool
 	# Set up and compile a C++ test program that tries to use
 	# the time function
 	set src time[pid].cc
@@ -890,113 +853,87 @@  proc check_v3_target_time { } {
 	if [string match "" $lines] {
 	    # No error message, compilation succeeded.
 	    verbose "check_v3_target_time: compilation succeeded" 2
-	    set et_time_saved 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_time: compilation failed" 2
+	    return 0
 	}
-    }
-    return $et_time_saved
+    }]
 }
 
 proc check_v3_target_namedlocale { args } {
-    global et_namedlocale
-    global tool
-
-    set et_namedlocale 0
-
-    # Set up, compile, and execute a C++ test program that tries to use
-    # the required named locale.
-    set exe nlocale[pid].x
-
-    if ![file exists ./$exe] {
-      set src nlocale[pid].cc
-
-      set f [open $src "w"]
-      puts $f "#include <locale>"
-      puts $f "#include <cstdio>"
-      puts $f "#include <cstring>"
-      puts $f "using namespace std;"
-      puts $f "char *transform_locale(const char *name)"
-      puts $f "{"
-      puts $f "    char *result = new char\[50\];"
-      puts $f "    strcpy(result, name);"
-      puts $f "#if defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__"
-      puts $f "    /* fall-through */"
-      puts $f "#else"
-      puts $f "    if (strstr(result, \"ISO8859-15\")) {"
-      puts $f "        strcat(result, \"@euro\");"
-      puts $f "    }"
-      puts $f "#endif"
-      puts $f "    return result;"
-      puts $f "}"
-      puts $f "int main (int argc, char** argv)"
-      puts $f "{"
-      puts $f "  if (argc < 2)"
-      puts $f "  {"
-      puts $f "    printf(\"locale support test not supported\\n\");"
-      puts $f "    return 1;"
-      puts $f "  }"
-      puts $f "  const char *namedloc = transform_locale(*(argv + 1));"
-      puts $f "  try"
-      puts $f "  {"
-      puts $f "    locale((const char*)namedloc);"
-      puts $f "    delete\[\] namedloc;"
-      puts $f "    return 0;"
-      puts $f "  }"
-      puts $f "  catch(...)"
-      puts $f "  {"
-      puts $f "    printf(\"locale '%s' not supported\\n\", namedloc);"
-      puts $f "    delete\[\] namedloc;"
-      puts $f "    return 1;"
-      puts $f "  }"
-      puts $f "}"
-      close $f
-
-      set lines [v3_target_compile $src $exe executable ""]
-      file delete $src
-
-      if ![string match "" $lines] {
-	verbose "check_v3_target_namedlocale: compilation failed" 2
-	return $et_namedlocale
-      }
-      # else No error message, compilation succeeded.
-    }
-
-    set result [${tool}_load "./$exe" "$args" ""]
-    set status [lindex $result 0]
+    set key "et_namedlocale $args"
+    return [check_v3_target_prop_cached $key {
+	global tool
+	# Set up, compile, and execute a C++ test program that tries to use
+	# the required named locale.
+	set exe nlocale[pid].x
+	set src nlocale[pid].cc
 
-    verbose "check_v3_target_namedlocale <$args>: status is <$status>" 2
+	set f [open $src "w"]
+	puts $f "#include <locale>"
+	puts $f "#include <cstdio>"
+	puts $f "#include <cstring>"
+	puts $f "using namespace std;"
+	puts $f "char *transform_locale(const char *name)"
+	puts $f "{"
+	puts $f "    char *result = new char\[50\];"
+	puts $f "    strcpy(result, name);"
+	puts $f "#if defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__"
+	puts $f "    /* fall-through */"
+	puts $f "#else"
+	puts $f "    if (strstr(result, \"ISO8859-15\")) {"
+	puts $f "        strcat(result, \"@euro\");"
+	puts $f "    }"
+	puts $f "#endif"
+	puts $f "    return result;"
+	puts $f "}"
+	puts $f "int main (int argc, char** argv)"
+	puts $f "{"
+	puts $f "  if (argc < 2)"
+	puts $f "  {"
+	puts $f "    printf(\"locale support test not supported\\n\");"
+	puts $f "    return 1;"
+	puts $f "  }"
+	puts $f "  const char *namedloc = transform_locale(*(argv + 1));"
+	puts $f "  try"
+	puts $f "  {"
+	puts $f "    locale((const char*)namedloc);"
+	puts $f "    delete\[\] namedloc;"
+	puts $f "    return 0;"
+	puts $f "  }"
+	puts $f "  catch(...)"
+	puts $f "  {"
+	puts $f "    printf(\"locale '%s' not supported\\n\", namedloc);"
+	puts $f "    delete\[\] namedloc;"
+	puts $f "    return 1;"
+	puts $f "  }"
+	puts $f "}"
+	close $f
 
-    if { $status == "pass" } {
-      set et_namedlocale 1
-    }
-    return $et_namedlocale
-}
+	set lines [v3_target_compile $src $exe executable ""]
+	file delete $src
 
-proc check_v3_target_debug_mode { } {
-    global et_debug_mode
-    global tool
+	if ![string match "" $lines] {
+	  verbose "check_v3_target_namedlocale: compilation failed" 2
+	  return 0
+	}
 
-    if { ![info exists et_debug_mode_target_name] } {
-	set et_debug_mode_target_name ""
-    }
+	set result [${tool}_load "./$exe" "$args" ""]
+	set status [lindex $result 0]
 
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_debug_mode_target_name } {
-	verbose "check_v3_target_debug_mode: `$et_debug_mode_target_name'" 2
-	set et_debug_mode_target_name $current_target
-	if [info exists et_debug_mode] {
-	    verbose "check_v3_target_debug_mode: removing cached result" 2
-	    unset et_debug_mode
-	}
-    }
+	verbose "check_v3_target_namedlocale <$args>: status is <$status>" 2
 
-    if [info exists et_debug_mode] {
-	verbose "check_v3_target_debug_mode: using cached result" 2
-    } else {
-	set et_debug_mode 0
+	if { $status == "pass" } {
+	    return 1
+	  }
+	return 0
+    }]
+}
 
+proc check_v3_target_debug_mode { } {
+    return [check_v3_target_prop_cached et_debug_mode {
+	global tool
 	# Set up and preprocess a C++ test program that depends
 	# on debug mode activated.
 	set src debug_mode[pid].cc
@@ -1012,37 +949,15 @@  proc check_v3_target_debug_mode { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_debug_mode 1
+	    return 1
 	}
-    }
-    verbose "check_v3_target_debug_mode: $et_debug_mode" 2
-    return $et_debug_mode
+	return 0
+    }]
 }
 
 proc check_v3_target_profile_mode { } {
-    global et_profile_mode
-    global tool	
-
-    if { ![info exists et_profile_mode_target_name] } {
-	set et_profile_mode_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_profile_mode_target_name } {
-	verbose "check_v3_target_profile_mode: `$et_profile_mode_target_name'" 2
-	set et_profile_mode_target_name $current_target
-	if [info exists et_profile_mode] {
-	    verbose "check_v3_target_profile_mode: removing cached result" 2
-	    unset et_profile_mode
-	}
-    }
-
-    if [info exists et_profile_mode] {
-	verbose "check_v3_target_profile_mode: using cached result" 2
-    } else {
-	set et_profile_mode 0
-
+    return [check_v3_target_prop_cached et_profile_mode {
+	global tool
 	# Set up and preprocess a C++ test program that depends
 	# on profile mode activated.
 	set src profile_mode[pid].cc
@@ -1058,37 +973,15 @@  proc check_v3_target_profile_mode { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_profile_mode 1
+	    return 1
 	}
-    }
-    verbose "check_v3_target_profile_mode: $et_profile_mode" 2
-    return $et_profile_mode
+	return 0
+    }]
 }
 
 proc check_v3_target_normal_mode { } {
-    global et_normal_mode
-    global tool
-
-    if { ![info exists et_normal_mode_target_name] } {
-	set et_normal_mode_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_normal_mode_target_name } {
-	verbose "check_v3_target_normal_mode: `$et_normal_mode_target_name'" 2
-	set et_normal_mode_target_name $current_target
-	if [info exists et_normal_mode] {
-	    verbose "check_v3_target_normal_mode: removing cached result" 2
-	    unset et_normal_mode
-	}
-    }
-
-    if [info exists et_normal_mode] {
-	verbose "check_v3_target_normal_mode: using cached result" 2
-    } else {
-	set et_normal_mode 0
-
+    return [check_v3_target_prop_cached et_normal_mode {
+	global tool
 	# Set up and compile a C++ test program that depends
 	# on normal mode activated.
 	set src normal_mode[pid].cc
@@ -1107,37 +1000,15 @@  proc check_v3_target_normal_mode { } {
 
 	if [string match "" $lines] {
 	    # No error message, compilation succeeded.
-	    set et_normal_mode 1
+	    return 1
 	}
-    }
-    verbose "check_v3_target_normal_mode: $et_normal_mode" 2
-    return $et_normal_mode
+	return 0
+    }]
 }
 
 proc check_v3_target_normal_namespace { } {
-    global et_normal_namespace
-    global tool
-
-    if { ![info exists et_normal_namespace_target_name] } {
-	set et_normal_namespace_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_normal_namespace_target_name } {
-	verbose "check_v3_target_normal_namespace: `$et_normal_namespace_target_name'" 2
-	set et_normal_namespace_target_name $current_target
-	if [info exists et_normal_namespace] {
-	    verbose "check_v3_target_normal_namespace: removing cached result" 2
-	    unset et_normal_namespace
-	}
-    }
-
-    if [info exists et_normal_namespace] {
-	verbose "check_v3_target_normal_namespace: using cached result" 2
-    } else {
-	set et_normal_namespace 0
-
+    return [check_v3_target_prop_cached et_normal_namespace {
+	global tool
 	# Set up and compile a C++ test program that depends
 	# on normal std namespace.
 	set src normal_namespace[pid].cc
@@ -1154,76 +1025,28 @@  proc check_v3_target_normal_namespace { } {
 
 	if [string match "" $lines] {
 	    # No error message, compilation succeeded.
-	    set et_normal_namespace 1
+	    return 1
 	}
-    }
-    verbose "check_v3_target_normal_namespace: $et_normal_namespace" 2
-    return $et_normal_namespace
+	return 0
+    }]
 }
 
 proc check_v3_target_parallel_mode { } {
-    global cxxflags
-    global v3-libgomp
-    global et_parallel_mode
-
-    global tool
-
-    if { ![info exists et_parallel_mode_target_name] } {
-	set et_parallel_mode_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_parallel_mode_target_name } {
-	verbose "check_v3_target_parallel_mode: `$et_parallel_mode_target_name'" 2
-	set et_parallel_mode_target_name $current_target
-	if [info exists et_parallel_mode] {
-	    verbose "check_v3_target_parallel_mode: removing cached result" 2
-	    unset et_parallel_mode
-	}
-    }
-
-    if [info exists et_parallel_mode] {
-	verbose "check_v3_target_parallel_mode: using cached result" 2
-    } else {
-	set et_parallel_mode 0
-
+    return [check_v3_target_prop_cached et_parallel_mode {
+	global cxxflags
+	global v3-libgomp
 	# If 'make check-parallel' is running the test succeeds.
 	if { ${v3-libgomp} == 1 && [regexp "libgomp" $cxxflags] } {
-	    set et_parallel_mode 1
+	    return1 1
 	}
-    }
-    verbose "check_v3_target_parallel_mode: $et_parallel_mode" 2
-    return $et_parallel_mode
+	return 0
+    }]
 }
 
 proc check_v3_target_cstdint { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_cstdint
-
-    global tool
-
-    if { ![info exists et_cstdint_target_name] } {
-	set et_cstdint_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_cstdint_target_name } {
-	verbose "check_v3_target_cstdint: `$et_cstdint_target_name'" 2
-	set et_cstdint_target_name $current_target
-	if [info exists et_cstdint] {
-	    verbose "check_v3_target_cstdint: removing cached result" 2
-	    unset et_cstdint
-	}
-    }
-
-    if [info exists et_cstdint] {
-	verbose "check_v3_target_cstdint: using cached result" 2
-    } else {
-	set et_cstdint 0
-
+    return [check_v3_target_prop_cached et_cstdint {
+	global DEFAULT_CXXFLAGS
+	global cxxflags
 	# Set up and preprocess a C++0x test program that depends
 	# on the C99 stdint facilities to be available.
 	set src cstdint[pid].cc
@@ -1244,42 +1067,18 @@  proc check_v3_target_cstdint { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocess succeeded.
-	    set et_cstdint 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_cstdint: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_cstdint: $et_cstdint" 2
-    return $et_cstdint
+    }]
 }
 
 proc check_v3_target_cmath { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_c99_math
-
-    global tool
-
-    if { ![info exists et_c99_math_target_name] } {
-	set et_c99_math_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_c99_math_target_name } {
-	verbose "check_v3_target_c99_math: `$et_c99_math_target_name'" 2
-	set et_c99_math_target_name $current_target
-	if [info exists et_c99_math] {
-	    verbose "check_v3_target_c99_math: removing cached result" 2
-	    unset et_c99_math
-	}
-    }
-
-    if [info exists et_c99_math] {
-	verbose "check_v3_target_c99_math: using cached result" 2
-    } else {
-	set et_c99_math 0
-
+    return [check_v3_target_prop_cached et_c99_math {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 	# Set up and preprocess a C++0x test program that depends
 	# on the C99 math facilities to be available.
 	set src c99_math[pid].cc
@@ -1300,41 +1099,18 @@  proc check_v3_target_cmath { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocess succeeded.
-	    set et_c99_math 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_c99_math: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_c99_math: $et_c99_math" 2
-    return $et_c99_math
+    }]
 }
 
 proc check_v3_target_thread_fence { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_thread_fence
-
-    global tool
-
-    if { ![info exists et_thread_fence_target_name] } {
-	set et_thread_fence_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_thread_fence_target_name } {
-	verbose "check_v3_target_thread_fence: `$et_thread_fence_target_name'" 2
-	set et_thread_fence_target_name $current_target
-	if [info exists et_thread_fence] {
-	    verbose "check_v3_target_thread_fence: removing cached result" 2
-	    unset et_thread_fence
-	}
-    }
-
-    if [info exists et_thread_fence] {
-	verbose "check_v3_target_thread_fence: using cached result" 2
-    } else {
-	set et_thread_fence 0
+    return [check_v3_target_prop_cached et_thread_fence {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 
 	# Set up and preprocess a C++11 test program that depends
 	# on the thread fence to be available.
@@ -1356,41 +1132,18 @@  proc check_v3_target_thread_fence { } {
 
 	if [string match "" $lines] {
 	    # No error message, linking succeeded.
-	    set et_thread_fence 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_thread_fence: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_thread_fence: $et_thread_fence" 2
-    return $et_thread_fence
+    }]
 }
 
 proc check_v3_target_atomic_builtins { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_atomic_builtins
-
-    global tool
-
-    if { ![info exists et_atomic_builtins_target_name] } {
-	set et_atomic_builtins_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_atomic_builtins_target_name } {
-	verbose "check_v3_target_atomic_builtins: `$et_atomic_builtins_target_name'" 2
-	set et_atomic_builtins_target_name $current_target
-	if [info exists et_atomic_builtins] {
-	    verbose "check_v3_target_atomic_builtins: removing cached result" 2
-	    unset et_atomic_builtins
-	}
-    }
-
-    if [info exists et_atomic_builtins] {
-	verbose "check_v3_target_atomic_builtins: using cached result" 2
-    } else {
-	set et_atomic_builtins 0
+    return [check_v3_target_prop_cached et_atomic_builtins {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 
 	# Set up and preprocess a C++11 test program that depends
 	# on the atomic builtin facilities to be available.
@@ -1414,41 +1167,18 @@  proc check_v3_target_atomic_builtins { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocess succeeded.
-	    set et_atomic_builtins 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_atomic_builtins: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_atomic_builtins: $et_atomic_builtins" 2
-    return $et_atomic_builtins
+    }]
 }
 
 proc check_v3_target_gthreads { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_gthreads
-
-    global tool
-
-    if { ![info exists et_gthreads_target_name] } {
-	set et_gthreads_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_gthreads_target_name } {
-	verbose "check_v3_target_gthreads: `$et_gthreads_target_name'" 2
-	set et_gthreads_target_name $current_target
-	if [info exists et_gthreads] {
-	    verbose "check_v3_target_gthreads: removing cached result" 2
-	    unset et_gthreads
-	}
-    }
-
-    if [info exists et_gthreads] {
-	verbose "check_v3_target_gthreads: using cached result" 2
-    } else {
-	set et_gthreads 0
+    return [check_v3_target_prop_cached et_gthreads {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 
 	# Set up and preprocess a C++0x test program that depends
 	# on the gthreads facilities to be available.
@@ -1470,42 +1200,18 @@  proc check_v3_target_gthreads { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_gthreads 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_gthreads: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_gthreads: $et_gthreads" 2
-    return $et_gthreads
+    }]
 }
 
 proc check_v3_target_gthreads_timed { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_gthreads_timed
-
-    global tool
-
-    if { ![info exists et_gthreads_timed_target_name] } {
-	set et_gthreads_timed_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_gthreads_timed_target_name } {
-	verbose "check_v3_target_gthreads_timed: `$et_gthreads_timed_target_name'" 2
-	set et_gthreads_timed_target_name $current_target
-	if [info exists et_gthreads_timed] {
-	    verbose "check_v3_target_gthreads_timed: removing cached result" 2
-	    unset et_gthreads_timed
-	}
-    }
-
-    if [info exists et_gthreads_timed] {
-	verbose "check_v3_target_gthreads_timed: using cached result" 2
-    } else {
-	set et_gthreads_timed 0
-
+    return [check_v3_target_prop_cached et_gthreads_timed {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 	# Set up and preprocess a C++0x test program that depends
 	# on the gthreads timed mutex facilities to be available.
 	set src gthreads_timed[pid].cc
@@ -1529,43 +1235,18 @@  proc check_v3_target_gthreads_timed { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_gthreads_timed 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_gthreads_timed: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_gthreads_timed: $et_gthreads_timed" 2
-    return $et_gthreads_timed
+    }]
 }
 
-
 proc check_v3_target_sleep { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_sleep
-
-    global tool
-
-    if { ![info exists et_sleep_target_name] } {
-	set et_sleep_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_sleep_target_name } {
-	verbose "check_v3_target_sleep: `$et_sleep_target_name'" 2
-	set et_sleep_target_name $current_target
-	if [info exists et_sleep] {
-	    verbose "check_v3_target_sleep: removing cached result" 2
-	    unset et_sleep
-	}
-    }
-
-    if [info exists et_sleep] {
-	verbose "check_v3_target_sleep: using cached result" 2
-    } else {
-	set et_sleep 0
-	
+    return [check_v3_target_prop_cached et_sleep {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 	# Set up and preprocess a C++11 test program that depends
 	# on the sleep facilities to be available.
 	set src sleep[pid].cc
@@ -1588,41 +1269,18 @@  proc check_v3_target_sleep { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_sleep 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_sleep: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_sleep: $et_sleep" 2
-    return $et_sleep
+    }]
 }
 
 proc check_v3_target_sched_yield { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_sched_yield
-
-    global tool
-
-    if { ![info exists et_sched_yield_target_name] } {
-	set et_sched_yield_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_sched_yield_target_name } {
-	verbose "check_v3_target_sched_yield: `$et_sched_yield_target_name'" 2
-	set et_sched_yield_target_name $current_target
-	if [info exists et_sched_yield] {
-	    verbose "check_v3_target_sched_yield: removing cached result" 2
-	    unset et_sched_yield
-	}
-    }
-
-    if [info exists et_sched_yield] {
-	verbose "check_v3_target_sched_yield: using cached result" 2
-    } else {
-	set et_sched_yield 0
+    return [check_v3_target_prop_cached et_sched_yield {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 
 	# Set up and preprocess a C++0x test program that depends
 	# on the sched_yield facility to be available.
@@ -1644,42 +1302,18 @@  proc check_v3_target_sched_yield { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_sched_yield 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_sched_yield: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_sched_yield: $et_sched_yield" 2
-    return $et_sched_yield
+    }]
 }
 
 proc check_v3_target_string_conversions { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_string_conversions
-
-    global tool
-
-    if { ![info exists et_string_conversions_target_name] } {
-	set et_string_conversions_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_string_conversions_target_name } {
-	verbose "check_v3_target_string_conversions: `$et_string_conversions_target_name'" 2
-	set et_string_conversions_target_name $current_target
-	if [info exists et_string_conversions] {
-	    verbose "check_v3_target_string_conversions: removing cached result" 2
-	    unset et_string_conversions
-	}
-    }
-
-    if [info exists et_string_conversions] {
-	verbose "check_v3_target_string_conversions: using cached result" 2
-    } else {
-	set et_string_conversions 0
-	
+    return [check_v3_target_prop_cached et_string_conversions {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 	# Set up and preprocess a C++0x test program that depends
 	# on the string_conversions facilities to be available.
 	set src string_conversions[pid].cc
@@ -1700,42 +1334,18 @@  proc check_v3_target_string_conversions { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_string_conversions 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_string_conversions: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_string_conversions: $et_string_conversions" 2
-    return $et_string_conversions
+    }]
 }
 
 proc check_v3_target_swprintf { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_swprintf
-
-    global tool
-
-    if { ![info exists et_swprintf_target_name] } {
-	set et_swprintf_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_swprintf_target_name } {
-	verbose "check_v3_target_swprintf: `$et_swprintf_target_name'" 2
-	set et_swprintf_target_name $current_target
-	if [info exists et_swprintf] {
-	    verbose "check_v3_target_swprintf: removing cached result" 2
-	    unset et_swprintf
-	}
-    }
-
-    if [info exists et_swprintf] {
-	verbose "check_v3_target_swprintf: using cached result" 2
-    } else {
-	set et_swprintf 0
-	
+    return [check_v3_target_prop_cached et_swprintf {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 	# Set up and preprocess a C++0x test program that depends
 	# on a standard swprintf function to be available.
 	set src swprintf[pid].cc
@@ -1756,42 +1366,18 @@  proc check_v3_target_swprintf { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_swprintf 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_swprintf: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_swprintf: $et_swprintf" 2
-    return $et_swprintf
+    }]
 }
 
 proc check_v3_target_binary_io { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_binary_io
-
-    global tool
-
-    if { ![info exists et_binary_io_target_name] } {
-	set et_binary_io_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_binary_io_target_name } {
-	verbose "check_v3_target_binary_io: `$et_binary_io_target_name'" 2
-	set et_binary_io_target_name $current_target
-	if [info exists et_binary_io] {
-	    verbose "check_v3_target_binary_io: removing cached result" 2
-	    unset et_binary_io
-	}
-    }
-
-    if [info exists et_binary_io] {
-	verbose "check_v3_target_binary_io: using cached result" 2
-    } else {
-	set et_binary_io 0
-	
+    return [check_v3_target_prop_cached et_binary_io {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 	# Set up and preprocess a C++0x test program that depends
 	# on text and binary I/O being the same.
 	set src binary_io[pid].cc
@@ -1812,42 +1398,18 @@  proc check_v3_target_binary_io { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_binary_io 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_binary_io: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_binary_io: $et_binary_io" 2
-    return $et_binary_io
+    }]
 }
 
 proc check_v3_target_nprocs { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_nprocs
-
-    global tool
-
-    if { ![info exists et_nprocs_target_name] } {
-	set et_nprocs_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_nprocs_target_name } {
-	verbose "check_v3_target_nprocs: `$et_nprocs_target_name'" 2
-	set et_nprocs_target_name $current_target
-	if [info exists et_nprocs] {
-	    verbose "check_v3_target_nprocs: removing cached result" 2
-	    unset et_nprocs
-	}
-    }
-
-    if [info exists et_nprocs] {
-	verbose "check_v3_target_nprocs: using cached result" 2
-    } else {
-	set et_nprocs 0
-
+    return [check_v3_target_prop_cached et_nprocs {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 	# Set up and preprocess a C++0x test program that depends
 	# on either get_nprocs or sysconf to be available.
 	set src nprocs[pid].cc
@@ -1873,27 +1435,18 @@  proc check_v3_target_nprocs { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocess succeeded.
-	    set et_nprocs 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_nprocs: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_nprocs: $et_nprocs" 2
-    return $et_nprocs
+    }]
 }
 
 proc check_v3_target_static_libstdcxx { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_static_libstdcxx
-
-    global tool
-
-    if [info exists et_static_libstdcxx] {
-	verbose "check_v3_target_static_libstdcxx: using cached result" 2
-    } else {
-	set et_static_libstdcxx 0
-
+    return [check_v3_target_prop_cached et_static_libstdcxx {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 	# Set up and link a C++0x test program that depends
 	# on static linking
 	set src static-maybe[pid].cc
@@ -1916,42 +1469,18 @@  proc check_v3_target_static_libstdcxx { } {
 
 	if [string match "" $lines] {
 	    # No error message, link succeeded.
-	    set et_static_libstdcxx 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_static_libstdcxx: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_static_libstdcxx: $et_static_libstdcxx" 2
-    return $et_static_libstdcxx
+    }]
 }
 
 proc check_v3_target_little_endian { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_little_endian
-
-    global tool
-
-    if { ![info exists et_little_endian_target_name] } {
-	set et_little_endian_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_little_endian_target_name } {
-	verbose "check_v3_target_little_endian: `$et_little_endian_target_name'" 2
-	set et_little_endian_target_name $current_target
-	if [info exists et_little_endian] {
-	    verbose "check_v3_target_little_endian: removing cached result" 2
-	    unset et_little_endian
-	}
-    }
-
-    if [info exists et_little_endian] {
-	verbose "check_v3_target_little_endian: using cached result" 2
-    } else {
-	set et_little_endian 0
-	
+    return [check_v3_target_prop_cached et_little_endian {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 	set src little_endian[pid].cc
 
 	set f [open $src "w"]
@@ -1969,43 +1498,20 @@  proc check_v3_target_little_endian { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_little_endian 1
+	    return 1
 	} else {
 	    verbose "check_v3_target_little_endian: compilation failed" 2
+	    return 0
 	}
-    }
-    verbose "check_v3_target_little_endian: $et_little_endian" 2
-    return $et_little_endian
+    }]
 }
 
 # Return 1 if the Filesystem TS is supported, 0 otherwise.
 # Cache the result.
 proc check_v3_target_filesystem_ts { } {
-    global cxxflags
-    global DEFAULT_CXXFLAGS
-    global et_filesystem_ts
-    global tool
-
-    if { ![info exists et_filesystem_ts_target_name] } {
-	set et_filesystem_ts_target_name ""
-    }
-
-    # If the target has changed since we set the cached value, clear it.
-    set current_target [current_target_name]
-    if { $current_target != $et_filesystem_ts_target_name } {
-	verbose "check_v3_target_filesystem_ts: `$et_filesystem_ts_target_name'" 2
-	set et_filesystem_ts_target_name $current_target
-	if [info exists et_filesystem_ts] {
-	    verbose "check_v3_target_filesystem_ts: removing cached result" 2
-	    unset et_filesystem_ts
-	}
-    }
-
-    if [info exists et_filesystem_ts] {
-	verbose "check_v3_target_filesystem_ts: using cached result" 2
-    } else {
-	set et_filesystem_ts 0
-
+    return [check_v3_target_prop_cached et_filesystem_ts {
+	global cxxflags
+	global DEFAULT_CXXFLAGS
 	# Set up and preprocess a C++ test program that depends
 	# on the Filesystem TS feature-test macro being defined.
 	set src filesystem_ts[pid].cc
@@ -2026,11 +1532,10 @@  proc check_v3_target_filesystem_ts { } {
 
 	if [string match "" $lines] {
 	    # No error message, preprocessing succeeded.
-	    set et_filesystem_ts 1
+	    return 1
 	}
-    }
-    verbose "check_v3_target_filesystem_ts: $et_filesystem_ts" 2
-    return $et_filesystem_ts
+	return 0
+    }]
 }
 
 # Return 1 if the "cxx11" ABI is in use using the current flags, 0 otherwise.