[llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/McGill/Makefile README.txt chomp.c exptree.c misr.c queens.c
Chris Lattner
lattner at cs.uiuc.edu
Tue Oct 5 13:58:50 PDT 2004
Changes in directory llvm-test/SingleSource/Benchmarks/McGill:
Makefile added (r1.1)
README.txt added (r1.1)
chomp.c added (r1.1)
exptree.c added (r1.1)
misr.c added (r1.1)
queens.c added (r1.1)
---
Log message:
New benchmarks
---
Diffs of the changes: (+1466 -0)
Index: llvm-test/SingleSource/Benchmarks/McGill/Makefile
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/Makefile:1.1
*** /dev/null Tue Oct 5 15:58:47 2004
--- llvm-test/SingleSource/Benchmarks/McGill/Makefile Tue Oct 5 15:58:37 2004
***************
*** 0 ****
--- 1,5 ----
+ LEVEL = ../../..
+ LDFLAGS += -lm
+ FP_TOLERANCE := 0.001
+
+ include $(LEVEL)/SingleSource/Makefile.singlesrc
Index: llvm-test/SingleSource/Benchmarks/McGill/README.txt
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/README.txt:1.1
*** /dev/null Tue Oct 5 15:58:50 2004
--- llvm-test/SingleSource/Benchmarks/McGill/README.txt Tue Oct 5 15:58:37 2004
***************
*** 0 ****
--- 1,3 ----
+ These benchmarks were downloaded from:
+ http://www.prolangs.rutgers.edu/public.html
+
Index: llvm-test/SingleSource/Benchmarks/McGill/chomp.c
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/chomp.c:1.1
*** /dev/null Tue Oct 5 15:58:50 2004
--- llvm-test/SingleSource/Benchmarks/McGill/chomp.c Tue Oct 5 15:58:37 2004
***************
*** 0 ****
--- 1,424 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ #define NDATA (int *)malloc(ncol * sizeof(int))
+ #define NLIST (struct _list *)malloc(sizeof(struct _list))
+ #define NPLAY (struct _play *)malloc(sizeof(struct _play))
+
+ struct _list
+ {
+ int *data;
+ struct _list *next;
+ } *wanted;
+
+ struct _play
+ {
+ int value;
+ int *state;
+ struct _list *first;
+ struct _play *next;
+ } *game_tree;
+
+ int nrow,ncol; /* global so as to avoid passing them all over the place */
+
+ int *copy_data(data) /* creates a duplicate of a given -data list */
+ int *data;
+ {
+ int *new = NDATA;
+ int counter = ncol;
+ while (counter --)
+ new[counter] = data[counter];
+ return new;
+ }
+
+ int next_data(int *data) /* gives the next logical setup to the one passed */
+ /* new setup replaces the old. Returns 0 if no valid */
+ { /* setup exists after the one passed */
+ int counter = 0;
+ int valid = 0; /* default to none */
+ while ((counter != ncol) && (! valid)) /* until its done */
+ {
+ if (data[counter] == nrow) /* if we hit a border */
+ {
+ data[counter] = 0; /* reset it to zero */
+ counter ++; /* and take next column */
+ }
+ else
+ {
+ data[counter] ++; /* otherwise, just increment row number */
+ valid = 1; /* and set valid to true. */
+ }
+ }
+ return valid; /* return whether or not */
+ } /* a next could be found */
+
+ void melt_data(int *data1,int *data2) /* melts 2 _data's into the first one. */
+ {
+ int counter = ncol;
+ while (counter --) /* do every column */
+ {
+ if (data1[counter] > data2[counter]) /* take the lowest one */
+ data1[counter] = data2[counter]; /* and put in first _data */
+ }
+ }
+
+ int equal_data(int *data1,int *data2) /* check if both _data's are equal */
+ {
+ int counter = ncol;
+ while ((counter --) && (data1[counter] == data2[counter]));
+ return (counter < 0);
+ }
+
+ int valid_data(int *data) /* checks if the play could ever be achieved. */
+ {
+ int low; /* var to hold the current height */
+ int counter = 0;
+ low = nrow; /* default to top of board */
+ while (counter != ncol) /* for every column */
+ {
+ if (data[counter] > low) break; /* if you get something higher */
+ low = data[counter]; /* set this as current height */
+ counter ++;
+ }
+ return (counter == ncol);
+ }
+
+ void dump_list(struct _list *list) /* same for a _list structure */
+ {
+ if (list != NULL)
+ {
+ dump_list(list -> next); /* dump the rest of it */
+ free(list -> data); /* and its _data structure */
+ free(list);
+ }
+ }
+
+ void dump_play(play) /* and for the entire game tree */
+ struct _play *play;
+ {
+ if (play != NULL)
+ {
+ dump_play(play -> next); /* dump the rest of the _play */
+ dump_list(play -> first); /* its _list */
+ free(play -> state); /* and its _data */
+ free(play);
+ }
+ }
+
+ int get_value(int *data) /* get the value (0 or 1) for a specific _data */
+ {
+ struct _play *search;
+ search = game_tree; /* start at the begginig */
+ while (! equal_data(search -> state,data)) /* until you find a match */
+ search = search -> next; /* take next element */
+ return search -> value; /* return its value */
+ }
+
+ void show_data(int *data) /* little display routine to give off results */
+ {
+ int counter = 0;
+ while (counter != ncol)
+ {
+ printf("%d",data[counter ++]);
+ if (counter != ncol) putchar(',');
+ }
+ }
+
+ void show_move(int *data) /* puts in the "(" and ")" for show_data() */
+ {
+ putchar('(');
+ show_data(data);
+ printf(")\n");
+ }
+
+ void show_list(struct _list *list) /* show the entire list of moves */
+ {
+ while (list != NULL)
+ {
+ show_move(list -> data);
+ list = list -> next;
+ }
+ }
+
+ void show_play(struct _play *play) /* to diplay the whole tree */
+ {
+ while (play != NULL)
+ {
+ printf("For state :\n");
+ show_data(play -> state);
+ printf(" value = %d\n",play -> value);
+ printf("We get, in order :\n");
+ show_list(play -> first);
+ play = play -> next;
+ }
+ }
+
+ int in_wanted(int *data) /* checks if the current _data is in the wanted list */
+ {
+ struct _list *current;
+ current = wanted; /* start at the begginig */
+ while (current != NULL) /* unitl the last one */
+ {
+ if (equal_data(current -> data,data)) break; /* break if found */
+ current = current -> next; /* take next element */
+ }
+ if (current == NULL) return 0; /* if at the end, not found */
+ return 1;
+ }
+
+ int *make_data(int row,int col) /* creates a new _data with the correct */
+ /* contents for the specified row & col */
+ {
+ int count;
+ int *new = NDATA;
+ for (count = 0;count != col;count ++) /* creates col-1 cells with nrow */
+ new[count] = nrow;
+ for (;count != ncol;count ++) /* and the rest with row as value */
+ new[count] = row;
+ return new; /* and return pointer to first element */
+ }
+
+ struct _list *make_list(int *data,int *value,int *all) /* create the whole _list of moves */
+ /* for the _data structure data */
+ {
+ int row,col;
+ int *temp;
+ struct _list *head,*current;
+ *value = 1; /* set to not good to give */
+ head = NLIST; /* create dummy header */
+ head -> next = NULL; /* set NULL as next element */
+ current = head; /* start from here */
+ for (row = 0;row != nrow;row ++) /* for every row */
+ {
+ for (col = 0;col != ncol;col ++) /* for every column */
+ {
+ temp = make_data(row,col); /* create _data for this play */
+ melt_data(temp,data); /* melt it with the current one */
+ if (! equal_data(temp,data)) /* if they are different, it good */
+ {
+ current -> next = NLIST; /* create new element in list */
+ current -> next -> data = copy_data(temp); /* copy data, and place in list */
+ current -> next -> next = NULL; /* NULL the next element */
+ current = current -> next; /* advance pointer */
+ if (*value == 1) /* if still not found a good one */
+ *value = get_value(temp); /* look at this value */
+ if ((! *all) && (*value == 0))
+ { /* if we found it, and all is not set */
+ col = ncol - 1; /* do what it take sto break out now */
+ row = nrow - 1;
+ if (in_wanted(temp)) /* if in the wanted list */
+ *all = 2; /* flag it */
+ }
+ }
+ else /* if its not a valid move */
+ {
+ if (col == 0) row = nrow - 1; /* break out if at first column */
+ col = ncol - 1; /* but make sure you break out */
+ } /* of the col for-loop anyway */
+ free(temp); /* dump this unneeded space */
+ }
+ }
+ current = head -> next; /* skip first element */
+ free(head); /* dump it */
+ if (current != NULL) *value = 1 - *value; /* invert value if its */
+ return current; /* not the empty board */
+ }
+
+ struct _play *make_play(int all) /* make up the entire tree-like stuff */
+ {
+ int val;
+ int *temp;
+ struct _play *head,*current;
+ head = NPLAY; /* dummy header again */
+ current = head; /* start here */
+ game_tree = NULL; /* no elements yet */
+ temp = make_data(0,0); /* new data, for empty board */
+ temp[0] --; /* set it up at (-1,xx) so that next_data() returns (0,xx) */
+ while (next_data(temp)) /* take next one, and break if none */
+ {
+ if (valid_data(temp)) /* if board position is possible */
+ {
+ current -> next = NPLAY; /* create a new _play cell */
+ if (game_tree == NULL) game_tree = current -> next;
+ /* set up game_tree if it was previously NULL */
+ current -> next -> state = copy_data(temp); /* make a copy of temp */
+ current -> next -> first = make_list(temp,&val,&all);
+ /* make up its whole list of possible moves */
+ current -> next -> value = val; /* place its value */
+ current -> next -> next = NULL; /* no next element */
+ current = current -> next; /* advance pointer */
+ if (all == 2) /* if found flag is on */
+ {
+ free(temp); /* dump current temp */
+ temp = make_data(nrow,ncol); /* and create one that will break */
+ }
+ }
+ }
+ current = head -> next; /* skip first element */
+ free(head); /* dump it */
+ return current; /* and return pointer to start of list */
+ }
+
+ void make_wanted(int *data) /* makes up the list of positions from the full board */
+ {
+ /* everything here is almost like in the previous function. */
+ /* The reason its here, is that it does not do as much as */
+ /* the one before, and thus goes faster. Also, it saves the */
+ /* results directly in wanted, which is a global variable. */
+
+ int row,col;
+ int *temp;
+ struct _list *head,*current;
+ head = NLIST;
+ head -> next = NULL;
+ current = head;
+ for (row = 0;row != nrow;row ++)
+ {
+ for (col = 0;col != ncol;col ++)
+ {
+ temp = make_data(row,col);
+ melt_data(temp,data);
+ if (! equal_data(temp,data))
+ {
+ current -> next = NLIST;
+ current -> next -> data = copy_data(temp);
+ current -> next -> next = NULL;
+ current = current -> next;
+ }
+ else
+ {
+ if (col == 0) row = nrow - 1;
+ col = ncol - 1;
+ }
+ free(temp);
+ }
+ }
+ current = head -> next;
+ free(head);
+ wanted = current;
+ }
+
+ int *get_good_move(struct _list *list) /* gets the first good move from a _list */
+ {
+ if (list == NULL) return NULL; /* if list is NULL, say so */
+ /* until end-of-list or a good one is found */
+ /* a good move is one that gives off a zero value */
+ while ((list -> next != NULL) && (get_value(list -> data)))
+ list = list -> next;
+ return copy_data(list -> data); /* return the value */
+ }
+
+ int *get_winning_move(struct _play *play) /* just scans for the first good move */
+ /* in the last _list of a _play. This */
+ { /* is the full board */
+ int *temp;
+ while (play -> next != NULL) play = play -> next; /* go to end of _play */
+ temp = get_good_move(play -> first); /* get good move */
+ return temp; /* return it */
+ }
+
+ struct _list *where(int *data,struct _play *play)
+ {
+ while (! equal_data(play -> state,data)) /* search for given _data */
+ play = play -> next;
+ return play -> first; /* return the pointer */
+ }
+
+ void get_real_move(int *data1,int *data2,int *row,int *col) /* returns row & col of the move */
+ /* which created data1 from data2 */
+ {
+ *col = 0;
+ while (data1[*col] == data2[*col]) /* until there is a change */
+ (*col) ++; /* and increment col number */
+ *row = data1[*col]; /* row is given by the content of the structure */
+ }
+
+ void main(void)
+ {
+ int row,col,maxrow,player;
+ int *win,*current,*temp;
+ struct _play *tree,*look;
+ /* allow user to select mode */
+ printf("Mode : 1 -> multiple first moves\n");
+ printf(" 2 -> report game\n");
+ printf(" 3 -> good positions\n");
+ printf(" Selection : ");
+ #if 0
+ scanf("%d",&row); /* put it in row for now */
+ #else
+ row = 2;
+ #endif
+ switch (row)
+ {
+ case 1:
+ printf("Enter number of Columns : ");
+ scanf("%d",&ncol);
+ printf("Enter Initial number of Rows : ");
+ scanf("%d",&nrow);
+ printf("Enter Maximum number of Rows : ");
+ scanf("%d",&maxrow);
+ for (;nrow <= maxrow;nrow ++)
+ {
+ make_wanted(make_data(nrow,ncol)); /* created wanted list */
+ tree = make_play(0); /* create tree */
+ win = get_winning_move(tree); /* get the winning move */
+ /* get the coordinates of this move */
+ get_real_move(win,make_data(nrow,ncol),&row,&col);
+ /* print it out nicely */
+ printf("The winning initial move for %d x %d CHOMP is (%d,%d)\n",nrow,ncol,row,col);
+ dump_play(tree); /* dump for memory management */
+ dump_list(wanted);
+ }
+ break;
+ case 2:
+ printf("Enter number of Columns : ");
+ #if 0
+ scanf("%d",&ncol);
+ #else
+ ncol = 7;
+ #endif
+ printf("Enter number of Rows : ");
+ #if 0
+ scanf("%d",&nrow);
+ #else
+ nrow = 8;
+ #endif
+ tree = make_play(1); /* create entire tree structure, not just the */
+ player = 0; /* needed part for first move */
+ current = make_data(nrow,ncol); /* start play at full board */
+ while (current != NULL)
+ {
+ temp = get_good_move(where(current,tree)); /* get best move */
+ if (temp != NULL) /* temp = NULL when the poison pill is taken */
+ {
+ get_real_move(temp,current,&row,&col); /* calculate coordinates */
+ /* print it out nicely */
+ printf("player %d plays at (%d,%d)\n",player,row,col);
+ player = 1 - player; /* next player to do the same */
+ free(current); /* dump for memory management */
+ }
+ current = temp; /* update board */
+ }
+ dump_play(tree); /* dump unneeded tree */
+ printf("player %d loses\n",1 - player); /* display winning player */
+ break;
+ case 3:
+ printf("Enter number of Columns : ");
+ scanf("%d",&ncol);
+ printf("Enter number of Rows : ");
+ scanf("%d",&nrow);
+ printf("ATTENTION : representation is as in a _data structure\n");
+ tree = make_play(1); /* create tree */
+ look = tree; /* start here */
+ while (look != NULL)
+ {
+ if (look -> value == 0) /* show all positions bad for player 2 */
+ show_move(look -> state); /* i.e. bad positions to be in */
+ look = look -> next; /* with zero value */
+ }
+ dump_play(tree); /* dump for memory management */
+ break;
+ }
+ }
+
+ /*****************************************************************************/
Index: llvm-test/SingleSource/Benchmarks/McGill/exptree.c
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/exptree.c:1.1
*** /dev/null Tue Oct 5 15:58:50 2004
--- llvm-test/SingleSource/Benchmarks/McGill/exptree.c Tue Oct 5 15:58:37 2004
***************
*** 0 ****
--- 1,388 ----
+ /***************************************************************************
+
+ PART 1: PROGRAM
+
+ Pierre Ouellet ID 9009791
+
+ The problem solved by this program is stated as follows:
+
+ Given a set S of k nonzero natural numbers, labeled n1..nk,
+ a "total" t, which is also a nonzero natural number, find
+ an expression tree, whose leaves are taken from S, and whose
+ interior nodes are each labeled one of {+, -, *, /}, and that
+ evaluates to t. There is the additional restriction that any
+ subtree must evaluate to a natural number greater than 0.
+ Division is permitted only if the value of the left child
+ is exactly divisible by the value of the right child. Also,
+ numbers in S may not be used more times than they appear,
+ e.g. if S = { 2, 3, 3 }, "3" may be used at most twice.
+
+ The program uses a brute-force search, more precisely an
+ iterative deepening depth-first search. The search can be
+ viewed as an attempt to build the tree bottom-up: whenever
+ the value t is not present, we try to obtain it by "combining"
+ two available values, which are taken from the "work list",
+ which consists of those elements of S not yet used and the values
+ obtained by previous combinations. This is the equivalent of
+ creating a new root and making the two operands its children.
+
+ The work list is an array of integers, originally containing
+ the elements of S. When elements are combined, they're marked
+ used and the result of combining them (the result of evaluating
+ the new root) is added at the end of the list.
+
+ The combinations are saved in an array of Comb, to be printed out
+ when a solution is found.
+
+ ***************************************************************************/
+
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ #define NOOP 0
+ #define ADD 1
+ #define SUB 2
+ #define MUL 3
+ #define DIV 4
+
+ typedef struct
+ {
+ int operand1, operand2;
+ int operation;
+
+ } Comb;
+
+ /* Global variables are used to save time during the search */
+
+ static int goal; /* the value of t explained above */
+ static int listLength; /* |S| */
+ static int *workList;
+ static Comb *combList;
+ static Comb *solution;
+ static int best = 0; /* value of best solution found yet */
+ static int dmax; /* maximal depth of search */
+ static int stopSearch; /* flag so we stop at first solution */
+ static int bestDepth = 0; /* depth of best solution; used if no exact
+ solution is found */
+ static int nbNodes; /* statistics: number of nodes examined
+ (number of calls to recSearch) */
+
+ /************************* INITIALIZATION STUFF *************************/
+
+ int *newWorkList( int length )
+
+ /* Create a "work list", which is an array of integers with length
+ elements
+ */
+
+ {
+ int *newList = (int *) calloc( length, sizeof( int ) );
+
+ if( newList ) return newList;
+
+ else
+ {
+ fprintf( stderr, "Out of memory for work list\n" );
+ exit( 1 );
+ }
+ }
+
+ Comb *newCombList( int length )
+
+ /* Create a "combination list", which is to be used all the way through
+ the search. It contains the combinations attempted so far in the search.
+ */
+
+ {
+ Comb *newList = (Comb *) calloc( length, sizeof( Comb ) );
+
+ if( newList ) return newList;
+
+ else
+ {
+ fprintf( stderr, "Out of memory for combination list\n" );
+ exit( 1 );
+ }
+ }
+
+ void initWorkList( int *workList, int *givenList, int length )
+
+ {
+ int i;
+
+ for( i = 0; i < length; i++ )
+ workList[i] = givenList[i];
+ }
+
+ void initCombList( Comb *combList, int length )
+ {
+ int i;
+
+ for( i = 0; i < length; i++ )
+ combList[i].operation = NOOP;
+ }
+
+ /************************* AUXILIARY FUNCTIONS *************************/
+
+ void saveSolution( Comb *sol, Comb *combList, int length )
+
+ /* Copy a sequence of combinations.
+ */
+
+ {
+ int i;
+
+ for( i = 0; i < length; i++ )
+ {
+ sol[i].operand1 = combList[i].operand1;
+ sol[i].operand2 = combList[i].operand2;
+ sol[i].operation = combList[i].operation;
+ }
+
+ sol[length].operation = NOOP; /* End marker */
+
+ }
+
+ int calculate( Comb *comb )
+
+ /* Compute the value generated by a combination.
+ */
+
+ {
+ switch( comb->operation )
+ {
+ case ADD: return comb->operand1 + comb->operand2;
+ case SUB: return comb->operand1 - comb->operand2;
+ case MUL: return comb->operand1 * comb->operand2;
+ case DIV: return comb->operand1 / comb->operand2;
+
+ default: return 0;
+ }
+ }
+
+ /************************* OUTPUT STUFF *************************/
+
+ void printSolution( Comb *combList, int length )
+ {
+ int i;
+
+ for( i = 0; i < length; i++ )
+ {
+ printf( "%d", combList[i].operand1 );
+
+ switch( combList[i].operation )
+ {
+ case NOOP: printf( " " ); break;
+ case ADD: printf( "+" ); break;
+ case SUB: printf( "-" ); break;
+ case MUL: printf( "*" ); break;
+ case DIV: printf( ":" ); break;
+
+ default: printf( " d%d ", combList[i].operation );
+ }
+
+ printf( "%d=%d", combList[i].operand2, calculate( &combList[i] ) );
+
+ if( i < length - 1 ) printf( "; " ); else printf( ".\n" );
+ }
+
+ printf( "\n" );
+ }
+
+ void printList( int *list, int length, int mask )
+ {
+ int i;
+
+ for( i = 0; i < length; i++ )
+ {
+ if( ( 1 << i ) & mask ) continue;
+
+ printf( "%d ", list[i] );
+ }
+
+ printf( "\n" );
+ }
+
+ /************************* ACTUAL SEARCH STUFF *************************/
+
+ void recSearch( int searchDepth, int usedMask )
+
+ /* searchDepth: current depth within the search.
+ usedMask: used to tell which elements of the work list
+ have been used.
+ */
+
+ {
+ int currOp; /* current operation under consideration */
+ int newMask; /* or'ed with old mask to mark used numbers from work list */
+ int operand1; /* offset of operand 1 of combination within work list */
+ int operand2; /* offset of operand 2 of combination within work list */
+
+ if( stopSearch ) return; /* unroll recursion when solution is found */
+
+ nbNodes++; /* Statistics */
+
+ if( searchDepth == dmax )
+ {
+ /* check whether last number generated is nearer to t than best */
+ if( abs( workList[listLength + searchDepth - 1] - goal )
+ < abs( best - goal ) )
+ {
+ /* if so, save solution */
+ best = workList[listLength + searchDepth - 1];
+ bestDepth = searchDepth;
+ saveSolution( solution, combList, searchDepth );
+
+ if( best == goal )
+ {
+ printSolution( combList, searchDepth );
+ stopSearch = 1;
+ }
+ }
+ }
+
+ else
+ {
+ int working1, working2; /* hold values of numbers considered
+ for combination */
+ int temp; /* for swapping */
+
+ /* iterate over all four operators {+, -, *, /} */
+ for( currOp = ADD; currOp <= DIV; currOp++ )
+ {
+ for( operand1 = 0; operand1 < listLength + searchDepth;
+ operand1++ )
+ {
+ /* do not use already used numbers */
+ if( ( 1 << operand1 ) & usedMask ) continue;
+
+ for( operand2 = 0; operand2 < operand1; operand2++ )
+ {
+ if( ( 1 << operand2 ) & usedMask ) continue;
+
+ working1 = workList[operand1];
+ working2 = workList[operand2];
+
+ /* x * 1 = 1 * x = x; x / 1 = x */
+ if( ( currOp == MUL || currOp == DIV ) &&
+ ( working1 == 1 || working2 == 1 ) ) continue;
+
+ /* could arise from combination a - a for some a */
+ if( working1 == 0 || working2 == 0 ) continue;
+
+ /* make dure operand2 divides operand1 */
+ if( currOp == DIV &&
+ ( working1 % working2 ) ) continue;
+
+ /* make sure operand1 >= operand2 for subtraction and
+ division */
+ if( ( currOp == DIV || currOp == SUB ) &&
+ ( working1 < working2 ) )
+ {
+ temp = working1;
+ working1 = working2;
+ working2 = temp;
+ }
+
+ /* mark operands used */
+ newMask = usedMask |
+ ( 1 << operand1 ) |
+ ( 1 << operand2 );
+
+ /* save current combination */
+ combList[searchDepth].operand1 =
+ working1;
+ combList[searchDepth].operand2 =
+ working2;
+ combList[searchDepth].operation = currOp;
+
+ workList[listLength + searchDepth] =
+ calculate( &combList[searchDepth] );
+
+ /* search deeper */
+ recSearch( searchDepth + 1, newMask );
+ }
+ }
+ }
+ }
+ }
+
+ void doSearch(void)
+
+ /* Preliminary search. Takes care of the special case where |S| = 1
+ and the only element of S is t.
+ */
+ {
+ int i;
+
+ for( i = 0; i < listLength; i++ )
+ if( abs( workList[i] - goal ) < abs( best - goal ) )
+ {
+ best = workList[i];
+ }
+
+ if( best == goal )
+ {
+ printf( ".\n" );
+ return;
+ }
+
+ for( dmax = 1; dmax < listLength; dmax++ )
+ {
+ recSearch( 0, 0 );
+
+ if( stopSearch ) break;
+ }
+
+ /* If no exact solution was found */
+ if( stopSearch == 0 )
+ printSolution( solution, bestDepth );
+ }
+
+ int getInput(void)
+ {
+ int nums[16];
+ int i = 0;
+ int c;
+ nums[0] = 13;
+ nums[1] = 32;
+ nums[2] = 14;
+ nums[3] = 1412;
+
+ while( ( c = getchar() ) != '\n' && c != EOF )
+ {
+ ungetc( c, stdin );
+ fscanf( stdin, "%d", &nums[i] );
+ i++;
+ }
+
+ if( i == 0 ) i = 4;
+
+ listLength = i - 1;
+ goal = nums[listLength];
+
+ workList = newWorkList( 2 * listLength );
+ combList = newCombList( listLength );
+ solution = newCombList( listLength );
+
+ initWorkList( workList, nums, listLength );
+ initCombList( combList, listLength );
+ initCombList( solution, listLength );
+
+ return( listLength );
+ }
+
+ void search(void)
+ {
+ /* set up global variables for search */
+ stopSearch = 0;
+ nbNodes = 0;
+
+ doSearch();
+ }
+
+ void main( int argc, char *argv[] )
+ {
+ if( getInput() )
+ search();
+ }
Index: llvm-test/SingleSource/Benchmarks/McGill/misr.c
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/misr.c:1.1
*** /dev/null Tue Oct 5 15:58:50 2004
--- llvm-test/SingleSource/Benchmarks/McGill/misr.c Tue Oct 5 15:58:37 2004
***************
*** 0 ****
--- 1,280 ----
+ /* the name was converted to pgm5.c */
+ /*******************************************************
+
+ program: MISR.C
+
+
+ This program creates two MISR's one which contains the
+ true outputs and the other in which the outputs are
+ not currupted with the probability given in the input.
+ The values of the MISR's are compared to see if the
+ introduced errors have cancelled themselves.
+
+ The usage is : MISR fileout reg_len #_vectors prob
+ #_times [structure] [seed] [seed] [seed].
+ fileout has been nullified in this case to fit with
+ the description of the project.
+ reg_len is the length of the MISR's in considerstion.
+ #_vectors is the number of vectors to input to the
+ MISR's before checking to see of they are
+ identical. If '0', assume large value (infinite).
+ prob described above.
+ #_times is the number of times that the MISR's are
+ initialized and the experiment done before the
+ # of times outputs same/ # of times it is run
+ (#_times) is calculated.
+ [structure] gives the feedback structure of the MISR's.
+ if it is omitted, the situition where the end
+ feeds back to the beginning is used.
+ [seed]* is the seed to be used to initialize the random
+ generator.
+ *******************************************************/
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <mp.h>
+
+ #define INF 10000
+ #define MAX_REG_LN 100
+ #define BIN_MASK 1
+ #define TRUE 1
+ #define FALSE 0
+
+ int reg_len;
+
+ typedef struct cells {
+ int f_free;
+ int faulty;
+ struct cells *next;
+ }misr_type;
+
+ /* Prototypes */
+
+ int simulate(int iterations, misr_type *present, double prob, char *structure);
+ void init(misr_type *present);
+ void kill_list(misr_type *present);
+ void create_link_list(misr_type *cell_array);
+
+ /* Main Program */
+
+ void main(int argc,char *argv[])
+ {
+ misr_type cell_array;
+ int num_vect, num_times, num_true, i;
+ double prob;
+ char structure[MAX_REG_LN];
+ unsigned short seed[3];
+
+ /* Check usage */
+ if (0 && argc < 6)
+ {
+ printf("Usage: MISR fileout reg_len #_vectors prob #_times [structure] [seed] [seed] [seed]\n");
+ return;
+ }
+
+ /* input and translate arguments */
+ /*sscanf(argv[2], "%lu", ®_len);
+ sscanf(argv[3], "%lu", &num_vect);
+ sscanf(argv[4], "%le", &prob);
+ sscanf(argv[5], "%lu", &num_times);*/
+
+ reg_len = num_vect = 10;
+ prob = .25;
+ num_times = 100000;
+
+
+ if (argc > 6) strcpy(structure, argv[6]);
+ else {
+ for (i=1; i<reg_len; i++)
+ structure[i] = '0';
+ structure[0] = '1';
+ structure[reg_len] = NULL;
+ }
+ if (argc > 7) sscanf(argv[7], "%hu", &seed[0]); else seed[0] = 1;
+ if (argc > 8) sscanf(argv[8], "%hu", &seed[1]); else seed[1] = 0;
+ if (argc > 9) sscanf(argv[9], "%hu", &seed[2]); else seed[2] = 0;
+
+
+ /* Check validity of input */
+ if (reg_len > MAX_REG_LN)
+ {
+ printf("Register too long; Max. = %d\n", MAX_REG_LN);
+ return;
+ }
+ if ((prob > 1) || (prob < 0))
+ {
+ printf("Prob. out of range 0=<Prob>=1\n");
+ return;
+ }
+ if (strlen(structure) != reg_len)
+ {
+ printf("Structure does not match Register length:\n");
+ return;
+ }
+
+
+ /*initialize random f'n generator */
+ seed48(seed);
+
+
+ /* create MISRs of reg_len length */
+ create_link_list(&cell_array);
+
+ /* simulate both circuits */
+ num_true = 0;
+ if (num_vect != 0)
+ {
+ for (i=0; i<num_times; i++)
+ {
+ init(&cell_array);
+ num_true += simulate(num_vect, &cell_array, prob, structure);
+ }
+ }
+ else /* ie. infinite case */
+ {
+ init(&cell_array);
+ simulate(INF, &cell_array, prob, structure);
+ for(i=0; i<num_times; i++)
+ {
+ num_true += simulate(1, &cell_array, prob, structure);
+ }
+ }
+
+
+ /* output results */
+ printf("reg_len #_vect prob #_tms struct seed1 seed2 seed3 Prob same output\n ");
+
+ printf("%d %d %.3e %d %s %d %d %d %.8e\n", reg_len, num_vect, prob, num_times, structure, seed[0], seed[1], seed[2],(double)(num_times - num_true)/(double)num_times);
+ //kill_list(&cell_array);
+ }
+
+ /*************************************************************
+ create and initialize the MISR's which is a linked list of
+ misr_type.
+ *************************************************************/
+ void create_link_list(misr_type *cell_array)
+ {
+ int i;
+ misr_type *temp, *present;
+
+ memset(cell_array, 0, sizeof(*cell_array));
+ present = cell_array ;
+ for(i=0; i<reg_len+1; i++)
+ {
+ temp = (misr_type *) malloc(sizeof(misr_type));
+ temp->f_free = 1;
+ temp->faulty = 1;
+ temp->next = NULL;
+ present->next = temp;
+ present = present->next;
+ }
+ }
+
+
+ /*************************************************************
+ release linked list when finished
+ *************************************************************/
+ void kill_list(misr_type *present)
+ {
+ misr_type *temp;
+
+ while(present)
+ {
+ temp = present->next;
+ free(present);
+ present = temp;
+ }
+ return;
+ }
+
+
+ /************************************************************
+ make both MISR's identical to start the experiment
+ ************************************************************/
+ void init(misr_type *present)
+ {
+
+ while(present->next != NULL)
+ {
+ present->faulty = present->f_free;
+ present = present->next;
+ }
+ }
+
+
+ /***********************************************************
+ this proceedure is the workhorse of the program. Each time it
+ is called, it calculates the next value of each cell in the
+ MISR's and does this for hte number of times necessary.
+ ***********************************************************/
+ int simulate(int iterations, misr_type *present, double prob, char *structure)
+ {
+ misr_type *temp;
+ int different, savef_free, savefaulty;
+ int rem, quot, h, i, j;
+ long rand;
+ double randprob;
+
+ different = FALSE;
+ quot = (reg_len-1) / 31;
+ rem = (reg_len-1) % 31;
+ temp = present;
+
+ for(h=0; h<iterations; h++)
+ {
+ savef_free = 0;
+ savefaulty = 0;
+ for (i=0; i<quot; i++)
+ {
+ rand = lrand48();
+ for (j=0; j<31; j++)
+ {
+ if (structure[i*31 + j] == '1')
+ {
+ savef_free += temp->f_free;
+ savefaulty += temp->faulty;
+ }
+ temp->f_free = ((temp->next->f_free + rand) & BIN_MASK);
+ randprob = ((double)(lrand48() % 1000) / 1000);
+ if (prob > randprob) rand ^= BIN_MASK;
+ temp->faulty = ((temp->next->faulty + rand) & BIN_MASK);
+ temp = temp->next;
+ rand >>= 1;
+ }
+ }
+ rand = lrand48();
+ for (j=0; j<rem; j++)
+ {
+ if (structure[quot*31 + j] == '1')
+ {
+ savef_free += temp->f_free;
+ savefaulty += temp->faulty;
+ }
+ temp->f_free = ((temp->next->f_free + rand) & BIN_MASK);
+ randprob = ((double)(lrand48() % 1000) / 1000); if (prob > randprob) rand ^= BIN_MASK;
+ temp->faulty = ((temp->next->faulty + rand) & BIN_MASK);
+ temp = temp->next;
+ rand >>= 1;
+ }
+ rand = lrand48();
+ if (structure[reg_len - 1] == '1')
+ {
+ savef_free += temp->f_free;
+ savefaulty += temp->faulty;
+ }
+ temp->f_free = ((savef_free + rand) & BIN_MASK);
+ randprob = ((double)(lrand48() % 10000) / 10000);
+ if (prob > randprob) rand ^= BIN_MASK;
+ temp->faulty = ((savefaulty + rand) & BIN_MASK);
+
+ temp = present;
+ }
+
+ for (i=0; i<reg_len; i++)
+ {
+ if (temp->f_free != temp->faulty) different = TRUE;
+ temp = temp->next;
+ }
+ return different;
+
+ }
Index: llvm-test/SingleSource/Benchmarks/McGill/queens.c
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/queens.c:1.1
*** /dev/null Tue Oct 5 15:58:50 2004
--- llvm-test/SingleSource/Benchmarks/McGill/queens.c Tue Oct 5 15:58:37 2004
***************
*** 0 ****
--- 1,366 ----
+ /*
+ ** queens.c -- Find solutions to the Eight-Queens chess problem.
+ ** Roberto Sierra 3/19/84 Version 1.1
+ **
+ ** Description:
+ ** This program finds all the possible ways that N queens can
+ ** be placed on an NxN chessboard so that the queens cannot
+ ** capture one another -- that is, so that no rank, file or
+ ** diagonal is occupied by more than one queen. By default,
+ ** the program prints the first solution it finds. You can
+ ** use the -a option to print all solutions, or the -c option
+ ** just to count them. The program allows the chess board
+ ** to be from 1x1 (trivial case) to 100x100. Warning: the
+ ** larger the chess board, the longer it typically takes to
+ ** find each solution, even though there may be more of them.
+ **
+ ** This is a terrific example of the utility of recursion. The
+ ** algorithm uses recursion to drastically limit the number
+ ** of board positions that are tested. The program is able
+ ** to find all 8x8 queen solutions in a fraction of a second
+ ** (not counting print time). The code makes no attempt to
+ ** eliminate symmetrical solutions, so the number of solutions
+ ** reported will always be higher than the actual number of
+ ** distinct solutions.
+ **
+ **
+ ** Usage:
+ ** queens [-ac] n
+ **
+ ** n Number of queens (rows and columns). An integer from 1 to 100.
+ ** -a Find and print all solutions.
+ ** -c Count all solutions, but do not print them.
+ **
+ ** The output is sent to stdout. All errors messages are
+ ** sent to stderr. If a problem arises, the return code is -1.
+ **
+ **
+ ** Examples:
+ **
+ ** queens 8 ## Show an 8x8 solution
+ ** 8 queens on a 8x8 board...
+ ** Q - - - - - - -
+ ** - - - - Q - - -
+ ** - - - - - - - Q
+ ** - - - - - Q - -
+ ** - - Q - - - - -
+ ** - - - - - - Q -
+ ** - Q - - - - - -
+ ** - - - Q - - - -
+ **
+ ** queens -c 8 ## Count all 8x8 solutions
+ ** 8 queens on a 8x8 board...
+ ** ...there are 92 solutions.
+ **
+ ** queens -a 4 ## Show all 4x4 solutions
+ ** 4 queens on a 4x4 board...
+ **
+ ** Solution #1:
+ ** - Q - -
+ ** - - - Q
+ ** Q - - -
+ ** - - Q -
+ **
+ ** Solution #2:
+ ** - - Q -
+ ** Q - - -
+ ** - - - Q
+ ** - Q - -
+ **
+ ** ...there are 2 solutions.
+ **
+ **
+ ** Build Instructions:
+ ** You'll need an ANSI C compiler (or the willingness to edit
+ ** the program a bit). If you've got Gnu C, then you can
+ ** compile and load the program as follows:
+ **
+ ** gcc queens.c -ansi -o queens
+ **
+ ** [If you're using MPW on the Mac, define '-d MPW' on the
+ ** compile line so that background processing will occur.]
+ **
+ **
+ ** Algorithm:
+ ** In a 1984 Byte article, I ran across an interesting letter
+ ** from a high school student who was attempting to solve the
+ ** Eight Queens problem using a BASIC interpreter. He had
+ ** developed a program which placed eight queens successively
+ ** on all sixty-four squares, testing for conflicts at each
+ ** iteration. Of course, such a program would require 64^8
+ ** iterations (about 2.8x10^14 iterations). Even in C on a,
+ ** fast CPU, this could take months or years. Byte's answer was
+ ** to alter the loops so that the queens resided on separate
+ ** ranks, thereby reducing the number of iterations required
+ ** to find all solutions to 8^8 iterations (about 16 million).
+ ** More reasonable, but still requiring a chunk of CPU time.
+ **
+ ** I puzzled about this problem a bit, and came to realize that
+ ** this was still wasting a lot of CPU cycles. Though I'm sure
+ ** others have come up with good algorithms, I decided to come
+ ** up with my own, with a particular eye on efficiency. The
+ ** resulting algorithm finds all 8x8 solutions in a fraction
+ ** of a second (there are 92 solutions, including rotations).
+ ** On a Sun 4, it'll find all 365,596 solutions on a 14x14 board
+ ** in a bit over 2 minutes (printing them out requires extra
+ ** time, of course). Even Byte's solution would require 14^14
+ ** iterations (about 10^16) which would take aeons.
+ **
+ ** My algorithm works as follows:
+ ** (1) Place a queen in the top left corner.
+ ** (2) Place another queen immediately below.
+ ** (3) Test for conflicts. If the second queen conflicts (it
+ ** does at first), then move it one square to the right.
+ ** (4) Loop step 3 until there are no conflicts. Place
+ ** the next queen on the board and recurse.
+ ** (5) If any queen reaches the right edge of the board,
+ ** remove it and 'pop' to the previous recursion level.
+ ** (6) Now repeat these steps recursively until all eight
+ ** queens (or however many) have been placed without
+ ** conflict -- the result is a solution to the problem,
+ ** which is counted and optionally printed.
+ **
+ ** Because conflicts are tested as the recursion proceeds,
+ ** this has the effect of 'pruning' the recursion so that
+ ** a large number of board positions are not even attempted.
+ ** The result is that the algorithm runs in reasonable time.
+ **
+ ** I used a few tricks to make the test-for-conflict code
+ ** extremely efficient -- there is no 'inner' loop to search
+ ** along ranks, files, or diagonals. A series of arrays are
+ ** maintained instead which indicate which queen currently
+ ** 'owns' each rank, file or diagonal. This makes the
+ ** algorithm really fly, though the code is a little hard to
+ ** read. Lastly, pointer arithmetic is used to reduce the
+ ** number of implicit multiplications used in array addressing.
+ **
+ **
+ ** Contact:
+ ** For queries regarding this program, contact Roberto Sierra
+ ** at any of the following addresses:
+ **
+ ** Roberto Sierra
+ ** bert at netcom.com (preferred address)
+ ** 73557.2101 at compuserve.com
+ **
+ ** Tempered MicroDesigns
+ ** P.O. Box 170638
+ ** San Francisco, CA 94117
+ **
+ **
+ ** Fine Print:
+ ** This program is in the public domain and can be used for
+ ** any purpose whatsoever, including commercial application.
+ ** [I'd like to hear what you do with it, though.]
+ ** Absolutely no warranty or liability is implied or extended
+ ** by the author.
+ **
+ **
+ ** Modification History:
+ ** PRS 3/19/84 v1.0 -- Original version.
+ ** PRS 7/25/93 v1.1 -- ANSIfied the code. More efficient pointers.
+ */
+
+
+ #include <stdio.h> /* Need standard I/O functions */
+ #include <stdlib.h> /* Need exit() routine interface */
+ #include <string.h> /* Need strcmp() interface */
+ #ifdef MPW /* Macintosh MPW ONLY */
+ # include <CursorCtl.h> /* Need cursor control interfaces */
+ #endif
+
+ #define MAXQUEENS 100 /* Max number of queens */
+ #define MAXRANKS MAXQUEENS /* Max number of ranks (rows) */
+ #define MAXFILES MAXQUEENS /* Max number of files (columns) */
+ #define MAXDIAGS (MAXRANKS+MAXFILES-1) /* Max number of diagonals */
+ #define EMPTY (MAXQUEENS+1) /* Marks unoccupied file or diagonal */
+
+ /* GLOBAL VARIABLES */
+
+ int queens; /* Number of queens to place */
+ int ranks; /* Number of ranks (rows) */
+ int files; /* Number of files (columns) */
+ int printing = 1; /* TRUE if printing positions */
+ int findall = 0; /* TRUE if finding all solutions */
+
+ unsigned long solutions = 0; /* Number of solutions found */
+ int queen[MAXRANKS]; /* File on which each queen is located */
+ int file[MAXFILES]; /* Which queen 'owns' each file */
+ int fordiag[MAXDIAGS]; /* Which queen 'owns' forward diagonals */
+ int bakdiag[MAXDIAGS]; /* Which queen 'owns' reverse diagonals */
+ char *progname = NULL; /* The name of this program */
+
+
+ /* -------------------------- PROTOTYPES ----------------------- */
+
+ void pboard(void);
+ void find(register int level);
+
+
+ /*-------------------------- main() ----------------------------
+ ** MAIN program. The main purpose of this routine is to deal
+ ** with decoding the command line arguments, initializing the
+ ** various arrays, and starting the recursive search routine.
+ */
+ void main(int argc, char **argv)
+ {
+ register int i; /* Loop variable */
+ register char *p; /* Ptr to argument */
+ char *usage =
+ "Usage: %s [-ac] n\n\
+ \tn\tNumber of queens (rows and columns). An integer from 1 to 100.\n\
+ \t-a\tFind and print all solutions.\n\
+ \t-c\tCount all solutions, but do not print them.\n";
+
+ #ifdef MPW /* Macintosh MPW ONLY */
+ InitCursorCtl(0); /* Enable cursor control */
+ #endif
+
+ progname = argv[0]; /* Name of the program */
+
+ /**** DECODE COMMAND LINE ARGUMENTS ****/
+ printing = 0;
+ queens = 14;
+ findall = 1;
+
+ for(i = 1; i < argc; ++i) { /* Scan through arguments */
+ p = argv[i]; /* Ptr to base of argument */
+ if(*p == '-') { /* Command line option? */
+ while(*++p) { /* Loop through characters */
+ switch(*p) { /* What is the character */
+ case 'c': /* '-c' option */
+ printing = 0; /* Counting, not printing */
+ case 'a': /* '-a' option */
+ findall = 1; /* Find all solutions */
+ break;
+ default: /* Illegal option */
+ fprintf(stderr,"%s: Illegal option '%s'\n",progname,argv[i]);
+ fprintf(stderr,usage,progname);
+ exit(-1);
+ } /* End of switch */
+ } /* End of loop */
+ } /* End of option test */
+ else {
+ if(sscanf(p,"%d",&queens) != 1) { /* Read integer argument */
+ fprintf(stderr,"%s: Non-integer argument '%s'\n",progname,p);
+ exit(-1);
+ }
+ if(queens <= 0) { /* N must be positive */
+ fprintf(stderr,"%s: n must be positive integer\n",progname);
+ exit(-1);
+ }
+ if(queens > MAXQUEENS) { /* N can't be too large */
+ fprintf(stderr,"%s: Can't have more than %d queens\n",
+ progname, MAXQUEENS);
+ exit(-1);
+ }
+ } /* End of argument test */
+ } /* End of argument scan loop */
+ if(!queens) {
+ fprintf(stderr,"%s: Missing n argument\n",progname);
+ fprintf(stderr,usage,progname);
+ exit(-1);
+ }
+
+ ranks = files = queens; /* NxN board for N queens */
+ printf("%d queen%s on a %dx%d board...\n",
+ queens, queens > 1 ? "s" : "", ranks, files);
+ fflush(stdout);
+
+ /* Initialization */
+ solutions = 0; /* No solutions yet */
+ for(i = 0; i < MAXFILES; ++i) file[i] = EMPTY;
+ for(i = 0; i < MAXDIAGS; ++i) fordiag[i] = bakdiag[i] = EMPTY;
+
+ /* Find all solutions (begin recursion) */
+ find(0);
+ if(printing && solutions) putchar('\n');
+
+ /* Report results */
+ if(solutions == 1) printf("...there is 1 solution\n");
+ else printf("...there are %ld solutions\n", solutions);
+
+ exit(0); /* No errors */
+ }
+
+
+ /***********************/
+ /**** ROUTINES ****/
+ /***********************/
+
+ /*------------------------- pboard() ---------------------------
+ ** This routines prints the board for a particular solution.
+ ** The output is sent to stdout.
+ */
+ void pboard(void)
+ {
+ register int i, j; /* Rank/File indices */
+
+ if(findall) /* Only if searching for all */
+ printf("\nSolution #%lu:\n",solutions); /* Print solution number */
+
+ for(i = 0; i < ranks; ++i) { /* Loop through all ranks */
+ for(j = 0; j < files; ++j) { /* Loop through all files */
+ putchar(' '); /* Output a space */
+ if(j == queen[i]) putchar('Q'); /* Output Q for queen... */
+ else putchar('-'); /* or '-' if empty */
+ }
+ putchar('\n'); /* Break line */
+ }
+ fflush(stdout); /* Flush solution to output */
+ }
+
+
+ /*-------------------------- find() ----------------------------
+ ** FIND is the recursive heart of the program, and finds all
+ ** solutions given a set of level-1 fixed queen positions.
+ ** The routine moves a single queen through all files (columns)
+ ** at the current rank (recursion level). As the queen is moved,
+ ** conflict tests are made. If the queen can be placed without
+ ** conflict, then the routine recurses to the next level. When
+ ** all queens have been placed without conflict, a solution is
+ ** counted and reported.
+ */
+ void find(register int level)
+ {
+ register int f; /* Indexes through files */
+ register int *fp, *fdp, *bdp; /* Ptrs to file/diagonal entries */
+
+ #ifdef MPW /* Macintosh MPW ONLY */
+ if(level & 7 == 0) /* Periodically break for... */
+ SpinCursor(1); /* background processing */
+ #endif
+
+ if(level == queens) { /* Placed all queens? Stop. */
+ ++solutions; /* This is a solution! */
+ if(printing) pboard(); /* Print board if printing */
+ if(!findall) exit(0); /* May stop after first solution */
+ #ifdef MPW /* Macintosh MPW ONLY */
+ SpinCursor(1); /* background processing */
+ #endif
+ }
+ else { /* Not at final level yet */
+ for( /* Move queen through all files */
+ f = 0, /* Queen starts at left (file 0) */
+ fp = file, /* Ptr to base of file array */
+ fdp = &fordiag[level], /* Ptr to first fwd diag entry */
+ bdp = &bakdiag[level+files-1] /* Ptr to first bak diag entry */
+ ;
+ f < files /* Loop through all files */
+ ;
+ ++f, /* Advance index */
+ ++fp, ++fdp, --bdp /* Advance pointers */
+ ) {
+ if(*fp >= level && /* No queen on the file? */
+ *fdp >= level && *bdp >= level /* No queens on diagonals? */
+ ) {
+ queen[level] = f; /* Note new position of queen */
+ *fp = *fdp = *bdp = level; /* Place queen on file & diags */
+ find(level+1); /* This level OK, recurse to next */
+ *fp = *fdp = *bdp = EMPTY; /* Remove queen from file & diags */
+ } /* End of conflict test */
+ } /* End of file loop */
+ } /* End if (level == queens) */
+ }
+
+
More information about the llvm-commits
mailing list