// combined "Peeps + ConstProp + GVN" solver (extended version of the one in Combining Analyses, Combining Optimizations 7.3.2) // // returns isomorphic node (might be the same node). Node* peephole_node(Optimizer* opt, Node* n) { Node* k; bool progress = false; // potential mutations from ideal() means we need to get rehash. hashset_remove(opt->gvn_nodes, n); // iterative convergence (rewrite peepholes): // we'll settle on a fixpoint and be happy. while (k = ideal(n), k) { n = k; } // tries to deduce the value of an op based on the // types of the inputs, if both inputs were deduced // constant we might be constant and if both inputs were // ranges we might infer extra data if not a constant. Type* t = value(opt, n); k = try_as_const(opt, n, t); if (k) { return k; } // this is ops which replace the node with a direct // input (x + 0 => x), because of this we don't need // to rerun const prop since they don't change nodes // just referenced existing ones (which are either in // normal form or waiting on the worklist). // // identity(opt, n) will always return a node, either n // or a direct replacement k = identity(opt, n); if (k != n) { return k; } // GVN, we literally just place nodes into a hash table. // no need to rerun it's ruleset if it's just referencing // an existing node. k = hashset_get(opt->gvn_nodes, n); if (k) { hashset_put(opt->gvn_nodes, k); return k; } return n; }