Fix n² complexity in cfkey

The optimizer has a helper that checks statements for equality, cfkey.  It is currently n², and could be made linear by memoization.
What if we do

```lua
function memoize(f)
  local cache = {}
  return cache, function (arg)
    local cached = cache[arg]
    if cached ~= nil then return cached end
    local result = f(arg)
    cache[arg] = result
    return result
  end
end

local cfkey_cache, cfkey = memoize(function (expr)
  [body of ckey here, as it was]
end)
```

that way we separate the caching from the logic of cfkey.