From 86ab48144bda740ba2b3781894abf9cfa939eb43 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Mon, 13 Mar 2017 20:22:10 -0700
Subject: [PATCH 10/16] More efficient AggState->pertrans iteration.

Turns out AggStatePerTrans is so large that multiplications are needed
to access elements of AggState->pertrans on x86.

Author: Andres Freund
---
 src/backend/executor/nodeAgg.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 7e521459d6..291f15fd94 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -960,14 +960,15 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup *sort_pergroups, AggStat
 	int			numHashes = aggstate->num_hashes;
 	int			numTrans = aggstate->numtrans;
 	TupleTableSlot *slot = aggstate->evalslot;
+	AggStatePerTrans pertrans;
 
 	/* compute input for all aggregates */
 	if (aggstate->evalproj)
 		aggstate->evalslot = ExecProject(aggstate->evalproj);
 
-	for (transno = 0; transno < numTrans; transno++)
+	for (transno = 0, pertrans = &aggstate->pertrans[0];
+		 transno < numTrans; transno++, pertrans++)
 	{
-		AggStatePerTrans pertrans = &aggstate->pertrans[transno];
 		ExprState  *filter = pertrans->aggfilter;
 		int			numTransInputs = pertrans->numTransInputs;
 		int			i;
@@ -1098,6 +1099,7 @@ combine_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
 	int			transno;
 	int			numTrans = aggstate->numtrans;
 	TupleTableSlot *slot;
+	AggStatePerTrans pertrans;
 
 	/* combine not supported with grouping sets */
 	Assert(aggstate->phase->numsets <= 1);
@@ -1105,9 +1107,9 @@ combine_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
 	/* compute input for all aggregates */
 	slot = ExecProject(aggstate->evalproj);
 
-	for (transno = 0; transno < numTrans; transno++)
+	for (transno = 0, pertrans = &aggstate->pertrans[0];
+		 transno < numTrans; transno++, pertrans++)
 	{
-		AggStatePerTrans pertrans = &aggstate->pertrans[transno];
 		AggStatePerGroup pergroupstate = &pergroup[transno];
 		FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
 		int			inputoff = pertrans->inputoff;
@@ -2659,6 +2661,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 	AggState   *aggstate;
 	AggStatePerAgg peraggs;
 	AggStatePerTrans pertransstates;
+	AggStatePerTrans pertrans;
 	Plan	   *outerPlan;
 	ExprContext *econtext;
 	int			numaggs,
@@ -3349,9 +3352,9 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 	 */
 	combined_inputeval = NIL;
 	column_offset = 0;
-	for (transno = 0; transno < aggstate->numtrans; transno++)
+	for (transno = 0, pertrans = &pertransstates[0];
+		 transno < aggstate->numtrans; transno++, pertrans++)
 	{
-		AggStatePerTrans pertrans = &pertransstates[transno];
 		ListCell   *arg;
 
 		pertrans->inputoff = column_offset;
@@ -3842,6 +3845,7 @@ ExecEndAgg(AggState *node)
 	int			transno;
 	int			numGroupingSets = Max(node->maxsets, 1);
 	int			setno;
+	AggStatePerTrans pertrans;
 
 	/* Make sure we have closed any open tuplesorts */
 
@@ -3850,10 +3854,9 @@ ExecEndAgg(AggState *node)
 	if (node->sort_out)
 		tuplesort_end(node->sort_out);
 
-	for (transno = 0; transno < node->numtrans; transno++)
+	for (transno = 0, pertrans = &node->pertrans[0];
+		 transno < node->numtrans; transno++, pertrans++)
 	{
-		AggStatePerTrans pertrans = &node->pertrans[transno];
-
 		for (setno = 0; setno < numGroupingSets; setno++)
 		{
 			if (pertrans->sortstates[setno])
@@ -3890,6 +3893,7 @@ ExecReScanAgg(AggState *node)
 	int			transno;
 	int			numGroupingSets = Max(node->maxsets, 1);
 	int			setno;
+	AggStatePerTrans pertrans;
 
 	node->agg_done = false;
 
@@ -3921,12 +3925,11 @@ ExecReScanAgg(AggState *node)
 	}
 
 	/* Make sure we have closed any open tuplesorts */
-	for (transno = 0; transno < node->numtrans; transno++)
+	for (transno = 0, pertrans = &node->pertrans[0];
+		 transno < node->numtrans; transno++, pertrans++)
 	{
 		for (setno = 0; setno < numGroupingSets; setno++)
 		{
-			AggStatePerTrans pertrans = &node->pertrans[transno];
-
 			if (pertrans->sortstates[setno])
 			{
 				tuplesort_end(pertrans->sortstates[setno]);
-- 
2.14.1.2.g4274c698f4.dirty

