return (count == 1);
}
-/* Eventually, we'll need a proper scheduling, grouping instructions
- * into clauses and ordering/assigning grouped instructions to the
- * appropriate FMA/ADD slots. Right now we do the dumbest possible
- * thing just to have the scheduler stubbed out so we can focus on
- * codegen */
-
-void
-bi_schedule(bi_context *ctx)
+/* Insert a clause wrapping a single instruction */
+
+bi_clause *
+bi_make_singleton(void *memctx, bi_instruction *ins,
+ bi_block *block,
+ unsigned scoreboard_id,
+ unsigned dependencies,
+ bool osrb)
{
- unsigned ids = 0;
- unsigned last_id = 0;
- bool is_first = true;
+ unsigned props = bi_class_props[ins->type];
- bi_foreach_block(ctx, block) {
- bi_block *bblock = (bi_block *) block;
+ bi_clause *u = rzalloc(memctx, bi_clause);
+ u->bundle_count = 1;
- list_inithead(&bblock->clauses);
+ /* Check for scheduling restrictions */
- bi_foreach_instr_in_block(bblock, ins) {
- /* Convenient time to lower */
- bi_lower_fmov(ins);
+ bool can_fma = props & BI_SCHED_FMA;
+ ASSERTED bool can_add = props & BI_SCHED_ADD;
+
+ can_fma &= !bi_ambiguous_abs(ins);
+ can_fma &= !bi_icmp(ins);
+ can_fma &= !bi_imath_small(ins);
- unsigned props = bi_class_props[ins->type];
+ assert(can_fma || can_add);
- bi_clause *u = rzalloc(ctx, bi_clause);
- u->bundle_count = 1;
+ if (can_fma)
+ u->bundles[0].fma = ins;
+ else
+ u->bundles[0].add = ins;
- /* Check for scheduling restrictions */
+ u->scoreboard_id = scoreboard_id;
+ u->staging_barrier = osrb;
+ u->dependencies = dependencies;
- bool can_fma = props & BI_SCHED_FMA;
- ASSERTED bool can_add = props & BI_SCHED_ADD;
+ if (ins->type == BI_ATEST)
+ u->dependencies |= (1 << 6);
- can_fma &= !bi_ambiguous_abs(ins);
- can_fma &= !bi_icmp(ins);
- can_fma &= !bi_imath_small(ins);
+ if (ins->type == BI_BLEND)
+ u->dependencies |= (1 << 6) | (1 << 7);
- assert(can_fma || can_add);
+ /* Let's be optimistic, we'll fix up later */
+ u->flow_control = BIFROST_FLOW_NBTB;
- if (can_fma)
- u->bundles[0].fma = ins;
- else
- u->bundles[0].add = ins;
+ u->constant_count = 1;
+ u->constants[0] = ins->constant.u64;
- u->scoreboard_id = ids++;
+ if (ins->type == BI_BRANCH && ins->branch_target)
+ u->branch_constant = true;
- if (is_first)
- is_first = false;
- else {
- /* Rule: first instructions cannot have write barriers */
- u->dependencies |= (1 << last_id);
- u->staging_barrier = true;
- }
+ /* We always prefetch except unconditional branches */
+ u->next_clause_prefetch = !(
+ (ins->type == BI_BRANCH) &&
+ (ins->cond == BI_COND_ALWAYS));
- if (ins->type == BI_ATEST)
- u->dependencies |= (1 << 6);
+ u->message_type = bi_message_type_for_ins(ins);
+ u->block = block;
- if (ins->type == BI_BLEND)
- u->dependencies |= (1 << 6) | (1 << 7);
+ return u;
+}
- ids = ids & 1;
- last_id = u->scoreboard_id;
+/* Eventually, we'll need a proper scheduling, grouping instructions
+ * into clauses and ordering/assigning grouped instructions to the
+ * appropriate FMA/ADD slots. Right now we do the dumbest possible
+ * thing just to have the scheduler stubbed out so we can focus on
+ * codegen */
- /* Let's be optimistic, we'll fix up later */
- u->flow_control = BIFROST_FLOW_NBTB;
+void
+bi_schedule(bi_context *ctx)
+{
+ bool is_first = true;
- u->constant_count = 1;
- u->constants[0] = ins->constant.u64;
+ bi_foreach_block(ctx, block) {
+ bi_block *bblock = (bi_block *) block;
- if (ins->type == BI_BRANCH && ins->branch_target)
- u->branch_constant = true;
+ list_inithead(&bblock->clauses);
- /* We always prefetch except unconditional branches */
- u->next_clause_prefetch = !(
- (ins->type == BI_BRANCH) &&
- (ins->cond == BI_COND_ALWAYS));
+ bi_foreach_instr_in_block(bblock, ins) {
+ /* Convenient time to lower */
+ bi_lower_fmov(ins);
- u->message_type = bi_message_type_for_ins(ins);
- u->block = (struct bi_block *) block;
+ bi_clause *u = bi_make_singleton(ctx, ins,
+ bblock, 0, (1 << 0),
+ !is_first);
+ is_first = false;
list_addtail(&u->link, &bblock->clauses);
}