| 191 | MGB_TYPEINFO_OBJ_IMPL(CondExecPred::GlobalRegistry); |
| 192 | |
| 193 | void CondExecPred::GlobalRegistry::on_new_opr(OperatorNodeBase* const opr) { |
| 194 | // mask that controls execution of this opr |
| 195 | ExecutionMask* mask = nullptr; |
| 196 | |
| 197 | auto opr_type = opr->dyn_typeinfo(); |
| 198 | bool opr_is_mark = opr_type->is<CondExecMark>(), |
| 199 | opr_is_merge = opr_type->is<CondExecMerge>(), |
| 200 | opr_is_pred_logical = opr_type->is<CondExecPredLogical>(); |
| 201 | |
| 202 | using MergeMode = CondExecMerge::Mode; |
| 203 | MergeMode merge_mode = opr_is_merge ? opr->cast_final<CondExecMerge>().param().mode |
| 204 | : static_cast<MergeMode>(-1); |
| 205 | bool opr_follow_pred = |
| 206 | opr_is_mark || (opr_is_merge && merge_mode == MergeMode::SUM_COND_OUT); |
| 207 | |
| 208 | // find mask from inputs |
| 209 | auto&& inputs = opr->input(); |
| 210 | for (size_t idx = 0; idx < inputs.size(); ++idx) { |
| 211 | auto i_var = inputs[idx]; |
| 212 | ExecutionMask* i_mask = nullptr; |
| 213 | auto i_owner = i_var->owner_opr(); |
| 214 | |
| 215 | bool i_is_pred = false; |
| 216 | if (i_owner->same_type<CondExecPred>() || |
| 217 | i_owner->same_type<CondExecPredLogical>()) { |
| 218 | i_is_pred = true; |
| 219 | mgb_throw_if( |
| 220 | !((opr_follow_pred && i_var == opr->input().back()) || |
| 221 | opr_is_pred_logical), |
| 222 | GraphError, |
| 223 | "predicate proxy var not received by CondExec " |
| 224 | "mark/merge opr: var=%s recv_opr=%s{%s}", |
| 225 | cg::dump_var_info({i_var}).c_str(), opr->cname(), |
| 226 | opr->dyn_typeinfo()->name); |
| 227 | } |
| 228 | |
| 229 | if (opr_follow_pred && i_var == opr->input().back()) { |
| 230 | // CondExecMerge(with SUM_COND_OUT) and CondExecMark are controlled |
| 231 | // by given pred |
| 232 | mgb_assert(i_is_pred); |
| 233 | i_mask = m_var2mask.at(i_var); |
| 234 | if (mask) { |
| 235 | // here we handle the nested case; note that pred is the last |
| 236 | // input, so other inputs have been processed and mask is |
| 237 | // derived from other inputs |
| 238 | mgb_throw_if( |
| 239 | !can_prove_imply(i_mask, mask), GraphError, |
| 240 | "can not prove opr mask implies inputs mask: " |
| 241 | "opr=%s{%s}: opr_mask=%s " |
| 242 | "inputs_mask=%s", |
| 243 | opr->cname(), opr->dyn_typeinfo()->name, |
| 244 | mask2str(i_mask).c_str(), mask2str(mask).c_str()); |
| 245 | } |
| 246 | mask = i_mask; |
| 247 | break; |
| 248 | } |
| 249 | |
| 250 | if (!i_mask) { |
no test coverage detected