+#define foreach_array_safe(__array, __list) \
+ list_for_each_entry_safe(struct ir3_array, __array, __list, node)
+
+/* Check if condition is true for any src instruction.
+ */
+static inline bool
+check_src_cond(struct ir3_instruction *instr, bool (*cond)(struct ir3_instruction *))
+{
+ /* Note that this is also used post-RA so skip the ssa iterator: */
+ foreach_src (reg, instr) {
+ struct ir3_instruction *src = reg->instr;
+
+ if (!src)
+ continue;
+
+ /* meta:split/collect aren't real instructions, the thing that
+ * we actually care about is *their* srcs
+ */
+ if ((src->opc == OPC_META_SPLIT) || (src->opc == OPC_META_COLLECT)) {
+ if (check_src_cond(src, cond))
+ return true;
+ } else {
+ if (cond(src))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#define IR3_PASS(ir, pass, ...) ({ \
+ bool progress = pass(ir, ##__VA_ARGS__); \
+ if (progress) { \
+ ir3_debug_print(ir, "AFTER: " #pass); \
+ ir3_validate(ir); \
+ } \
+ progress; \
+ })
+
+/* validate: */
+void ir3_validate(struct ir3 *ir);