1 / 12

The compilation process

The compilation process. To produce assembly code: gcc –S test.c produces test.s To produce object code: gcc –c test.c produces test.o To produce executable code: gcc test.c produces a.out. The purpose of a linker.

velasco
Download Presentation

The compilation process

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The compilation process • To produce assembly code: gcc –S test.c • produces test.s • To produce object code: gcc –c test.c • produces test.o • To produce executable code: gcc test.c • produces a.out

  2. The purpose of a linker • The linker is a program that takes one or more object files and assembles them into a single executable program. • The linker resolves references to undefined symbols by finding out which other object defines the symbol in question, and replaces placeholders with the symbol's address.

  3. Loader • Before we can start executing a program, the O/S must load it: • Loading involves 5 steps: • Allocates memory for the program's execution • Copies the text and data segments from the executable into memory • Copies program arguments (command line arguments) onto the stack • Initializes registers: sets $sp to point to top of stack, clears the rest • Jumps to start routine, which: 1) copies main's arguments off of the stack, and 2) jumps to main.

  4. Compiler • Purpose: convert high-level code into low-level assembly • Four key steps: lexing  parsing  code optimizations  code generation • Code generation: • instruction selection (depends on ISA; easier for RISC or CISC?) • instruction scheduling (later in the course, CS 433) • register allocation (today’s topic)  CS 421, 426 

  5. Register allocation • The compiler initially produces “intermediate” code that assumes an infinite number of registers $t0, $t1, … and maps each variable to a unique register • To get actual code, variables must share registers • Suppose there are only 3 real registers $t1, $t2, $t3 • An easy case: every scope defines at most three variables • But scope is an over-estimate, as in this example: // a, b, c defined in this scope for(int i = 0; i < a; i += b) // stuff c = 0; c is not live here live  in scope, converse not true

  6. Live variable analysis • A variable x is live at a point p in the code if: • x is defined at point d “” p • x is read at a point r “” p • x is not redefined between p and r • Intuitively, x holds a value that may be needed in the future • Liveness computed at compile time • may have to over-estimate liveness (for correctness) • If at some point p, number_of_live_variables(p)  number_of_registers, we obviously have to spill some variables to memory • Is the converse true?

  7. Example • Consider the following code snippet: a = 0; b = a + 1; c = b + 1; a = c + 1; • We define a graph G where • vertices are variables • edge between two variables if their live regions overlap • We want to assign variables to registers so that two variables that share an edge are not assigned the same register a a  $t1 loop: b c b  $t2 c  $t1 Graph coloring j loop At most two live variables Suppose we have two registers $t1, $t2

  8. Graph Coloring • Color the vertices of a graph with k colors so that no two neighboring vertices get the same color • A tree is always 2-colorable • A map is always 4-colorable • There isn’t an efficient way to decide if a graph is 3-colorable • unless “P = NP” (the biggest open problem in CS!) • Fortunately, there are some efficient heuristics that can produce a near-optimal coloring

  9. Which variables should be spilled? • Register Allocation Problem asks two key questions: • Are we forced to spill registers? • Yes iff min_colors(graph)  number_of_registers • If so, which registers should we spill? • Also hard to compute optimum • Before good heuristics for graph coloring, register allocation was hard for RISC architectures with many registers • Now we have good graph coloring heuristics, so the focus shifts to the second problem • much more critical with CISC architectures with few registers

  10. Excess-k notation • A method for representing signed integers • add excess amount k to every number to obtain a positive integer (smallest number that can be represented is k) • most significant bit represents sign (1 = positive, 0 = negative) • Examples (excess-128): 1 0 1 0 0 0 0 1 = +33 0 1 0 1 1 1 1 1 = 33 1 0 0 0 0 0 0 0 = 0 unique representation of 0! • If bias k = 2n-1, then excess-k is almost identical to two’s complement • sign-bit reversed (1 means positive) • comparing integers identical to the unsigned case • Big endian (MSB first) vs. little endian (LSB first) 128 64 32 16 8 4 2 1

  11. Floating Point Numbers • How can we represent 3.14 ? • What’s wrong with: (int_part, frac_part) • 3.14 and 3.014 have the same representation! • The leading-zeroes problem can be solved if numbers are normalized • write the number in the form d.f  10e , d is a single non-zero digit • normalized(3.14) = 3.14  100, normalized(0.314) = 3.14  101 • In binary, the “d” part will always be 1 (zero is a special case) • this implicit 1 can be ignored • Ideal representation scheme has these features: • can represent positive and negative, low and high magnitude • it is easy to compare two numbers • it is easy to do basic math

  12. single precision float 1 sign bit 1 = negative 0 = positive 8-bit exponent e excess-127 notation 23-bit fraction f double precision double 1 sign bit 1 = negative 0 = positive 11-bit exponent e excess-1023 notation 52-bit fraction f IEEE 754 standard • Format for single-precision (32-bit) and double-precision (64-bit) reals • The normalized (non-zero) binary number  1.f  2e is stored as • Comparison of floats almost identical to comparison of ints! • MIPS has separate floating point registers and instructions

More Related