Guest User

Untitled

a guest
Apr 25th, 2018
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.18 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "s3inst.h"
  5. #include "cmdline.h"
  6. #include "functions.h"
  7.  
  8. extern int num_errors;
  9. extern int yyerror();
  10. extern int yywrap();
  11. extern int yyparse();
  12. extern int cmdlex();
  13. extern int count;
  14.  
  15. void c_optimize(void);
  16. void codegen_entry(FILE *fptr);
  17. void codegen_exit(FILE *fptr);
  18. void find_function(void);
  19. void print_inst(FILE*, inst_t, ddg_t *ddg);
  20. void print_list(FILE*, inst_t, ddg_t *ddg);
  21.  
  22. inst_t instList; /* list of instructions found by parser */
  23. int last_cycle;
  24. int previous_type;
  25.  
  26. int main(int argc, char **argv) {
  27. arglim = argv + argc;
  28. targv = argv + 1;
  29.  
  30. cmdlex();
  31.  
  32. if (outfile == NULL)
  33. outfile = strdup("out.asm");
  34.  
  35. if (infile[0]) {
  36. c_optimize();
  37. }
  38.  
  39. return 0;
  40. }
  41.  
  42. void c_optimize() {
  43. /* file pointer to dump output code */
  44. FILE *fptr = fopen(outfile, "w");
  45. block_array cfg;
  46. ddg_t ddg;
  47. inst_t *inst_list;
  48. inst_t list;
  49. int min_index;
  50. int max_index, length;
  51. inst_t *temp_list;
  52. int i;
  53. #ifdef MULTIOP
  54. int offset = 0;
  55. int max_cycle;
  56. #endif
  57.  
  58. codegen_entry(fptr);
  59.  
  60. yywrap();
  61. yyparse();
  62.  
  63. if (num_errors > 0)
  64. return;
  65.  
  66. if (verbose)
  67. print_list(stdout, instList, &ddg);
  68.  
  69. find_function(); /* remove extra instructions needed for simulation */
  70.  
  71. /************************************************************************/
  72. /************************************************************************/
  73. /************************************************************************/
  74. /************************************************************************/
  75. /* Call your implementation from here */
  76.  
  77. /* Find single basic block loops and perform Iterative Modulo Scheduling */
  78.  
  79. //count--; // decrement counter for .opt files
  80.  
  81. for (list = instList; list->op != OP_RET; list = list->next);
  82. count = list->count + 1;
  83.  
  84. list = instList;
  85.  
  86. inst_list = (inst_t*) malloc(count * sizeof (inst_t));
  87.  
  88. for (i = 0; i < count; inst_list[i++] = NULL); // initialize list of instructions to NULL
  89.  
  90. while (list) {
  91. inst_list[list->count] = list;
  92. list = list->next;
  93. }
  94.  
  95. last_cycle = -1;
  96. previous_type = -1;
  97. cfg = generate_cfg();
  98. ddg = generate_ddg();
  99.  
  100. calcLiveness(&cfg);
  101.  
  102. for (min_index = 0; inst_list[min_index] == NULL; min_index++);
  103. while (min_index < count) {
  104. max_index = min_index;
  105. while (inst_list[max_index] != NULL) {
  106. if (inst_list[max_index]->next != NULL) {
  107. if (inst_list[max_index]->next->label || inst_list[max_index]->next->op == OP_BR)
  108. break;
  109. } else
  110. break;
  111.  
  112. max_index++;
  113. }
  114. length = max_index - min_index + 1;
  115.  
  116. temp_list = (inst_t*) malloc(length * sizeof (inst_t));
  117. for (i = 0; i < length; i++) {
  118. temp_list[i] = inst_list[min_index + i];
  119. }
  120.  
  121. calc_depth(temp_list, 0, length - 1);
  122.  
  123. free(temp_list);
  124.  
  125. if (inst_list[max_index]->next != NULL)
  126. if (inst_list[max_index]->next->op == OP_BR)
  127. max_index++;
  128.  
  129. min_index = max_index + 1;
  130. }
  131.  
  132. sort_by_depth(inst_list);
  133.  
  134. ddg.ready_cycle = (int *) malloc(count * sizeof (int));
  135. ddg.schedule_time = (int *) malloc(count * sizeof (int));
  136.  
  137. for (i = 0; i < count; ddg.schedule_time[i++] = -1);
  138. for (i = 0; i < count; ddg.ready_cycle[i++] = 0);
  139.  
  140. #ifdef MULTIOP
  141. for (min_index = 0; inst_list[min_index] == NULL; min_index++);
  142. while (min_index < count) {
  143. max_index = min_index;
  144. while (inst_list[max_index] != NULL) {
  145. if (inst_list[max_index]->next != NULL) {
  146. if (inst_list[max_index]->next->label || inst_list[max_index]->next->op == OP_BR)
  147. break;
  148. } else
  149. break;
  150.  
  151. max_index++;
  152. }
  153. length = max_index - min_index + 1;
  154.  
  155. temp_list = (inst_t*) malloc(length * sizeof (inst_t));
  156. for (i = 0; i < length; i++) {
  157. temp_list[i] = inst_list[min_index + i];
  158. }
  159.  
  160. #ifdef debug
  161. for (i = 0; i <= length - 1; i++) {
  162. if (temp_list[i]->label)
  163. printf("%s\n", temp_list[i]->label);
  164. printf("%d", temp_list[i]->op);
  165. if (temp_list[i]->op == OP_BRA)
  166. printf(" branch here!\n");
  167. else
  168. printf("\n");
  169. }
  170. #endif
  171.  
  172. max_cycle = cycle_schedule(temp_list, &ddg, w, 0, length - 1, offset);
  173.  
  174. if (inst_list[max_index]->next != NULL) {
  175. if (inst_list[max_index]->next->op == OP_BR) {
  176. ddg.schedule_time[inst_list[max_index]->next->count] = max_cycle;
  177. offset = max_cycle + 1;
  178. max_index++;
  179. } else
  180. offset = 0;
  181. }
  182.  
  183. if (inst_list[max_index]->op == OP_BRA) {
  184. ddg.schedule_time[inst_list[max_index]->count] = max_cycle - 1;
  185. }
  186.  
  187. free(temp_list);
  188. min_index = max_index + 1;
  189. }
  190. #endif
  191.  
  192. /*inst_t list;
  193. for (list = instList; list; list = list->next) {
  194. if (list->label)
  195. printf("%s:\t", list->label);
  196.  
  197. printf("%d\n", list->depth);
  198. }*/
  199.  
  200. sort_by_cycle(&ddg, inst_list);
  201.  
  202. if (flag_regalloc) {
  203. // perform register allocation
  204. printf("Perform register allocation.\n"); // REMOVE ME
  205. }
  206.  
  207. if (flag_sched) {
  208. // perform scheduling
  209. printf("Perform scheduling.\n"); // REMOVE ME
  210. }
  211.  
  212.  
  213. /************************************************************************/
  214. /************************************************************************/
  215. /************************************************************************/
  216. /************************************************************************/
  217.  
  218. print_list(fptr, instList, &ddg); /* dump code to output file */
  219.  
  220. codegen_exit(fptr);
  221. fclose(fptr); /* close file */
  222. }
  223.  
  224. /**************************************************************************
  225. * Support for generating code
  226. */
  227.  
  228. void codegen_entry(FILE *fptr) {
  229. fprintf(fptr, "\t.ORIG x2000\n");
  230. fprintf(fptr, "\tJSR main\n");
  231. fprintf(fptr, "\tHALT\n");
  232. }
  233.  
  234. void codegen_exit(FILE *fptr) {
  235. fprintf(fptr, "\t.END\n");
  236. }
  237.  
  238. void find_function() {
  239. /* Need to remove first three instructions */
  240. inst_t tmp, tmp1, tmp2;
  241. inst_t oldhead;
  242. int found = 0;
  243.  
  244. if (instList->op == OP_ORIG) {
  245. tmp = instList->next;
  246. if (tmp->op == OP_JSR && strcmp(tmp->ops[0].label, "main") == 0) {
  247. tmp = tmp->next;
  248. if (tmp->op == OP_HALT) {
  249. found = 1;
  250. tmp = tmp->next;
  251. while (instList != tmp) {
  252. oldhead = instList;
  253. instList = instList->next;
  254. free(oldhead);
  255. }
  256. }
  257. }
  258. }
  259.  
  260. if (!found) {
  261. printf("Warning: Beginning of input not in the expected format!\n");
  262. }
  263.  
  264. /* Remove last instruction: END */
  265. tmp = instList;
  266. tmp1 = tmp;
  267. tmp2 = tmp1;
  268. while (tmp != NULL) {
  269. tmp2 = tmp1;
  270. tmp1 = tmp;
  271. tmp = tmp->next;
  272. }
  273.  
  274. if (tmp1->op == OP_END && tmp2 != tmp1) {
  275. tmp2->next = NULL;
  276. free(tmp1);
  277. } else {
  278. /*printf("Warning: Did not find .END.\n");*/
  279. }
  280. }
  281.  
  282. void print_cc(FILE *fptr, int ccode) {
  283. if (ccode & CC_N)
  284. fprintf(fptr, "n");
  285. if (ccode & CC_Z)
  286. fprintf(fptr, "z");
  287. if (ccode & CC_P)
  288. fprintf(fptr, "p");
  289.  
  290. fprintf(fptr, " ");
  291. }
  292.  
  293. void print_op(FILE *fptr, struct operand op) {
  294. enum op_type t = op.t;
  295. switch (t) {
  296. case op_reg:
  297. fprintf(fptr, "R%d", op.reg);
  298. break;
  299. case op_imm:
  300. fprintf(fptr, "#%d", op.imm);
  301. break;
  302. case op_label:
  303. fprintf(fptr, "%s", op.label);
  304. break;
  305. }
  306. }
  307.  
  308. void print_inst(FILE* fptr, inst_t i, ddg_t *ddg) {
  309. #ifdef debug
  310. fprintf(fptr, "count = %d\t", i->count);
  311. fprintf(fptr, "depth = %d\t", i->depth);
  312. #endif
  313.  
  314. int current_cycle = ddg->schedule_time[i->count];
  315. #ifdef debug
  316. if (i->label)
  317. printf("%s\n", i->label);
  318. //printf("current cycle = %d\n", current_cycle);
  319. //printf("last cycle = %d\n", last_cycle);
  320. printf("depth = %d\n", i->depth);
  321. #endif
  322.  
  323. #ifdef MULTIOP
  324. if (current_cycle == last_cycle) {
  325. fprintf(fptr, " . ");
  326.  
  327. if (previous_type == OP_BR || previous_type == OP_SET)
  328. fprintf(fptr, "\t");
  329. else if (previous_type == OP_OUT || previous_type == OP_IN)
  330. fprintf(fptr, "\t\t");
  331. } else if (last_cycle != -1)
  332. #endif
  333. fprintf(fptr, "\n");
  334.  
  335. if (i->label) {
  336. fprintf(fptr, "%s:", i->label);
  337. }
  338.  
  339. if (i->op == OP_BR) {
  340. fprintf(fptr, "\t%s", opnames[i->op]);
  341. print_cc(fptr, i->ccode);
  342. } else
  343. fprintf(fptr, "\t%s ", opnames[i->op]);
  344.  
  345. switch (i->op) {
  346.  
  347. /* 3 operands */
  348. case OP_ADD:
  349. case OP_AND:
  350. case OP_ANDL:
  351. case OP_DIV:
  352. case OP_LDR:
  353. case OP_MUL:
  354. case OP_OR:
  355. case OP_ORL:
  356. case OP_STR:
  357. case OP_SUB:
  358. print_op(fptr, i->ops[0]);
  359. fprintf(fptr, ", ");
  360. print_op(fptr, i->ops[1]);
  361. fprintf(fptr, ", ");
  362. print_op(fptr, i->ops[2]);
  363. break;
  364. /* 2 operands */
  365. case OP_BR:
  366. case OP_SET:
  367. case OP_ST:
  368. case OP_STI:
  369. case OP_LD:
  370. case OP_LDI:
  371. case OP_LEA:
  372. case OP_NOT:
  373. case OP_NOTL:
  374. print_op(fptr, i->ops[0]);
  375. fprintf(fptr, ", ");
  376. print_op(fptr, i->ops[1]);
  377. break;
  378.  
  379. /* one operand */
  380. case OP_JSRR:
  381. case OP_BRA:
  382. case OP_JMP:
  383. case OP_JSR:
  384. print_op(fptr, i->ops[0]);
  385.  
  386. default:
  387. break;
  388. }
  389. last_cycle = current_cycle;
  390. previous_type = i->op;
  391. //fprintf(fptr, "\n");
  392. }
  393.  
  394. void print_list(FILE *fptr, inst_t head, ddg_t *ddg) {
  395. int max_latency = 1;
  396. int curr_sched;
  397. int prev_sched = 0;
  398.  
  399. while (head) {
  400.  
  401. #ifdef debug
  402. if (head->label)
  403. printf("%s\n", head->label);
  404. printf("%d\n", ddg->schedule_time[head->count]);
  405. #endif
  406.  
  407. curr_sched = ddg->schedule_time[head->count];
  408.  
  409. if (curr_sched == prev_sched)
  410. max_latency = max(latency(head), max_latency);
  411. else if (head->op == OP_RET) {
  412. while (max_latency != 1) {
  413. fprintf(fptr, "\n\tNOP");
  414. max_latency--;
  415. }
  416. } else {
  417. max_latency = latency(head);
  418. }
  419.  
  420. print_inst(fptr, head, ddg);
  421.  
  422. prev_sched = ddg->schedule_time[head->count];
  423.  
  424. head = head->next;
  425. }
  426. fprintf(fptr, "\n");
  427. }
Add Comment
Please, Sign In to add comment