Yasir Explains/Compiler Design/Intermediate Code Generation/Indirect Triples
Intermediate Code Generation

Indirect Triples

On this page

Definition: Indirect TriplesThe ExampleThe Advantage: Optimization Without RenumberingQuadruples vs Triples vs Indirect TriplesKey Points
Intermediate Code Generation

Indirect Triples

How indirect triples represent three-address code as a list of pointers (the instruction array) into a separate triple table, why this makes reordering and optimization cheap (no renumbering), and how it compares with quadruples and plain triples on one shared example.

Definition: Indirect Triples

Indirect triples represent a program as a list of pointers to triples — the instruction array — kept separately from the triple table itself. The order of execution is given by the pointer list, not by the triples' own positions.

Plain triples number each operation by its position in the table and refer to a result through that position (n). The trouble is that the position is the identity: move a triple and every (n) reference must be renumbered.

Indirect triples add one level of indirection. The triples are stored once, with fixed numbers, and a short array of pointers names them in program order. To change the program order you rearrange the pointers; the triples never move.

The Example

We translate the same assignment used throughout the chapter.

Example
x = (a + b) \* (c - d)

This compiles to four triples. Each triple holds an operator and two arguments; a result is referenced by the triple's own position (n).

Triple table

posoparg1arg2
(0)+ab
(1)-cd
(2)*(0)(1)
(3)=x(2)

With indirect triples we keep that table and add an instruction array of pointers giving the program order. (The instruction array is shown starting at address 35 to stress that its own indices are unrelated to the triple numbers.)

Example
Instruction array Triple table
35 -> (0) (0) + a b
36 -> (1) (1) - c d
37 -> (2) (2) \* (0) (1)
38 -> (3) (3) = x (2)

Execution walks the instruction array top to bottom: positions 35, 36, 37, 38, which point to triples (0), (1), (2), (3). So the program still runs a + b, then c - d, then the multiply, then the assignment — the indirection changes how order is stored, not the computation.

The Advantage: Optimization Without Renumbering

An optimizer constantly reorders, inserts, and deletes statements. With indirect triples it does this by editing only the short pointer list; the triples keep their original numbers, so every (n) reference stays valid.

Reordering — one line. Suppose we want statement (3) to run earlier. We just permute the instruction array:

Example
before: 35 -> (0) 36 -> (1) 37 -> (2) 38 -> (3)
after: 35 -> (0) 36 -> (3) 37 -> (1) 38 -> (2) (now 35,38,36,37 order)

The triple table is untouched — (2) still says \* (0) (1), and (3) still says = x (2). With plain triples, moving an operation would shift its position and force every reference to it to be renumbered.

Sharing identical triples. If the same subexpression is computed twice, both occurrences can be two pointers to the same triple. The triple exists once; the instruction array references it wherever needed — direct support for common-subexpression reuse.

Example
... -> (0) (0) + a b <- computed once
... -> (0) both instructions point here

Quadruples vs Triples vs Indirect Triples

All three encode three-address code; they differ in how a result is named and how easily code can be rearranged.

AspectQuadruplesTriplesIndirect Triples
Structure(op, arg1, arg2, result)(op, arg1, arg2); result = position (n)triple table + pointer array of positions
Stores temp names?Yes — explicit result fieldNo — result is the positionNo — result is the position
SpaceLargest (extra result field)SmallestTriples + an extra O(n) pointer array
Reorder / optimizeEasy — results are names, unaffected by positionHard — moving a triple forces renumbering of all (n) refsEasy — permute pointers only; triples never renumbered

Quadruples buy easy reordering by spending a result field on every line; indirect triples get the same flexibility by paying for one small pointer array instead, while the triples stay compact and stable.

Key Points

  • Two structures. Indirect triples = a triple table plus an instruction (pointer) array that lists triples in execution order.
  • Order lives in the pointers. The program runs in the order of the pointer array, not the order triples sit in the table.
  • No renumbering. Reorder, insert, or delete by editing the pointer array; triple numbers (n) stay fixed, so references never break.
  • Sharing. Identical triples can be pointed to from several instructions — built-in common-subexpression reuse.
  • Cost. One extra O(n) array of pointers, in exchange for cheap reordering — unlike plain triples, which are compact but painful to optimize.