There is support for intrinsics in Instruction::isCommunative, but there
is no equivalent implementation for isAssociative. This patch builds
support for associative intrinsics with TRE is an application. TRE can
now have associative intrinsics as an accumulator. For example:
struct Node { Node *next; unsigned val; } unsigned maxval(struct Node *n) { if (!n) return 0; return std::max(n->val, maxval(n->next)); }
Can be transformed into:
unsigned maxval(struct Node *n) { struct Node *head = n; unsigned max = 0; // Identity of unsigned std::max while (true) { if (!head) return max; max = std::max(max, head->val); head = head->next; } return max; }
This example results in about 5x speedup in local runs.
We conservatively only consider min/max and saturating add intrinsics as
associative for this patch to limit testing scope. There are probably
other intrinsics that could be considered associative. There are a few
consumers of isAssociative() that could be impacted. Testing has only
required to Reassociate pass be updated.