Hi Richard, Thanks for the review!
The 09/27/2018 09:40, Richard Sandiford wrote: > Tamar Christina <tamar.christ...@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 --