CHƯƠNG VII: MÔI TRƯỜNG THỜI GIAN THỰC HIỆNI.CHƯƠNG TRÌNH CONII.TỔ CHỨC BỘ NHỚIII.CHIESN LƯỢC CẤP PHÁT BỘ NHỚIV.TRUY XUẤT TÊN KHÔNG CỤC BỘV.TRUYỀN THAM SỐVI.BẢN KÝ HIỆUCHƯƠNG VIII: SINH MÃ TRUNG GIANI.NGÔN NGỮ TRUNG GIANII.KHAI BÁOIII.LỆNH GÁNIV.BIỂU THỨC LOGICV.LỆNH CASECHƯƠNG IX: SINH MÃ ĐÍCHI.CÁC VẤN ĐÈ VỀ THIẾT KẾ BỘ SINH MÃII.MÁY ĐÍCHIII.QUẢN LÝ BỘ NHỚ TRONG THỜI GIAN THỰC HIỆNIV.KHỐI CƠ BẢN VÀ LƯU ĐỒV.THÔNG TIN SỬ DỤNG TIẾPVI.BỘ SINH MÃ ĐƠN GIẢNVVIVII
CHƯƠNG VII MÔI TRƯỜNG THỜI GIAN THỰC HIỆN I CHƯƠNG TRÌNH CON Ðịnh nghĩa chương trình Ðịnh nghĩa chương trình khai báo Dạng đơn giản kết hợp tên chương trình thân Khi tên chương trình xuất phần thân chương trình ta nói chương trình gọi điểm s Cây hoạt động Trong q trình thực chương trình thì: Dòng điều khiển tuần tự: tức việc thực chương trình bao gồm chuỗi bước Tại bước có điều khiển xác định Việc thực chương trình bắt đầu điểm bắt đầu thân chương trình trả điều khiển cho chương trình gọi điểm nằm sau lời gọi việc thực chương trình kết thúc Thời gian tồn chương trình p chuỗi bước bước bước cuối thực thân chương trình bao gồm thời gian thực chương trình gọi p Nếu a b hai hoạt động hai chương trình tương ứng thời gian tồn chúng tách biệt lồng Một chương trình đệ quy hoạt động bắt đầu trước hoạt động trước chương trình kết thúc Ðể đặc tả cách thức điều khiển vào hoạt động chương trình ta dùng cấu trúc gọi hoạt động Mỗi nút biểu diễn cho hoạt động chương trình Nút gốc biểu diễn cho hoạt động chương trình Nút a cha b dòng điều khiển hoạt động từ a sang b Nút a bên trái nút b thời gian tồn a xuất trước thời gian tồn b Ngăn xếp điều khiển Dòng điều khiển chương trình tương ứng với phép duyệt theo chiều sâu hoạt độ ng Bắt đầu từ nút gốc, thăm nút trước thăm cách quy nút từ trái sang phải Chúng ta dùng Stack, gọi Stack điều khiển, để lưu trữ hoạt động chương trình Khi hoạt động chương trình bắt đầu đẩy nút tương ứng với hoạt động lên đỉnh Stack Khi hoạt động kết thúc pop nút khỏi Stack Nội dung Stack thể đường dẫn đến nút gốc hoạt động Khi nút n nằm đỉnh Stack Stack chứa nút nằm đường từ n đến gốc Tầm vực khai báo Ðoạn chương trình chịu ảnh hưởng khai báo gọi tầm vực khai báo Trong chương trình có nhiều khai báo trùng tên ví dụ biến i chương trình sort Các khai báo độc lập với chịu chi phối quy tắc tầm ngôn ngữ vực khai báo nằm chương trình con, ngược lại gọi không cục (nonlocal) Liên kết tên Trong ngơn ngữ ngơn ngữ lập trình, thuật ngữ môi trường (enviroment) để ánh xạ từ tên đến vị trí nhớ thuật ngữ trạng thái (state) để ánh xạ từ vị trí nhớ tới giá trị lưu trữ Môi trường khác trạng thái: lệnh gán làm thay đổi trạng thái không thay đổi môi trường Khi mơi trường kết hợp vị trí nhớ s với tên x ta nói x liên kết tới s Sự kết hợp gọi mối liên kết x Liên kết động (dynamic counterpart) khai báo Chúng ta có tương ứng ký hiệu động tĩnh: Các vấn đề cần quan tâm Sự xuất tên chương trình gọi cục (local) chương trình tầm m chương trình dịch Các vấn đề cần đặt tổ chức lưu trữ liên kết tên: Chương trình đệ quy khơng? Ðiều xảy cho giá trị tên cục trả điều khiển từ hoạt động chương trình Một chương trình tham khảo tới tên cục không? Các tham số truyền gọi chương trình Một chương trình truyền tham số? Một chương trình trả kết quả? Bộ nhớ có cấp phát động khơng? Bộ nhớ có phải giải phóng cách tường minh? II TỔ CHỨC BỘ NHỚ Tổ chức nhớ thời gian thực sử dụng cho ngôn ngữ Fortran, Pascal C Phân chia nhớ thời gian thực Bộ nhớ chia để lưu trữ phần: Mã đích Ðối tượng liệu Bản Stack điều khiển để lưu trữ hoạt động chương trình Trong đ ó kích thước mã đích xác định thời gian dịch cấp phát tĩnh vùng thấp nhớ Tương tự kích thước mộ t số đối tượng liệu biết thời gian dịch cấp phát tĩnh Cài đặt ngôn ngữ Pascal, C dùng mở rộng Stack điều khiển để quản lý hoạt động chương trình Khi có lời gọi chương trình con, thể hoạt động bị ngắt thơng tin tình trạng máy, chẳng hạn giá trị đếm chương trình (program counter) ghi lưu vào Stack Khi điều khiển trả từ lời gọi, hoạt động tiếp tục sau khôi phục lại giá trị ghi đặt đếm chương trình vào sau lời gọi Ðối tượng liệu mà thời gian tồn chứa hoạt động lưu Stack Một vùng khác nhớ gọi Heap lưu trữ tất thông tin khác Mẩu tin hoạt động Thông tin cần thiết để thực chương trình quản lý cách dùng mẩu tin hoạt động bao gồm số trường sau : Giá trị tạm thời: lưu giữ trình đánh giá biểu thức Dữ liệu cục bộ: Lưu trữ liệu cục thực chương trình Trạng thái máy: lưu giữ thông tin trạng thái máy trước chương trình gọi Thơng tin máy bao gồm đếm chương trình ghi lệnh mà phục hồi điều khiển trả từ chương trình Liên kết truy nhập: tham khảo tới liệu không cục lưu mẩu tin hoạt động khác Liên kết điều khiển: trỏ tới mẩu tin hoạt động chương trình gọi Các tham số thực tế: sử dụng chương trình gọi chương trình gọi Thơng thường tham số lưu ghi mẩu tin hoạt động Giá trị trả về: dùng chương trình gọi để trả cho chương trình gọi giá trị Trong thực tế giá trị thường trả ghi III CHIẾN LƯỢC CẤP PHÁT BỘ NHỚ Ðối với vùng nhớ khác tổ chức nhớ, ta có chiến lược cấp phát khác : Cấp phát tĩnh cho tất đối tượng liệu thời gian dịch Cấp phát sử dụng Stack cho nhớ thời gian thực Ðối với vùng liệu Heap sử dụng cấp phát thu hồi dạng Heap Cấp phát tĩnh Trong cấp phát tĩnh, tên liên kết với vùng nhớ lúc chương trình dịch Vì mối liên kết không thay đổi thời gian chạy nên lần chương trình kích hoạt, tên liên kết với vùng nhớ Tính chất cho phép giá trị tên cục giữ lại thông qua hoạt động chương trình Từ kiểu tên, trình biên dịch xác định kích thước nhớ Do trình biên dịch xác định vị trí mẩu tin kích hoạt đoạn mã chương trình mẩu tin kích hoạt khác Trong thời gian biên dịch, điền vào đoạn địa mà mã lệnh tìm đến để truy xuất liệu Tương tự địa vùng lưu trữ thơng tin chương trình gọi xác định thời gian dịch Tuy nhiên cấp phát tĩnh có số hạn chế sau: Kích thước vị trí đối tượng liệu nhớ phải xác định thời gian dịch Khơng cho phép gọi đệ quy tất kích hoạt chương trình dùng chung liên kết tên cục Cấu trúc liệu cấp phát động khơng có chế để cấp phát thời gian thực Cấp phát ô nhớ sử dụng Stack Bộ nhớ tổ chức Stack Các mẩu tin kích hoạt push vào Stack hoạt động bắt đầu pop khỏi Stack hoạt động kết thúc Bộ nhớ cho liệu cục lần gọi chương trình chứa mẩu tin kích hoạt cho lần gọi Như tên cục liên kết với nhớ hoạt động, mẩu tin kích hoạt push vào Stack có lời gọi chương trình Dữ liệu biến cục bị xóa bỏ thực chương trình kết thúc Giả sử ghi top đánh dấu đỉnh Stack Tại thời gian thực mẩu tin kích hoạt cấp phát thu hồi cách tăng giảm ghi top bằòng kích thước mẩu tin kích hoạt Gọi thực chương trình Gọi chương trình thực lệnh gọi mã đích - lệnh gọi cấp phát mẩu tin kích hoạt đưa thông tin vào cho trường - lệnh trở phục hồi trạng thái máy để chương trình gọi tiếp tục thực Hình mơ tả mối quan hệ mẩu tin kích hoạt chương trình gọi chương trình bị gọi Mỗi mẩu tin có ba trường chủ yếu: tham số thực tế trị trả về, mối liên kết trạng thái máy cuối trường liệu tạm cục Thanh ghi top.sp đến cuối trường mối liên kết trạng thái máy Vị trí biết chương trình gọi Ðoạn mã cho chương trình bị gọi truy xuất liệu tạm cục cách sử dụng độ dời (offsets) từ top.sp Lệnh gọi thực công việc sau : Chương trình gọi đánh giá tham số thực tế Chương trình gọi lưu địa trả giá trị cũ top.sp vào mẩu tin kích hoạt chương trình bị gọi Sau tăng giá trị top.sp Chương trình gọi lưu giá trị ghi thông tin trạng thái khác Chương trình gọi khởi tạo liệu cục bắt đầu thực Lệnh trả thực cơng việc sau: Chương trình bị gọi gởi giá trị trả vào mẩu tin kích hoạt chương trình gọi Căn vào thơng tin trường trạng thái, chương trình bị gọi khơi phục top_sp giá trị ghi truyền tới địa trả mã chương trình gọi Mặc dù top_sp bị giảm, chương trình gọi cần chép giá trị trả vào mẩu tin kích hoạt để sử dụng cho việc tính tốn biểu thức Dữ liệu có kích thước thay đổi Một số ngôn ngữ cho phép liệu có kích thước thay đổi Chẳng hạn chương trình p có mảng có kích thước thay đổi, mảng lưu trữ ngồi mẩu tin kích hoạt p Trong mẩu tin kích hoạt p chứa trỏ trỏ tới điểm bắt đầu mảng Ðịa tương đối trỏ biết thời gian dịch nên mã đích truy nhập tới phần tử mảng thơng qua trỏ Hình sau trình bày chương trình q gọi p Mẩu tin kích hoạt q nằm sau mảng p Truy nhập vào liệu Stack thông qua hai trỏ top, top.sp: top đỉnh Stack nơi mẩu tin kích hoạt bắt đầu top_sp dùng để tìm liệu cục Cấp phát Heap Chiến thuật cấp phát sử dụng Stack không đáp ứng yêu cầu sau: Giá trị tên cục giữ lại hoạt động chương trình kết thúc Hoạt động chương trình bị gọi tồn sau chương trình gọi Các yêu cầu cấp phát thu hồi theo chế LIFO (Last – In, First – Out) tức tổ chức theo Stack Heap khối ô nhớ liên tục chia nhỏ để cấp phát cho mẩu tin kích hoạt đối tượng liệu khác Sự khác cấp phát Stack Heap chỗ mẩu tin cho hoạt động giữ lại hoạt động kết thúc Về mặt vật lý, mẩu tin kích hoạt cho q(1,9) khơng phụ thuộc mẩu tin kích hoạt cho r Khi mẩu tin kích hoạt cho r bị giải phóng quản lý Heap dùng vùng nhớ tự để cấp phát cho mẩu tin khác Một số vấn đề thuộc quản lý hiệu Heap trình bày mục VIII IV TRUY XUẤT TÊN KHÔNG CỤC BỘ Quy tắc tầm vực Quy tắc tầm vực ngôn ngữ xác định việc xử lý tham khảo đến tên không cục Quy tắc tầm vực bao gồm hai loại: Quy tắc tầm tĩnh quy tắc tầm động Quy tắc tầm tĩnh (static - scope rule): Xác định khai báo áp dụng cho tên cách kiểm tra văn chương trình nguồn Các ngơn ngữ Pascal, C Ada sử dụng quy tắc tầm tĩnh với quy định bổ sung: “tầm gần nhất” Cấu trúc khối Một khối bắt đầu tập hợp khai báo cho tên (khai báo biến, định nghĩa kiểu, định nghĩa ) sau tập hợp lệnh mà tên tham khảo Cấu trúc khối thường sử dụng ngôn ngữ cấu trúc Pascal, Ada, PL/1 Trong chương trình hay chương trình tổ chức thành khối lồng Ngôn ngữ cấu trúc khối sử dụng quy tắc tầm tĩnh Tầm khai báo cho quy tắc tầm gần (most closely nested) Một khai báo đầu khối xác định tên cục khối Bất kỳ tham khảo tới tên thân khối xem xét tham khảo tới liệu cục khối tồn Nếu tên x tham khảo thân khối B x không khai báo B x xem tham khảo tới khai báo B’ khối nhỏ chứa B Nếu B’ khơng có khai báo cho x lại tham khảo tới B’’ khối nhỏ chứa B’ Nếu khối chứa định nghĩa khối khác khai báo khối hoàn toàn bị che dấu khối ngồi Cấu trúc khối cài đặt cách sử dụng chế cấp phát Stack Khi điều khiển vào khối nhớ cho tên cấp phát chúng bị thu hồi điều khiển rời khỏi khối Tầm tĩnh với chương trình khơng lồng Quy tắc tầm tĩnh ngôn ngữ C đơn giản so với Pascal định nghĩa chương trình C khơng lồng Một chương trình C chuỗi khai báo biến hàm Nếu có tham khảo không cục đến tên a hàm a phải tham khảo bên tất hàm Tất tên khai báo bên ngồi hàm Đều cấp phát tĩnh Vị trí nhớ biết thời gian dịch tham khảo tới tên không cục thân hàm xác định địa tuyệt đối Các tên cục hàm nằm mẩu tin hoạt động đỉnh Stack xác định cách sử dụng địa tương đối Tầm tĩnh với chương trình lồng Trong ngơn ngữ Pascal chương trình lồng nhiều cấp Liên kết truy xuất Ðể cài đặt tầm tĩnh cho chương trình lồng ta dùng trỏ liên kết truy xuất mẩu tin kích hoạt Nếu chương trình p lồng trực tiếp q liên kết mẩu tin kích hoạt p trỏ tới liên kết truy xuất mẩu tin kích hoạt hành q Liên kết truy xuất s rỗng s khơng có bao đóng Liên kết truy xuất mẩu tin kích hoạt chương trình trỏ đến mẩu tin kích hoạt bao đóng Giả sử chương trình p có độ lồng sâu np tham khảo tới tên khơng cục a có độ lồng sâu na cần hạ hai cấp Từ p(1,3) hạ cấp đến q(1,3) theo liên kết truy xuất Từ q(1,3) hạ cấp đến s theo liên kết truy xuất đến s nơi a khai báo Ðể xác định v cần tính np- nv = 3- = => cần hạ cấp xuốn q(1,3) nơi v khai báo Giả sử chương trình p có độ lồng sâu np gọi chương trình e độ lồng sâu ne Ðoạn mã để thiết lập liên kết truy xuất phụ thuộc vào việc chương trình gọi có định nghĩa chương trình gọi hay khơng? Trường hợp 1: np < ne: Chương trình e có độ lồng sâu lớn chương trình p e lồng p p tham khảo đến e (e bị che dấu khỏi p) Ví dụ sort gọi quickort, quicksort gọi partition Trường hợp 2: np >= ne: chương trình e có độ lồng sâu nhỏ độ lồng sâu chương trình p Theo quy tắc tầm tĩnh p tham khảo e Ví dụ quicksort gọi nó, partition gọi exchange Từ chương trình gọi np-ne +1 bước làm theo liên kết truy nhập ta tìm mẩu tin kích hoạt bao đóng gần chứa chương trình gọi chương trình gọi Chẳng hạn p(1,3) gọi e(1,3), np =3, ne =2 Ta phải làm - + hai bước theo liên kết truy xuất từ p đến s Display: để truy xuất nhanh tên không cục người ta dùng mảng d trỏ tới mẩu tin kích hoạt mảng gọi display Giả sử điều khiển nằm hoạt động chương trình t có độ lồng sâu j j-1 phần tử display trỏ tới mẩu tin kích hoạt bao đóng gần p d[j] trỏ tới kích hoạt p Một tên khơng cục a có độ sâu I nằm mẩu tin kích hoạt trỏ d[i] (a): Tình trạng trước q(1,3) bắt đầu, quicksort có độ lồng sâu cấp 2, d[2] gửi cho mẩu tin kích hoạt quick sort bắt đầu giá trị d[2] lưu mẩu tin kích hoạt q(1,9) (b): Khi q(1,3) bắt đầu d[2] trỏ tới mẩu tin kích hoạt mức ứng với q(1,3), giá trị d[2] lại lưu mẩu tin Giá trị cần thiết để phục hồi display cũ điều khiển trả cho q(1,9) Như mẩu tin kích họat đẩy vào Stack thì: - Lưu giá trị d[i] vào mẩu tin - Ðặt d[i] trỏ tới mẩu tin Khi mẩu tin pop khỏi Stack d[i] phục hồi Giả sử chương trình có độ lồng sâu cấp j gọi chương trình có độ lồng sâu cấp i Có hai trường hợp xảy phụ thuộc chương trình gọi có định nghĩa chương trình gọi hay không Trường hợp 2: j < i => i = j + 1: thêm ô nhớ d[i], cấp phát mẩu tin kích hoạt cho chương trình I, ghi d[i] vào đặt d[i] trỏ tới Trường hợp 2: j >= i: Ghi giá trị cũ d[i] vào mẩu tin kích hoạt đặt d[i] trỏ vào mẩu tin cuối Tầm động Với khái niệm tầm động, hoạt động kế thừa liên kết tồn tên không cục Tên không cục a hoạt động chương trình gọi tham khảo đến ô nhớ hoạt động chương trình gọi Ðối với tên cục liên kết thiết lập tới ô nhớ mẩu tin hoạt động V TRUYỀN THAM SỐ Khi chương trình gọi chương trình khác phương pháp thông thường để giao tiếp chúng thông qua tên không cục thông qua tham số chương trình gọi Ví dụ 7.10: Ðể đổi hai giá trị a[i] a[j] cho ta dùng (1) procedure exchange(i,j : integer); (2) var x : integer; (3) begin (4) (5) x := a[i]; a[i] := a[j]; a[j] := x; end; mảng a tên khơng cục i,j tham số Có nhiều phương pháp truyền tham số MOV # Stackstart, SP /* khởi động Stack */ Ðoạn mã cho chương trình HALT /* kết thúc thực thi */ Trong thị MOV #Stackstart, SP khởi động Stack theo cách đặt SP với địa bắt đầu Stack vùng nhớ Chuỗi gọi tăng giá trị SP, lưu giữ địa trả chuyển quyền điều khiển chương trình gọi ADD # caller.recordsize, SP MOV # here + 16, *SP /* lưu địa trả */ GOTO callee.code_area Thuộc tính caller.recordsize biểu diễn kích thước mẩu tin hoạt động Vì thế, thị ADD đưa SP trỏ tới phần bắt đầu mẩu tin hoạt động #here +16 thị MOV địa thị theo sau GOTO, lưu địa trỏ SP Chuỗi trả gồm hai thị: Chương trình chuyển quyền điều khiển tới địa trả GOTO *0(SP) /* trả chương trình gọi */ SUB Trong O(SP) địa ô nhớ mẩu tin hoạt động *O(SP) trả địa lưu Chỉ thị SUB #caller.recordsize, SP: Giảm giá trị SP xuống khoảng kích thước mẩu tin hoạt động chương trình gọi Như mẩu tin hoạt động chương trình bị gọi xóa khỏi Stack Ðịa tên thời gian thực Chiến lược cấp phát lưu trữ xếp đặt liệu cục mẩu tin hoạt động chương trình xác định cách thức truy xuất vùng nhớ tên Nếu dùng chế cấp phát tĩnh với vùng liệu cấp phát địa static Với lệnh gán x := 0, địa tương đối x bảng danh biểu 12 Vậy địa x nhớ static + 12 Lệnh gán x:=0 chuyển sang mã ba địa static[12] := Nếu vùng liệu bắt đầu địa 100, mã đích cho thị là: MOV #0,112 Nếu ngôn ngữ dùng chế display để truy xuất tên không cục bộ, giả sử x tên cục chương trình hành ghi R3 lưu giữ địa bắt đầu mẩu tin hoạt động dịch lệnh x := sang chuỗi mã ba địa chỉ: t1 := 12 + R3 * t1 := Từ ta chuyển sang mã đích: MOV #0, 12(R3) Chú ý rằng, giá trị ghi R3 không xác định thời gian biên dịch IV KHỐI CƠ BẢN VÀ LƯU ÐỒ Ðồ thị biểu diễn lệnh ba địa chỉ, gọi lưu đồ, giúp ta hiểu giải thuật sinh mã đồ thị không xác định cụ thể giải thuật sinh mã Các nút lưu đồ biểu diễn tính tốn, cạnh biểu diễn dòng điều khiển Khối Khối (basic block) chuỗi lệnh dòng điều khiển vào lệnh khối lệnh cuối khối mà không bị dừng rẽ nhánh Ví dụ chuỗi lệnh ba địa sau tạo nên khối t1 := a * a t2 := a * b t3 := * t2 t4 := t1 + t2 t5 := b * b t6 := t4 + t5 Lệnh ba địa x := y + z dùng giá trị chứa vị trí nhớ y, z để thực phép cộng xác định địa x để lưu kết phép cộng vào Một tên khối gọi ‘sống‘ điểm giá trị sử dụng sau điểm chương trình dùng khối khác Giải thuật sau phân chia chuỗi lệnh ba địa sang khối Giải thuật 9.1: Phân chia khối Input: Các lệnh ba địa Output: Danh sách khối với chuỗi lệnh ba địa cho khối Phương pháp: Xác định tập lệnh dẫn đầu (leader), lệnh khối bản, ta dùng quy tắc sau: i) Lệnh lệnh dẫn đầu ii) Bất kỳ lệnh đích nhảy đến lệnh GOTO có điều kiện khơng điều kiện lệnh dẫn đầu iii) Bất kỳ lệnh sau lệnh GOTO có điều kiện không điều kiện lệnh dẫn đầu Với lệnh dẫn đầu, khối gồm có tất lệnh không gồm lệnh dẫn đầu khác lệnh kết thúc chương trình Sự chuyển đổi khối Khối tính biểu thức Các biểu thức giá trị tên “sống” khỏi khối Hai khối tương đương chúng tính biểu thức giống Một số chuyển đổi áp dụng vào khối mà không làm thay đổi biểu thức tính tốn Nhiều phép chuyển đổi có ích cải thiện chất lượng mã đích sinh từ khối Hai phương pháp chuyển đổi cục quan trọng áp dụng cho khối chuyển đổi bảo toàn cấu trúc chuyển đổi đại số Chuyển đổi bảo toàn cấu trúc Những chuyển đổi bảo toàn cấu trúc khối bao gồm: Loại bỏ biểu thức chung Loại bỏ mã chết Ðặt tên lại biến tạm Hoán đổi hai lệnh độc lập kề Giả sử khối không chứa dãy, trỏ hay lời gọi chương trình Loại bỏ biểu thức chung Khối sau: a := b + c b := a d c := b + c d := a-d Câu lệnh thứ hai thứ tư tính biểu thức b + c - d Vì vậy, khối chuyển thành khối tương đương sau: a := b + c b := a d c := b + c d := b Loại bỏ mã lệnh chết Giả sử x khơng sử dụng Nếu câu lệnh x := y + z xuất khối lệnh bị loại mà không làm thay đổi giá trị khối Ðặt lại tên cho biến tạm Giả sử ta có lệnh t := b + c với t biến tạm Nếu ta viết lại lệnh thành u := b + c mà u biến tạm thay t u chỗ xuất t giá trị khối không bị thay đổi Thực tế, ta chuyển khối sang khối tương đương Và ta gọi khối tạo dạng chuẩn Giả sử khối với hai câu lệnh kế tiếp: t1 := b + c t2 := x +y Ta hốn đổi hai lệnh mà khơng làm thay đổi giá trị khối x y t1 b c t2 Khối có dạng chuẩn cho phép tất lệnh có quyền hốn đổi Chuyển đổi đại số Các biểu thức khối chuyển đổi sang biểu thức tương đương Phép chuyển đổi đại số giúp ta đơn giản hoá biểu thức thay biểu thức có giá cao biểu thức có giá rẻ Chẳng hạn, câu lệnh x := x + x := x * loại bỏ khỏi khối mà không làm thay đối giá trị biểu thức Toán tử lũy thừa câu lệnh x := y ** cần lời gọi hàm để thực Tuy nhiên, lệnh thay lệnh tương đương có giá rẻ mà không cần lời gọi hàm Lưu đồ Ta thêm thơng tin dòng điều khiển vào tập khối việc xây dựng đồ thị trực tiếp gọi lưu đồ (flew graph) Các nút lưu đồ khối Một nút gọi khởi đầu chứa lệnh chương trình Cạnh nối trực tiếp từ khối B1 đến khối B2 B2 khối đứng sau B1 chuỗi thực Nghĩa là, nếu: Lệnh nhảy khơng có điều kiện từ lệnh cuối B1 đến lệnh B2 đứng sau B1 thứ tự chương trình B1 khơng kết thúc lệnh nhảy không điều kiện Chúng ta nói B1 tiền bối (predecessor) B2 hay B2 hậu duệ (sucecssor) B1 Ví dụ prod := i := B1 t1 := * i B2 t2 := a[t1] t3 := * i t4 := b[t3] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i +1 i := t7 if i, >=,,