Lab 2: Construct Control Flow Graph
Construct the Control Flow Graph (CFG) from a given set of
Three Address Code (TAC) instructions.
Source code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_INS 200
#define MAX_LEN 200
// Store instructions
char irCode[MAX_INS][MAX_LEN];
int irLineNo[MAX_INS];
int leaderMarks[MAX_INS];
int blockStart[MAX_INS];
int irCount = 0, totalBlocks = 0;
// Check if instruction contains branch
int isBranchInstr(const char *stmt) {
return (strstr(stmt, "goto") || strstr(stmt,
"if"));
}
// Extract target line number
int extractTarget(const char *stmt) {
for (int i = 0; stmt[i]; i++) {
if (stmt[i] == '(') {
return atoi(&stmt[i + 1]);
}
}
return -1;
}
// Identify leaders
void findLeaders() {
leaderMarks[0] = 1; // first always leader
for (int i = 0; i < irCount; i++) {
if (isBranchInstr(irCode[i])) {
int dest = extractTarget(irCode[i]);
// mark destination as leader
for (int j = 0; j < irCount; j++) {
if (irLineNo[j] == dest) {
leaderMarks[j] = 1;
}
}
// next instruction is also leader
if (i + 1 < irCount) {
leaderMarks[i + 1] = 1;
}
}
}
}
// Generate blocks from leaders
void buildBlocks() {
for (int i = 0; i < irCount; i++) {
if (leaderMarks[i]) {
blockStart[totalBlocks++] = i;
}
}
}
// Map line → block index
int lineToBlock(int line) {
for (int i = 0; i < totalBlocks; i++) {
if (irLineNo[blockStart[i]] == line) {
return i;
}
}
return -1;
}
// Print leaders
void displayLeaders() {
printf("\nLeaders:\n");
for (int i = 0; i < irCount; i++) {
if (leaderMarks[i]) {
printf("Line (%d): %s\n", irLineNo[i],
irCode[i]);
}
}
}
// Print blocks
void displayBlocks() {
printf("\nBasic Blocks:\n");
for (int i = 0; i < totalBlocks; i++) {
printf("Block%d:\n", i);
int start = blockStart[i];
int end = (i + 1 < totalBlocks) ?
blockStart[i + 1] - 1 : irCount - 1;
for (int j = start; j <= end; j++) {
printf(" (%d) %s\n", irLineNo[j],
irCode[j]);
}
}
}
// Print CFG edges
void displayCFG() {
printf("\nControl Flow Graph (Edges):\n");
for (int i = 0; i < totalBlocks; i++) {
int start = blockStart[i];
int end = (i + 1 < totalBlocks) ?
blockStart[i + 1] - 1 : irCount - 1;
char *last = irCode[end];
if (strstr(last, "if")) {
int target = extractTarget(last);
int blk = lineToBlock(target);
if (blk != -1) {
printf("Block%d -> Block%d
(true)\n", i, blk);
}
if (i + 1 < totalBlocks) {
printf("Block%d -> Block%d
(false)\n", i, i + 1);
}
} else if (strstr(last, "goto")) {
int target = extractTarget(last);
int blk = lineToBlock(target);
if (blk != -1) {
printf("Block%d -> Block%d\n", i,
blk);
}
} else {
if (i + 1 < totalBlocks) {
printf("Block%d -> Block%d\n", i, i
+ 1);
}
}
}
}
int main() {
printf("Enter number of TAC instructions:
");
scanf("%d", &irCount);
getchar();
printf("Enter TAC instructions (with line
numbers in parentheses):\n");
for (int i = 0; i < irCount; i++) {
char buffer[MAX_LEN];
fgets(buffer, MAX_LEN, stdin);
buffer[strcspn(buffer, "\n")] = '\0';
sscanf(buffer, "(%d)", &irLineNo[i]);
char *p = strchr(buffer, ')');
if (p) p++;
while (p && *p == ' ') p++;
if (p) strcpy(irCode[i], p);
}
findLeaders();
buildBlocks();
displayLeaders();
displayBlocks();
displayCFG();
return 0;
}
Output :