Fix undefined behavior in recursion detection.

We were performing lookups in fCallGraph using `operator[]` while
looping through fCallGraph via range-based for. `operator[]` will add
entries to the map if the key is not found. This happens if built-in
functions are called, such as `sin`, `cos`, `tan`, etc; this mutates
the call graph mid-loop, which causes unpredictable behavior. In
practice, this can occasionally cause a rehash, which reorders the hash
map and causes items to be skipped over or checked twice.

This flaw meant that over many repeated runs, recursion was occasionally
not detected, and compiling a program with recursion would succeed a
small percentage of the time. The PipelineStageCodeGenerator asserts and
then crashes when presented with such a program.

The fCallGraph is now held as a const pointer, which makes it
impossible to mutate, and lookups are done via .find() which are
non-mutating. Compiling the fuzzer-generated program 10,000 times now
succeeds.

Change-Id: I6915fcfa4a0b1e9f86e5eb4ffd053bc718aed9fb
Bug: oss-fuzz:36655
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/437096
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
1 file changed