DSC Report
DSC Report
Feb 2024
Bangalore – 560054
SUBMITTED BY
Joann Mary Joseph 1MS22CS072
P. Nitya Reddy 1MS22CS098
Pranshu Saraswat 1MS22CS105
SUPERVISED BY
Faculty
Ms. Manjula Raghu
1
Department of Computer Science and Engineering
Ramaiah Institute of Technology
(Autonomous Institute, Affiliated to VTU)
Bangalore – 54
CERTIFICATE
This is to certify that Joann M. Joseph: 1MS22CS072, P.Nitya Reddy: 1MS22CS098 and
Pranshu Saraswat: 1MS22CS105 have completed the “Design and implementation of a queue
compiler” as part of Technical Codethan. We declare that the entire content embodied in this B.E. 3rd
Semester report contents are not copied.
Guided by-
Ms. Manjula Raghu
Submitted by
Name: USN:
Joann M. Joseph 1MS22CS072
2
Department of Computer Science and Engineering
Ramaiah Institute of Technology
(Autonomous Institute, Affiliated to VTU)
Bangalore – 54
Evaluation Sheet
Evaluated By
Name: Ms. Manjula Raghu
Department: Computer Science & Engineering, RIT
Signature: HOD, CSE
3
Table of Contents
Page No
1. Abstract 5
2. Introduction 6
3. Literature Survey 7
5. Implementation 10
7. Conclusion 18
8. References 19
4
Chapter 1
Abstract:
• Queue processors are a viable alternative for high performance embedded computing and parallel
processing. We present the design and implementation of a compiler for a queue-based processor.
Instructions of a queue processor implicitly reference their operands making the programs free of false
dependencies. Compiling for a queue machine differs from traditional compilation methods for
register machines. The queue compiler is responsible for scheduling the program in level-order
manner to expose natural parallelism and calculating instructions relative offset values to access their
operands..
The foundation of the compiler lies in the Queue Computational Model, utilizing a queue to manage the
flow of instructions and their dependencies. LDAGs represent the program's structure, where each node
corresponds to an instruction, and edges define their order of execution. Symbolic execution is employed
to track the Queue Head (QH) position, vital for accurate instruction scheduling.
• The heart of the compiler is its instruction scheduling algorithm, which strategically orders
instructions to reduce pipeline stalls and improve overall program performance. Offset calculation
ensures proper memory access, and the final output is optimized assembly code tailored for the target
architecture.
• Users interact with the compiler by providing high-level code, allowing the system to generate
LDAGs, perform symbolic execution, and produce optimized assembly code. The project aims to
deliver improved performance, portability across architectures, and a user-friendly interface for
seamless interaction.
• In conclusion, this project presents an innovative compiler design, leveraging the Queue
Computational Model to enhance instruction scheduling. Through LDAGs, symbolic execution, and
careful algorithmic design, the compiler strives to contribute to the generation of efficient and
optimized machine code, addressing the evolving needs of modern computing environments.
5
Chapter 2
Introduction
2.1 Introduction
2.2 Evaluation:
An evaluation of the queue compiler's performance is presented, assessing its effectiveness in generating
efficient and compact code. This section provides insights into the compiler's capabilities and limitations
based on experimental results.
6
Chapter 3
LITERATURE SURVEY-
3.1 Queue computing overview
Queue computing, distinguished by its reliance on a first-in-first-out (FIFO) queue, offers a unique approach
to expression evaluation.
The proposed infrastructure employs algorithms and data structures to maintain code generation
independence, emphasizing level-order scheduling of programs and instruction offset calculation as unique
features.
3.3 Code Size Analysis: Code size was measured from the object code's text segment, considering the small,
two-byte instructions. Normalized code size results reveal that on average, queue programs exhibit
approximately 30% higher code density compared to fully optimized register machine code. Ongoing work
includes exploring additional classical optimizations to further enhance these results.
3.4 Compile-Time Parallelism: To gauge compile-time parallelism, we maintained the same compiler
configuration and measured the exposed parallelism. On average, the queue compiler, even without ILP
optimizations, demonstrated approximately 7% more parallelism compared to fully optimized register code.
We anticipate that integrating advanced ILP optimizations into the queue compiler could further enhance ILP
extraction, considering the machine-independent nature of these transformations, potentially benefiting queue
programs.
7
Chapter 4
ADT Queue {
data: array or linked list to store elements
capacity: maximum number of elements the queue can hold
size: current number of elements in the queue
operations:
- enqueue(element): Add an element to the rear of the queue
- dequeue(): Remove and return the element from the front of the queue
- front(): Return the element at the front of the queue without removing it
- isEmpty(): Check if the queue is empty
- isFull(): Check if the queue is full
- size(): Return the current size of the queue
}
4.2 Leveled Directed Acyclic Graph Node (LDAGNode) Abstract Data Type (ADT):
ADT LDAGNode {
operation: symbol representing the operation of the node ('+', '*', '/', etc.)
operand: symbol representing the operand or variable ('A', 'B', 'C', etc.)
level: level of the node in the LDAG
qhPosition: position of the Queue Head (QH) relative to the node
4.3 Leveled Directed Acyclic Graph (LDAG) Abstract Data Type (ADT):
8
ADT LDAG {
root: pointer to the root node of the LDAG
operations:
- createNode(operation, operand, level): Create a new LDAG node with the given attributes
- addChild(parent, child): Add a child node to a parent node in the LDAG
- removeNode(node): Remove a node from the LDAG
- traverseLevelOrder(): Traverse the LDAG in level-order fashion
- symbolicExecution(): Perform symbolic execution to track QH positions in the LDAG
- calculateDistance(u, v): Calculate the distance between two nodes in the LDAG
- calculateQHPosition(u): Calculate the QH position relative to a node in the LDAG
- calculateOffsetReference(instruction, operand): Calculate the offset reference value for an
operand
}
9
Chapter 5
IMPLEMENTATION
#include <stdio.h>
#include <stdlib.h>
typedef struct LDAGNode {
char operation; // Operation symbol: '+', '*', '/'
char operand; // Variable symbol: 'A', 'B', 'C', 'D'
int level; // Level of the node in the LDAG
int qhPosition; // QH position relative to the node
struct LDAGNode* left;
struct LDAGNode* right;
} LDAGNode;
typedef struct QueueNode {
LDAGNode* node;
struct QueueNode* next;
} QueueNode;
typedef struct {
QueueNode* front;
QueueNode* rear;
} Queue;
// Function to create a new LDAG node
LDAGNode* createNode(char operation, char operand, int level) {
LDAGNode* newNode = (LDAGNode*)malloc(sizeof(LDAGNode));
newNode->operation = operation;
newNode->operand = operand;
newNode->level = level;
newNode->qhPosition = 0;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
Queue* createQueue() {
Queue* queue = (Queue*)malloc(sizeof(Queue));
10
queue->front = NULL;
queue->rear = NULL;
return queue;
}
void printQueueContent(Queue* queue) {
QueueNode* temp = queue->front;
while (temp != NULL) {
printf("%c\t",temp->node->operation);
temp = temp->next;
}
}
void enqueue(Queue* queue, LDAGNode* node) {
QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
newNode->node = node;
newNode->next = NULL;
if (queue->rear == NULL) {
queue->front = newNode;
queue->rear = newNode;
} else {
queue->rear->next = newNode;
queue->rear = newNode;
}
}
void enqueueInOrder(Queue* queue, LDAGNode* node) {
if (node != NULL) {
enqueueInOrder(queue, node->left);
enqueue(queue, node);
enqueueInOrder(queue, node->right);}}
void symbolicExecution(LDAGNode* root, int qhPosition) {
if (root != NULL) {
// Assign QH position
root->qhPosition = qhPosition;
int count = 0;
int front = 0, rear = 0;
LDAGNode* queue[100]; // Assuming a maximum of 100 nodes in the LDAG
// Process the current node (you can count, print, or perform other operations)
count++;
return count;
}
12
int calculateQHPosition(LDAGNode* u) {
return u->qhPosition;
}
// Function to calculate the distance between two nodes in a LDAG
int calculateDistance(LDAGNode* u, LDAGNode* v) {
if (u == NULL || v == NULL) {
return -1; // Invalid input
}
// Initialize a distance array to track the distance from the source node u
int* distanceArray = (int*)malloc(sizeof(int) * 100); // Assuming a maximum of 100 nodes
for (int i = 0; i < 100; i++) {
distanceArray[i] = -1; // Initialize distances to -1 (indicating not visited)
}
// Explore neighbors
if (current->left != NULL && distanceArray[current->left->level] == -1) {
queue[rear++] = current->left;
distanceArray[current->left->level] = distanceArray[current->level] + 1;
}
return distance;
}
int main() {
LDAGNode* root = createNode('/', '\0', 1);
root->left = createNode('+', '\0', 2);
root->left->left = createNode('A', 'A', 3);
root->left->right = createNode('*', '\0', 3);
root->left->right->left = createNode('B', 'B', 4);
root->left->right->right = createNode('C', 'C', 4);
root->right = createNode('D', 'D', 2);
14
printf("Calculating levels-\n");
printLDAGNodeLvl(root);
// Perform level-order traversal and count nodes
int nodeCount = countNodesInLevelOrder(root);
printf("\n");
printf("Number of nodes in LDAG: %d\n\n", nodeCount);
15
Chapter 6
RESULTS
16
DISCUSSIONS-
The Queue Compiler project pioneers a revolutionary approach to code generation tailored for the distinctive
queue computation model, characterized by first-in-first-out (FIFO) queue operations.
1. Offset Calculation: Given the absence of explicit registers, the compiler introduces offset references
for operands. Leveled Directed Acyclic Graphs (LDAGs) efficiently manage data dependencies,
enabling effective offset calculation. The project introduces schemes to handle offset references
exceeding the maximum allowed, ensuring correctness and efficiency.
2. Instruction Scheduling: Operating on LDAGs, the scheduling algorithm generates a linear low-level
intermediate representation (QTL) in level order. Reflecting the nature of the queue computation
model, QTL emphasizes a single operand per instruction, augmented by annotations facilitating
machine-dependent transformations.
3. Performance Evaluation: Code size and instruction-level parallelism (ILP) analyses affirm the
compiler's efficacy. Queue programs exhibit superior code density compared to optimized register
machine code. Despite lacking ILP optimizations, the compiler demonstrates notable parallelism,
hinting at further improvement possibilities through advanced ILP techniques.
Future Implementations :
• The Queue Compiler project lays a formidable foundation, inviting future implementations to refine
functionality, enhance performance, and broaden versatility. Optimization strategies hold promise for
significant code generation improvements.
• Language support can be extended beyond the current scope, enhancing the compiler's versatility.
Additional front-ends for diverse programming languages would broaden the user base and encourage
the adoption of the queue computation model across various application domains.
CONCLUSION-
The queue compiler adeptly addresses the challenges inherent in code generation for queue-based
architectures, presenting an innovative solution through the construction of a robust data flow graph
representation. Leveraging well-chosen data structures, the compiler efficiently calculates essential conditions
The Queue Compiler infrastructure emerges as a pioneering solution for the unique challenges posed by the
queue computation model. Through meticulous phases of AST parsing, instruction selection, offset
calculation, instruction scheduling, and assembly generation, the compiler seamlessly transforms high-level C
language constructs into optimized assembly code for the QueueCore processor. The versatility of the
infrastructure, coupled with its machine-independent design, positions it as a powerful tool for the evolving
landscape of queue-based computing. As the field continues to progress, this compiler stands ready to
contribute to the efficient translation of diverse applications into executable code for queue processors,
18
REFERENCES
• [1] B. Abderazek, S. Kawata, M. Sowa, Design and architecture for an embedded 32-bit QueueCore,
Journal of Embedded Computing 2 (2) (2006) 191–205.
• [2] B. Abderazek, T. Yoshinaga, M. Sowa, High-level modeling and FPGA prototyping of produced
order parallel queue processor core, Journal of Supercomputing 38 (1) (2006) 3–15.
• [3] V. Agarwal, M. Hrishikesh, S.W. Keckler, D. Burger, Clock rate versus ipc: the end of the road for
conventional microarchitectures, ACM SIGARCH Computer Architecture News 28 (2) (2000) 248–259.
• [4] A.V. Aho, R. Sethi, J.D. Ullman, Compilers Principles, Addison-Wesley, 1986.
• [5] R. Allen, K. Kennedy, Optimizing Compilers for Modern Architectures, Morgan Kaufman, 2002.
• [6] D. Burger, S.W. Keckler, K.S. McKinley, M. Dahlin, L.K. John, C. Lin, C.R. Moore, J. Burrill, R.
McDonald, W. Yoder, Scaling to the end of silicon with EDGE architectures, IEEE Computer 37 (7)
(2004) 45–55.
• [7] A. Canedo, Code Generation Algorithms for Consumed and Produced Order Queue Machines,
Master’s Thesis, University of Electro-Communications, Tokyo, Japan, September 2006.
• [8] A. Canedo, B. Abderazek, M. Sowa, A new code generation algorithm for 2 offset producer order
queue computation model, Journal of Computer Languages, Systems and Structures 34 (4) (2008)
184–194.
• [9] A. Canedo, B. Abderazek, M. Sowa, A GCC-based compiler for the queue register processor, in:
Proceedings of International Workshop on Modern Science and Technology, Wuhan, China, May
2006, pp. 250–255.
19